From 015a50bafde606b6125aca8681893932e8e94a26 Mon Sep 17 00:00:00 2001 From: Anshul Maheshwari Date: Mon, 7 Jul 2014 17:45:12 +0530 Subject: [PATCH 1/9] put wtv specific dump in WTV_DEBUG macro --- src/ccextractor.c | 6 +++++- src/constants.h | 2 ++ src/general_loop.c | 3 ++- src/params.c | 4 ++++ src/params_dump.c | 4 ++++ src/stream_functions.c | 2 ++ src/timing.c | 2 ++ 7 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/ccextractor.c b/src/ccextractor.c index 0688c3caf..5fe45e746 100644 --- a/src/ccextractor.c +++ b/src/ccextractor.c @@ -614,9 +614,11 @@ int main(int argc, char *argv[]) case CCX_SM_MP4: mprint ("\rFile seems to be a MP4\n"); break; +#ifdef WTV_DEBUG case CCX_SM_HEX_DUMP: mprint ("\rFile seems to be an hexadecimal dump\n"); break; +#endif case CCX_SM_MYTH: case CCX_SM_AUTODETECT: fatal(EXIT_BUG_BUG, "Cannot be reached!"); @@ -693,10 +695,12 @@ int main(int argc, char *argv[]) close_input_file(); // No need to have it open. GPAC will do it for us processmp4 (inputfile[0]); break; +#ifdef WTV_DEBUG case CCX_SM_HEX_DUMP: close_input_file(); // processhex will open it in text mode - processhex (inputfile[0]); + processhex (inputfile[0]); break; +#endif case CCX_SM_AUTODETECT: fatal(EXIT_BUG_BUG, "Cannot be reached!"); break; diff --git a/src/constants.h b/src/constants.h index 0b7418ba4..902c938ef 100644 --- a/src/constants.h +++ b/src/constants.h @@ -173,7 +173,9 @@ enum ccx_stream_mode_enum CCX_SM_RCWT = 5, // Raw Captions With Time, not used yet. CCX_SM_MYTH = 6, // Use the myth loop CCX_SM_MP4 = 7, // MP4, ISO- +#ifdef WTV_DEBUG CCX_SM_HEX_DUMP = 8, // Hexadecimal dump generated by wtvccdump +#endif CCX_SM_WTV = 9, CCX_SM_AUTODETECT = 16 }; diff --git a/src/general_loop.c b/src/general_loop.c index ffda75ac6..af2b779fa 100644 --- a/src/general_loop.c +++ b/src/general_loop.c @@ -266,6 +266,7 @@ LLONG general_getmoredata(void) return bytesread; } +#ifdef WTV_DEBUG // Hexadecimal dump process void processhex (char *filename) { @@ -425,7 +426,7 @@ void processhex (char *filename) } fclose(fr); } - +#endif // Raw file process void raw_loop () { diff --git a/src/params.c b/src/params.c index 274b71e10..4e8d7dda0 100644 --- a/src/params.c +++ b/src/params.c @@ -318,8 +318,10 @@ void set_input_format (const char *format) auto_stream = CCX_SM_RCWT; else if (strcmp (format,"mp4")==0) auto_stream = CCX_SM_MP4; +#ifdef WTV_DEBUG else if (strcmp (format,"hex")==0) auto_stream = CCX_SM_HEX_DUMP; +#endif else fatal (EXIT_MALFORMED_PARAMETER, "Unknown input file format: %s\n", format); } @@ -391,7 +393,9 @@ void usage (void) mprint (" bin -> CCExtractor's own binary format.\n"); mprint (" raw -> For McPoodle's raw files.\n"); mprint (" mp4 -> MP4/MOV/M4V and similar.\n"); +#ifdef WTV_DEBUG mprint (" hex -> Hexadecimal dump as generated by wtvccdump.\n"); +#endif mprint (" -ts, -ps, -es, -mp4, -wtv and -asf (or --dvr-ms) can be used as shorts.\n\n"); mprint ("Output formats:\n\n"); mprint (" -out=format\n\n"); diff --git a/src/params_dump.c b/src/params_dump.c index 2e46aed05..298f9051e 100644 --- a/src/params_dump.c +++ b/src/params_dump.c @@ -56,9 +56,11 @@ void params_dump(void) case CCX_SM_MP4: mprint ("MP4"); break; +#ifdef WTV_DEBUG case CCX_SM_HEX_DUMP: mprint ("Hex"); break; +#endif default: fatal (EXIT_BUG_BUG, "BUG: Unknown stream mode.\n"); break; @@ -283,9 +285,11 @@ void print_file_report(void) case CCX_SM_RCWT: printf("BIN\n"); break; +#ifdef WTV_DEBUG case CCX_SM_HEX_DUMP: printf("Hex\n"); break; +#endif default: break; } diff --git a/src/stream_functions.c b/src/stream_functions.c index 38a80b3d2..9573c12fd 100644 --- a/src/stream_functions.c +++ b/src/stream_functions.c @@ -30,6 +30,7 @@ void detect_stream_type (void) startbytes[3]==0x20) stream_mode=CCX_SM_WTV; } +#ifdef WTV_DEBUG if (stream_mode==CCX_SM_ELEMENTARY_OR_NOT_FOUND && startbytes_avail>=6) { // Check for hexadecimal dump generated by wtvccdump @@ -42,6 +43,7 @@ void detect_stream_type (void) startbytes[5]=='D') stream_mode= CCX_SM_HEX_DUMP; } +#endif if (stream_mode==CCX_SM_ELEMENTARY_OR_NOT_FOUND && startbytes_avail>=11) { diff --git a/src/timing.c b/src/timing.c index 2d2b7aa69..f8b2cc62f 100644 --- a/src/timing.c +++ b/src/timing.c @@ -37,7 +37,9 @@ void set_fts(void) case CCX_SM_MCPOODLESRAW: case CCX_SM_RCWT: case CCX_SM_MP4: +#ifdef WTV_DEBUG case CCX_SM_HEX_DUMP: +#endif dif = 0; break; default: From 5371f854fc7faf0d6fd3fed807b13706d89510d2 Mon Sep 17 00:00:00 2001 From: Anshul Maheshwari Date: Fri, 11 Jul 2014 16:59:20 +0530 Subject: [PATCH 2/9] indentation of 608_srt.c --- src/608_srt.c | 203 +++++++++++++++++++++++++------------------------- 1 file changed, 101 insertions(+), 102 deletions(-) diff --git a/src/608_srt.c b/src/608_srt.c index cd6cf277c..2a5351f31 100644 --- a/src/608_srt.c +++ b/src/608_srt.c @@ -1,85 +1,84 @@ #include "ccextractor.h" - /* The timing here is not PTS based, but output based, i.e. user delay must be accounted for if there is any */ void write_stringz_as_srt (char *string, struct s_context_cc608 *context, LLONG ms_start, LLONG ms_end) { - unsigned h1,m1,s1,ms1; - unsigned h2,m2,s2,ms2; + unsigned h1,m1,s1,ms1; + unsigned h2,m2,s2,ms2; - mstotime (ms_start,&h1,&m1,&s1,&ms1); - mstotime (ms_end-1,&h2,&m2,&s2,&ms2); // -1 To prevent overlapping with next line. - char timeline[128]; - context->srt_counter++; + mstotime (ms_start,&h1,&m1,&s1,&ms1); + mstotime (ms_end-1,&h2,&m2,&s2,&ms2); // -1 To prevent overlapping with next line. + char timeline[128]; + context->srt_counter++; sprintf(timeline, "%u\r\n", context->srt_counter); - enc_buffer_used=encode_line (enc_buffer,(unsigned char *) timeline); + enc_buffer_used=encode_line (enc_buffer,(unsigned char *) timeline); write(context->out->fh, enc_buffer, enc_buffer_used); - sprintf (timeline, "%02u:%02u:%02u,%03u --> %02u:%02u:%02u,%03u\r\n", - h1,m1,s1,ms1, h2,m2,s2,ms2); - enc_buffer_used=encode_line (enc_buffer,(unsigned char *) timeline); - dbg_print(CCX_DMT_608, "\n- - - SRT caption - - -\n"); - dbg_print(CCX_DMT_608, "%s",timeline); - + sprintf (timeline, "%02u:%02u:%02u,%03u --> %02u:%02u:%02u,%03u\r\n", + h1,m1,s1,ms1, h2,m2,s2,ms2); + enc_buffer_used=encode_line (enc_buffer,(unsigned char *) timeline); + dbg_print(CCX_DMT_608, "\n- - - SRT caption - - -\n"); + dbg_print(CCX_DMT_608, "%s",timeline); + write(context->out->fh, enc_buffer, enc_buffer_used); - int len=strlen (string); - unsigned char *unescaped= (unsigned char *) malloc (len+1); - unsigned char *el = (unsigned char *) malloc (len*3+1); // Be generous - if (el==NULL || unescaped==NULL) - fatal (EXIT_NOT_ENOUGH_MEMORY, "In write_stringz_as_srt() - not enough memory.\n"); - int pos_r=0; - int pos_w=0; - // Scan for \n in the string and replace it with a 0 - while (pos_rout->fh, el, u); write(context->out->fh, encoded_crlf, encoded_crlf_length); - begin+= strlen ((const char *) begin)+1; - } + begin+= strlen ((const char *) begin)+1; + } + + dbg_print(CCX_DMT_608, "- - - - - - - - - - - -\r\n"); - dbg_print(CCX_DMT_608, "- - - - - - - - - - - -\r\n"); - write(context->out->fh, encoded_crlf, encoded_crlf_length); free(el); } int write_cc_buffer_as_srt(struct eia608_screen *data, struct s_context_cc608 *context) { - unsigned h1,m1,s1,ms1; - unsigned h2,m2,s2,ms2; + unsigned h1,m1,s1,ms1; + unsigned h2,m2,s2,ms2; LLONG ms_start, ms_end; - int wrote_something = 0; + int wrote_something = 0; ms_start = context->current_visible_start_ms; int prev_line_start=-1, prev_line_end=-1; // Column in which the previous line started and ended, for autodash int prev_line_center1=-1, prev_line_center2=-1; // Center column of previous line text int empty_buf=1; - for (int i=0;i<15;i++) - { - if (data->row_used[i]) + for (int i=0;i<15;i++) + { + if (data->row_used[i]) { empty_buf=0; break; @@ -88,47 +87,47 @@ int write_cc_buffer_as_srt(struct eia608_screen *data, struct s_context_cc608 *c if (empty_buf) // Prevent writing empty screens. Not needed in .srt return 0; - ms_start+=subs_delay; - if (ms_start<0) // Drop screens that because of subs_delay start too early - return 0; + ms_start+=subs_delay; + if (ms_start<0) // Drop screens that because of subs_delay start too early + return 0; - ms_end=get_visible_end()+subs_delay; + ms_end=get_visible_end()+subs_delay; - mstotime (ms_start,&h1,&m1,&s1,&ms1); - mstotime (ms_end-1,&h2,&m2,&s2,&ms2); // -1 To prevent overlapping with next line. - char timeline[128]; + mstotime (ms_start,&h1,&m1,&s1,&ms1); + mstotime (ms_end-1,&h2,&m2,&s2,&ms2); // -1 To prevent overlapping with next line. + char timeline[128]; context->srt_counter++; sprintf(timeline, "%u\r\n", context->srt_counter); - enc_buffer_used=encode_line (enc_buffer,(unsigned char *) timeline); + enc_buffer_used=encode_line (enc_buffer,(unsigned char *) timeline); write(context->out->fh, enc_buffer, enc_buffer_used); - sprintf (timeline, "%02u:%02u:%02u,%03u --> %02u:%02u:%02u,%03u\r\n", - h1,m1,s1,ms1, h2,m2,s2,ms2); - enc_buffer_used=encode_line (enc_buffer,(unsigned char *) timeline); + sprintf (timeline, "%02u:%02u:%02u,%03u --> %02u:%02u:%02u,%03u\r\n", + h1,m1,s1,ms1, h2,m2,s2,ms2); + enc_buffer_used=encode_line (enc_buffer,(unsigned char *) timeline); dbg_print(CCX_DMT_608, "\n- - - SRT caption ( %d) - - -\n", context->srt_counter); - dbg_print(CCX_DMT_608, "%s",timeline); - - write (context->out->fh, enc_buffer,enc_buffer_used); - for (int i=0;i<15;i++) - { - if (data->row_used[i]) - { - if (ccx_options.sentence_cap) - { - capitalize (i,data); - correct_case(i,data); - } + dbg_print(CCX_DMT_608, "%s",timeline); + + write (context->out->fh, enc_buffer,enc_buffer_used); + for (int i=0;i<15;i++) + { + if (data->row_used[i]) + { + if (ccx_options.sentence_cap) + { + capitalize (i,data); + correct_case(i,data); + } if (ccx_options.autodash && ccx_options.trim_subs) { int first=0, last=31, center1=-1, center2=-1; - unsigned char *line = data->characters[i]; + unsigned char *line = data->characters[i]; int do_dash=1, colon_pos=-1; find_limit_characters(line,&first,&last); if (first==-1 || last==-1) // Probably a bug somewhere though break; // Is there a speaker named, for example: TOM: What are you doing? for (int j=first;j<=last;j++) - { + { if (line[j]==':') { colon_pos=j; @@ -146,20 +145,20 @@ int write_cc_buffer_as_srt(struct eia608_screen *data, struct s_context_cc608 *c if (first>prev_line_start && lastprev_line_start && firstprev_line_start && lastprev_line_start && last=prev_line_center1-1 && center1<=prev_line_center1+1 && center1!=-1) // Center align @@ -175,21 +174,21 @@ int write_cc_buffer_as_srt(struct eia608_screen *data, struct s_context_cc608 *c prev_line_center2=center2; } - int length = get_decoder_line_encoded (subline, i, data); - if (ccx_options.encoding!=CCX_ENC_UNICODE) - { - dbg_print(CCX_DMT_608, "\r"); - dbg_print(CCX_DMT_608, "%s\n",subline); - } + int length = get_decoder_line_encoded (subline, i, data); + if (ccx_options.encoding!=CCX_ENC_UNICODE) + { + dbg_print(CCX_DMT_608, "\r"); + dbg_print(CCX_DMT_608, "%s\n",subline); + } write(context->out->fh, subline, length); write(context->out->fh, encoded_crlf, encoded_crlf_length); - wrote_something=1; - // fprintf (wb->fh,encoded_crlf); - } - } - dbg_print(CCX_DMT_608, "- - - - - - - - - - - -\r\n"); - - // fprintf (wb->fh, encoded_crlf); - write (context->out->fh, encoded_crlf, encoded_crlf_length); - return wrote_something; + wrote_something=1; + // fprintf (wb->fh,encoded_crlf); + } + } + dbg_print(CCX_DMT_608, "- - - - - - - - - - - -\r\n"); + + // fprintf (wb->fh, encoded_crlf); + write (context->out->fh, encoded_crlf, encoded_crlf_length); + return wrote_something; } From 0f06f47ab487f8ae6f1c1ad98ac22697e4280e02 Mon Sep 17 00:00:00 2001 From: Anshul Maheshwari Date: Fri, 11 Jul 2014 18:40:00 +0530 Subject: [PATCH 3/9] logic to devide time between frames --- src/608.c | 52 +++++++++++++++++++++++++++++++++++++--- src/608.h | 5 +++- src/608_srt.c | 4 ++-- src/cc_decoders_common.h | 10 ++++++++ 4 files changed, 65 insertions(+), 6 deletions(-) create mode 100644 src/cc_decoders_common.h diff --git a/src/608.c b/src/608.c index f926e91f4..d1dbdb267 100644 --- a/src/608.c +++ b/src/608.c @@ -1,5 +1,6 @@ #include "ccextractor.h" #include "608_spupng.h" +#include "cc_decoders_common.h" static const int rowdata[] = {11,-1,1,2,3,4,12,13,14,15,5,6,7,8,9,10}; // Relationship between the first PAC byte and the row number @@ -477,7 +478,18 @@ struct eia608_screen *get_current_visible_buffer(struct s_context_cc608 *context int write_cc_buffer(struct s_context_cc608 *context) { struct eia608_screen *data; + struct cc_subtitle *sub = NULL; int wrote_something=0; + LLONG start_time; + LLONG end_time; + + if(!context->sub) + { + sub = + context->sub = malloc(sizeof(struct cc_subtitle)); + } + else + sub = context->sub; if (ccx_options.screens_to_process!=-1 && context->screenfuls_counter >= ccx_options.screens_to_process) { @@ -490,12 +502,45 @@ int write_cc_buffer(struct s_context_cc608 *context) else data = &context->buffer2; + if (context->mode == MODE_FAKE_ROLLUP_1 && // Use the actual start of data instead of last buffer change + context->ts_start_of_current_line != -1) + start_time = context->ts_start_of_current_line; + else + start_time = context->current_visible_start_ms; + + end_time = get_visible_end() + subs_delay; + if (!data->empty) { - if (context->mode == MODE_FAKE_ROLLUP_1 && // Use the actual start of data instead of last buffer change - context->ts_start_of_current_line != -1) - context->current_visible_start_ms = context->ts_start_of_current_line; + sub->data = (struct eia608_screen *) realloc(sub->data,sub->size + sizeof(*data)); + memcpy(sub->data + sub->size, data, sizeof(*data)); + sub->size += sizeof(*data); + wrote_something = 1; + if(start_time < end_time) + { + int i = 0; + int nb_data = sub->size/sizeof(*data); + for(i = 0; i < nb_data; i++) + { + data = sub->data + (i * sizeof(*data) ); + data->start_time = start_time + ( ( (end_time - start_time)/nb_data ) * i ); + data->end_time = start_time + ( ( (end_time - start_time)/nb_data ) * (i + 1) ); + } + } + else + { + data = sub->data; + data->start_time = 0; + data->end_time = 0; + } + + + } + for(data = sub->data; sub->size ; sub->size -= sizeof(struct eia608_screen)) + { + if(!data->start_time) + break; new_sentence=1; switch (ccx_options.write_format) { @@ -528,6 +573,7 @@ int write_cc_buffer(struct s_context_cc608 *context) if (ccx_options.gui_mode_reports) write_cc_buffer_to_gui(data, context); + data = sub->data + sizeof(struct eia608_screen); } return wrote_something; } diff --git a/src/608.h b/src/608.h index 90f90757e..bdc71077a 100644 --- a/src/608.h +++ b/src/608.h @@ -18,7 +18,9 @@ struct eia608_screen // A CC buffer unsigned char colors[15][33]; unsigned char fonts[15][33]; // Extra char at the end for a 0 int row_used[15]; // Any data in row? - int empty; // Buffer completely empty? + int empty; // Buffer completely empty? + LLONG start_time; + LLONG end_time; }; struct s_context_cc608 @@ -44,6 +46,7 @@ struct s_context_cc608 long bytes_processed_608; // To be written ONLY by process_608 struct ccx_s_write *out; int have_cursor_position; + struct cc_subtitle *sub; }; extern unsigned char *enc_buffer; diff --git a/src/608_srt.c b/src/608_srt.c index 2a5351f31..bdbcc0817 100644 --- a/src/608_srt.c +++ b/src/608_srt.c @@ -71,7 +71,7 @@ int write_cc_buffer_as_srt(struct eia608_screen *data, struct s_context_cc608 *c unsigned h2,m2,s2,ms2; LLONG ms_start, ms_end; int wrote_something = 0; - ms_start = context->current_visible_start_ms; + ms_start = data->start_time; int prev_line_start=-1, prev_line_end=-1; // Column in which the previous line started and ended, for autodash int prev_line_center1=-1, prev_line_center2=-1; // Center column of previous line text @@ -91,7 +91,7 @@ int write_cc_buffer_as_srt(struct eia608_screen *data, struct s_context_cc608 *c if (ms_start<0) // Drop screens that because of subs_delay start too early return 0; - ms_end=get_visible_end()+subs_delay; + ms_end = data->end_time; mstotime (ms_start,&h1,&m1,&s1,&ms1); mstotime (ms_end-1,&h2,&m2,&s2,&ms2); // -1 To prevent overlapping with next line. diff --git a/src/cc_decoders_common.h b/src/cc_decoders_common.h new file mode 100644 index 000000000..3e278905f --- /dev/null +++ b/src/cc_decoders_common.h @@ -0,0 +1,10 @@ +#ifndef _CC_DECODER_COMMON +#define _CC_DECODER_COMMON + +struct cc_subtitle +{ + void *data; + size_t size; + enum ccx_encoding_type format; +}; +#endif From 9c0792c5a0f1aa177e9e62c2ecbc7f4863efa277 Mon Sep 17 00:00:00 2001 From: Anshul Maheshwari Date: Fri, 11 Jul 2014 18:51:04 +0530 Subject: [PATCH 4/9] using time from data structure --- src/608_sami.c | 4 ++-- src/608_smptett.c | 4 ++-- src/608_spupng.c | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/608_sami.c b/src/608_sami.c index 921f793d1..d5b40d60d 100644 --- a/src/608_sami.c +++ b/src/608_sami.c @@ -75,13 +75,13 @@ int write_cc_buffer_as_sami(struct eia608_screen *data, struct s_context_cc608 * { LLONG startms, endms; int wrote_something=0; - startms = context->current_visible_start_ms; + startms = data->start_time; startms+=subs_delay; if (startms<0) // Drop screens that because of subs_delay start too early return 0; - endms = get_visible_end()+subs_delay; + endms = data->end_time; endms--; // To prevent overlapping with next line. sprintf ((char *) str, "

