From 6a9a25943dfea697a393ca8bf9e1eb3bce8f88f7 Mon Sep 17 00:00:00 2001 From: John Stebbins Date: Wed, 30 May 2018 09:21:56 -0700 Subject: [PATCH] encx264: fix encoding of very short duration frames We had a hash of limited size where we stored frame durations in encx264. This hash has not been necessary since we moved to using libavformat for muxing. Since the limited size of the hash put constraints on how short frame durations could be, I've eliminated it. This means that after the encoder, hb_buffer_t s.stop and s.duration are no longer valid. But since they are not used during muxing, this is not a problem. Fixes https://github.com/HandBrake/HandBrake/issues/1374 --- libhb/encx264.c | 43 ++----------------------------------------- libhb/sync.c | 6 +----- 2 files changed, 3 insertions(+), 46 deletions(-) diff --git a/libhb/encx264.c b/libhb/encx264.c index b49d55518..638cf4ff7 100644 --- a/libhb/encx264.c +++ b/libhb/encx264.c @@ -28,24 +28,6 @@ hb_work_object_t hb_encx264 = #define DTS_BUFFER_SIZE 32 -/* - * The frame info struct remembers information about each frame across calls - * to x264_encoder_encode. Since frames are uniquely identified by their - * timestamp, we use some bits of the timestamp as an index. The LSB is - * chosen so that two successive frames will have different values in the - * bits over any plausible range of frame rates. (Starting with bit 8 allows - * any frame rate slower than 352fps.) The MSB determines the size of the array. - * It is chosen so that two frames can't use the same slot during the - * encoder's max frame delay (set by the standard as 16 frames) and so - * that, up to some minimum frame rate, frames are guaranteed to map to - * different slots. (An MSB of 17 which is 2^(17-8+1) = 1024 slots guarantees - * no collisions down to a rate of .7 fps). - */ -#define FRAME_INFO_MAX2 (8) // 2^8 = 256; 90000/256 = 352 frames/sec -#define FRAME_INFO_MIN2 (17) // 2^17 = 128K; 90000/131072 = 1.4 frames/sec -#define FRAME_INFO_SIZE (1 << (FRAME_INFO_MIN2 - FRAME_INFO_MAX2 + 1)) -#define FRAME_INFO_MASK (FRAME_INFO_SIZE - 1) - struct hb_work_private_s { hb_job_t * job; @@ -56,10 +38,6 @@ struct hb_work_private_s hb_chapter_queue_t * chapter_queue; - struct { - int64_t duration; - } frame_info[FRAME_INFO_SIZE]; - char filename[1024]; // Multiple bit-depth @@ -663,22 +641,6 @@ void encx264Close( hb_work_object_t * w ) w->private_data = NULL; } -/* - * see comments in definition of 'frame_info' in pv struct for description - * of what these routines are doing. - */ -static void save_frame_info( hb_work_private_t * pv, hb_buffer_t * in ) -{ - int i = (in->s.start >> FRAME_INFO_MAX2) & FRAME_INFO_MASK; - pv->frame_info[i].duration = in->s.stop - in->s.start; -} - -static int64_t get_frame_duration( hb_work_private_t * pv, int64_t pts ) -{ - int i = (pts >> FRAME_INFO_MAX2) & FRAME_INFO_MASK; - return pv->frame_info[i].duration; -} - static hb_buffer_t *nal_encode( hb_work_object_t *w, x264_picture_t *pic_out, int i_nal, x264_nal_t *nal ) { @@ -692,9 +654,9 @@ static hb_buffer_t *nal_encode( hb_work_object_t *w, x264_picture_t *pic_out, buf->s.frametype = 0; // use the pts to get the original frame's duration. - buf->s.duration = get_frame_duration( pv, pic_out->i_pts ); + buf->s.duration = AV_NOPTS_VALUE; buf->s.start = pic_out->i_pts; - buf->s.stop = buf->s.start + buf->s.duration; + buf->s.stop = AV_NOPTS_VALUE; buf->s.renderOffset = pic_out->i_dts; if ( !w->config->init_delay && pic_out->i_dts < 0 ) { @@ -882,7 +844,6 @@ static hb_buffer_t *x264_encode( hb_work_object_t *w, hb_buffer_t *in ) // Remember info about this frame that we need to pass across // the x264_encoder_encode call (since it reorders frames). - save_frame_info( pv, in ); /* Feed the input PTS to x264 so it can figure out proper output PTS */ pv->pic_in.i_pts = in->s.start; diff --git a/libhb/sync.c b/libhb/sync.c index f0b1b9abc..639baad46 100644 --- a/libhb/sync.c +++ b/libhb/sync.c @@ -1264,8 +1264,7 @@ static void streamFlush( sync_stream_t * stream ) { stream->max_frame_duration = buf->s.duration; } - if ((buf->s.start < 0) || - (stream->type == SYNC_TYPE_VIDEO && buf->s.duration < 256)) + if (buf->s.start < 0) { // The pipeline can't handle negative timestamps // and it is sometimes not possible to avoid one @@ -1275,9 +1274,6 @@ static void streamFlush( sync_stream_t * stream ) // until we have seen the first PTS for all streams // so sometimes we may start before we have seen // the earliest PTS - // - // Also, encx264.c can't handle timestamps that are spaced - // less than 256 ticks apart. saveChap(stream, buf); hb_buffer_close(&buf); } -- 2.40.0