Index: libhb/render.c =================================================================== --- libhb/render.c (revision 1034) +++ libhb/render.c (working copy) @@ -9,6 +9,11 @@ #include "ffmpeg/avcodec.h" #include "ffmpeg/swscale.h" +/* Used for keeping track of when frames are dropped by detelecine. */ +uint32_t dropped_frames = 0; +uint32_t extended_durations = 0; +int wait_for_ivtc_fifo = 2; + struct hb_work_private_s { hb_job_t * job; @@ -19,6 +24,7 @@ AVPicture pic_tmp_out; hb_buffer_t * buf_scale; hb_fifo_t * subtitle_queue; + hb_fifo_t * ivtc_fifo; }; int renderInit( hb_work_object_t *, hb_job_t * ); @@ -181,6 +187,8 @@ hb_fifo_push( pv->subtitle_queue, hb_buffer_init(0) ); } + hb_log("in pts: %lld", in->start); + /* Setup render buffer */ hb_buffer_t * buf_render = hb_buffer_init( 3 * job->width * job->height / 2 ); @@ -225,8 +233,21 @@ } else if( result == FILTER_DROP ) { - hb_fifo_get( pv->subtitle_queue ); - buf_tmp_in = NULL; + /* A drop means detelecine's latched its teeth onto + something and has duped frames to discard. */ + hb_log("DROPPING frame at pts: %lld", buf_tmp_in->start); + if ( job->vfr ) + { + dropped_frames++; + wait_for_ivtc_fifo++; + hb_fifo_get( pv->subtitle_queue ); + buf_tmp_in = NULL; + } + else + { + buf_tmp_in = buf_tmp_out; + } + break; } } @@ -291,18 +312,68 @@ memcpy( buf_render->data, buf_tmp_in->data, buf_render->size ); hb_buffer_copy_settings( buf_render, buf_tmp_in ); } + + hb_log("pushing pts %lld", buf_render->start); + + if ( wait_for_ivtc_fifo ) + { + hb_fifo_push( pv->ivtc_fifo, buf_render ); + *buf_out = NULL; + wait_for_ivtc_fifo--; + } + else + { + hb_fifo_push( pv->ivtc_fifo, buf_render ); + *buf_out = NULL; + //hb_log("getting frame"); + // if (hb_fifo_see(pv->ivtc_fifo)) + buf_render = hb_fifo_get( pv->ivtc_fifo ); + } + if ( buf_render ) + { + /* Pass VFR NTSC IVTC frame durations on through the workflow. + I totally wish I could slip some cryptic abbreviations into + the last sentence. + + (90090000 / 120000) is the rational equivalent of 750.75. + That's the number of ticks by which a 23.976 frame is + longer than a 29.97 frame. God I hate fractions. + */ + + hb_log("out pts: %lld", buf_render->start); + + if ( (dropped_frames) && ( ( dropped_frames * 4 ) > extended_durations ) ) + { + buf_render->stop = buf_render->stop + (90090000 / 120000); + extended_durations++; + hb_log("extending pts: %lld", buf_render->start); + } +/* else if (buf_render->flags & 16) + { + buf_render->stop = buf_render->stop + (90090000 / 120000); + } +*/ + + } + + return HB_WORK_OK; } void renderClose( hb_work_object_t * w ) { + hb_log("render: dropped frames: %i (%i ticks)", dropped_frames, (dropped_frames * 3003) ); + hb_log("render: extended frames: %i (%i ticks)", extended_durations, (extended_durations * (90090000 / 120000) ) ); + hb_log("render: Lost time: %i frames (%i ticks)", (dropped_frames * 4) - (extended_durations), (dropped_frames * 3003) - (extended_durations * (90090000 / 120000) ) ); + hb_work_private_t * pv = w->private_data; /* Cleanup subtitle queue */ if( pv->subtitle_queue ) { hb_fifo_close( &pv->subtitle_queue ); + hb_fifo_close( &pv->ivtc_fifo ); } /* Cleanup filters */ @@ -352,6 +423,7 @@ /* Setup FIFO queue for subtitle cache */ pv->subtitle_queue = hb_fifo_init( 8 ); + pv->ivtc_fifo = hb_fifo_init( 8 ); /* Setup filters */ /* TODO: Move to work.c? */