+ if (*buf_out && job->vfr)
+ {
+ 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( job->vfr )
+ {
+ if( hb_fifo_size( pv->delay_queue ) >= 4 )
+ {
+ *buf_out = hb_fifo_get( pv->delay_queue );
+ }
+ }
+
+ if( *buf_out && job->vfr)
+ {
+ /* The current frame exists. That means it hasn't been dropped by a filter.
+ Make it accessible as ivtc_buffer so we can edit its duration if needed. */
+ ivtc_buffer = *buf_out;
+
+ if( pv->lost_time[3] > 0 )
+ {
+ /*
+ * A frame's been dropped earlier by VFR detelecine.
+ * Gotta make up the lost time. This will also
+ * 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
+ * the dropped frame, so to slow down the right
+ * ones you need a 2 frame delay between
+ * reading input and writing output.
+ */
+
+ /* We want to extend the outputted frame's duration by the value
+ stored in the 4th slot of the lost_time array. Because we need
+ to adjust all the values in the array so they're contiguous,
+ extend the duration inside the array first, before applying
+ it to the current frame buffer. */
+ pv->last_stop[3] += pv->lost_time[3];
+
+ /* Log how much time has been added back in to the video. */
+ pv->total_gained_time += pv->lost_time[3];
+
+ /* We've pulled the 4th value from the lost_time array
+ and added it to the last_stop array's 4th slot. Now, rotate the
+ lost_time array so the 4th slot now holds the 3rd's value, and
+ so on down the line, and set the 0 index 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;
+
+ /* Log how many frames have had their durations extended. */
+ pv->extended_frames++;
+ }
+
+ /* 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.
+ If it needed its duration extended to make up
+ lost time, it will have happened above. */
+ ivtc_buffer->start = pv->last_start[3];
+ ivtc_buffer->stop = pv->last_stop[3];
+
+ /* Set the 3rd cached frame to start when this one stops,
+ and so on down the line. If any of them need to be
+ extended as well to make up lost time, it'll be handled
+ on the next loop through the renderer. */
+ int i;
+ for (i = 2; i >= 0; i--)
+ {
+ int temp_duration = pv->last_stop[i] - pv->last_start[i];
+ pv->last_start[i] = pv->last_stop[i+1];
+ pv->last_stop[i] = pv->last_start[i] + temp_duration;
+ }
+
+ /* If we have a pending chapter mark and this frame is at
+ or after the time of the mark, mark this frame & clear
+ our pending mark. */
+ if( pv->chapter_time && pv->chapter_time <= ivtc_buffer->start )
+ {
+ ivtc_buffer->new_chap = pv->chapter_val;
+ pv->chapter_time = 0;
+ }
+
+ }
+