ref: 0bb7bb6df8c2dcce22d0151676183f589bcf27a1
parent: a1fdfbb174487e5efb76e6e77119d2e50840086e
author: Angie Chiang <angiebird@google.com>
date: Thu Jun 17 16:23:30 EDT 2021
Add use_simple_encode_api to oxcf Use this flag to change the encoder behavior when SimpleEncode APIs are used BUG=webm:1733 Change-Id: I9f0852a03ff99faa01cdd8eee8ab71718cc58632
--- a/vp9/encoder/vp9_encodeframe.c
+++ b/vp9/encoder/vp9_encodeframe.c
@@ -4603,15 +4603,18 @@
encode_sb(cpi, td, tile_info, tp, mi_row, mi_col, output_enabled, bsize,
pc_tree);
#if CONFIG_RATE_CTRL
- // Store partition, motion vector of the superblock.
- if (output_enabled) {
- const int num_unit_rows = get_num_unit_4x4(cpi->frame_info.frame_height);
- const int num_unit_cols = get_num_unit_4x4(cpi->frame_info.frame_width);
- store_superblock_info(pc_tree, cm->mi_grid_visible, cm->mi_stride,
- num_4x4_blocks_wide_lookup[BLOCK_64X64],
- num_unit_rows, num_unit_cols, mi_row << 1,
- mi_col << 1, cpi->partition_info,
- cpi->motion_vector_info);
+ if (oxcf->use_simple_encode_api) {
+ // Store partition, motion vector of the superblock.
+ if (output_enabled) {
+ const int num_unit_rows =
+ get_num_unit_4x4(cpi->frame_info.frame_height);
+ const int num_unit_cols = get_num_unit_4x4(cpi->frame_info.frame_width);
+ store_superblock_info(pc_tree, cm->mi_grid_visible, cm->mi_stride,
+ num_4x4_blocks_wide_lookup[BLOCK_64X64],
+ num_unit_rows, num_unit_cols, mi_row << 1,
+ mi_col << 1, cpi->partition_info,
+ cpi->motion_vector_info);
+ }
}
#endif // CONFIG_RATE_CTRL
}
@@ -5981,9 +5984,14 @@
for (i = 0; i < BLOCK_SIZES; ++i) {
for (j = 0; j < MAX_MODES; ++j) {
tile_data->thresh_freq_fact[i][j] = RD_THRESH_INIT_FACT;
-#if CONFIG_CONSISTENT_RECODE || CONFIG_RATE_CTRL
+#if CONFIG_RATE_CTRL
+ if (cpi->oxcf.use_simple_encode_api) {
+ tile_data->thresh_freq_fact_prev[i][j] = RD_THRESH_INIT_FACT;
+ }
+#endif // CONFIG_RATE_CTRL
+#if CONFIG_CONSISTENT_RECODE
tile_data->thresh_freq_fact_prev[i][j] = RD_THRESH_INIT_FACT;
-#endif // CONFIG_CONSISTENT_RECODE || CONFIG_RATE_CTRL
+#endif // CONFIG_CONSISTENT_RECODE
tile_data->mode_map[i][j] = j;
}
}
@@ -6406,7 +6414,12 @@
void vp9_encode_frame(VP9_COMP *cpi) {
VP9_COMMON *const cm = &cpi->common;
-#if CONFIG_CONSISTENT_RECODE || CONFIG_RATE_CTRL
+#if CONFIG_RATE_CTRL
+ if (cpi->oxcf.use_simple_encode_api) {
+ restore_encode_params(cpi);
+ }
+#endif // CONFIG_RATE_CTRL
+#if CONFIG_CONSISTENT_RECODE
restore_encode_params(cpi);
#endif
--- a/vp9/encoder/vp9_encoder.c
+++ b/vp9/encoder/vp9_encoder.c
@@ -1022,10 +1022,12 @@
cpi->mi_ssim_rdmult_scaling_factors = NULL;
#if CONFIG_RATE_CTRL
- free_partition_info(cpi);
- free_motion_vector_info(cpi);
- free_fp_motion_vector_info(cpi);
- free_tpl_stats_info(cpi);
+ if (cpi->oxcf.use_simple_encode_api) {
+ free_partition_info(cpi);
+ free_motion_vector_info(cpi);
+ free_fp_motion_vector_info(cpi);
+ free_tpl_stats_info(cpi);
+ }
#endif
vp9_free_ref_frame_buffers(cm->buffer_pool);
@@ -2669,10 +2671,12 @@
#if CONFIG_RATE_CTRL
encode_command_init(&cpi->encode_command);
- partition_info_init(cpi);
- motion_vector_info_init(cpi);
- fp_motion_vector_info_init(cpi);
- tpl_stats_info_init(cpi);
+ if (oxcf->use_simple_encode_api) {
+ partition_info_init(cpi);
+ motion_vector_info_init(cpi);
+ fp_motion_vector_info_init(cpi);
+ tpl_stats_info_init(cpi);
+ }
#endif
return cpi;
@@ -4470,11 +4474,6 @@
loop_at_this_size = 0;
}
-#if CONFIG_RATE_CTRL
- if (cpi->encode_command.use_external_target_frame_bits) {
- q = rq_model_predict_q_index(rq_model, rq_history, rc->this_frame_target);
- }
-#endif // CONFIG_RATE_CTRL
// Decide frame size bounds first time through.
if (loop_count == 0) {
vp9_rc_compute_frame_size_bounds(cpi, rc->this_frame_target,
@@ -4517,10 +4516,16 @@
#if CONFIG_RATE_CTRL
// TODO(angiebird): This is a hack for making sure the encoder use the
// external_quantize_index exactly. Avoid this kind of hack later.
- if (cpi->encode_command.use_external_quantize_index) {
- q = cpi->encode_command.external_quantize_index;
+ if (cpi->oxcf.use_simple_encode_api) {
+ if (cpi->encode_command.use_external_target_frame_bits) {
+ q = rq_model_predict_q_index(rq_model, rq_history,
+ rc->this_frame_target);
+ }
+ if (cpi->encode_command.use_external_quantize_index) {
+ q = cpi->encode_command.external_quantize_index;
+ }
}
-#endif
+#endif // CONFIG_RATE_CTRL
if (cpi->ext_ratectrl.ready && !ext_rc_recode) {
vpx_codec_err_t codec_status;
const GF_GROUP *gf_group = &cpi->twopass.gf_group;
@@ -4607,33 +4612,36 @@
ext_rc_recode = 1;
}
#if CONFIG_RATE_CTRL
- // This part needs to be after save_coding_context() because
- // restore_coding_context will be called in the end of this function.
- // TODO(angiebird): This is a hack for making sure the encoder use the
- // external_quantize_index exactly. Avoid this kind of hack later.
- if (cpi->encode_command.use_external_quantize_index) {
- break;
- }
+ if (cpi->oxcf.use_simple_encode_api) {
+ // This part needs to be after save_coding_context() because
+ // restore_coding_context will be called in the end of this function.
+ // TODO(angiebird): This is a hack for making sure the encoder use the
+ // external_quantize_index exactly. Avoid this kind of hack later.
+ if (cpi->encode_command.use_external_quantize_index) {
+ break;
+ }
- if (cpi->encode_command.use_external_target_frame_bits) {
- const double percent_diff = get_bits_percent_diff(
- rc->this_frame_target, rc->projected_frame_size);
- update_rq_history(rq_history, rc->this_frame_target,
- rc->projected_frame_size, q);
- loop_count += 1;
+ if (cpi->encode_command.use_external_target_frame_bits) {
+ const double percent_diff = get_bits_percent_diff(
+ rc->this_frame_target, rc->projected_frame_size);
+ update_rq_history(rq_history, rc->this_frame_target,
+ rc->projected_frame_size, q);
+ loop_count += 1;
- rq_model_update(rq_history, rc->this_frame_target, rq_model);
+ rq_model_update(rq_history, rc->this_frame_target, rq_model);
- // Check if we hit the target bitrate.
- if (percent_diff <= cpi->encode_command.target_frame_bits_error_percent ||
- rq_history->recode_count >= RATE_CTRL_MAX_RECODE_NUM ||
- rq_history->q_index_low >= rq_history->q_index_high) {
- break;
- }
+ // Check if we hit the target bitrate.
+ if (percent_diff <=
+ cpi->encode_command.target_frame_bits_error_percent ||
+ rq_history->recode_count >= RATE_CTRL_MAX_RECODE_NUM ||
+ rq_history->q_index_low >= rq_history->q_index_high) {
+ break;
+ }
- loop = 1;
- restore_coding_context(cpi);
- continue;
+ loop = 1;
+ restore_coding_context(cpi);
+ continue;
+ }
}
#endif // CONFIG_RATE_CTRL
@@ -5368,17 +5376,81 @@
}
#if !CONFIG_REALTIME_ONLY
-static void update_encode_frame_result(
+static void update_encode_frame_result_basic(
+ FRAME_UPDATE_TYPE update_type, int show_idx, int quantize_index,
+ ENCODE_FRAME_RESULT *encode_frame_result) {
+ encode_frame_result->show_idx = show_idx;
+ encode_frame_result->update_type = update_type;
+ encode_frame_result->quantize_index = quantize_index;
+}
+
+#if CONFIG_RATE_CTRL
+static void yv12_buffer_to_image_buffer(const YV12_BUFFER_CONFIG *yv12_buffer,
+ IMAGE_BUFFER *image_buffer) {
+ const uint8_t *src_buf_ls[3] = { yv12_buffer->y_buffer, yv12_buffer->u_buffer,
+ yv12_buffer->v_buffer };
+ const int src_stride_ls[3] = { yv12_buffer->y_stride, yv12_buffer->uv_stride,
+ yv12_buffer->uv_stride };
+ const int w_ls[3] = { yv12_buffer->y_crop_width, yv12_buffer->uv_crop_width,
+ yv12_buffer->uv_crop_width };
+ const int h_ls[3] = { yv12_buffer->y_crop_height, yv12_buffer->uv_crop_height,
+ yv12_buffer->uv_crop_height };
+ int plane;
+ for (plane = 0; plane < 3; ++plane) {
+ const int src_stride = src_stride_ls[plane];
+ const int w = w_ls[plane];
+ const int h = h_ls[plane];
+ const uint8_t *src_buf = src_buf_ls[plane];
+ uint8_t *dst_buf = image_buffer->plane_buffer[plane];
+ int r;
+ assert(image_buffer->plane_width[plane] == w);
+ assert(image_buffer->plane_height[plane] == h);
+ for (r = 0; r < h; ++r) {
+ memcpy(dst_buf, src_buf, sizeof(*src_buf) * w);
+ src_buf += src_stride;
+ dst_buf += w;
+ }
+ }
+}
+// This function will update extra information specific for simple_encode APIs
+static void update_encode_frame_result_simple_encode(
int ref_frame_flags, FRAME_UPDATE_TYPE update_type,
const YV12_BUFFER_CONFIG *source_frame, const RefCntBuffer *coded_frame_buf,
- RefCntBuffer *ref_frame_buf[MAX_INTER_REF_FRAMES], int quantize_index,
+ RefCntBuffer *ref_frame_bufs[MAX_INTER_REF_FRAMES], int quantize_index,
uint32_t bit_depth, uint32_t input_bit_depth, const FRAME_COUNTS *counts,
-#if CONFIG_RATE_CTRL
const PARTITION_INFO *partition_info,
const MOTION_VECTOR_INFO *motion_vector_info,
const TplDepStats *tpl_stats_info,
+ ENCODE_FRAME_RESULT *encode_frame_result) {
+ PSNR_STATS psnr;
+ update_encode_frame_result_basic(update_type, coded_frame_buf->frame_index,
+ quantize_index, encode_frame_result);
+#if CONFIG_VP9_HIGHBITDEPTH
+ vpx_calc_highbd_psnr(source_frame, &coded_frame_buf->buf, &psnr, bit_depth,
+ input_bit_depth);
+#else // CONFIG_VP9_HIGHBITDEPTH
+ (void)bit_depth;
+ (void)input_bit_depth;
+ vpx_calc_psnr(source_frame, &coded_frame_buf->buf, &psnr);
+#endif // CONFIG_VP9_HIGHBITDEPTH
+ encode_frame_result->frame_coding_index = coded_frame_buf->frame_coding_index;
+
+ vp9_get_ref_frame_info(update_type, ref_frame_flags, ref_frame_bufs,
+ encode_frame_result->ref_frame_coding_indexes,
+ encode_frame_result->ref_frame_valid_list);
+
+ encode_frame_result->psnr = psnr.psnr[0];
+ encode_frame_result->sse = psnr.sse[0];
+ encode_frame_result->frame_counts = *counts;
+ encode_frame_result->partition_info = partition_info;
+ encode_frame_result->motion_vector_info = motion_vector_info;
+ encode_frame_result->tpl_stats_info = tpl_stats_info;
+ if (encode_frame_result->coded_frame.allocated) {
+ yv12_buffer_to_image_buffer(&coded_frame_buf->buf,
+ &encode_frame_result->coded_frame);
+ }
+}
#endif // CONFIG_RATE_CTRL
- ENCODE_FRAME_RESULT *encode_frame_result);
#endif // !CONFIG_REALTIME_ONLY
static void encode_frame_to_data_rate(
@@ -5473,10 +5545,14 @@
memset(cpi->mode_chosen_counts, 0,
MAX_MODES * sizeof(*cpi->mode_chosen_counts));
#endif
-#if CONFIG_CONSISTENT_RECODE || CONFIG_RATE_CTRL
+#if CONFIG_CONSISTENT_RECODE
// Backup to ensure consistency between recodes
save_encode_params(cpi);
-#endif // CONFIG_CONSISTENT_RECODE || CONFIG_RATE_CTRL
+#elif CONFIG_RATE_CTRL
+ if (cpi->oxcf.use_simple_encode_api) {
+ save_encode_params(cpi);
+ }
+#endif
if (cpi->sf.recode_loop == DISALLOW_RECODE) {
if (!encode_without_recode_loop(cpi, size, dest)) return;
@@ -5568,10 +5644,12 @@
assert(encode_frame_result == NULL);
#else // CONFIG_REALTIME_ONLY
if (encode_frame_result != NULL) {
- const int ref_frame_flags = get_ref_frame_flags(cpi);
const RefCntBuffer *coded_frame_buf =
get_ref_cnt_buffer(cm, cm->new_fb_idx);
RefCntBuffer *ref_frame_bufs[MAX_INTER_REF_FRAMES];
+ FRAME_UPDATE_TYPE update_type =
+ cpi->twopass.gf_group.update_type[cpi->twopass.gf_group.index];
+ int quantize_index = vp9_get_quantizer(cpi);
get_ref_frame_bufs(cpi, ref_frame_bufs);
// update_encode_frame_result() depends on twopass.gf_group.index and
// cm->new_fb_idx, cpi->Source, cpi->lst_fb_idx, cpi->gld_fb_idx and
@@ -5589,15 +5667,21 @@
// This function needs to be called before vp9_update_reference_frames().
// TODO(angiebird): Improve the codebase to make the update of frame
// dependent variables more robust.
- update_encode_frame_result(
- ref_frame_flags,
- cpi->twopass.gf_group.update_type[cpi->twopass.gf_group.index],
- cpi->Source, coded_frame_buf, ref_frame_bufs, vp9_get_quantizer(cpi),
- cm->bit_depth, cpi->oxcf.input_bit_depth, cpi->td.counts,
+
+ update_encode_frame_result_basic(update_type, coded_frame_buf->frame_index,
+ quantize_index, encode_frame_result);
#if CONFIG_RATE_CTRL
- cpi->partition_info, cpi->motion_vector_info, cpi->tpl_stats_info,
+ if (cpi->oxcf.use_simple_encode_api) {
+ const int ref_frame_flags = get_ref_frame_flags(cpi);
+ update_encode_frame_result_simple_encode(
+ ref_frame_flags,
+ cpi->twopass.gf_group.update_type[cpi->twopass.gf_group.index],
+ cpi->Source, coded_frame_buf, ref_frame_bufs, quantize_index,
+ cm->bit_depth, cpi->oxcf.input_bit_depth, cpi->td.counts,
+ cpi->partition_info, cpi->motion_vector_info, cpi->tpl_stats_info,
+ encode_frame_result);
+ }
#endif // CONFIG_RATE_CTRL
- encode_frame_result);
}
#endif // CONFIG_REALTIME_ONLY
@@ -7517,7 +7601,9 @@
#endif // CONFIG_NON_GREEDY_MV
#if CONFIG_RATE_CTRL
- accumulate_frame_tpl_stats(cpi);
+ if (cpi->oxcf.use_simple_encode_api) {
+ accumulate_frame_tpl_stats(cpi);
+ }
#endif // CONFIG_RATE_CTRL
}
@@ -7544,206 +7630,6 @@
}
}
}
-
-#if !CONFIG_REALTIME_ONLY
-#if CONFIG_RATE_CTRL
-static void copy_frame_counts(const FRAME_COUNTS *input_counts,
- FRAME_COUNTS *output_counts) {
- int i, j, k, l, m, n;
- for (i = 0; i < BLOCK_SIZE_GROUPS; ++i) {
- for (j = 0; j < INTRA_MODES; ++j) {
- output_counts->y_mode[i][j] = input_counts->y_mode[i][j];
- }
- }
- for (i = 0; i < INTRA_MODES; ++i) {
- for (j = 0; j < INTRA_MODES; ++j) {
- output_counts->uv_mode[i][j] = input_counts->uv_mode[i][j];
- }
- }
- for (i = 0; i < PARTITION_CONTEXTS; ++i) {
- for (j = 0; j < PARTITION_TYPES; ++j) {
- output_counts->partition[i][j] = input_counts->partition[i][j];
- }
- }
- for (i = 0; i < TX_SIZES; ++i) {
- for (j = 0; j < PLANE_TYPES; ++j) {
- for (k = 0; k < REF_TYPES; ++k) {
- for (l = 0; l < COEF_BANDS; ++l) {
- for (m = 0; m < COEFF_CONTEXTS; ++m) {
- output_counts->eob_branch[i][j][k][l][m] =
- input_counts->eob_branch[i][j][k][l][m];
- for (n = 0; n < UNCONSTRAINED_NODES + 1; ++n) {
- output_counts->coef[i][j][k][l][m][n] =
- input_counts->coef[i][j][k][l][m][n];
- }
- }
- }
- }
- }
- }
- for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; ++i) {
- for (j = 0; j < SWITCHABLE_FILTERS; ++j) {
- output_counts->switchable_interp[i][j] =
- input_counts->switchable_interp[i][j];
- }
- }
- for (i = 0; i < INTER_MODE_CONTEXTS; ++i) {
- for (j = 0; j < INTER_MODES; ++j) {
- output_counts->inter_mode[i][j] = input_counts->inter_mode[i][j];
- }
- }
- for (i = 0; i < INTRA_INTER_CONTEXTS; ++i) {
- for (j = 0; j < 2; ++j) {
- output_counts->intra_inter[i][j] = input_counts->intra_inter[i][j];
- }
- }
- for (i = 0; i < COMP_INTER_CONTEXTS; ++i) {
- for (j = 0; j < 2; ++j) {
- output_counts->comp_inter[i][j] = input_counts->comp_inter[i][j];
- }
- }
- for (i = 0; i < REF_CONTEXTS; ++i) {
- for (j = 0; j < 2; ++j) {
- for (k = 0; k < 2; ++k) {
- output_counts->single_ref[i][j][k] = input_counts->single_ref[i][j][k];
- }
- }
- }
- for (i = 0; i < REF_CONTEXTS; ++i) {
- for (j = 0; j < 2; ++j) {
- output_counts->comp_ref[i][j] = input_counts->comp_ref[i][j];
- }
- }
- for (i = 0; i < SKIP_CONTEXTS; ++i) {
- for (j = 0; j < 2; ++j) {
- output_counts->skip[i][j] = input_counts->skip[i][j];
- }
- }
- for (i = 0; i < TX_SIZE_CONTEXTS; i++) {
- for (j = 0; j < TX_SIZES; j++) {
- output_counts->tx.p32x32[i][j] = input_counts->tx.p32x32[i][j];
- }
- for (j = 0; j < TX_SIZES - 1; j++) {
- output_counts->tx.p16x16[i][j] = input_counts->tx.p16x16[i][j];
- }
- for (j = 0; j < TX_SIZES - 2; j++) {
- output_counts->tx.p8x8[i][j] = input_counts->tx.p8x8[i][j];
- }
- }
- for (i = 0; i < TX_SIZES; i++) {
- output_counts->tx.tx_totals[i] = input_counts->tx.tx_totals[i];
- }
- for (i = 0; i < MV_JOINTS; i++) {
- output_counts->mv.joints[i] = input_counts->mv.joints[i];
- }
- for (k = 0; k < 2; k++) {
- nmv_component_counts *const comps = &output_counts->mv.comps[k];
- const nmv_component_counts *const comps_t = &input_counts->mv.comps[k];
- for (i = 0; i < 2; i++) {
- comps->sign[i] = comps_t->sign[i];
- comps->class0_hp[i] = comps_t->class0_hp[i];
- comps->hp[i] = comps_t->hp[i];
- }
- for (i = 0; i < MV_CLASSES; i++) {
- comps->classes[i] = comps_t->classes[i];
- }
- for (i = 0; i < CLASS0_SIZE; i++) {
- comps->class0[i] = comps_t->class0[i];
- for (j = 0; j < MV_FP_SIZE; j++) {
- comps->class0_fp[i][j] = comps_t->class0_fp[i][j];
- }
- }
- for (i = 0; i < MV_OFFSET_BITS; i++) {
- for (j = 0; j < 2; j++) {
- comps->bits[i][j] = comps_t->bits[i][j];
- }
- }
- for (i = 0; i < MV_FP_SIZE; i++) {
- comps->fp[i] = comps_t->fp[i];
- }
- }
-}
-
-static void yv12_buffer_to_image_buffer(const YV12_BUFFER_CONFIG *yv12_buffer,
- IMAGE_BUFFER *image_buffer) {
- const uint8_t *src_buf_ls[3] = { yv12_buffer->y_buffer, yv12_buffer->u_buffer,
- yv12_buffer->v_buffer };
- const int src_stride_ls[3] = { yv12_buffer->y_stride, yv12_buffer->uv_stride,
- yv12_buffer->uv_stride };
- const int w_ls[3] = { yv12_buffer->y_crop_width, yv12_buffer->uv_crop_width,
- yv12_buffer->uv_crop_width };
- const int h_ls[3] = { yv12_buffer->y_crop_height, yv12_buffer->uv_crop_height,
- yv12_buffer->uv_crop_height };
- int plane;
- for (plane = 0; plane < 3; ++plane) {
- const int src_stride = src_stride_ls[plane];
- const int w = w_ls[plane];
- const int h = h_ls[plane];
- const uint8_t *src_buf = src_buf_ls[plane];
- uint8_t *dst_buf = image_buffer->plane_buffer[plane];
- int r;
- assert(image_buffer->plane_width[plane] == w);
- assert(image_buffer->plane_height[plane] == h);
- for (r = 0; r < h; ++r) {
- memcpy(dst_buf, src_buf, sizeof(*src_buf) * w);
- src_buf += src_stride;
- dst_buf += w;
- }
- }
-}
-#endif // CONFIG_RATE_CTRL
-
-static void update_encode_frame_result(
- int ref_frame_flags, FRAME_UPDATE_TYPE update_type,
- const YV12_BUFFER_CONFIG *source_frame, const RefCntBuffer *coded_frame_buf,
- RefCntBuffer *ref_frame_bufs[MAX_INTER_REF_FRAMES], int quantize_index,
- uint32_t bit_depth, uint32_t input_bit_depth, const FRAME_COUNTS *counts,
-#if CONFIG_RATE_CTRL
- const PARTITION_INFO *partition_info,
- const MOTION_VECTOR_INFO *motion_vector_info,
- const TplDepStats *tpl_stats_info,
-#endif // CONFIG_RATE_CTRL
- ENCODE_FRAME_RESULT *encode_frame_result) {
-#if CONFIG_RATE_CTRL
- PSNR_STATS psnr;
-#if CONFIG_VP9_HIGHBITDEPTH
- vpx_calc_highbd_psnr(source_frame, &coded_frame_buf->buf, &psnr, bit_depth,
- input_bit_depth);
-#else // CONFIG_VP9_HIGHBITDEPTH
- (void)bit_depth;
- (void)input_bit_depth;
- vpx_calc_psnr(source_frame, &coded_frame_buf->buf, &psnr);
-#endif // CONFIG_VP9_HIGHBITDEPTH
- encode_frame_result->frame_coding_index = coded_frame_buf->frame_coding_index;
-
- vp9_get_ref_frame_info(update_type, ref_frame_flags, ref_frame_bufs,
- encode_frame_result->ref_frame_coding_indexes,
- encode_frame_result->ref_frame_valid_list);
-
- encode_frame_result->psnr = psnr.psnr[0];
- encode_frame_result->sse = psnr.sse[0];
- copy_frame_counts(counts, &encode_frame_result->frame_counts);
- encode_frame_result->partition_info = partition_info;
- encode_frame_result->motion_vector_info = motion_vector_info;
- encode_frame_result->tpl_stats_info = tpl_stats_info;
- if (encode_frame_result->coded_frame.allocated) {
- yv12_buffer_to_image_buffer(&coded_frame_buf->buf,
- &encode_frame_result->coded_frame);
- }
-#else // CONFIG_RATE_CTRL
- (void)ref_frame_flags;
- (void)bit_depth;
- (void)input_bit_depth;
- (void)source_frame;
- (void)coded_frame_buf;
- (void)ref_frame_bufs;
- (void)counts;
-#endif // CONFIG_RATE_CTRL
- encode_frame_result->show_idx = coded_frame_buf->frame_index;
- encode_frame_result->update_type = update_type;
- encode_frame_result->quantize_index = quantize_index;
-}
-#endif // !CONFIG_REALTIME_ONLY
void vp9_init_encode_frame_result(ENCODE_FRAME_RESULT *encode_frame_result) {
encode_frame_result->show_idx = -1; // Actual encoding doesn't happen.
--- a/vp9/encoder/vp9_encoder.h
+++ b/vp9/encoder/vp9_encoder.h
@@ -291,6 +291,7 @@
int row_mt;
unsigned int motion_vector_unit_test;
int delta_q_uv;
+ int use_simple_encode_api; // Use SimpleEncode APIs or not
} VP9EncoderConfig;
static INLINE int is_lossless_requested(const VP9EncoderConfig *cfg) {
--- a/vp9/encoder/vp9_firstpass.c
+++ b/vp9/encoder/vp9_firstpass.c
@@ -1114,8 +1114,10 @@
vp9_variance_fn_ptr_t v_fn_ptr = cpi->fn_ptr[bsize];
#if CONFIG_RATE_CTRL
- // Store zero mv as default
- store_fp_motion_vector(cpi, &mv, mb_row, mb_col, LAST_FRAME, 0);
+ if (cpi->oxcf.use_simple_encode_api) {
+ // Store zero mv as default
+ store_fp_motion_vector(cpi, &mv, mb_row, mb_col, LAST_FRAME, 0);
+ }
#endif // CONFIG_RAGE_CTRL
xd->plane[0].pre[0].buf = first_ref_buf->y_buffer + recon_yoffset;
@@ -1183,7 +1185,9 @@
}
}
#if CONFIG_RATE_CTRL
- store_fp_motion_vector(cpi, &mv, mb_row, mb_col, LAST_FRAME, 0);
+ if (cpi->oxcf.use_simple_encode_api) {
+ store_fp_motion_vector(cpi, &mv, mb_row, mb_col, LAST_FRAME, 0);
+ }
#endif // CONFIG_RAGE_CTRL
// Search in an older reference frame.
@@ -1207,7 +1211,10 @@
first_pass_motion_search(cpi, x, &zero_mv, &tmp_mv, &gf_motion_error);
#if CONFIG_RATE_CTRL
- store_fp_motion_vector(cpi, &tmp_mv, mb_row, mb_col, GOLDEN_FRAME, 1);
+ if (cpi->oxcf.use_simple_encode_api) {
+ store_fp_motion_vector(cpi, &tmp_mv, mb_row, mb_col, GOLDEN_FRAME,
+ 1);
+ }
#endif // CONFIG_RAGE_CTRL
if (gf_motion_error < motion_error && gf_motion_error < this_error)
@@ -1383,7 +1390,9 @@
} else {
fp_acc_data->sr_coded_error += (int64_t)this_error;
#if CONFIG_RATE_CTRL
- store_fp_motion_vector(cpi, NULL, mb_row, mb_col, INTRA_FRAME, 0);
+ if (cpi->oxcf.use_simple_encode_api) {
+ store_fp_motion_vector(cpi, NULL, mb_row, mb_col, INTRA_FRAME, 0);
+ }
#endif // CONFIG_RAGE_CTRL
}
fp_acc_data->coded_error += (int64_t)this_error;
@@ -1412,9 +1421,11 @@
vp9_tile_init(tile, cm, 0, 0);
#if CONFIG_RATE_CTRL
- fp_motion_vector_info_reset(cpi->frame_info.frame_width,
- cpi->frame_info.frame_height,
- cpi->fp_motion_vector_info);
+ if (cpi->oxcf.use_simple_encode_api) {
+ fp_motion_vector_info_reset(cpi->frame_info.frame_width,
+ cpi->frame_info.frame_height,
+ cpi->fp_motion_vector_info);
+ }
#endif
for (mb_row = 0; mb_row < cm->mb_rows; ++mb_row) {
@@ -2677,25 +2688,25 @@
return gop_coding_frames;
}
-static RANGE get_active_gf_inverval_range(
- const FRAME_INFO *frame_info, const RATE_CONTROL *rc, int arf_active_or_kf,
- int gf_start_show_idx, int active_worst_quality, int last_boosted_qindex) {
+static RANGE get_active_gf_inverval_range_simple(int min_gf_interval,
+ int arf_active_or_kf,
+ int frames_to_key) {
RANGE active_gf_interval;
-#if CONFIG_RATE_CTRL
- (void)frame_info;
- (void)gf_start_show_idx;
- (void)active_worst_quality;
- (void)last_boosted_qindex;
- active_gf_interval.min = rc->min_gf_interval + arf_active_or_kf + 2;
-
+ active_gf_interval.min = min_gf_interval + arf_active_or_kf + 2;
active_gf_interval.max = 16 + arf_active_or_kf;
- if ((active_gf_interval.max <= rc->frames_to_key) &&
- (active_gf_interval.max >= (rc->frames_to_key - rc->min_gf_interval))) {
- active_gf_interval.min = rc->frames_to_key / 2;
- active_gf_interval.max = rc->frames_to_key / 2;
+ if ((active_gf_interval.max <= frames_to_key) &&
+ (active_gf_interval.max >= (frames_to_key - min_gf_interval))) {
+ active_gf_interval.min = frames_to_key / 2;
+ active_gf_interval.max = frames_to_key / 2;
}
-#else
+ return active_gf_interval;
+}
+
+static RANGE get_active_gf_inverval_range(
+ const FRAME_INFO *frame_info, const RATE_CONTROL *rc, int arf_active_or_kf,
+ int gf_start_show_idx, int active_worst_quality, int last_boosted_qindex) {
+ RANGE active_gf_interval;
int int_max_q = (int)(vp9_convert_qindex_to_q(active_worst_quality,
frame_info->bit_depth));
int q_term = (gf_start_show_idx == 0)
@@ -2733,7 +2744,6 @@
}
active_gf_interval.max =
VPXMAX(active_gf_interval.max, active_gf_interval.min);
-#endif
return active_gf_interval;
}
@@ -2794,9 +2804,14 @@
vpx_clear_system_state();
- active_gf_interval = get_active_gf_inverval_range(
- frame_info, rc, arf_active_or_kf, gf_start_show_idx,
- twopass->active_worst_quality, rc->last_boosted_qindex);
+ if (oxcf->use_simple_encode_api) {
+ active_gf_interval = get_active_gf_inverval_range_simple(
+ rc->min_gf_interval, arf_active_or_kf, rc->frames_to_key);
+ } else {
+ active_gf_interval = get_active_gf_inverval_range(
+ frame_info, rc, arf_active_or_kf, gf_start_show_idx,
+ twopass->active_worst_quality, rc->last_boosted_qindex);
+ }
if (cpi->multi_layer_arf) {
int arf_layers = get_arf_layers(cpi->multi_layer_arf, oxcf->enable_auto_arf,
@@ -2806,25 +2821,21 @@
gop_intra_factor = 1.0;
}
+ gop_coding_frames = get_gop_coding_frame_num(
+ &use_alt_ref, frame_info, twopass, rc, gf_start_show_idx,
+ &active_gf_interval, gop_intra_factor, cpi->oxcf.lag_in_frames);
+ use_alt_ref &= allow_alt_ref;
#if CONFIG_RATE_CTRL
- {
+ // If the external gop_command is on, we will override the decisions
+ // of gop_coding_frames and use_alt_ref.
+ if (cpi->oxcf.use_simple_encode_api) {
const GOP_COMMAND *gop_command = &cpi->encode_command.gop_command;
assert(allow_alt_ref == 1);
if (gop_command->use) {
gop_coding_frames = gop_command_coding_frame_count(gop_command);
use_alt_ref = gop_command->use_alt_ref;
- } else {
- gop_coding_frames = get_gop_coding_frame_num(
- &use_alt_ref, frame_info, twopass, rc, gf_start_show_idx,
- &active_gf_interval, gop_intra_factor, cpi->oxcf.lag_in_frames);
- use_alt_ref &= allow_alt_ref;
}
}
-#else
- gop_coding_frames = get_gop_coding_frame_num(
- &use_alt_ref, frame_info, twopass, rc, gf_start_show_idx,
- &active_gf_interval, gop_intra_factor, cpi->oxcf.lag_in_frames);
- use_alt_ref &= allow_alt_ref;
#endif
// Was the group length constrained by the requirement for a new KF?
@@ -3855,12 +3866,19 @@
int frame_count;
double gop_intra_factor;
const int arf_active_or_kf = last_gop_use_alt_ref || first_is_key_frame;
- RANGE active_gf_interval = get_active_gf_inverval_range(
- frame_info, rc, arf_active_or_kf, show_idx, /*active_worst_quality=*/0,
- /*last_boosted_qindex=*/0);
+ RANGE active_gf_interval;
+ int arf_layers;
+ if (oxcf->use_simple_encode_api) {
+ active_gf_interval = get_active_gf_inverval_range_simple(
+ rc->min_gf_interval, arf_active_or_kf, rc->frames_to_key);
+ } else {
+ active_gf_interval = get_active_gf_inverval_range(
+ frame_info, rc, arf_active_or_kf, show_idx, /*active_worst_quality=*/0,
+ /*last_boosted_qindex=*/0);
+ }
- const int arf_layers = get_arf_layers(multi_layer_arf, oxcf->enable_auto_arf,
- active_gf_interval.max);
+ arf_layers = get_arf_layers(multi_layer_arf, oxcf->enable_auto_arf,
+ active_gf_interval.max);
if (multi_layer_arf) {
gop_intra_factor = 1.0 + 0.25 * arf_layers;
} else {
@@ -3877,7 +3895,7 @@
// Under CONFIG_RATE_CTRL, once the first_pass_info is ready, the number of
// coding frames (including show frame and alt ref) can be determined.
int vp9_get_coding_frame_num(const VP9EncoderConfig *oxcf,
- TWO_PASS *const twopass,
+ const TWO_PASS *const twopass,
const FRAME_INFO *frame_info, int multi_layer_arf,
int allow_alt_ref) {
const FIRST_PASS_INFO *first_pass_info = &twopass->first_pass_info;
--- a/vp9/encoder/vp9_firstpass.h
+++ b/vp9/encoder/vp9_firstpass.h
@@ -305,7 +305,7 @@
int last_gop_use_alt_ref, int *use_alt_ref);
int vp9_get_coding_frame_num(const struct VP9EncoderConfig *oxcf,
- TWO_PASS *const twopass,
+ const TWO_PASS *const twopass,
const FRAME_INFO *frame_info, int multi_layer_arf,
int allow_alt_ref);
--- a/vp9/encoder/vp9_ratectrl.c
+++ b/vp9/encoder/vp9_ratectrl.c
@@ -1720,10 +1720,12 @@
}
#if CONFIG_RATE_CTRL
- if (cpi->encode_command.use_external_target_frame_bits) {
- rc->this_frame_target = cpi->encode_command.target_frame_bits;
+ if (cpi->oxcf.use_simple_encode_api) {
+ if (cpi->encode_command.use_external_target_frame_bits) {
+ rc->this_frame_target = cpi->encode_command.target_frame_bits;
+ }
}
-#endif
+#endif // CONFIG_RATE_CTRL
// Target rate per SB64 (including partial SB64s.
rc->sb64_target_rate = (int)(((int64_t)rc->this_frame_target * 64 * 64) /
@@ -2536,26 +2538,25 @@
rc->min_gf_interval = FIXED_GF_INTERVAL;
rc->static_scene_max_gf_interval = FIXED_GF_INTERVAL;
} else {
+ double framerate = cpi->framerate;
// Set Maximum gf/arf interval
rc->max_gf_interval = oxcf->max_gf_interval;
rc->min_gf_interval = oxcf->min_gf_interval;
#if CONFIG_RATE_CTRL
+ if (oxcf->use_simple_encode_api) {
+ // In this experiment, we avoid framerate being changed dynamically during
+ // encoding.
+ framerate = oxcf->init_framerate;
+ }
+#endif // CONFIG_RATE_CTRL
if (rc->min_gf_interval == 0) {
rc->min_gf_interval = vp9_rc_get_default_min_gf_interval(
- oxcf->width, oxcf->height, oxcf->init_framerate);
+ oxcf->width, oxcf->height, framerate);
}
if (rc->max_gf_interval == 0) {
- rc->max_gf_interval = vp9_rc_get_default_max_gf_interval(
- oxcf->init_framerate, rc->min_gf_interval);
+ rc->max_gf_interval =
+ vp9_rc_get_default_max_gf_interval(framerate, rc->min_gf_interval);
}
-#else
- if (rc->min_gf_interval == 0)
- rc->min_gf_interval = vp9_rc_get_default_min_gf_interval(
- oxcf->width, oxcf->height, cpi->framerate);
- if (rc->max_gf_interval == 0)
- rc->max_gf_interval = vp9_rc_get_default_max_gf_interval(
- cpi->framerate, rc->min_gf_interval);
-#endif
// Extended max interval for genuinely static scenes like slide shows.
rc->static_scene_max_gf_interval = MAX_STATIC_GF_GROUP_LENGTH;
--- a/vp9/simple_encode.cc
+++ b/vp9/simple_encode.cc
@@ -793,6 +793,7 @@
if (enc_pass == VPX_RC_FIRST_PASS) {
oxcf.lag_in_frames = 0;
}
+ oxcf.use_simple_encode_api = 1;
return oxcf;
}
--- a/vp9/vp9_cx_iface.c
+++ b/vp9/vp9_cx_iface.c
@@ -652,6 +652,7 @@
}
if (get_level_index(oxcf->target_level) >= 0) config_target_level(oxcf);
+ oxcf->use_simple_encode_api = 0;
// vp9_dump_encoder_config(oxcf, stderr);
return VPX_CODEC_OK;
}
@@ -2288,6 +2289,8 @@
DUMP_STRUCT_VALUE(fp, oxcf, row_mt);
DUMP_STRUCT_VALUE(fp, oxcf, motion_vector_unit_test);
+ DUMP_STRUCT_VALUE(fp, oxcf, delta_q_uv);
+ DUMP_STRUCT_VALUE(fp, oxcf, use_simple_encode_api);
}
FRAME_INFO vp9_get_frame_info(const VP9EncoderConfig *oxcf) {