mirror of
https://github.com/CCExtractor/ccextractor.git
synced 2024-12-25 04:11:38 +00:00
Custom TTXT
Almost done, still left to do: - update telxx.c to reflect changes - add new commandline parameter + parsing. 608 & XDS are working already for normal & UCLA mode, nothing broken/changed output wise.
This commit is contained in:
parent
0d463342f3
commit
a0f9387889
132
src/608.c
132
src/608.c
@ -360,79 +360,81 @@ void write_cc_line_as_transcript(struct eia608_screen *data, struct s_context_cc
|
||||
}
|
||||
if (length>0)
|
||||
{
|
||||
if (timestamps_on_transcript)
|
||||
if (context->ts_start_of_current_line == -1)
|
||||
{
|
||||
const char *mode="???";
|
||||
switch (context->mode)
|
||||
{
|
||||
case MODE_POPON:
|
||||
mode="POP";
|
||||
break;
|
||||
case MODE_FAKE_ROLLUP_1:
|
||||
mode="RU1";
|
||||
break;
|
||||
case MODE_ROLLUP_2:
|
||||
mode="RU2";
|
||||
break;
|
||||
case MODE_ROLLUP_3:
|
||||
mode="RU3";
|
||||
break;
|
||||
case MODE_ROLLUP_4:
|
||||
mode="RU4";
|
||||
break;
|
||||
case MODE_TEXT:
|
||||
mode="TXT";
|
||||
break;
|
||||
case MODE_PAINTON:
|
||||
mode="PAI";
|
||||
break;
|
||||
}
|
||||
// CFS: Means that the line has characters but we don't have a timestamp for the first one. Since the timestamp
|
||||
// is set for example by the write_char function, it possible that we don't have one in empty lines (unclear)
|
||||
// For now, let's not consider this a bug as before and just return.
|
||||
// fatal (EXIT_BUG_BUG, "Bug in timedtranscript (ts_start_of_current_line==-1). Please report.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (context->ts_start_of_current_line == -1)
|
||||
{
|
||||
// CFS: Means that the line has characters but we don't have a timestamp for the first one. Since the timestamp
|
||||
// is set for example by the write_char function, it possible that we don't have one in empty lines (unclear)
|
||||
// For now, let's not consider this a bug as before and just return.
|
||||
// fatal (EXIT_BUG_BUG, "Bug in timedtranscript (ts_start_of_current_line==-1). Please report.");
|
||||
return;
|
||||
if (ccx_options.transcript_settings.showStartTime){
|
||||
char buf1[80];
|
||||
if (ccx_options.transcript_settings.relativeTimestamp){
|
||||
millis_to_date(context->ts_start_of_current_line + subs_delay, buf1);
|
||||
fdprintf(context->out->fh, "%s|", buf1);
|
||||
}
|
||||
if (ccx_options.ucla_settings)
|
||||
{
|
||||
else {
|
||||
mstotime(context->ts_start_of_current_line + subs_delay, &h1, &m1, &s1, &ms1);
|
||||
mstotime (get_fts()+subs_delay,&h2,&m2,&s2,&ms2);
|
||||
|
||||
// SSC-1182 BEGIN
|
||||
// Changed output format to be more like ZVBI
|
||||
|
||||
char buffer[80];
|
||||
time_t start_time_int = (context->ts_start_of_current_line + subs_delay) / 1000;
|
||||
int start_time_dec = (context->ts_start_of_current_line + subs_delay) % 1000;
|
||||
struct tm *start_time_struct = gmtime(&start_time_int);
|
||||
strftime(buffer, sizeof(buffer), "%Y%m%d%H%M%S", start_time_struct);
|
||||
fdprintf(context->out->fh, "%s.%03d|", buffer, start_time_dec);
|
||||
|
||||
time_t end_time_int = (get_fts()+subs_delay)/1000;
|
||||
int end_time_dec = (get_fts()+subs_delay)%1000;
|
||||
struct tm *end_time_struct = gmtime(&end_time_int);
|
||||
strftime(buffer, sizeof(buffer), "%Y%m%d%H%M%S", end_time_struct);
|
||||
fdprintf(context->out->fh, "%s.%03d|", buffer, end_time_dec);
|
||||
|
||||
fdprintf(context->out->fh, "CC%d|%s|", context->my_field == 1 ? context->channel : context->channel + 2, // Data from field 2 is CC3 or 4
|
||||
mode);
|
||||
// SSC-1182 END
|
||||
struct tm *start_time_struct = gmtime(&start_time_int);
|
||||
strftime(buf1, sizeof(buf1), "%Y%m%d%H%M%S", start_time_struct);
|
||||
fdprintf(context->out->fh, "%s%c%03d|", buf1,ccx_options.millis_separator,start_time_dec);
|
||||
}
|
||||
else
|
||||
{
|
||||
char buf1[80], buf2[80];
|
||||
char timeline[256];
|
||||
millis_to_date(context->ts_start_of_current_line + subs_delay, buf1);
|
||||
millis_to_date (get_fts()+subs_delay, buf2);
|
||||
sprintf (timeline, "%s|%s|%s|",
|
||||
buf1, buf2,mode);
|
||||
enc_buffer_used=encode_line (enc_buffer,(unsigned char *) timeline);
|
||||
write(context->out->fh, enc_buffer, enc_buffer_used);
|
||||
}
|
||||
}
|
||||
|
||||
if (ccx_options.transcript_settings.showEndTime){
|
||||
char buf2[80];
|
||||
if (ccx_options.transcript_settings.relativeTimestamp){
|
||||
millis_to_date(get_fts() + subs_delay, buf2);
|
||||
fdprintf(context->out->fh, "%s|", buf2);
|
||||
}
|
||||
else {
|
||||
mstotime(get_fts() + subs_delay, &h2, &m2, &s2, &ms2);
|
||||
time_t end_time_int = (get_fts() + subs_delay) / 1000;
|
||||
int end_time_dec = (get_fts() + subs_delay) % 1000;
|
||||
struct tm *end_time_struct = gmtime(&end_time_int);
|
||||
strftime(buf2, sizeof(buf2), "%Y%m%d%H%M%S", end_time_struct);
|
||||
fdprintf(context->out->fh, "%s%c%03d|", buf2,ccx_options.millis_separator,end_time_dec);
|
||||
}
|
||||
}
|
||||
|
||||
if (ccx_options.transcript_settings.showCC){
|
||||
fdprintf(context->out->fh, "CC%d|", context->my_field == 1 ? context->channel : context->channel + 2); // Data from field 2 is CC3 or 4
|
||||
}
|
||||
|
||||
if (ccx_options.transcript_settings.showMode){
|
||||
const char *mode = "???";
|
||||
switch (context->mode)
|
||||
{
|
||||
case MODE_POPON:
|
||||
mode = "POP";
|
||||
break;
|
||||
case MODE_FAKE_ROLLUP_1:
|
||||
mode = "RU1";
|
||||
break;
|
||||
case MODE_ROLLUP_2:
|
||||
mode = "RU2";
|
||||
break;
|
||||
case MODE_ROLLUP_3:
|
||||
mode = "RU3";
|
||||
break;
|
||||
case MODE_ROLLUP_4:
|
||||
mode = "RU4";
|
||||
break;
|
||||
case MODE_TEXT:
|
||||
mode = "TXT";
|
||||
break;
|
||||
case MODE_PAINTON:
|
||||
mode = "PAI";
|
||||
break;
|
||||
}
|
||||
|
||||
fdprintf(context->out->fh, "%s|", mode);
|
||||
}
|
||||
|
||||
write(context->out->fh, subline, length);
|
||||
write(context->out->fh, encoded_crlf, encoded_crlf_length);
|
||||
}
|
||||
|
@ -11,11 +11,16 @@ void xds_cea608_test();
|
||||
|
||||
struct ccx_s_options ccx_options;
|
||||
|
||||
#define TRANSCRIPT_PREDEFINED_SETTINGS_COUNT 10
|
||||
|
||||
ccx_transcript_format ccx_transcript_predefined_settings[TRANSCRIPT_PREDEFINED_SETTINGS_COUNT] = {
|
||||
{ .name = "General", .showTimes = 1, .showStartTime = 1, .showEndTime = 1, .relativeTimestamp = 1, .xds = 0, .useColors = 1 }, // This one will be used as default.
|
||||
{ .name = "UCLA", .showTimes = 1, .showStartTime = 1, .showEndTime = 1, .relativeTimestamp = 0, .xds = 1, .useColors = 1 } // Predefined one for the UCLA project.
|
||||
// These are the default settings for plain transcripts. No times, no CC or caption mode, and no XDS.
|
||||
ccx_transcript_format ccx_default_transcript_settings =
|
||||
{
|
||||
.showStartTime = 0,
|
||||
.showEndTime = 0,
|
||||
.showCC = 0,
|
||||
.showMode = 0,
|
||||
.relativeTimestamp = 1,
|
||||
.xds = 0,
|
||||
.useColors = 1
|
||||
};
|
||||
|
||||
extern unsigned char *filebuffer;
|
||||
@ -83,7 +88,6 @@ LLONG fts_at_gop_start=0;
|
||||
|
||||
/* Time info for timed-transcript */
|
||||
LLONG ts_start_of_xds=-1; // Time at which we switched to XDS mode, =-1 hasn't happened yet
|
||||
int timestamps_on_transcript=0; /* Write time info on transcripts? */
|
||||
uint64_t utc_refvalue=UINT64_MAX; /* _UI64_MAX means don't use UNIX, 0 = use current system time as reference, +1 use a specific reference */
|
||||
|
||||
int max_gop_length=0; // (Maximum) length of a group of pictures
|
||||
@ -137,7 +141,6 @@ void init_options (struct ccx_s_options *options)
|
||||
/* Levenshtein's parameters, for string comparison */
|
||||
options->levdistmincnt=2; // Means 2 fails or less is "the same"...
|
||||
options->levdistmaxpct=10; // ...10% or less is also "the same"
|
||||
options->export_xds=0; // Export XDS to transcript?
|
||||
options->investigate_packets = 0; // Look for captions in all packets when everything else fails
|
||||
options->fullbin=0; // Disable pruning of padding cc blocks
|
||||
options->nosync=0; // Disable syncing
|
||||
@ -153,7 +156,8 @@ void init_options (struct ccx_s_options *options)
|
||||
options->teletext_mode=CCX_TXT_AUTO_NOT_YET_FOUND; // 0=Disabled, 1 = Not found, 2=Found
|
||||
|
||||
options->ucla_settings=0; // Enables convenient settings for UCLA's project.
|
||||
options->transcript_settings = ccx_transcript_predefined_settings[0];
|
||||
|
||||
options->transcript_settings = ccx_default_transcript_settings;
|
||||
options->millis_separator=',';
|
||||
options->screens_to_process=-1; // How many screenfuls we want?
|
||||
options->encoding = CCX_ENC_UTF_8;
|
||||
@ -527,7 +531,7 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
}
|
||||
|
||||
if (ccx_options.export_xds)
|
||||
if (ccx_options.transcript_settings.xds)
|
||||
{
|
||||
if (ccx_options.write_format==CCX_OF_TRANSCRIPT)
|
||||
{
|
||||
|
@ -35,15 +35,17 @@ struct ccx_boundary_time
|
||||
|
||||
typedef struct {
|
||||
// TODO: add more options, and (perhaps) reduce other ccextractor options?
|
||||
char name[20]; // Unique identifier for easy access to a predefined setting
|
||||
int showTimes; // Show times or not
|
||||
int showStartTime, showEndTime; // Show start and/or end time. showTimes must be 1 for this.
|
||||
int showStartTime, showEndTime; // Show start and/or end time.
|
||||
int showCC; // Show which CC channel has been captured.
|
||||
int showMode; // Show which mode if available (E.G.: POP, RU1, ...)
|
||||
int relativeTimestamp; // Timestamps relative to start of sample or in UTC?
|
||||
int xds; // Show XDS or not
|
||||
int useColors; // Add colors or no colors
|
||||
|
||||
} ccx_transcript_format;
|
||||
|
||||
extern ccx_transcript_format ccx_default_transcript_settings;
|
||||
|
||||
struct ccx_s_options // Options from user parameters
|
||||
{
|
||||
int extract; // Extract 1st, 2nd or both fields
|
||||
@ -80,7 +82,6 @@ struct ccx_s_options // Options from user parameters
|
||||
int messages_target; // 0 = nowhere (quiet), 1=stdout, 2=stderr
|
||||
/* Levenshtein's parameters, for string comparison */
|
||||
int levdistmincnt, levdistmaxpct; // Means 2 fails or less is "the same", 10% or less is also "the same"
|
||||
int export_xds; // Export XDS to transcript?
|
||||
int investigate_packets; // Look for captions in all packets when everything else fails
|
||||
int fullbin; // Disable pruning of padding cc blocks
|
||||
int nosync; // Disable syncing
|
||||
@ -611,7 +612,7 @@ extern int PIDs_seen[65536];
|
||||
extern struct PMT_entry *PIDs_programs[65536];
|
||||
|
||||
extern LLONG ts_start_of_xds;
|
||||
extern int timestamps_on_transcript;
|
||||
//extern int timestamps_on_transcript;
|
||||
|
||||
extern unsigned teletext_mode;
|
||||
|
||||
|
15
src/params.c
15
src/params.c
@ -263,14 +263,17 @@ void set_output_format (const char *format)
|
||||
else if (strcmp (format,"transcript")==0 || strcmp (format,"txt")==0)
|
||||
{
|
||||
ccx_options.write_format=CCX_OF_TRANSCRIPT;
|
||||
timestamps_on_transcript=0;
|
||||
}
|
||||
else if (strcmp (format,"timedtranscript")==0 || strcmp (format,"ttxt")==0)
|
||||
{
|
||||
ccx_options.write_format=CCX_OF_TRANSCRIPT;
|
||||
if (ccx_options.date_format==ODF_NONE)
|
||||
ccx_options.date_format=ODF_HHMMSSMS;
|
||||
timestamps_on_transcript=1;
|
||||
// Sets the right things so that timestamps and the mode are printed.
|
||||
ccx_options.transcript_settings.showStartTime = 1;
|
||||
ccx_options.transcript_settings.showEndTime = 1;
|
||||
ccx_options.transcript_settings.showCC = 0;
|
||||
ccx_options.transcript_settings.showMode = 1;
|
||||
}
|
||||
else if (strcmp (format,"report")==0)
|
||||
{
|
||||
@ -1227,7 +1230,7 @@ void parse_parameters (int argc, char *argv[])
|
||||
}
|
||||
if (strcmp (argv[i],"-xds")==0)
|
||||
{
|
||||
ccx_options.export_xds=1;
|
||||
ccx_options.transcript_settings.xds = 1;
|
||||
continue;
|
||||
}
|
||||
if (strcmp (argv[i],"-xdsdebug")==0)
|
||||
@ -1388,8 +1391,12 @@ void parse_parameters (int argc, char *argv[])
|
||||
}
|
||||
if (strcmp (argv[i],"-UCLA")==0 || strcmp (argv[i],"-ucla")==0)
|
||||
{
|
||||
ccx_options.ucla_settings = 1;
|
||||
ccx_options.millis_separator='.';
|
||||
ccx_options.transcript_settings.showStartTime = 1;
|
||||
ccx_options.transcript_settings.showEndTime = 1;
|
||||
ccx_options.transcript_settings.showCC = 1;
|
||||
ccx_options.transcript_settings.showMode = 1;
|
||||
ccx_options.transcript_settings.relativeTimestamp = 0;
|
||||
continue;
|
||||
}
|
||||
if (strcmp (argv[i],"-lf")==0 || strcmp (argv[i],"-LF")==0)
|
||||
|
98
src/xds.c
98
src/xds.c
@ -151,57 +151,66 @@ void xds_write_transcript_line_prefix (struct ccx_s_write *wb)
|
||||
if (!wb || wb->fh==-1)
|
||||
return;
|
||||
|
||||
if (timestamps_on_transcript)
|
||||
if (ts_start_of_xds == -1)
|
||||
{
|
||||
const char *mode="XDS";
|
||||
if (ts_start_of_xds == -1)
|
||||
{
|
||||
// Means we entered XDS mode without making a note of the XDS start time. This is a bug.
|
||||
fatal (EXIT_BUG_BUG, "Bug in timedtranscript (XDS). Please report.");
|
||||
;
|
||||
}
|
||||
if (ccx_options.ucla_settings)
|
||||
{
|
||||
mstotime (ts_start_of_xds+subs_delay,&h1,&m1,&s1,&ms1);
|
||||
mstotime (get_fts()+subs_delay,&h2,&m2,&s2,&ms2);
|
||||
// Means we entered XDS mode without making a note of the XDS start time. This is a bug.
|
||||
fatal (EXIT_BUG_BUG, "Bug in timedtranscript (XDS). Please report.");
|
||||
;
|
||||
}
|
||||
|
||||
// SSC-1182 BEGIN
|
||||
// Changed output format to be more like ZVBI
|
||||
|
||||
char buffer[80];
|
||||
time_t start_time_int = (ts_start_of_xds+subs_delay)/1000;
|
||||
int start_time_dec = (ts_start_of_xds+subs_delay)%1000;
|
||||
struct tm *start_time_struct = gmtime(&start_time_int);
|
||||
strftime(buffer, sizeof(buffer), "%Y%m%d%H%M%S", start_time_struct);
|
||||
fdprintf(wb->fh, "%s.%03d|", buffer, start_time_dec);
|
||||
|
||||
time_t end_time_int = (get_fts()+subs_delay)/1000;
|
||||
int end_time_dec = (get_fts()+subs_delay)%1000;
|
||||
struct tm *end_time_struct = gmtime(&end_time_int);
|
||||
strftime(buffer, sizeof(buffer), "%Y%m%d%H%M%S", end_time_struct);
|
||||
fdprintf(wb->fh, "%s.%03d|", buffer, end_time_dec);
|
||||
fdprintf(wb->fh, "%s|%s|", mode,XDSclasses_short[cur_xds_packet_class]);
|
||||
// SSC-1182 END
|
||||
}
|
||||
else
|
||||
{
|
||||
if (utc_refvalue==UINT64_MAX)
|
||||
if (ccx_options.transcript_settings.showStartTime){
|
||||
char buffer[80];
|
||||
if (ccx_options.transcript_settings.relativeTimestamp){
|
||||
if (utc_refvalue == UINT64_MAX)
|
||||
{
|
||||
mstotime (ts_start_of_xds+subs_delay,&h1,&m1,&s1,&ms1);
|
||||
mstotime (get_fts()+subs_delay,&h2,&m2,&s2,&ms2);
|
||||
char timeline[256];
|
||||
sprintf (timeline, "%02u:%02u:%02u,%03u | %02u:%02u:%02u,%03u | %s | ",
|
||||
h1,m1,s1,ms1,h2,m2,s2,ms2,mode);
|
||||
enc_buffer_used=encode_line (enc_buffer,(unsigned char *) timeline);
|
||||
write (wb->fh, enc_buffer,enc_buffer_used);
|
||||
mstotime(ts_start_of_xds + subs_delay, &h1, &m1, &s1, &ms1);
|
||||
fdprintf(wb->fh, "%02u:%02u:%02u%c%03u|", h1, m1, s1, ccx_options.millis_separator, ms1);
|
||||
}
|
||||
else {
|
||||
fdprintf(wb->fh, "%lld%c%03d|", (ts_start_of_xds + subs_delay) / 1000, ccx_options.millis_separator, (ts_start_of_xds + subs_delay) % 1000);
|
||||
}
|
||||
}
|
||||
else {
|
||||
mstotime(ts_start_of_xds + subs_delay, &h1, &m1, &s1, &ms1);
|
||||
time_t start_time_int = (ts_start_of_xds + subs_delay) / 1000;
|
||||
int start_time_dec = (ts_start_of_xds + subs_delay) % 1000;
|
||||
struct tm *start_time_struct = gmtime(&start_time_int);
|
||||
strftime(buffer, sizeof(buffer), "%Y%m%d%H%M%S", start_time_struct);
|
||||
fdprintf(wb->fh, "%s%c%03d|", buffer,ccx_options.millis_separator,start_time_dec);
|
||||
}
|
||||
}
|
||||
|
||||
if (ccx_options.transcript_settings.showEndTime){
|
||||
char buffer[80];
|
||||
if (ccx_options.transcript_settings.relativeTimestamp){
|
||||
if (utc_refvalue == UINT64_MAX)
|
||||
{
|
||||
mstotime(get_fts() + subs_delay, &h2, &m2, &s2, &ms2);
|
||||
fdprintf(wb->fh, "%02u:%02u:%02u%c%03u|", h2, m2, s2, ccx_options.millis_separator, ms2);
|
||||
}
|
||||
else
|
||||
{
|
||||
fdprintf(wb->fh, "%lld.%03d|", (ts_start_of_xds+subs_delay)/1000,(ts_start_of_xds+subs_delay)%1000 );
|
||||
fdprintf(wb->fh, "%lld.%03d|", (get_fts()+subs_delay)/1000,(get_fts()+subs_delay)%1000 );
|
||||
fdprintf(wb->fh, "%lld%s%03d|", (get_fts() + subs_delay) / 1000, ccx_options.millis_separator, (get_fts() + subs_delay) % 1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
mstotime(get_fts() + subs_delay, &h2, &m2, &s2, &ms2);
|
||||
time_t end_time_int = (get_fts() + subs_delay) / 1000;
|
||||
int end_time_dec = (get_fts() + subs_delay) % 1000;
|
||||
struct tm *end_time_struct = gmtime(&end_time_int);
|
||||
strftime(buffer, sizeof(buffer), "%Y%m%d%H%M%S", end_time_struct);
|
||||
fdprintf(wb->fh, "%s%c%03d|", buffer, ccx_options.millis_separator, end_time_dec);
|
||||
}
|
||||
}
|
||||
|
||||
if (ccx_options.transcript_settings.showMode){
|
||||
const char *mode = "XDS";
|
||||
fdprintf(wb->fh, "%s|", mode);
|
||||
}
|
||||
|
||||
if (ccx_options.transcript_settings.showCC){
|
||||
fdprintf(wb->fh, "%s|", XDSclasses_short[cur_xds_packet_class]);
|
||||
}
|
||||
}
|
||||
|
||||
void xdsprint (const char *fmt,...)
|
||||
@ -637,7 +646,8 @@ int xds_do_current_and_future ()
|
||||
}
|
||||
}
|
||||
if (!(ccx_options.debug_mask & CCX_DMT_XDS) && current_program_type_reported &&
|
||||
ccx_options.export_xds==0)
|
||||
ccx_options.transcript_settings.xds == 0)
|
||||
//ccx_options.export_xds==0)
|
||||
break;
|
||||
memcpy (current_xds_program_type,cur_xds_payload,cur_xds_payload_length);
|
||||
current_xds_program_type[cur_xds_payload_length]=0;
|
||||
|
Loading…
Reference in New Issue
Block a user