\r\n", diff --git a/src/608_smptett.c b/src/608_smptett.c index 591bca459..48f514b50 100644 --- a/src/608_smptett.c +++ b/src/608_smptett.c @@ -102,13 +102,13 @@ int write_cc_buffer_as_smptett(struct eia608_screen *data, struct s_context_cc60 unsigned h2,m2,s2,ms2; LLONG endms; int wrote_something=0; - LLONG startms = context->current_visible_start_ms; + LLONG startms = data->start_time; startms+=subs_delay; if (startms<0) // Drop screens that because of subs_delay start too early return 0; - endms = get_visible_end()+subs_delay; + endms = data->end_time; endms--; // To prevent overlapping with next line. mstotime (startms,&h1,&m1,&s1,&ms1); mstotime (endms-1,&h2,&m2,&s2,&ms2); diff --git a/src/608_spupng.c b/src/608_spupng.c index 9b7c802b5..100c335b0 100644 --- a/src/608_spupng.c +++ b/src/608_spupng.c @@ -196,7 +196,7 @@ int spupng_write_ccbuffer(struct spupng_t *sp, struct eia608_screen* data, struct s_context_cc608 *context) { - LLONG ms_start = context->current_visible_start_ms + subs_delay; + LLONG ms_start = data->start_time + subs_delay; if (ms_start < 0) { dbg_print(CCX_DMT_VERBOSE, "Negative start\n"); @@ -220,7 +220,7 @@ spupng_write_ccbuffer(struct spupng_t *sp, struct eia608_screen* data, return 0; } - LLONG ms_end = get_visible_end() + subs_delay; + LLONG ms_end = data->end_time; sprintf(sp->pngfile, "%s/sub%04d.png", sp->dirname, sp->fileIndex++); if ((sp->fppng = fopen(sp->pngfile, "wb")) == NULL) From 4d6693d948fd0372c63a8d860bedf1a224eb7162 Mon Sep 17 00:00:00 2001 From: Anshul Maheshwari Date: Fri, 11 Jul 2014 19:09:34 +0530 Subject: [PATCH 5/9] cleaned mp4.c file --- src/gpacmp4/mp4.c | 179 ++++++++++++++++++++++++++-------------------- 1 file changed, 102 insertions(+), 77 deletions(-) diff --git a/src/gpacmp4/mp4.c b/src/gpacmp4/mp4.c index f5a1debb4..2bfd85afc 100644 --- a/src/gpacmp4/mp4.c +++ b/src/gpacmp4/mp4.c @@ -4,6 +4,7 @@ #include #include "../ccextractor.h" +#include "../utility.h" void do_NAL (unsigned char *NALstart, LLONG NAL_length); // From avc_functions.c void set_fts(void); // From timing.c @@ -30,8 +31,8 @@ static int process_avc_sample(u32 timescale, GF_AVCConfig* c, GF_ISOSample* s) u32 i; s32 signed_cts=(s32) s->CTS_Offset; // Convert from unsigned to signed. GPAC uses u32 but unsigned values are legal. current_pts=(LLONG )(s->DTS + signed_cts)*MPEG_CLOCK_FREQ/timescale ; // Convert frequency to official one - - if (pts_set==0) + + if (pts_set==0) pts_set=1; set_fts(); @@ -59,7 +60,7 @@ static int process_avc_sample(u32 timescale, GF_AVCConfig* c, GF_ISOSample* s) temp_debug=0; if (nal_length>0) - do_NAL ((unsigned char *) &(s->data[i]) ,nal_length); + do_NAL ((unsigned char *) &(s->data[i]) ,nal_length); i += nal_length; } // outer for assert(i == s->dataLength); @@ -71,7 +72,8 @@ static int process_xdvb_track(const char* basename, GF_ISOFile* f, u32 track) u32 timescale, i, sample_count; int status; - if((sample_count = gf_isom_get_sample_count(f, track)) < 1){ + if((sample_count = gf_isom_get_sample_count(f, track)) < 1) + { return 0; } @@ -79,29 +81,30 @@ static int process_xdvb_track(const char* basename, GF_ISOFile* f, u32 track) status = 0; - for(i = 0; i < sample_count; i++){ + for(i = 0; i < sample_count; i++) + { u32 sdi; GF_ISOSample* s = gf_isom_get_sample(f, track, i + 1, &sdi); - if (s!=NULL) { - - s32 signed_cts=(s32) s->CTS_Offset; // Convert from unsigned to signed. GPAC uses u32 but unsigned values are legal. - current_pts=(LLONG )(s->DTS + signed_cts)*MPEG_CLOCK_FREQ/timescale ; // Convert frequency to official one - if (pts_set==0) - pts_set=1; - set_fts(); + if (s!=NULL) + { + s32 signed_cts=(s32) s->CTS_Offset; // Convert from unsigned to signed. GPAC uses u32 but unsigned values are legal. + current_pts=(LLONG )(s->DTS + signed_cts)*MPEG_CLOCK_FREQ/timescale ; // Convert frequency to official one + if (pts_set==0) + pts_set=1; + set_fts(); - process_m2v ((unsigned char *) s->data,s->dataLength); + process_m2v ((unsigned char *) s->data,s->dataLength); gf_isom_sample_del(&s); } - int progress = (int) ((i*100) / sample_count); - if (last_reported_progress != progress) - { - int cur_sec = (int) (get_fts() / 1000); - activity_progress(progress, cur_sec/60, cur_sec%60); - last_reported_progress = progress; - } + int progress = (int) ((i*100) / sample_count); + if (last_reported_progress != progress) + { + int cur_sec = (int) (get_fts() / 1000); + activity_progress(progress, cur_sec/60, cur_sec%60); + last_reported_progress = progress; + } } int cur_sec = (int) (get_fts() / 1000); activity_progress(100, cur_sec/60, cur_sec%60); @@ -115,7 +118,8 @@ static int process_avc_track(const char* basename, GF_ISOFile* f, u32 track) int status; GF_AVCConfig* c = NULL; - if((sample_count = gf_isom_get_sample_count(f, track)) < 1){ + if((sample_count = gf_isom_get_sample_count(f, track)) < 1) + { return 0; } @@ -123,19 +127,24 @@ static int process_avc_track(const char* basename, GF_ISOFile* f, u32 track) status = 0; - for(i = 0; i < sample_count; i++){ + for(i = 0; i < sample_count; i++) + { u32 sdi; GF_ISOSample* s = gf_isom_get_sample(f, track, i + 1, &sdi); - if(s != NULL){ - if(sdi != last_sdi){ - if(c != NULL){ + if(s != NULL) + { + if(sdi != last_sdi) + { + if(c != NULL) + { gf_odf_avc_cfg_del(c); c = NULL; } - if((c = gf_isom_avc_config_get(f, track, sdi)) == NULL){ + if((c = gf_isom_avc_config_get(f, track, sdi)) == NULL) + { gf_isom_sample_del(&s); status = -1; break; @@ -148,23 +157,25 @@ static int process_avc_track(const char* basename, GF_ISOFile* f, u32 track) gf_isom_sample_del(&s); - if(status != 0){ + if(status != 0) + { break; } } - int progress = (int) ((i*100) / sample_count); - if (last_reported_progress != progress) - { - int cur_sec = (int) (get_fts() / 1000); - activity_progress(progress, cur_sec/60, cur_sec%60); - last_reported_progress = progress; - } + int progress = (int) ((i*100) / sample_count); + if (last_reported_progress != progress) + { + int cur_sec = (int) (get_fts() / 1000); + activity_progress(progress, cur_sec/60, cur_sec%60); + last_reported_progress = progress; + } } int cur_sec = (int) (get_fts() / 1000); activity_progress(100, cur_sec/60, cur_sec%60); - if(c != NULL){ + if(c != NULL) + { gf_odf_avc_cfg_del(c); c = NULL; } @@ -180,7 +191,7 @@ static int process_avc_track(const char* basename, GF_ISOFile* f, u32 track) if track is AVC track for each sample in track for each NALU in sample - send to avc.cpp for processing + send to avc.c for processing close(media) } @@ -189,10 +200,14 @@ int processmp4 (char *file) { GF_ISOFile* f; u32 i, j, track_count, avc_track_count, cc_track_count; - + mprint("opening \'%s\': ", file); +#ifdef MP4_DEBUG + gf_log_set_tool_level(GF_LOG_CONTAINER,GF_LOG_DEBUG); +#endif - if((f = gf_isom_open(file, GF_ISOM_OPEN_READ, NULL)) == NULL){ + if((f = gf_isom_open(file, GF_ISOM_OPEN_READ, NULL)) == NULL) + { mprint("failed to open\n"); return -2; } @@ -218,7 +233,8 @@ int processmp4 (char *file) avc_track_count++; } - for(i = 0; i < track_count; i++){ + for(i = 0; i < track_count; i++) + { const u32 type = gf_isom_get_media_type(f, i + 1); const u32 subtype = gf_isom_get_media_subtype(f, i + 1, 1); @@ -226,10 +242,12 @@ int processmp4 (char *file) { if (cc_track_count && !ccx_options.mp4vidtrack) continue; - if(process_xdvb_track(file, f, i + 1) != 0){ + if(process_xdvb_track(file, f, i + 1) != 0) + { mprint("error\n"); return -3; - } } + } + } if( type == GF_ISOM_MEDIA_VISUAL && subtype == GF_ISOM_SUBTYPE_AVC_H264) { @@ -240,12 +258,13 @@ int processmp4 (char *file) { for (j=0; jsequenceParameterSets);j++) { - GF_AVCConfigSlot* seqcnf=(GF_AVCConfigSlot* )gf_list_get(cnf->sequenceParameterSets,j); - do_NAL ((unsigned char *) seqcnf->data,seqcnf->size); + GF_AVCConfigSlot* seqcnf=(GF_AVCConfigSlot* )gf_list_get(cnf->sequenceParameterSets,j); + do_NAL ((unsigned char *) seqcnf->data,seqcnf->size); } } - if(process_avc_track(file, f, i + 1) != 0){ + if(process_avc_track(file, f, i + 1) != 0) + { mprint("error\n"); return -3; } @@ -257,16 +276,20 @@ int processmp4 (char *file) if (avc_track_count && ccx_options.mp4vidtrack) continue; - /* unsigned num_streams = gf_isom_get_sample_description_count (f,i+1); */ +#ifdef MP4_DEBUG + unsigned num_streams = gf_isom_get_sample_description_count (f,i+1); +#endif unsigned num_samples = gf_isom_get_sample_count (f,i+1); u32 ProcessingStreamDescriptionIndex = 0; // Current track we are processing, 0 = we don't know yet u32 timescale = gf_isom_get_media_timescale(f,i+1); - // u64 duration = gf_isom_get_media_duration(f,i+1); - /* mprint ("%u streams\n",num_streams); +#ifdef MP$DEBUG + u64 duration = gf_isom_get_media_duration(f,i+1); + mprint ("%u streams\n",num_streams); mprint ("%u sample counts\n",num_samples); mprint ("%u timescale\n",(unsigned) timescale); - mprint ("%u duration\n",(unsigned) duration); */ + mprint ("%u duration\n",(unsigned) duration); +#endif for (unsigned k = 0; k dataLength); - /* const LLONG timestamp = (LLONG )((sample->DTS + sample->CTS_Offset) * 1000) / timescale; */ +#ifdef DEBUG + mprint ("Data length: %lu\n",sample->dataLength); + const LLONG timestamp = (LLONG )((sample->DTS + sample->CTS_Offset) * 1000) / timescale; +#endif current_pts=(LLONG )(sample->DTS + sample->CTS_Offset)*MPEG_CLOCK_FREQ/timescale ; // Convert frequency to official one if (pts_set==0) pts_set=1; set_fts(); - // Change by Willem - - // Apparently the first 4 bytes are the sample length, and then comes 'cdat', and then the data itself - /*if (sample->dataLength>8 && strncmp (sample->data+4, "cdat", 4)==0) + int atomStart = 0; + // process Atom by Atom + while (atomStart < sample->dataLength) { - //dump (256,( unsigned char *) sample->data+8,sample->dataLength-8,0, 1); - process608((const unsigned char *)sample->data + 8, sample->dataLength - 8, &context_cc608_field_1); - }*/ - - // Based on https://developer.apple.com/library/prerelease/mac/documentation/QuickTime/QTFF/QTFFChap3/qtff3.html#//apple_ref/doc/uid/TP40000939-CH205-SW87 - // An atom consists of the Atom size, Atom Type and the data. - // First 4 bytes are length in bytes of this atom - // byte 5-8 are the atom type. Should be either cdat or cdt2 - // byte 9-x are actual data. - // This means a sample can contain multiple atoms! - if (sample->dataLength > 8 && strncmp(sample->data + 4, "cdat", 4) == 0){ // The format of the closed captioning sample data is a sequence of one or more atoms, one of which must be a 'cdat' atom. - int atomStart = 0; - // process Atom by Atom - while (atomStart < sample->dataLength){ - unsigned int atomLength = (unsigned char)sample->data[atomStart] << 24 | (unsigned char)sample->data[atomStart + 1] << 16 | (unsigned char)sample->data[atomStart + 2] << 8 | (unsigned char)sample->data[atomStart + 3]; - if (atomLength > 8 && (strncmp(sample->data + atomStart + 4, "cdat", 4) == 0 || strncmp(sample->data + atomStart + 4, "cdt2", 4) == 0)){ - dump(256, (unsigned char *)sample->data +atomStart+ 8, atomLength - 8, 0, 1); - process608((const unsigned char *)sample->data + atomStart + 8, atomLength - 8, &context_cc608_field_1); - } - atomStart += atomLength; + char *data = sample->data + atomStart; + unsigned int atomLength = RB32(data); + if(atomLength < 8 || atomLength > sample->dataLength) + { + mprint ("Invalid atom.\n"); + break; } + + data += 4; + if (!strncmp(data, "cdat", 4) || !strncmp(data, "cdt2", 4)) + { + data += 4; +#ifdef MP4_DEBUG + dump(256, (unsigned char *)data, atomLength - 8, 0, 1); +#endif + process608((unsigned char*)data, atomLength - 8, &context_cc608_field_1); + } + atomStart += atomLength; + } // End of change @@ -321,7 +343,7 @@ int processmp4 (char *file) if (last_reported_progress != progress) { int cur_sec = (int) (get_fts() / 1000); - activity_progress(progress, cur_sec/60, cur_sec%60); + activity_progress(progress, cur_sec/60, cur_sec%60); last_reported_progress = progress; } } @@ -336,9 +358,12 @@ int processmp4 (char *file) f = NULL; mprint ("ok\n"); - if(avc_track_count == 0){ + if(avc_track_count == 0) + { mprint("Found no AVC track(s). ", file); - }else{ + } + else + { mprint("Found %d AVC track(s). ", avc_track_count); } if (cc_track_count) From cc0a7860043523eb1193f0cdd5c5da7449f4f92a Mon Sep 17 00:00:00 2001 From: Anshul Maheshwari Date: Fri, 11 Jul 2014 22:13:33 +0530 Subject: [PATCH 6/9] compile on windows --- src/608.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/608.c b/src/608.c index d1dbdb267..85bfeb9cc 100644 --- a/src/608.c +++ b/src/608.c @@ -514,7 +514,7 @@ int write_cc_buffer(struct s_context_cc608 *context) { sub->data = (struct eia608_screen *) realloc(sub->data,sub->size + sizeof(*data)); - memcpy(sub->data + sub->size, data, sizeof(*data)); + memcpy((struct eia608_screen *)sub->data + (sub->size/sizeof(*data)), data, sizeof(*data)); sub->size += sizeof(*data); wrote_something = 1; if(start_time < end_time) @@ -523,7 +523,7 @@ int write_cc_buffer(struct s_context_cc608 *context) int nb_data = sub->size/sizeof(*data); for(i = 0; i < nb_data; i++) { - data = sub->data + (i * sizeof(*data) ); + data = (struct eia608_screen *)sub->data + i; data->start_time = start_time + ( ( (end_time - start_time)/nb_data ) * i ); data->end_time = start_time + ( ( (end_time - start_time)/nb_data ) * (i + 1) ); } @@ -573,7 +573,7 @@ int write_cc_buffer(struct s_context_cc608 *context) if (ccx_options.gui_mode_reports) write_cc_buffer_to_gui(data, context); - data = sub->data + sizeof(struct eia608_screen); + data = (struct eia608_screen*)sub->data + 1; } return wrote_something; } From a5ef2d15740026e89bc2235d01e66ac1bcc94a7d Mon Sep 17 00:00:00 2001 From: Anshul Maheshwari Date: Fri, 11 Jul 2014 13:13:48 -0700 Subject: [PATCH 7/9] some memory check before accessing --- src/608.c | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/src/608.c b/src/608.c index 85bfeb9cc..0dc30b9be 100644 --- a/src/608.c +++ b/src/608.c @@ -487,9 +487,16 @@ int write_cc_buffer(struct s_context_cc608 *context) { sub = context->sub = malloc(sizeof(struct cc_subtitle)); + memset(context->sub, 0, sizeof(struct cc_subtitle)); } else sub = context->sub; + if (!sub) + { + mprint("No Memory Left"); + return 0; + } + if (ccx_options.screens_to_process!=-1 && context->screenfuls_counter >= ccx_options.screens_to_process) { @@ -512,11 +519,16 @@ int write_cc_buffer(struct s_context_cc608 *context) if (!data->empty) { - sub->data = (struct eia608_screen *) realloc(sub->data,sub->size + sizeof(*data)); + sub->data = (struct eia608_screen *) realloc(sub->data,sub->size + sizeof(*data)); + if (!sub->data) + { + mprint("No Memory left"); + return 0; + } - memcpy((struct eia608_screen *)sub->data + (sub->size/sizeof(*data)), data, sizeof(*data)); - sub->size += sizeof(*data); - wrote_something = 1; + memcpy(((struct eia608_screen *)sub->data) + (sub->size/sizeof(*data)), data, sizeof(*data)); + sub->size += sizeof(*data); + wrote_something = 1; if(start_time < end_time) { int i = 0; @@ -539,7 +551,7 @@ int write_cc_buffer(struct s_context_cc608 *context) } for(data = sub->data; sub->size ; sub->size -= sizeof(struct eia608_screen)) { - if(!data->start_time) + if(!data || !data->start_time) break; new_sentence=1; switch (ccx_options.write_format) @@ -574,7 +586,13 @@ int write_cc_buffer(struct s_context_cc608 *context) if (ccx_options.gui_mode_reports) write_cc_buffer_to_gui(data, context); data = (struct eia608_screen*)sub->data + 1; + if (sub->data && !sub->size) + { + free(sub->data); + sub->data = NULL; + } } + return wrote_something; } From 95e2f7665b5536de41ed359c03404630bd51d913 Mon Sep 17 00:00:00 2001 From: Anshul Maheshwari Date: Sat, 12 Jul 2014 11:28:43 +0530 Subject: [PATCH 8/9] corrected time roll up --- src/608.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/608.c b/src/608.c index 0dc30b9be..8cf36b3c6 100644 --- a/src/608.c +++ b/src/608.c @@ -511,10 +511,9 @@ int write_cc_buffer(struct s_context_cc608 *context) if (context->mode == MODE_FAKE_ROLLUP_1 && // Use the actual start of data instead of last buffer change context->ts_start_of_current_line != -1) - start_time = context->ts_start_of_current_line; - else - start_time = context->current_visible_start_ms; + context->current_visible_start_ms = context->ts_start_of_current_line; + start_time = context->current_visible_start_ms; end_time = get_visible_end() + subs_delay; if (!data->empty) From 08996a3253d8aa0d9a9c3e0850e17e950012477c Mon Sep 17 00:00:00 2001 From: Anshul Maheshwari Date: Sat, 12 Jul 2014 19:42:38 +0530 Subject: [PATCH 9/9] using freep and removing redundant code --- src/608.c | 8 +++----- src/dvb_subtitle_decoder.c | 9 --------- src/utility.c | 9 +++++++++ src/utility.h | 1 + 4 files changed, 13 insertions(+), 14 deletions(-) diff --git a/src/608.c b/src/608.c index 8cf36b3c6..b42020e87 100644 --- a/src/608.c +++ b/src/608.c @@ -1,6 +1,7 @@ #include "ccextractor.h" #include "608_spupng.h" #include "cc_decoders_common.h" +#include "utility.h" static const int rowdata[] = {11,-1,1,2,3,4,12,13,14,15,5,6,7,8,9,10}; // Relationship between the first PAC byte and the row number @@ -585,11 +586,8 @@ int write_cc_buffer(struct s_context_cc608 *context) if (ccx_options.gui_mode_reports) write_cc_buffer_to_gui(data, context); data = (struct eia608_screen*)sub->data + 1; - if (sub->data && !sub->size) - { - free(sub->data); - sub->data = NULL; - } + if (!sub->size) + freep(&sub->data); } return wrote_something; diff --git a/src/dvb_subtitle_decoder.c b/src/dvb_subtitle_decoder.c index f24c83406..060b654d0 100644 --- a/src/dvb_subtitle_decoder.c +++ b/src/dvb_subtitle_decoder.c @@ -188,15 +188,6 @@ static __inline unsigned int get_bits1(GetBitContext *s) return result; } - -static void freep(void *arg) -{ - void **ptr = (void **) arg; - if (*ptr) - free(*ptr); - *ptr = NULL; - -} #ifdef DEBUG struct transIntensity diff --git a/src/utility.c b/src/utility.c index 1e3c387fb..86f750a3d 100644 --- a/src/utility.c +++ b/src/utility.c @@ -336,3 +336,12 @@ int string_cmp(const void *p1,const void *p2) { return string_cmp2(p1, p2, NULL); } + +void freep(void *arg) +{ + void **ptr = (void **) arg; + if (*ptr) + free(*ptr); + *ptr = NULL; + +} diff --git a/src/utility.h b/src/utility.h index c5ab031f4..9ebb26754 100644 --- a/src/utility.h +++ b/src/utility.h @@ -13,5 +13,6 @@ void shell_sort(void *base, int nb,size_t size,int (*compar)(const void*p1,const void *p2,void*arg),void *arg); int string_cmp(const void *p1,const void *p2); int string_cmp2(const void *p1,const void *p2,void *arg); +void freep(void *arg); #endif