Index: libhb/render.c===================================================================--- libhb/render.c (revision 1047)+++ libhb/render.c (working copy)@@ -19,6 +19,8 @@ AVPicture pic_tmp_out; hb_buffer_t * buf_scale; hb_fifo_t * subtitle_queue;+ hb_fifo_t * delay_queue;+ int ivtc_frames; }; int renderInit( hb_work_object_t *, hb_job_t * );@@ -153,10 +155,14 @@ hb_job_t * job = pv->job; hb_title_t * title = job->title; hb_buffer_t * in = *buf_in, * buf_tmp_in = *buf_in;+ hb_buffer_t * ivtc_buffer = NULL; if(!in->data) {- /* If the input buffer is end of stream, send out an empty one to the next stage as well. */+ /* If the input buffer is end of stream, send out an empty one+ * to the next stage as well. Note that this will result in us+ * losing the current contents of the delay queue.+ */ *buf_out = hb_buffer_init(0); return HB_WORK_OK; }@@ -227,6 +233,10 @@ { hb_fifo_get( pv->subtitle_queue ); buf_tmp_in = NULL;+ if( job->vfr )+ {+ pv->ivtc_frames = 3;+ } break; } }@@ -292,6 +302,64 @@ hb_buffer_copy_settings( buf_render, buf_tmp_in ); }+ if( pv->ivtc_frames == 3 )+ {+ /*+ * We have just detected a dropped frame and variable frame rate + * is enabled. We need to rewrite the times on the last two+ * buffers, and also the next two to arrive.+ */++ ivtc_buffer = hb_fifo_see2( pv->delay_queue );++ if( ivtc_buffer )+ {+ /*+ * This is the buffer from 2 frames ago, rewrite the duration on it.+ */+ ivtc_buffer->stop = ivtc_buffer->stop + (90090000 / 120000);+ }++ ivtc_buffer = hb_fifo_see( pv->delay_queue );++ if( ivtc_buffer )+ {+ /*+ * This is the buffer from 1 frame ago, rewrite the duration on it.+ */+ ivtc_buffer->stop = ivtc_buffer->stop + (90090000 / 120000);+ }++ /*+ * Process the next 2 frames to arrive as well.+ */+ pv->ivtc_frames = 2;+ }++ if( *buf_out )+ {+ if( pv->ivtc_frames )+ {+ /*+ * This is an ivtc frame, rewrite the duration on it.+ */+ ivtc_buffer = *buf_out;+ ivtc_buffer->stop = ivtc_buffer->stop + (90090000 / 120000);+ pv->ivtc_frames--;+ }+ hb_fifo_push( pv->delay_queue, *buf_out );+ *buf_out = NULL;+ }++ /*+ * Keep the last three frames in our queue, this ensures that we have the last+ * two always in there should we need to rewrite the durations on them.+ */+ if( hb_fifo_size( pv->delay_queue ) >= 3 )+ {+ *buf_out = hb_fifo_get( pv->delay_queue );+ } + return HB_WORK_OK; }@@ -304,7 +372,12 @@ { hb_fifo_close( &pv->subtitle_queue ); }- ++ if( pv->delay_queue )+ {+ hb_fifo_close( &pv->delay_queue );+ }+ /* Cleanup filters */ /* TODO: Move to work.c? */ if( pv->job->filters )@@ -351,7 +424,9 @@ } /* Setup FIFO queue for subtitle cache */- pv->subtitle_queue = hb_fifo_init( 8 ); + pv->subtitle_queue = hb_fifo_init( 8 );+ pv->delay_queue = hb_fifo_init( 8 );+ pv->ivtc_frames = 0; /* Setup filters */ /* TODO: Move to work.c? */Index: libhb/common.h===================================================================--- libhb/common.h (revision 1047)+++ libhb/common.h (working copy)@@ -172,6 +172,7 @@ int crf; char *x264opts; int areBframes;+ int vfr; /* Audio tracks: audios: Indexes in hb_title_t's audios list, starting from 0.