From: Anton Mitrofanov Date: Mon, 20 Sep 2010 09:10:13 +0000 (+0400) Subject: Fix DTS/bitrate calculation if the first PTS wasn't zero X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=f655f8ad1554cef6fc0040d7b7fa2fcf22ba3b15;p=x264 Fix DTS/bitrate calculation if the first PTS wasn't zero Fix bitrate calculation with DTS compression. --- diff --git a/common/common.h b/common/common.h index efb25be8..132cfeeb 100644 --- a/common/common.h +++ b/common/common.h @@ -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; diff --git a/encoder/encoder.c b/encoder/encoder.c index a9326a95..beffda8b 100644 --- a/encoder/encoder.c +++ b/encoder/encoder.c @@ -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 d9239c70..3bb3a0d0 100644 --- 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 cbf332e6..73e0bbad 100644 --- 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