]> git.sesse.net Git - x264/commitdiff
Fix DTS/bitrate calculation if the first PTS wasn't zero
authorAnton Mitrofanov <BugMaster@narod.ru>
Mon, 20 Sep 2010 09:10:13 +0000 (13:10 +0400)
committerFiona Glaser <fiona@x264.com>
Mon, 27 Sep 2010 19:55:45 +0000 (12:55 -0700)
Fix bitrate calculation with DTS compression.

common/common.h
encoder/encoder.c
x264.c
x264.h

index efb25be81796c3cbf9c00b9affcb53087b97cfbf..132cfeeb539b7069b1aa758aa2bdd6506e00318f 100644 (file)
@@ -499,6 +499,7 @@ struct x264_t
         int i_delay;    /* Number of frames buffered for B reordering */
         int     i_bframe_delay;
         int64_t i_bframe_delay_time;
+        int64_t i_first_pts;
         int64_t i_init_delta;
         int64_t i_prev_reordered_pts[2];
         int64_t i_largest_pts;
index a9326a95c01be3f8291a9563e567fb8fb1207c61..beffda8bff0a990de5ea38cd9924a02a4032eed1 100644 (file)
@@ -2329,8 +2329,10 @@ int     x264_encoder_encode( x264_t *h,
 
         fenc->i_frame = h->frames.i_input++;
 
+        if( fenc->i_frame == 0 )
+            h->frames.i_first_pts = fenc->i_pts;
         if( h->frames.i_bframe_delay && fenc->i_frame == h->frames.i_bframe_delay )
-            h->frames.i_bframe_delay_time = fenc->i_pts;
+            h->frames.i_bframe_delay_time = fenc->i_pts - h->frames.i_first_pts;
 
         if( h->param.b_vfr_input && fenc->i_pts <= h->frames.i_largest_pts )
             x264_log( h, X264_LOG_WARNING, "non-strictly-monotonic PTS\n" );
@@ -2495,8 +2497,8 @@ int     x264_encoder_encode( x264_t *h,
             {
                 /* DTS compression */
                 if( h->i_frame == 1 )
-                    thread_current->frames.i_init_delta = h->fenc->i_reordered_pts * h->i_dts_compress_multiplier;
-                h->fdec->i_dts = h->i_frame * thread_current->frames.i_init_delta / h->i_dts_compress_multiplier;
+                    thread_current->frames.i_init_delta = (h->fenc->i_reordered_pts - h->frames.i_first_pts) * h->i_dts_compress_multiplier;
+                h->fdec->i_dts = h->i_frame * thread_current->frames.i_init_delta / h->i_dts_compress_multiplier + h->frames.i_first_pts * h->i_dts_compress_multiplier;
             }
         }
         else
@@ -3110,7 +3112,8 @@ void    x264_encoder_close  ( x264_t *h )
             f_bitrate = fps * SUM3(h->stat.i_frame_size) / i_count / 125;
         else
         {
-            float duration = (float)(2 * h->frames.i_largest_pts - h->frames.i_second_largest_pts) * h->param.i_timebase_num / h->param.i_timebase_den;
+            float duration = (float)(2 * h->frames.i_largest_pts - h->frames.i_second_largest_pts - h->frames.i_first_pts)
+                           * h->i_dts_compress_multiplier * h->param.i_timebase_num / h->param.i_timebase_den;
             f_bitrate = SUM3(h->stat.i_frame_size) / duration / 125;
         }
 
diff --git a/x264.c b/x264.c
index d9239c70a3505c4c17c66150d22bea040665204b..3bb3a0d007bfb0212d9b48c7c423ac76ddf806cc 100644 (file)
--- a/x264.c
+++ b/x264.c
@@ -1584,7 +1584,7 @@ static int  Encode( x264_param_t *param, cli_opt_t *opt )
     int64_t second_largest_pts = -1;
     int64_t ticks_per_frame;
     double  duration;
-    int     prev_timebase_den = param->i_timebase_den / gcd( param->i_timebase_num, param->i_timebase_den );
+    int     prev_timebase_den;
     int     dts_compress_multiplier;
     double  pulldown_pts = 0;
 
@@ -1603,6 +1603,8 @@ static int  Encode( x264_param_t *param, cli_opt_t *opt )
         param->i_timebase_den = param->i_fps_num * pulldown->fps_factor;
     }
 
+    prev_timebase_den = param->i_timebase_den / gcd( param->i_timebase_num, param->i_timebase_den );
+
     if( ( h = x264_encoder_open( param ) ) == NULL )
     {
         x264_cli_log( "x264", X264_LOG_ERROR, "x264_encoder_open failed\n" );
@@ -1727,6 +1729,8 @@ static int  Encode( x264_param_t *param, cli_opt_t *opt )
     if( pts_warning_cnt >= MAX_PTS_WARNING && cli_log_level < X264_LOG_DEBUG )
         x264_cli_log( "x264", X264_LOG_WARNING, "%d suppressed nonmonotonic pts warnings\n", pts_warning_cnt-MAX_PTS_WARNING );
 
+    largest_pts *= dts_compress_multiplier;
+    second_largest_pts *= dts_compress_multiplier;
     /* duration algorithm fails when only 1 frame is output */
     if( i_frame_output == 1 )
         duration = (double)param->i_fps_den / param->i_fps_num;
@@ -1734,8 +1738,6 @@ static int  Encode( x264_param_t *param, cli_opt_t *opt )
         duration = (double)(2 * last_dts - prev_dts - first_dts) * param->i_timebase_num / param->i_timebase_den;
     else
         duration = (double)(2 * largest_pts - second_largest_pts) * param->i_timebase_num / param->i_timebase_den;
-    if( !(opt->i_pulldown && !param->b_vfr_input) )
-        duration *= dts_compress_multiplier;
 
     i_end = x264_mdate();
     /* Erase progress indicator before printing encoding stats. */
@@ -1754,7 +1756,7 @@ static int  Encode( x264_param_t *param, cli_opt_t *opt )
     }
 
     filter.free( opt->hin );
-    output.close_file( opt->hout, largest_pts * dts_compress_multiplier, second_largest_pts * dts_compress_multiplier );
+    output.close_file( opt->hout, largest_pts, second_largest_pts );
 
     if( i_frame_output > 0 )
     {
diff --git a/x264.h b/x264.h
index cbf332e60410fec472ca03f63d08d85f90355d47..73e0bbad0e5605c9cdb731241a75b3d11a751e61 100644 (file)
--- a/x264.h
+++ b/x264.h
@@ -653,7 +653,7 @@ typedef struct
     int     b_keyframe;
     /* In: user pts, Out: pts of encoded picture (user)*/
     int64_t i_pts;
-    /* Out: frame dts. Since the pts of the first frame is always zero,
+    /* Out: frame dts. When the pts of the first frame is close to zero,
      *      initial frames may have a negative dts which must be dealt with by any muxer */
     int64_t i_dts;
     /* In: custom encoding parameters to be set from this frame forwards