diff options
author | John Stebbins <[email protected]> | 2017-02-14 16:25:40 -0700 |
---|---|---|
committer | John Stebbins <[email protected]> | 2017-02-14 16:27:26 -0700 |
commit | 5429a92c51682240acbbe7b150d314d993d7d3a0 (patch) | |
tree | 51b2b4ef27d3c3a97e76cf43c6a4b15c55ffac45 | |
parent | df5601053a8857ad8e2b59d56e82bac7f44e96fb (diff) |
mux: shift timestamps by largest encoder delay
This prevents libav from adding an mp4 edit list entry that causes a
properly functioning player to drop the first couple of audio frames.
-rw-r--r-- | libhb/common.h | 1 | ||||
-rw-r--r-- | libhb/encavcodec.c | 2 | ||||
-rw-r--r-- | libhb/encavcodecaudio.c | 7 | ||||
-rw-r--r-- | libhb/encx264.c | 4 | ||||
-rw-r--r-- | libhb/encx265.c | 4 | ||||
-rw-r--r-- | libhb/hbtypes.h | 2 | ||||
-rw-r--r-- | libhb/internal.h | 8 | ||||
-rw-r--r-- | libhb/muxavformat.c | 34 |
8 files changed, 49 insertions, 13 deletions
diff --git a/libhb/common.h b/libhb/common.h index aa2f2ba3e..06a22c2a8 100644 --- a/libhb/common.h +++ b/libhb/common.h @@ -749,7 +749,6 @@ struct hb_audio_config_s int normalize_mix_level; /* mix level normalization (boolean) */ int dither_method; /* dither algorithm */ char * name; /* Output track name */ - int delay; } out; /* Input */ diff --git a/libhb/encavcodec.c b/libhb/encavcodec.c index 63c325a40..76fe3e7c7 100644 --- a/libhb/encavcodec.c +++ b/libhb/encavcodec.c @@ -444,7 +444,7 @@ static void compute_dts_offset( hb_work_private_t * pv, hb_buffer_t * buf ) if ( ( pv->frameno_in ) == pv->job->areBframes ) { pv->dts_delay = buf->s.start; - pv->job->config.h264.init_delay = pv->dts_delay; + pv->job->config.init_delay = pv->dts_delay; } } } diff --git a/libhb/encavcodecaudio.c b/libhb/encavcodecaudio.c index e376d4436..9f07f4a79 100644 --- a/libhb/encavcodecaudio.c +++ b/libhb/encavcodecaudio.c @@ -200,6 +200,9 @@ static int encavcodecaInit(hb_work_object_t *w, hb_job_t *job) hb_error("encavcodecaInit: hb_avcodec_open() failed"); return 1; } + w->config->init_delay = av_rescale_q(context->delay, context->time_base, + (AVRational){1, 90000}); + // avcodec_open populates the opts dictionary with the // things it didn't recognize. AVDictionaryEntry *t = NULL; @@ -268,9 +271,6 @@ static int encavcodecaInit(hb_work_object_t *w, hb_job_t *job) w->config->extradata.length = context->extradata_size; } - audio->config.out.delay = av_rescale_q(context->delay, context->time_base, - (AVRational){1, 90000}); - return 0; } @@ -426,7 +426,6 @@ static void Encode(hb_work_object_t *w, hb_buffer_list_t *list) audio->config.out.samplerate)); frame.pts = av_rescale(frame.pts, pv->context->sample_rate, 90000); - // Encode ret = avcodec_send_frame(pv->context, &frame); if (ret < 0) diff --git a/libhb/encx264.c b/libhb/encx264.c index 1fccd7d27..1d2fd997e 100644 --- a/libhb/encx264.c +++ b/libhb/encx264.c @@ -654,9 +654,9 @@ static hb_buffer_t *nal_encode( hb_work_object_t *w, x264_picture_t *pic_out, buf->s.start = pic_out->i_pts; buf->s.stop = buf->s.start + buf->s.duration; buf->s.renderOffset = pic_out->i_dts; - if ( !w->config->h264.init_delay && pic_out->i_dts < 0 ) + if ( !w->config->init_delay && pic_out->i_dts < 0 ) { - w->config->h264.init_delay = -pic_out->i_dts; + w->config->init_delay = -pic_out->i_dts; } /* Determine what type of frame we have. */ diff --git a/libhb/encx265.c b/libhb/encx265.c index 0c5d4141a..90d786983 100644 --- a/libhb/encx265.c +++ b/libhb/encx265.c @@ -414,9 +414,9 @@ static hb_buffer_t* nal_encode(hb_work_object_t *w, buf->s.stop = pic_out->pts + buf->s.duration; buf->s.start = pic_out->pts; buf->s.renderOffset = pic_out->dts; - if (w->config->h264.init_delay == 0 && pic_out->dts < 0) + if (w->config->init_delay == 0 && pic_out->dts < 0) { - w->config->h264.init_delay -= pic_out->dts; + w->config->init_delay -= pic_out->dts; } switch (pic_out->sliceType) diff --git a/libhb/hbtypes.h b/libhb/hbtypes.h index 7c7d2c679..064ba7b6d 100644 --- a/libhb/hbtypes.h +++ b/libhb/hbtypes.h @@ -34,7 +34,7 @@ typedef struct hb_attachment_s hb_attachment_t; typedef struct hb_metadata_s hb_metadata_t; typedef struct hb_coverart_s hb_coverart_t; typedef struct hb_state_s hb_state_t; -typedef union hb_esconfig_u hb_esconfig_t; +typedef struct hb_esconfig_s hb_esconfig_t; typedef struct hb_work_private_s hb_work_private_t; typedef struct hb_work_object_s hb_work_object_t; typedef struct hb_filter_private_s hb_filter_private_t; diff --git a/libhb/internal.h b/libhb/internal.h index 1a7094429..1e79447f8 100644 --- a/libhb/internal.h +++ b/libhb/internal.h @@ -373,8 +373,12 @@ void hb_stream_set_need_keyframe( hb_stream_t *stream, int need_keyframe ); * Work objects **********************************************************************/ #define HB_CONFIG_MAX_SIZE (2*8192) -union hb_esconfig_u +struct hb_esconfig_s { + int init_delay; + + union + { struct { @@ -388,7 +392,6 @@ union hb_esconfig_u int sps_length; uint8_t pps[HB_CONFIG_MAX_SIZE]; int pps_length; - int init_delay; } h264; struct @@ -413,6 +416,7 @@ union hb_esconfig_u uint8_t headers[3][HB_CONFIG_MAX_SIZE]; char *language; } vorbis; + }; }; enum diff --git a/libhb/muxavformat.c b/libhb/muxavformat.c index e042a9d1c..5f15b7970 100644 --- a/libhb/muxavformat.c +++ b/libhb/muxavformat.c @@ -44,6 +44,7 @@ struct hb_mux_object_s AVFormatContext * oc; AVRational time_base; + int64_t delay; int ntracks; hb_mux_data_t ** tracks; @@ -107,6 +108,25 @@ static char* lookup_lang_code(int mux, char *iso639_2) return out; } +static int64_t compute_delay(hb_job_t * job) +{ + int64_t delay = 0; + + if (job->config.init_delay > delay) + delay = job->config.init_delay; + + int ii, count; + count = hb_list_count(job->list_audio); + for (ii = 0; ii < count; ii++) + { + hb_audio_t * audio = hb_list_item(job->list_audio, ii); + if (audio->priv.config.init_delay > delay) + delay = audio->priv.config.init_delay; + } + + return delay; +} + /********************************************************************** * avformatInit ********************************************************************** @@ -130,6 +150,7 @@ static int avformatInit( hb_mux_object_t * m ) uint8_t need_fonts = 0; char *lang; + m->delay = AV_NOPTS_VALUE; max_tracks = 1 + hb_list_count( job->list_audio ) + hb_list_count( job->list_subtitle ); @@ -1064,6 +1085,10 @@ static int avformatMux(hb_mux_object_t *m, hb_mux_data_t *track, hb_buffer_t *bu hb_job_t * job = m->job; uint8_t * sub_out = NULL; + if (m->delay == AV_NOPTS_VALUE) + { + m->delay = compute_delay(m->job); + } if (track->type == MUX_TYPE_VIDEO && (job->mux & HB_MUX_MASK_MP4)) { // compute dts duration for MP4 files @@ -1098,6 +1123,15 @@ static int avformatMux(hb_mux_object_t *m, hb_mux_data_t *track, hb_buffer_t *bu return 0; } + buf->s.start += m->delay; + if (buf->s.renderOffset != AV_NOPTS_VALUE) + { + buf->s.renderOffset += m->delay; + } + if (buf->s.stop != AV_NOPTS_VALUE) + { + buf->s.stop += m->delay; + } if (track->type == MUX_TYPE_VIDEO && (job->mux & HB_MUX_MASK_MKV) && buf->s.renderOffset < 0) { |