+ /*
+ * The concept of variable bitrate video was a bit too advanced for
+ * Microsoft so AVI doesn't support it. Since almost all dvd
+ * video is VBR we have to convert it to constant bit rate to
+ * put it in an AVI container. So here we duplicate, drop and
+ * otherwise trash video frames to appease the gods of Redmond.
+ */
+
+ /* mpeg durations are exact when expressed in ticks of the
+ * 27MHz System clock but not in HB's 90KHz PTS clock. To avoid
+ * a truncation bias that will eventually cause the audio to desync
+ * we compute the duration of the next frame using 27MHz ticks
+ * then truncate it to 90KHz. */
+ duration = ( (int64_t)(pv->count_frames + 1 ) * job->vrate_base ) / 300 -
+ pv->next_start;
+
+ /* We don't want the input & output clocks to be exactly in phase
+ * otherwise small variations in the time will cause us to think
+ * we're a full frame off & there will be lots of drops and dups.
+ * We offset the input clock by half the duration so it's maximally
+ * out of phase with the output clock. */
+ if( cur->start < pv->next_start - ( duration >> 1 ) )
+ {
+ /* current frame too old - drop it */
+ if ( cur->new_chap )
+ {
+ pv->chap_mark = cur->new_chap;
+ }
+ hb_buffer_close( &cur );
+ pv->cur = cur = hb_fifo_get( job->fifo_raw );
+ pv->next_pts = next->start;
+ ++pv->drops;
+ continue;
+ }
+
+ if( next->start > pv->next_start + duration + ( duration >> 1 ) )
+ {
+ /* next frame too far ahead - dup current frame */
+ buf_tmp = hb_buffer_init( cur->size );
+ hb_buffer_copy_settings( buf_tmp, cur );
+ memcpy( buf_tmp->data, cur->data, cur->size );
+ buf_tmp->sequence = cur->sequence;
+ ++pv->dups;
+ }
+ else
+ {
+ /* this frame in our time window & doesn't need to be duped */
+ buf_tmp = cur;
+ pv->cur = cur = hb_fifo_get( job->fifo_raw );
+ pv->next_pts = next->start;
+ }