Commit 74021a5a authored by Rostislav Pehlivanov's avatar Rostislav Pehlivanov

Implement twopass support for the xiphrc system

This commit implements support for twopass encoding using the xiphrc
experimental rate control system. Most of the code and logic comes
from the theora project encoder.

Currently support is limited to the bitrate targeting mode of the
rate control system and while it does visibly improve quality and does
bring rate closer to the target than the one pass mode there's still
tuning and bug fixing to be done.

Change-Id: Iae0d65bbce5ddfbb95b436e2238a43d6100a23b3
parent f0fbf9d9
......@@ -293,13 +293,16 @@ static aom_codec_err_t validate_config(aom_codec_alg_priv_t *ctx,
ERROR("Option --tune=ssim is not currently supported in AV1.");
if (cfg->g_pass == AOM_RC_LAST_PASS) {
#if !CONFIG_XIPHRC
const size_t packet_sz = sizeof(FIRSTPASS_STATS);
const int n_packets = (int)(cfg->rc_twopass_stats_in.sz / packet_sz);
const FIRSTPASS_STATS *stats;
#endif
if (cfg->rc_twopass_stats_in.buf == NULL)
ERROR("rc_twopass_stats_in.buf not set.");
#if !CONFIG_XIPHRC
if (cfg->rc_twopass_stats_in.sz % packet_sz)
ERROR("rc_twopass_stats_in.sz indicates truncated packet.");
......@@ -311,6 +314,7 @@ static aom_codec_err_t validate_config(aom_codec_alg_priv_t *ctx,
if ((int)(stats->count + 0.5) != n_packets - 1)
ERROR("rc_twopass_stats_in missing EOS stats packet");
#endif
}
#if !CONFIG_AOM_HIGHBITDEPTH
......
......@@ -2187,6 +2187,7 @@ AV1_COMP *av1_create_compressor(AV1EncoderConfig *oxcf,
cpi->od_rc.keyframe_rate = oxcf->key_freq;
cpi->od_rc.goldenframe_rate = FIXED_GF_INTERVAL;
cpi->od_rc.altref_rate = 25;
cpi->od_rc.firstpass_quant = 1;
cpi->od_rc.bit_depth = cm->bit_depth;
cpi->od_rc.minq = oxcf->best_allowed_q;
cpi->od_rc.maxq = oxcf->worst_allowed_q;
......@@ -2314,6 +2315,12 @@ AV1_COMP *av1_create_compressor(AV1EncoderConfig *oxcf,
kf_list = fopen("kf_list.stt", "w");
#endif
#if CONFIG_XIPHRC
if (oxcf->pass == 2) {
cpi->od_rc.twopass_allframes_buf = oxcf->two_pass_stats_in.buf;
cpi->od_rc.twopass_allframes_buf_size = oxcf->two_pass_stats_in.sz;
}
#else
if (oxcf->pass == 1) {
av1_init_first_pass(cpi);
} else if (oxcf->pass == 2) {
......@@ -2339,6 +2346,7 @@ AV1_COMP *av1_create_compressor(AV1EncoderConfig *oxcf,
av1_init_second_pass(cpi);
}
#endif
init_upsampled_ref_frame_bufs(cpi);
......@@ -3972,9 +3980,11 @@ static void set_frame_size(AV1_COMP *cpi) {
}
}
#if !CONFIG_XIPHRC
if (oxcf->pass == 2) {
av1_set_target_rate(cpi);
}
#endif
alloc_frame_mvs(cm, cm->new_fb_idx);
......@@ -4705,7 +4715,7 @@ static void make_update_tile_list_enc(AV1_COMP *cpi, const int tile_rows,
#endif
static void encode_frame_to_data_rate(AV1_COMP *cpi, size_t *size,
uint8_t *dest,
uint8_t *dest, int skip_adapt,
unsigned int *frame_flags) {
AV1_COMMON *const cm = &cpi->common;
const AV1EncoderConfig *const oxcf = &cpi->oxcf;
......@@ -4951,6 +4961,8 @@ static void encode_frame_to_data_rate(AV1_COMP *cpi, size_t *size,
// Build the bitstream
av1_pack_bitstream(cpi, dest, size);
if (skip_adapt) return;
#if CONFIG_REFERENCE_BUFFER
{
int i;
......@@ -5099,7 +5111,7 @@ static void encode_frame_to_data_rate(AV1_COMP *cpi, size_t *size,
}
static void Pass0Encode(AV1_COMP *cpi, size_t *size, uint8_t *dest,
unsigned int *frame_flags) {
int skip_adapt, unsigned int *frame_flags) {
#if CONFIG_XIPHRC
int64_t ip_count;
int frame_type, is_golden, is_altref;
......@@ -5132,12 +5144,13 @@ static void Pass0Encode(AV1_COMP *cpi, size_t *size, uint8_t *dest,
av1_rc_get_one_pass_vbr_params(cpi);
}
#endif
encode_frame_to_data_rate(cpi, size, dest, frame_flags);
encode_frame_to_data_rate(cpi, size, dest, skip_adapt, frame_flags);
}
#if !CONFIG_XIPHRC
static void Pass2Encode(AV1_COMP *cpi, size_t *size, uint8_t *dest,
unsigned int *frame_flags) {
encode_frame_to_data_rate(cpi, size, dest, frame_flags);
encode_frame_to_data_rate(cpi, size, dest, 0, frame_flags);
#if CONFIG_EXT_REFS
// Do not do post-encoding update for those frames that do not have a spot in
......@@ -5151,6 +5164,7 @@ static void Pass2Encode(AV1_COMP *cpi, size_t *size, uint8_t *dest,
av1_twopass_postencode_update(cpi);
#endif // CONFIG_EXT_REFS
}
#endif
static void init_ref_frame_bufs(AV1_COMMON *cm) {
int i;
......@@ -5673,7 +5687,9 @@ int av1_get_compressed_data(AV1_COMP *cpi, unsigned int *frame_flags,
} else {
*size = 0;
if (flush && oxcf->pass == 1 && !cpi->twopass.first_pass_done) {
#if !CONFIG_XIPHRC
#if CONFIG_XIPHRC
od_enc_rc_2pass_out(&cpi->od_rc, cpi->output_pkt_list, 1);
#else
av1_end_first_pass(cpi); /* get last stats packet */
#endif
cpi->twopass.first_pass_done = 1;
......@@ -5725,12 +5741,15 @@ int av1_get_compressed_data(AV1_COMP *cpi, unsigned int *frame_flags,
cpi->frame_flags = *frame_flags;
if (oxcf->pass == 2) {
#if !CONFIG_XIPHRC
#if CONFIG_XIPHRC
if (od_enc_rc_2pass_in(&cpi->od_rc) < 0) return -1;
}
#else
av1_rc_get_second_pass_params(cpi);
#endif
} else if (oxcf->pass == 1) {
set_frame_size(cpi);
}
#endif
if (cpi->oxcf.pass != 0 || frame_is_intra_only(cm) == 1) {
for (i = 0; i < TOTAL_REFS_PER_FRAME; ++i)
......@@ -5749,6 +5768,23 @@ int av1_get_compressed_data(AV1_COMP *cpi, unsigned int *frame_flags,
}
#endif
#if CONFIG_XIPHRC
if (oxcf->pass == 1) {
size_t tmp;
if (cpi->od_rc.cur_frame == 0) Pass0Encode(cpi, &tmp, dest, 1, frame_flags);
cpi->od_rc.firstpass_quant = cpi->od_rc.target_quantizer;
Pass0Encode(cpi, &tmp, dest, 0, frame_flags);
od_enc_rc_2pass_out(&cpi->od_rc, cpi->output_pkt_list, 0);
} else if (oxcf->pass == 2) {
Pass0Encode(cpi, size, dest, 0, frame_flags);
} else {
if (cpi->od_rc.cur_frame == 0) {
size_t tmp;
Pass0Encode(cpi, &tmp, dest, 1, frame_flags);
}
Pass0Encode(cpi, size, dest, 0, frame_flags);
}
#else
if (oxcf->pass == 1) {
cpi->td.mb.e_mbd.lossless[0] = is_lossless_requested(oxcf);
av1_first_pass(cpi, source);
......@@ -5756,8 +5792,9 @@ int av1_get_compressed_data(AV1_COMP *cpi, unsigned int *frame_flags,
Pass2Encode(cpi, size, dest, frame_flags);
} else {
// One pass encode
Pass0Encode(cpi, size, dest, frame_flags);
Pass0Encode(cpi, size, dest, 0, frame_flags);
}
#endif
if (!cm->error_resilient_mode)
cm->frame_contexts[cm->frame_context_idx] = *cm->fc;
......
......@@ -648,12 +648,15 @@ int od_enc_rc_select_quantizers_and_lambdas(od_rc_state *rc,
int is_altref_frame, int frame_type,
int *bottom_idx, int *top_idx) {
int frame_subtype;
int64_t log_cur_scale;
int lossy_quantizer_min;
int lossy_quantizer_max;
double mqp_i = OD_MQP_I;
double mqp_p = OD_MQP_P;
double mqp_gp = OD_MQP_GP;
double mqp_ap = OD_MQP_AP;
int reservoir_frames;
int nframes[OD_FRAME_NSUBTYPES];
int32_t mqp_Q12[OD_FRAME_NSUBTYPES];
int64_t dqp_Q45[OD_FRAME_NSUBTYPES];
/*Verify the closed-form frame type determination code matches what the
......@@ -677,6 +680,75 @@ int od_enc_rc_select_quantizers_and_lambdas(od_rc_state *rc,
OD_ASSERT(closed_form_altref == is_altref_frame);
OD_ASSERT(closed_form_golden == is_golden_frame);
}
log_cur_scale = (int64_t)rc->scalefilter[frame_type].y[0] << 33;
/*Count the various types and classes of frames.*/
reservoir_frames = frame_type_count(rc, nframes);
nframes[OD_I_FRAME] = od_rc_scale_drop(rc, OD_I_FRAME, nframes[OD_I_FRAME]);
nframes[OD_P_FRAME] = od_rc_scale_drop(rc, OD_P_FRAME, nframes[OD_P_FRAME]);
nframes[OD_GOLDEN_P_FRAME] =
od_rc_scale_drop(rc, OD_GOLDEN_P_FRAME, nframes[OD_GOLDEN_P_FRAME]);
nframes[OD_ALTREF_P_FRAME] =
od_rc_scale_drop(rc, OD_ALTREF_P_FRAME, nframes[OD_ALTREF_P_FRAME]);
switch (rc->twopass_state) {
default: break;
case 1: {
/*Pass 1 mode: use a fixed qi value.*/
return rc->firstpass_quant;
} break;
case 2: {
int i;
int64_t scale_sum[OD_FRAME_NSUBTYPES];
int qti;
/*Pass 2 mode: we know exactly how much of each frame type there is in
the current buffer window, and have estimates for the scales.*/
for (i = 0; i < OD_FRAME_NSUBTYPES; i++) {
nframes[i] = rc->nframes[i];
nframes[i] = rc->nframes[i];
scale_sum[i] = rc->scale_sum[i];
}
/*If we're not using the same frame type as in pass 1 (because someone
changed the keyframe interval), remove that scale estimate.
We'll add in a replacement for the correct frame type below.*/
qti = rc->cur_metrics.frame_type;
if (qti != frame_type) {
nframes[qti]--;
scale_sum[qti] -= od_bexp64_q24(rc->cur_metrics.log_scale);
}
/*Compute log_scale estimates for each frame type from the pass-1 scales
we measured in the current window.*/
for (qti = 0; qti < OD_FRAME_NSUBTYPES; qti++) {
rc->log_scale[qti] = nframes[qti] > 0
? od_blog64(scale_sum[qti]) -
od_blog64(nframes[qti]) - OD_Q57(24)
: -rc->log_npixels;
}
/*If we're not using the same frame type as in pass 1, add a scale
estimate for the corresponding frame using the current low-pass
filter value.
This is mostly to ensure we have a valid estimate even when pass 1 had
no frames of this type in the buffer window.
TODO: We could also plan ahead and figure out how many keyframes we'll
be forced to add in the current buffer window.*/
qti = rc->cur_metrics.frame_type;
if (qti != frame_type) {
int64_t scale;
scale = rc->log_scale[frame_type] < OD_Q57(23)
? od_bexp64(rc->log_scale[frame_type] + OD_Q57(24))
: 0x7FFFFFFFFFFFLL;
scale *= nframes[frame_type];
nframes[frame_type]++;
scale += od_bexp64_q24(log_cur_scale >> 33);
rc->log_scale[frame_type] =
od_blog64(scale) - od_blog64(nframes[qti]) - OD_Q57(24);
} else {
log_cur_scale = (int64_t)rc->cur_metrics.log_scale << 33;
}
} break;
}
/*Quantizer selection sticks to the codable, lossy portion of the quantizer
range.*/
lossy_quantizer_min = convert_to_ac_quant(rc->minq, rc->bit_depth);
......@@ -762,8 +834,6 @@ int od_enc_rc_select_quantizers_and_lambdas(od_rc_state *rc,
}
} else {
int clamp;
int reservoir_frames;
int nframes[OD_FRAME_NSUBTYPES];
int64_t rate_bias;
int64_t rate_total;
int base_quantizer;
......@@ -777,20 +847,6 @@ int od_enc_rc_select_quantizers_and_lambdas(od_rc_state *rc,
before the last keyframe in our current buffer window (after the current
frame), or the end of the buffer window, whichever comes first.*/
/*Single pass only right now.*/
/*Count the various types and classes of frames.*/
reservoir_frames = frame_type_count(rc, nframes);
/*Downgrade the delta frame rate to correspond to the recent drop count
history.
At the moment, drop frames can only be one frame type at a time:
B-frames only if B-frames are in use, otherwise P-frames only.
In the event this is extended later, the drop tracking watches all
frame types.*/
nframes[OD_I_FRAME] = od_rc_scale_drop(rc, OD_I_FRAME, nframes[OD_I_FRAME]);
nframes[OD_P_FRAME] = od_rc_scale_drop(rc, OD_P_FRAME, nframes[OD_P_FRAME]);
nframes[OD_GOLDEN_P_FRAME] =
od_rc_scale_drop(rc, OD_GOLDEN_P_FRAME, nframes[OD_GOLDEN_P_FRAME]);
nframes[OD_ALTREF_P_FRAME] =
od_rc_scale_drop(rc, OD_ALTREF_P_FRAME, nframes[OD_ALTREF_P_FRAME]);
/*If we've been missing our target, add a penalty term.*/
rate_bias = (rc->rate_bias / (rc->cur_frame + 1000)) * reservoir_frames;
/*rate_total is the total bits available over the next
......@@ -971,9 +1027,10 @@ int od_enc_rc_select_quantizers_and_lambdas(od_rc_state *rc,
}
*bottom_idx = lossy_quantizer_min;
*top_idx = lossy_quantizer_max;
return av1_qindex_from_ac(
rc->target_quantizer = av1_qindex_from_ac(
OD_CLAMPI(lossy_quantizer_min, rc->target_quantizer, lossy_quantizer_max),
rc->bit_depth);
return rc->target_quantizer;
}
int od_enc_rc_update_state(od_rc_state *rc, int64_t bits, int is_golden_frame,
......@@ -996,7 +1053,6 @@ int od_enc_rc_update_state(od_rc_state *rc, int64_t bits, int is_golden_frame,
bits = 0;
++rc->prev_drop_count[frame_subtype];
} else {
od_iir_bessel2 *f;
int64_t log_bits;
int64_t log_qexp;
/*Compute the estimated scale factor for this frame type.*/
......@@ -1004,6 +1060,27 @@ int od_enc_rc_update_state(od_rc_state *rc, int64_t bits, int is_golden_frame,
log_qexp = od_blog64(rc->target_quantizer);
log_qexp = (log_qexp >> 6) * (rc->exp[frame_type]);
log_scale = OD_MINI(log_bits - rc->log_npixels + log_qexp, OD_Q57(16));
}
switch (rc->twopass_state) {
case 1: {
int golden, altref;
int64_t ipc;
rc->cur_metrics.frame_type =
od_frame_type(rc, rc->cur_frame, &golden, &altref, &ipc);
/*Pass 1 mode: save the metrics for this frame.*/
rc->cur_metrics.log_scale = od_q57_to_q24(log_scale);
} break;
case 2: {
/*Pass 2 mode:*/
int m_frame_type = rc->cur_metrics.frame_type;
rc->nframes[m_frame_type]--;
rc->scale_sum[m_frame_type] -= od_bexp64_q24(rc->cur_metrics.log_scale);
} break;
}
if (bits > 0) {
od_iir_bessel2 *f;
/*If this is the first example of the given frame type we've
seen, we immediately replace the default scale factor guess
with the estimate we just computed using the first frame.*/
......@@ -1011,17 +1088,13 @@ int od_enc_rc_update_state(od_rc_state *rc, int64_t bits, int is_golden_frame,
f = rc->scalefilter + frame_type;
f->y[1] = f->y[0] = f->x[1] = f->x[0] = od_q57_to_q24(log_scale);
rc->log_scale[frame_type] = log_scale;
/*P frame stats are duplicated into a OD_GOLDEN_P_FRAME slot
for convenience in rate estimation code.*/
if (frame_type == OD_P_FRAME)
rc->log_scale[OD_GOLDEN_P_FRAME] = log_scale;
} else {
/*Lengthen the time constant for the inter filters as we collect more
frame statistics, until we reach our target.*/
if (frame_type == OD_P_FRAME &&
if (frame_type != OD_I_FRAME &&
rc->inter_p_delay < rc->inter_delay_target &&
rc->frame_count[OD_P_FRAME] >= rc->inter_p_delay) {
od_iir_bessel2_reinit(&rc->scalefilter[OD_P_FRAME],
rc->frame_count[frame_type] >= rc->inter_p_delay) {
od_iir_bessel2_reinit(&rc->scalefilter[frame_type],
++rc->inter_p_delay);
}
/*Update the low-pass scale filter for this frame type
......@@ -1057,7 +1130,7 @@ int od_enc_rc_update_state(od_rc_state *rc, int64_t bits, int is_golden_frame,
rc->prev_drop_count[frame_subtype] = 0;
}
/*Increment the frame count for filter adaptation purposes.*/
if (rc->frame_count[frame_type] < INT_MAX) ++rc->frame_count[frame_type];
if (!rc->twopass_state) rc->frame_count[frame_type]++;
}
rc->reservoir_fullness += rc->bits_per_frame - bits;
/*If we're too quick filling the buffer and overflow is capped,
......@@ -1075,3 +1148,101 @@ int od_enc_rc_update_state(od_rc_state *rc, int64_t bits, int is_golden_frame,
}
return dropped;
}
static inline void od_rc_buffer_val(od_rc_state *rc, int64_t val, int bytes) {
while (bytes-- > 0) {
rc->twopass_buffer[rc->twopass_buffer_bytes++] = (uint8_t)(val & 0xFF);
val >>= 8;
}
}
static inline int64_t od_rc_unbuffer_val(od_rc_state *rc, int bytes) {
int64_t ret = 0;
int shift = 0;
while (bytes-- > 0) {
ret |= ((int64_t)rc->twopass_buffer[rc->twopass_buffer_bytes++]) << shift;
shift += 8;
}
return ret;
}
int od_enc_rc_2pass_out(od_rc_state *rc, struct aom_codec_pkt_list *pkt_list,
int summary) {
int i;
struct aom_codec_cx_pkt pkt;
rc->twopass_buffer = rc->firstpass_buffer;
rc->twopass_buffer_bytes = 0;
if (!rc->twopass_state) {
rc->twopass_state = 1;
for (i = 0; i < OD_FRAME_NSUBTYPES; i++) {
rc->frame_count[i] = 0;
rc->exp[i] = 0;
rc->scale_sum[i] = 0;
}
}
if (summary) {
od_rc_buffer_val(rc, OD_RC_2PASS_MAGIC, 4);
od_rc_buffer_val(rc, OD_RC_2PASS_VERSION, 1);
for (i = 0; i < OD_FRAME_NSUBTYPES; i++) {
od_rc_buffer_val(rc, rc->frame_count[i], 4);
od_rc_buffer_val(rc, rc->exp[i], 4);
od_rc_buffer_val(rc, rc->scale_sum[i], 8);
}
} else {
int frame_type = rc->cur_metrics.frame_type;
rc->scale_sum[frame_type] += od_bexp64_q24(rc->cur_metrics.log_scale);
rc->frame_count[frame_type]++;
od_rc_buffer_val(rc, rc->cur_metrics.frame_type, 1);
od_rc_buffer_val(rc, rc->cur_metrics.log_scale, 4);
}
pkt.data.twopass_stats.buf = rc->firstpass_buffer;
pkt.data.twopass_stats.sz = rc->twopass_buffer_bytes;
pkt.kind = AOM_CODEC_STATS_PKT;
aom_codec_pkt_list_add(pkt_list, &pkt);
return 0;
}
int od_enc_rc_2pass_in(od_rc_state *rc) {
/* Enable pass 2 mode if this is the first call. */
if (rc->twopass_state == 0) {
uint32_t i, total_frames = 0;
if (!rc->twopass_allframes_buf ||
rc->twopass_allframes_buf_size < OD_RC_2PASS_MIN)
return -1;
/* Find summary packet at the end */
rc->twopass_buffer = rc->twopass_allframes_buf;
rc->twopass_buffer +=
rc->twopass_allframes_buf_size - OD_RC_2PASS_SUMMARY_SZ;
rc->twopass_buffer_bytes = 0;
if (od_rc_unbuffer_val(rc, 4) != OD_RC_2PASS_MAGIC) return -1;
if (od_rc_unbuffer_val(rc, 1) != OD_RC_2PASS_VERSION) return -1;
for (i = 0; i < OD_FRAME_NSUBTYPES; i++) {
rc->frame_count[i] = od_rc_unbuffer_val(rc, 4);
rc->exp[i] = od_rc_unbuffer_val(rc, 4);
rc->scale_sum[i] = od_rc_unbuffer_val(rc, 8);
rc->nframes[i] = rc->frame_count[i];
total_frames += rc->frame_count[i];
}
if (total_frames < 1) return -1;
if (total_frames * OD_RC_2PASS_PACKET_SZ > rc->twopass_allframes_buf_size)
return -1;
od_enc_rc_reset(rc);
/* Everything looks ok */
rc->twopass_buffer = rc->twopass_allframes_buf;
rc->twopass_state = 2;
rc->twopass_buffer_bytes = 0;
}
rc->cur_metrics.frame_type = od_rc_unbuffer_val(rc, 1);
rc->cur_metrics.log_scale = od_rc_unbuffer_val(rc, 4);
return 0;
}
......@@ -13,6 +13,7 @@
#define _ratectrl_xiph_H (1)
#include "av1/encoder/ratectrl.h"
#include "aom/internal/aom_codec_internal.h"
/*Frame types.*/
#define OD_I_FRAME (0)
......@@ -48,6 +49,12 @@
conversion (6.235 * 2^45) */
#define OD_LOG_QUANTIZER_OFFSET_Q45 (0x0000C7851EB851ECLL)
#define OD_RC_2PASS_MAGIC (0x53015641) /* [A, V, 1, S] in little endian */
#define OD_RC_2PASS_SUMMARY_SZ (4 + 1 + (4 + 4 + 8) * OD_FRAME_NSUBTYPES)
#define OD_RC_2PASS_PACKET_SZ (1 + 4)
#define OD_RC_2PASS_MIN (OD_RC_2PASS_PACKET_SZ + OD_RC_2PASS_SUMMARY_SZ)
#define OD_RC_2PASS_VERSION (1)
/*A 2nd order low-pass Bessel follower.
We use this for rate control because it has fast reaction time, but is
critically damped.*/
......@@ -58,6 +65,14 @@ typedef struct od_iir_bessel2 {
int32_t y[2];
} od_iir_bessel2;
/* The 2-pass metrics associated with a single frame. */
typedef struct od_frame_metrics {
/*The log base 2 of the scale factor for this frame in Q24 format.*/
int64_t log_scale;
/*The frame type from pass 1.*/
unsigned frame_type : 1;
} od_frame_metrics;
/*Rate control setup and working state information.*/
typedef struct od_rc_state {
/* Image format */
......@@ -83,6 +98,26 @@ typedef struct od_rc_state {
int maxq;
/* Min Q */
int minq;
/* Quantizer to use for the first pass */
int firstpass_quant;
/* 2-pass metrics */
od_frame_metrics cur_metrics;
/* 2-pass state */
int64_t scale_sum[OD_FRAME_NSUBTYPES];
int nframes[OD_FRAME_NSUBTYPES];
/* 2-pass bytestream reader/writer context */
uint8_t *twopass_buffer;
int twopass_buffer_bytes;
/* Pass 1 stats packet storage */
uint8_t firstpass_buffer[OD_RC_2PASS_SUMMARY_SZ];
/* Every state packet from the first pass in a single buffer */
uint8_t *twopass_allframes_buf;
size_t twopass_allframes_buf_size;
/* Actual returned quantizer */
int target_quantizer;
......@@ -157,4 +192,9 @@ int od_frame_type(od_rc_state *rc, int64_t coding_frame_count, int *is_golden,
int od_enc_rc_resize(od_rc_state *rc);
int od_enc_rc_2pass_out(od_rc_state *rc, struct aom_codec_pkt_list *pkt_list,
int summary);
int od_enc_rc_2pass_in(od_rc_state *rc);
#endif
......@@ -567,7 +567,11 @@ void av1_set_speed_features_framesize_independent(AV1_COMP *cpi) {
if (oxcf->mode == REALTIME)
set_rt_speed_feature(cpi, sf, oxcf->speed, oxcf->content);
else if (oxcf->mode == GOOD)
else if (oxcf->mode == GOOD
#if CONFIG_XIPHRC
|| oxcf->pass == 1
#endif
)
set_good_speed_feature(cpi, cm, sf, oxcf->speed);
// sf->partition_search_breakout_dist_thr is set assuming max 64x64
......@@ -607,9 +611,11 @@ void av1_set_speed_features_framesize_independent(AV1_COMP *cpi) {
}
}
#if !CONFIG_XIPHRC
// Slow quant, dct and trellis not worthwhile for first pass
// so make sure they are always turned off.
if (oxcf->pass == 1) sf->optimize_coefficients = 0;
#endif
// No recode for 1 pass.
if (oxcf->pass == 0) {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment