#define _ISOC99_SOURCE
#undef NDEBUG // always check asserts, the speed effect is far too small to disable them
-#include <math.h>
#include "common/common.h"
#include "ratecontrol.h"
if( h->param.rc.i_vbv_max_bitrate > 0 && h->param.rc.i_vbv_buffer_size > 0 )
{
+ /* We don't support changing the ABR bitrate right now,
+ so if the stream starts as CBR, keep it CBR. */
+ if( rc->b_vbv_min_rate )
+ h->param.rc.i_vbv_max_bitrate = h->param.rc.i_bitrate;
+
if( h->param.rc.i_vbv_buffer_size < (int)(h->param.rc.i_vbv_max_bitrate / rc->fps) )
{
h->param.rc.i_vbv_buffer_size = h->param.rc.i_vbv_max_bitrate / rc->fps;
h->param.rc.i_vbv_buffer_size );
}
- /* We don't support changing the ABR bitrate right now,
- so if the stream starts as CBR, keep it CBR. */
- if( rc->b_vbv_min_rate )
- h->param.rc.i_vbv_max_bitrate = h->param.rc.i_bitrate;
-
int vbv_buffer_size = h->param.rc.i_vbv_buffer_size * 1000;
int vbv_max_bitrate = h->param.rc.i_vbv_max_bitrate * 1000;
/* Init HRD */
- h->sps->vui.hrd.i_bit_rate_unscaled = vbv_max_bitrate;
- h->sps->vui.hrd.i_cpb_size_unscaled = vbv_buffer_size;
if( h->param.i_nal_hrd && b_init )
{
h->sps->vui.hrd.i_cpb_cnt = 1;
x264_log( h, X264_LOG_WARNING, "VBV parameters cannot be changed when NAL HRD is in use\n" );
return;
}
+ h->sps->vui.hrd.i_bit_rate_unscaled = vbv_max_bitrate;
+ h->sps->vui.hrd.i_cpb_size_unscaled = vbv_buffer_size;
+ if( rc->b_vbv_min_rate )
+ rc->bitrate = h->param.rc.i_bitrate * 1000.;
rc->buffer_rate = vbv_max_bitrate / rc->fps;
rc->vbv_max_rate = vbv_max_bitrate;
rc->buffer_size = vbv_buffer_size;
CMP_OPT_FIRST_PASS( "bframes", h->param.i_bframe );
CMP_OPT_FIRST_PASS( "b_pyramid", h->param.i_bframe_pyramid );
CMP_OPT_FIRST_PASS( "intra_refresh", h->param.b_intra_refresh );
- CMP_OPT_FIRST_PASS( "open_gop", h->param.i_open_gop );
+ CMP_OPT_FIRST_PASS( "open_gop", h->param.b_open_gop );
+ CMP_OPT_FIRST_PASS( "bluray_compat", h->param.b_bluray_compat );
if( (p = strstr( opts, "keyint=" )) )
{
char *tok, UNUSED *saveptr=NULL;
z->param = NULL;
z->f_bitrate_factor = 1;
- if( 3 <= sscanf(p, "%u,%u,q=%u%n", &z->i_start, &z->i_end, &z->i_qp, &len) )
+ if( 3 <= sscanf(p, "%d,%d,q=%d%n", &z->i_start, &z->i_end, &z->i_qp, &len) )
z->b_force_qp = 1;
- else if( 3 <= sscanf(p, "%u,%u,b=%f%n", &z->i_start, &z->i_end, &z->f_bitrate_factor, &len) )
+ else if( 3 <= sscanf(p, "%d,%d,b=%f%n", &z->i_start, &z->i_end, &z->f_bitrate_factor, &len) )
z->b_force_qp = 0;
- else if( 2 <= sscanf(p, "%u,%u%n", &z->i_start, &z->i_end, &len) )
+ else if( 2 <= sscanf(p, "%d,%d%n", &z->i_start, &z->i_end, &len) )
z->b_force_qp = 0;
else
{
int mincr = l->mincr;
- /* Blu-ray requires this */
- if( l->level_idc == 41 && h->param.i_nal_hrd )
+ if( h->param.b_bluray_compat )
mincr = 4;
/* High 10 doesn't require minCR, so just set the maximum to a large value. */
rc->qpa_rc =
rc->qpa_aq = 0;
- rc->qp = x264_clip3( (int)(q + 0.5), 0, QP_MAX );
+ rc->qp = x264_clip3( q + 0.5f, 0, QP_MAX );
h->fdec->f_qp_avg_rc =
h->fdec->f_qp_avg_aq =
rc->qpm = q;
int x264_ratecontrol_qp( x264_t *h )
{
x264_emms();
- return x264_clip3( h->rc->qpm + .5, h->param.rc.i_qp_min, h->param.rc.i_qp_max );
+ return x264_clip3( h->rc->qpm + 0.5f, h->param.rc.i_qp_min, h->param.rc.i_qp_max );
}
int x264_ratecontrol_mb_qp( x264_t *h )
float qp_offset = h->fdec->b_kept_as_ref ? h->fenc->f_qp_offset[h->mb.i_mb_xy] : h->fenc->f_qp_offset_aq[h->mb.i_mb_xy];
/* Scale AQ's effect towards zero in emergency mode. */
if( qp > QP_MAX_SPEC )
- qp_offset *= (QP_MAX - qp) / (QP_MAX_SPEC - QP_MAX);
+ qp_offset *= (QP_MAX - qp) / (QP_MAX - QP_MAX_SPEC);
qp += qp_offset;
}
- return x264_clip3( qp + .5, h->param.rc.i_qp_min, h->param.rc.i_qp_max );
+ return x264_clip3( qp + 0.5f, h->param.rc.i_qp_min, h->param.rc.i_qp_max );
}
/* In 2pass, force the same frame types as in the 1st pass */
{
x264_ratecontrol_t *rcc= h->rc;
x264_zone_t *zone = get_zone( h, frame_num );
- double q = pow( rce->blurred_complexity, 1 - rcc->qcompress );
+ double q;
+ if( h->param.rc.b_mb_tree )
+ {
+ double timescale = (double)h->sps->vui.i_num_units_in_tick / h->sps->vui.i_time_scale;
+ q = pow( BASE_FRAME_DURATION / CLIP_DURATION(rce->i_duration * timescale), 1 - h->param.rc.f_qcompress );
+ }
+ else
+ q = pow( rce->blurred_complexity, 1 - rcc->qcompress );
// avoid NaN's in the rc_eq
if( !isfinite(q) || rce->tex_bits + rce->mv_bits == 0 )
return q;
}
-static double get_diff_limited_q(x264_t *h, ratecontrol_entry_t *rce, double q)
+static double get_diff_limited_q(x264_t *h, ratecontrol_entry_t *rce, double q, int frame_num)
{
x264_ratecontrol_t *rcc = h->rc;
const int pict_type = rce->pict_type;
+ x264_zone_t *zone = get_zone( h, frame_num );
// force I/B quants as a function of P quants
const double last_p_q = rcc->last_qscale_for[SLICE_TYPE_P];
rcc->accum_p_qp = mask * (qscale2qp( q ) + rcc->accum_p_qp);
rcc->accum_p_norm = mask * (1 + rcc->accum_p_norm);
}
+
+ if( zone )
+ {
+ if( zone->b_force_qp )
+ q = qp2qscale( zone->i_qp );
+ else
+ q /= zone->f_bitrate_factor;
+ }
+
return q;
}
if( h->sps->vui.hrd.b_cbr_hrd && rct->buffer_fill_final > buffer_size )
{
- filler = ceil( (rct->buffer_fill_final - buffer_size) / (8. * h->sps->vui.i_time_scale) );
+ int64_t scale = (int64_t)h->sps->vui.i_time_scale * 8;
+ filler = (rct->buffer_fill_final - buffer_size + scale - 1) / scale;
bits = X264_MAX( (FILLER_OVERHEAD - h->param.b_annexb), filler ) * 8;
rct->buffer_fill_final -= (uint64_t)bits * h->sps->vui.i_time_scale;
}
rce.s_count = 0;
rce.qscale = 1;
rce.pict_type = pict_type;
+ rce.i_duration = h->fenc->i_duration;
if( h->param.rc.i_rc_method == X264_RC_CRF )
{
COPY(prev_zone);
COPY(qpbuf_pos);
/* these vars can be updated by x264_ratecontrol_init_reconfigurable */
- COPY(buffer_rate);
+ COPY(bitrate);
COPY(buffer_size);
+ COPY(buffer_rate);
+ COPY(vbv_max_rate);
COPY(single_frame_vbv);
COPY(cbr_decay);
- COPY(b_vbv_min_rate);
COPY(rate_factor_constant);
- COPY(bitrate);
+ COPY(rate_factor_max_increment);
#undef COPY
}
if( cur != next )
/* find qscale */
for( int i = 0; i < rcc->num_entries; i++ )
{
- qscale[i] = get_qscale( h, &rcc->entry[i], rate_factor, i );
+ qscale[i] = get_qscale( h, &rcc->entry[i], rate_factor, -1 );
rcc->last_qscale_for[rcc->entry[i].pict_type] = qscale[i];
}
/* fixed I/B qscale relative to P */
for( int i = rcc->num_entries-1; i >= 0; i-- )
{
- qscale[i] = get_diff_limited_q( h, &rcc->entry[i], qscale[i] );
+ qscale[i] = get_diff_limited_q( h, &rcc->entry[i], qscale[i], i );
assert(qscale[i] >= 0);
}