]> granicus.if.org Git - handbrake/commitdiff
encx264: fix encoding of very short duration frames
authorJohn Stebbins <jstebbins.hb@gmail.com>
Wed, 30 May 2018 16:21:56 +0000 (09:21 -0700)
committerJohn Stebbins <jstebbins.hb@gmail.com>
Wed, 30 May 2018 16:27:37 +0000 (09:27 -0700)
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
libhb/sync.c

index b49d5551805fd8f5d5304cd18e261b8e6bdd961e..638cf4ff78d103cb6c362db0153cfdbc89fc8520 100644 (file)
@@ -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;
index f0b1b9abc6953f3d256fe4fd3f57761d50b1c55e..639baad46c226616318e41e96e5e07543f894dbf 100644 (file)
@@ -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);
             }