Index: libhb/muxmp4.c===================================================================--- libhb/muxmp4.c (revision 1128)+++ libhb/muxmp4.c (working copy)@@ -412,16 +412,6 @@ duration = MP4_INVALID_DURATION; }- /* When we do get the first keyframe, use its duration as the- initial delay added to the frame order offset for b-frames.- Because of b-pyramid, double this duration when there are- b-pyramids, as denoted by job->areBframes equalling 2. */- if ((mux_data->track == 1) && (thisSample == 0) && (buf->frametype & HB_FRAME_KEY) && (job->vcodec == HB_VCODEC_X264))- {- initDelay = buf->renderOffset;- thisSample++;- }- /* Here's where the sample actually gets muxed. If it's an audio sample, don't offset the sample's playback. If it's a video sample and there are no b-frames, ditto.@@ -474,21 +464,6 @@ MP4SampleId i; MP4Duration renderingOffset = 2000000000, tmp;- // Find the smallest rendering offset- for(i = 1; i <= count; i++)- {- tmp = MP4GetSampleRenderingOffset(m->file, 1, i);- if(tmp < renderingOffset)- renderingOffset = tmp;- }- - // Adjust all ctts values down by renderingOffset- for(i = 1; i <= count; i++)- {- MP4SetSampleRenderingOffset(m->file,1,i,- MP4GetSampleRenderingOffset(m->file,1,i) - renderingOffset);- }- // Insert track edit to get A/V back in sync. The edit amount is // the rendering offset of the first sample. MP4AddTrackEdit(m->file, 1, MP4_INVALID_EDIT_ID, MP4GetSampleRenderingOffset(m->file,1,1),Index: libhb/encx264.c===================================================================--- libhb/encx264.c (revision 1128)+++ libhb/encx264.c (working copy)@@ -35,6 +35,7 @@ // Internal queue of DTS start/stop values. int64_t dts_start[DTS_BUFFER_SIZE]; int64_t dts_stop[DTS_BUFFER_SIZE];+ int64_t init_delay; int64_t dts_write_index; int64_t dts_read_index;@@ -250,6 +251,32 @@ pv->dts_read_index = 0; pv->next_chap = 0;+ if (job->areBframes)+ {+ /* Basic initDelay value is the clockrate divided by the FPS+ -- the length of one frame in clockticks. */+ pv->init_delay = (float)90000 / (float)((float)job->vrate / (float)job->vrate_base);++ /* 23.976-length frames are 3753.75 ticks long. That means 25%+ will come out as 3753, 75% will be 3754. The delay has to be+ the longest possible frame duration, 3754. However, 3753.75+ gets truncated to 3753, so if that's what it is, ++ it. */+ if (pv->init_delay == 3753)+ pv->init_delay++;++ /* For VFR, libhb sees the FPS as 29.97, but the longest frames+ will use the duration of frames running at 23.976fps instead.. */+ if (job->vfr)+ {+ pv->init_delay = 3754;+ }++ /* The delay is 2 frames for regular b-frames, 3 for b-pyramid.+ Since job->areBframes is 1 for b-frames and 2 for b-pyramid,+ add one to it and use it as a multiplier. */+ pv->init_delay *= ( job->areBframes + 1); + }+ return 0; }@@ -447,7 +474,7 @@ value is pretty much guaranteed to be positive. The muxing code will minimize the renderOffset at the end. */- buf->renderOffset = pic_out.i_pts - dts_start + 1000000;+ buf->renderOffset = pic_out.i_pts - dts_start + pv->init_delay; /* Send out the next dts values */ buf->start = dts_start;