rendered paste bodyIndex: libhb/dvd.c===================================================================--- libhb/dvd.c (revision 1372)+++ libhb/dvd.c (working copy)@@ -962,7 +962,7 @@ /*********************************************************************** * hb_dvd_is_break ***********************************************************************- * Returns 1 if the current block is a new chapter start+ * Returns chapter number if the current block is a new chapter start **********************************************************************/ int hb_dvd_is_break( hb_dvd_t * d ) {@@ -988,8 +988,7 @@ // This must not match against the start cell. if( pgc->cell_playback[cell].first_sector == d->block && cell != d->cell_start ) {- hb_log("dvd: Chapter Break Cell Found");- return 1;+ return i + 1; } } Index: libhb/decmpeg2.c===================================================================--- libhb/decmpeg2.c (revision 1372)+++ libhb/decmpeg2.c (working copy)@@ -37,12 +37,15 @@ { mpeg2dec_t * libmpeg2; const mpeg2_info_t * info;+ hb_job_t * job; int width; int height; int rate; int aspect_ratio;- int got_iframe;- int look_for_break;+ int got_iframe; /* set when we get our first iframe */+ int look_for_iframe; /* need an iframe to add chap break */+ int look_for_break; /* need gop start to add chap break */+ uint32_t nframes; /* number of frames we've decoded */ int64_t last_pts; }; @@ -58,7 +61,6 @@ m->libmpeg2 = mpeg2_init(); m->info = mpeg2_info( m->libmpeg2 ); m->last_pts = -1;- m->look_for_break = 0; return m; }@@ -74,7 +76,6 @@ mpeg2_state_t state; hb_buffer_t * buf; uint8_t * data;- int chap_break = 0; /* Feed libmpeg2 */ if( buf_es->start > -1 )@@ -117,10 +118,12 @@ } } }- else if( state == STATE_GOP && m->look_for_break == 2)+ else if( state == STATE_GOP && m->look_for_break) {- hb_log("MPEG2: Group of pictures found, searching for I-Frame");- m->look_for_break = 1;+ // we were looking for a gop to add a chapter break - we found it+ // so now start looking for an iframe.+ m->look_for_iframe = m->look_for_break;+ m->look_for_break = 0; } else if( ( state == STATE_SLICE || state == STATE_END ) && m->info->display_fbuf )@@ -128,15 +131,8 @@ if( ( m->info->display_picture->flags & PIC_MASK_CODING_TYPE ) == PIC_FLAG_CODING_TYPE_I ) {+ // we got an iframe so we can start decoding video now m->got_iframe = 1;-- // If we are looking for a break, insert the chapter break on an I-Frame- if( m->look_for_break == 1 )- {- hb_log("MPEG2: I-Frame Found");- m->look_for_break = 0;- chap_break = 1;- } } if( m->got_iframe )@@ -146,14 +142,6 @@ buf->sequence = buf_es->sequence; - // Was a good break point found?- if( chap_break )- {- hb_log("MPEG2: Chapter Break Inserted");- chap_break = 0;- buf->new_chap = 1;- }- memcpy( data, m->info->display_fbuf->buf[0], m->width * m->height ); data += m->width * m->height;@@ -187,6 +175,27 @@ } m->last_pts = buf->start; + if( m->look_for_iframe && ( m->info->display_picture->flags &+ PIC_MASK_CODING_TYPE ) == PIC_FLAG_CODING_TYPE_I )+ {+ // we were waiting for an iframe to insert a chapter mark+ // and we have one.+ buf->new_chap = m->look_for_iframe;+ m->look_for_iframe = 0;+ const char *chap_name = "";+ if ( m->job && buf->new_chap > 0 &&+ hb_list_item( m->job->title->list_chapter,+ buf->new_chap - 1 ) )+ {+ hb_chapter_t * c = hb_list_item( m->job->title->list_chapter,+ buf->new_chap - 1 );+ chap_name = c->title;+ }+ hb_log( "mpeg2: chapter %d \"%s\" at frame %u time %lld",+ buf->new_chap, chap_name, m->nframes, buf->start );+ }+ ++m->nframes;+ flag = m->info->display_picture->flags; /* Uncomment this block to see frame-by-frame picture flags, as the video encodes.@@ -362,6 +371,8 @@ pv->libmpeg2 = hb_libmpeg2_init(); pv->list = hb_list_init(); + pv->libmpeg2->job = job;+ return 0; } @@ -380,8 +391,7 @@ // stream. We need to shift it. if( (*buf_in)->new_chap ) {- hb_log("MPEG2: Chapter Break Cell Found, searching for GOP");- pv->libmpeg2->look_for_break = 2;+ pv->libmpeg2->look_for_break = (*buf_in)->new_chap; (*buf_in)->new_chap = 0; } Index: libhb/encx264.c===================================================================--- libhb/encx264.c (revision 1372)+++ libhb/encx264.c (working copy)@@ -50,6 +50,7 @@ x264_picture_t pic_in; uint8_t *x264_allocated_pic; + int chap_mark; // saved chap mark when we're propagating it int64_t dts_next; // DTS start time value for next output frame int64_t last_stop; // Debugging - stop time of previous input frame int64_t init_delay;@@ -384,6 +385,7 @@ if( pv->next_chap == 0 ) { pv->next_chap = in->start;+ pv->chap_mark = in->new_chap; } /* don't let 'work_loop' put a chapter mark on the wrong buffer */ in->new_chap = 0;@@ -496,7 +498,7 @@ if( pv->next_chap != 0 && pv->next_chap <= pic_out.i_pts ) { pv->next_chap = 0;- buf->new_chap = 1;+ buf->new_chap = pv->chap_mark; } break; case X264_TYPE_I:Index: libhb/muxmp4.c===================================================================--- libhb/muxmp4.c (revision 1372)+++ libhb/muxmp4.c (working copy)@@ -100,10 +100,16 @@ ********************************************************************** * Creates a buffer for a text track sample *********************************************************************/-static struct hb_text_sample_s *MP4GenerateChapterSample( hb_mux_object_t * m, uint64_t duration )+static struct hb_text_sample_s *MP4GenerateChapterSample( hb_mux_object_t * m,+ uint64_t duration,+ int chapter ) {- int chapter = m->current_chapter;- hb_chapter_t *chapter_data = hb_list_item( m->job->title->list_chapter, chapter - 1 );+ // We substract 1 from the chapter number because the chapters start at+ // 1 but our name array starts at 0. We substract another 1 because we're+ // writing the text of the previous chapter mark (when we get the start+ // of chapter 2 we know the duration of chapter 1 & can write its mark).+ hb_chapter_t *chapter_data = hb_list_item( m->job->title->list_chapter,+ chapter - 2 ); char tmp_buffer[1024]; char *string = tmp_buffer; @@ -116,7 +122,7 @@ if( strlen(string) == 0 || strlen(string) >= 1024 ) {- snprintf( tmp_buffer, 1023, "Chapter %03i", chapter );+ snprintf( tmp_buffer, 1023, "Chapter %03i", chapter - 2 ); string = tmp_buffer; } @@ -383,7 +389,7 @@ duration += buf->renderOffset * m->samplerate / 90000; } - sample = MP4GenerateChapterSample( m, duration );+ sample = MP4GenerateChapterSample( m, duration, buf->new_chap ); if( !MP4WriteSample(m->file, m->chapter_track,@@ -396,7 +402,7 @@ *job->die = 1; } free(sample);- m->current_chapter++;+ m->current_chapter = buf->new_chap; m->chapter_duration += duration; } @@ -461,7 +467,9 @@ /* Write our final chapter marker */ if( m->job->chapter_markers ) {- struct hb_text_sample_s *sample = MP4GenerateChapterSample( m, (m->sum_dur - m->chapter_duration) );+ struct hb_text_sample_s *sample = MP4GenerateChapterSample( m,+ (m->sum_dur - m->chapter_duration),+ m->current_chapter + 1 ); if( !MP4WriteSample(m->file, m->chapter_track,Index: libhb/sync.c===================================================================--- libhb/sync.c (revision 1372)+++ libhb/sync.c (working copy)@@ -52,6 +52,7 @@ int video_sequence; int count_frames; int count_frames_max;+ int chap_mark; /* to propagate chapter mark across a drop */ hb_buffer_t * cur; /* The next picture to process */ /* Audio */@@ -344,6 +345,11 @@ } ++pv->drop_count; buf_tmp = hb_fifo_get( job->fifo_raw );+ if ( buf_tmp->new_chap )+ {+ // don't drop a chapter mark when we drop the buffer+ pv->chap_mark = buf_tmp->new_chap;+ } hb_buffer_close( &buf_tmp ); continue; }@@ -521,6 +527,13 @@ buf_tmp->start = pv->next_start; pv->next_start += duration; buf_tmp->stop = pv->next_start;+ if ( pv->chap_mark )+ {+ // we have a pending chapter mark from a recent drop - put it on this+ // buffer (this may make it one frame late but we can't do any better).+ buf_tmp->new_chap = pv->chap_mark;+ pv->chap_mark = 0;+ } /* If we have a subtitle for this picture, copy it */ /* FIXME: we should avoid this memcpy */Index: libhb/work.c===================================================================--- libhb/work.c (revision 1372)+++ libhb/work.c (working copy)@@ -840,8 +840,9 @@ // 'buf_in' to NULL so that this code won't generate spurious duplicates.) if( buf_in && buf_out && buf_in->new_chap && buf_in->start == buf_out->start) {- hb_log("work %s: Copying Chapter Break @ %lld", w->name, buf_in->start);- buf_out->new_chap = 1;+ // restore log below to debug chapter mark propagation problems+ //hb_log("work %s: Copying Chapter Break @ %lld", w->name, buf_in->start);+ buf_out->new_chap = buf_in->new_chap; } if( buf_in )Index: libhb/muxmkv.c===================================================================--- libhb/muxmkv.c (revision 1372)+++ libhb/muxmkv.c (working copy)@@ -265,7 +265,12 @@ /* Make sure we're not writing a chapter that has 0 length */ if (mux_data->prev_chapter_tc != timecode) {- chapter_data = hb_list_item( title->list_chapter, mux_data->current_chapter++ );+ if ( buf->new_chap )+ {+ mux_data->current_chapter = buf->new_chap - 2;+ }+ chapter_data = hb_list_item( title->list_chapter,+ mux_data->current_chapter++ ); tmp_buffer[0] = '\0'; if( chapter_data != NULL )