rendered paste bodyIndex: libhb/detelecine.c===================================================================--- libhb/detelecine.c (revision 1022)+++ libhb/detelecine.c (working copy)@@ -975,7 +975,7 @@ } else {- goto output_frame;+ goto discard_frame; } } @@ -987,7 +987,7 @@ if (!frame) {- goto output_frame;+ goto discard_frame; } if( frame->length < 2 ) {@@ -995,19 +995,19 @@ if( !(buf_in->flags & PIC_FLAG_REPEAT_FIRST_FIELD) ) {- goto output_frame;+ goto discard_frame; } frame = pullup_get_frame( ctx ); if( !frame ) {- goto output_frame;+ goto discard_frame; } if( frame->length < 2 ) { pullup_release_frame( frame );- goto output_frame;+ goto discard_frame; } } }@@ -1034,6 +1034,15 @@ output_frame: *buf_out = pv->buf_out; return FILTER_OK;++/* This and all discard_frame calls shown above are+ the result of me restoring the functionality in+ pullup that huevos_rancheros disabled because+ HB couldn't handle it. */+discard_frame: + *buf_out = pv->buf_out;+ return FILTER_DROP;+ } Index: libhb/muxmp4.c===================================================================--- libhb/muxmp4.c (revision 1022)+++ libhb/muxmp4.c (working copy)@@ -380,7 +380,7 @@ /* Because we use the audio samplerate as the timescale, we have to use potentially variable durations so the video doesn't go out of sync */- duration = ( buf->stop * job->arate / 90000 ) - m->sum_dur;+ duration = ( ( buf->stop * job->arate / 90000 ) - ( buf->start * job->arate / 90000 ) ); m->sum_dur += duration; } elseIndex: libhb/render.c===================================================================--- libhb/render.c (revision 1022)+++ libhb/render.c (working copy)@@ -9,6 +9,10 @@ #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;+ struct hb_work_private_s { hb_job_t * job;@@ -225,6 +229,9 @@ } else if( result == FILTER_DROP ) {+ /* A drop means detelecine's latched its teeth onto+ something and has duped frames to discard. */+ dropped_frames++; hb_fifo_get( pv->subtitle_queue ); buf_tmp_in = NULL; break;@@ -271,6 +278,24 @@ /* Set output to render buffer */ (*buf_out) = buf_render; + if ( buf_tmp_in )+ {+ /* 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.+ */++ if ( (dropped_frames) &&( dropped_frames * 4 ) > extended_durations )+ {+ buf_render->stop = buf_render->stop + (90090000 / 120000);+ extended_durations++;+ }+ }+ if( buf_tmp_in == NULL ) { /* Teardown and cleanup buffers if we are emitting NULL */@@ -297,6 +322,10 @@ 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 ticks", (dropped_frames * 3003) - (extended_durations * (90090000 / 120000) ) );+ hb_work_private_t * pv = w->private_data; /* Cleanup subtitle queue */