Index: libhb/render.c===================================================================--- libhb/render.c (revision 1234)+++ libhb/render.c (working copy)@@ -20,11 +20,13 @@ hb_buffer_t * buf_scale; hb_fifo_t * subtitle_queue; hb_fifo_t * delay_queue;- int frames_to_extend; int dropped_frames; int extended_frames; uint64_t last_start[4]; uint64_t last_stop[4];+ uint64_t lost_time[4];+ uint64_t total_lost_time;+ uint64_t total_gained_time; }; int renderInit( hb_work_object_t *, hb_job_t * );@@ -280,9 +282,22 @@ { if( job->vfr ) {- pv->frames_to_extend += 4;+ /* We need to compensate for the time lost by dropping this frame.+ Spread its duration out in quarters, because usually dropped frames+ maintain a 1-out-of-5 pattern and this spreads it out amongst the remaining ones.+ Store these in the lost_time array, which has 4 slots in it.+ Because not every frame duration divides evenly by 4, and we can't lose the+ remainder, we have to go through an awkward process to preserve it in the 4th array index. */+ uint64_t temp_duration = buf_tmp_out->stop - buf_tmp_out->start;+ pv->lost_time[0] += (temp_duration / 4);+ pv->lost_time[1] += (temp_duration / 4);+ pv->lost_time[2] += (temp_duration / 4);+ pv->lost_time[3] += ( temp_duration - (temp_duration / 4) - (temp_duration / 4) - (temp_duration / 4) );++ pv->total_lost_time += temp_duration; pv->dropped_frames++;- hb_fifo_get( pv->subtitle_queue );++ hb_fifo_get( pv->subtitle_queue ); buf_tmp_in = NULL; } else@@ -385,13 +400,13 @@ if( *buf_out ) {- if( pv->frames_to_extend )+ if( pv->lost_time[3] > 0 ) { /* * A frame's been dropped by VFR detelecine. * Gotta make up the lost time. This will also- * slow down the video to 23.976fps.- * The dropped frame ran for 3003 ticks, so+ * slow down the video.+ * The dropped frame's has to be accounted for, so * divvy it up amongst the 4 frames left behind. * This is what the delay_queue is for; * telecined sequences start 2 frames before@@ -401,25 +416,37 @@ */ ivtc_buffer = *buf_out;- /* The 4th cached frame will be the to use. */+ /* We can't use the given time stamps. Previous frames+ might already have been extended, throwing off the+ raw values fed to render.c. Instead, their+ stop and start times are stored in arrays.+ The 4th cached frame will be the to use. */ ivtc_buffer->start = pv->last_start[3]; ivtc_buffer->stop = pv->last_stop[3];++ /* Extend the frame's duration by the value in the+ 4th slot of the lost_time array. */+ ivtc_buffer->stop += pv->lost_time[3];+ pv->total_gained_time += pv->lost_time[3];- if (pv->frames_to_extend % 4)- ivtc_buffer->stop += 751;- else- ivtc_buffer->stop += 750;- - /* Set the 3rd cached frame to start when this one stops,- and to stop 3003 ticks later -- a normal 29.97fps- length frame. If it needs to be extended as well to- make up lost time, it'll be handled on the next- loop through the renderer. */+ /* Set the 3rd cached frame to start when this one stops.+ If it needs to be extended as well to make up lost time,+ it'll be handled on the next loop through the renderer. */ int temp_duration = pv->last_stop[2] - pv->last_start[2]; pv->last_start[2] = ivtc_buffer->stop; pv->last_stop[2] = ivtc_buffer->stop + temp_duration;- pv->frames_to_extend--;+ /* We've pulled the 4th value from the lost_time array+ and added it to the outgoing frame. Now, rotate the+ array so the 4th slot now hold's the 3rd's value, and+ so on down the line, and set the 0 indez to a value of 0. */+ int i;+ for( i=2; i >= 0; i--)+ {+ pv->lost_time[i+1] = pv->lost_time[i];+ }+ pv->lost_time[0] = 0;+ pv->extended_frames++; }@@ -431,11 +458,11 @@ void renderClose( hb_work_object_t * w ) { hb_work_private_t * pv = w->private_data; - - hb_log("render: dropped frames: %i (%i ticks)", pv->dropped_frames, (pv->dropped_frames * 3003) );- hb_log("render: extended frames: %i (%i ticks)", pv->extended_frames, ( ( pv->extended_frames / 4 ) * 3003 ) );- hb_log("render: Lost time: %i frames (%i ticks)", (pv->dropped_frames * 4) - (pv->extended_frames), (pv->dropped_frames * 3003) - ( ( pv->extended_frames / 4 ) * 3003 ) );+ hb_log("render: lost time: %lld (%i frames)", pv->total_lost_time, pv->dropped_frames);+ hb_log("render: gained time: %lld (%i frames) (%lld not accounted for)", pv->total_gained_time, pv->extended_frames, pv->total_lost_time - pv->total_gained_time);+ hb_log("render: average dropped frame duration: %i", pv->total_lost_time / pv->dropped_frames);+ /* Cleanup subtitle queue */ if( pv->subtitle_queue ) {@@ -476,12 +503,17 @@ /* Setup FIFO queue for subtitle cache */ pv->subtitle_queue = hb_fifo_init( 8 ); pv->delay_queue = hb_fifo_init( 8 );- pv->frames_to_extend = 0; pv->dropped_frames = 0; pv->extended_frames = 0; pv->last_start[0] = 0; pv->last_stop[0] = 0;- + pv->total_lost_time = 0;+ pv->total_gained_time = 0;+ pv->lost_time[0] = 0;+ pv->lost_time[1] = 0;+ pv->lost_time[2] = 0;+ pv->lost_time[3] = 0;+ /* Setup filters */ /* TODO: Move to work.c? */ if( job->filters )