diff options
-rw-r--r-- | vp9/encoder/vp9_encodeframe.c | 37 | ||||
-rw-r--r-- | vp9/encoder/vp9_encoder.c | 394 | ||||
-rw-r--r-- | vp9/encoder/vp9_encoder.h | 1 | ||||
-rw-r--r-- | vp9/encoder/vp9_firstpass.c | 108 | ||||
-rw-r--r-- | vp9/encoder/vp9_firstpass.h | 2 | ||||
-rw-r--r-- | vp9/encoder/vp9_ratectrl.c | 29 | ||||
-rw-r--r-- | vp9/simple_encode.cc | 4 | ||||
-rw-r--r-- | vp9/vp9_cx_iface.c | 3 |
8 files changed, 250 insertions, 328 deletions
diff --git a/vp9/encoder/vp9_encodeframe.c b/vp9/encoder/vp9_encodeframe.c index dcd647658..00855319d 100644 --- a/vp9/encoder/vp9_encodeframe.c +++ b/vp9/encoder/vp9_encodeframe.c @@ -4603,15 +4603,18 @@ static int rd_pick_partition(VP9_COMP *cpi, ThreadData *td, 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 @@ void vp9_init_tile_data(VP9_COMP *cpi) { 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 @@ static void restore_encode_params(VP9_COMP *cpi) { 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 diff --git a/vp9/encoder/vp9_encoder.c b/vp9/encoder/vp9_encoder.c index 34646465a..bbd6dd030 100644 --- a/vp9/encoder/vp9_encoder.c +++ b/vp9/encoder/vp9_encoder.c @@ -1022,10 +1022,12 @@ static void dealloc_compressor_data(VP9_COMP *cpi) { 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 @@ VP9_COMP *vp9_create_compressor(const VP9EncoderConfig *oxcf, #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 @@ static void encode_with_recode_loop(VP9_COMP *cpi, size_t *size, uint8_t *dest 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 @@ static void encode_with_recode_loop(VP9_COMP *cpi, size_t *size, uint8_t *dest #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 @@ static void encode_with_recode_loop(VP9_COMP *cpi, size_t *size, uint8_t *dest 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 @@ static void set_mb_wiener_variance(VP9_COMP *cpi) { } #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 @@ static void encode_frame_to_data_rate( 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 @@ static void encode_frame_to_data_rate( 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 @@ static void encode_frame_to_data_rate( // 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 @@ static void setup_tpl_stats(VP9_COMP *cpi) { #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 } @@ -7545,206 +7631,6 @@ void vp9_get_ref_frame_info(FRAME_UPDATE_TYPE update_type, int ref_frame_flags, } } -#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. #if CONFIG_RATE_CTRL diff --git a/vp9/encoder/vp9_encoder.h b/vp9/encoder/vp9_encoder.h index 12520fb82..65a1d3328 100644 --- a/vp9/encoder/vp9_encoder.h +++ b/vp9/encoder/vp9_encoder.h @@ -291,6 +291,7 @@ typedef struct VP9EncoderConfig { 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) { diff --git a/vp9/encoder/vp9_firstpass.c b/vp9/encoder/vp9_firstpass.c index 28a22ded6..7343d1bc6 100644 --- a/vp9/encoder/vp9_firstpass.c +++ b/vp9/encoder/vp9_firstpass.c @@ -1114,8 +1114,10 @@ void vp9_first_pass_encode_tile_mb_row(VP9_COMP *cpi, ThreadData *td, 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 @@ void vp9_first_pass_encode_tile_mb_row(VP9_COMP *cpi, ThreadData *td, } } #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 @@ void vp9_first_pass_encode_tile_mb_row(VP9_COMP *cpi, ThreadData *td, 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 @@ void vp9_first_pass_encode_tile_mb_row(VP9_COMP *cpi, ThreadData *td, } 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 @@ static void first_pass_encode(VP9_COMP *cpi, FIRSTPASS_DATA *fp_acc_data) { 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 @@ static int get_gop_coding_frame_num( 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 @@ static RANGE get_active_gf_inverval_range( } active_gf_interval.max = VPXMAX(active_gf_interval.max, active_gf_interval.min); -#endif return active_gf_interval; } @@ -2794,9 +2804,14 @@ static void define_gf_group(VP9_COMP *cpi, int gf_start_show_idx) { 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 @@ static void define_gf_group(VP9_COMP *cpi, int gf_start_show_idx) { 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? @@ -3836,7 +3847,7 @@ void vp9_get_next_group_of_picture(const VP9_COMP *cpi, int *first_is_key_frame, if (gop_command->use) { *coding_frame_count = gop_command_coding_frame_count(gop_command); *use_alt_ref = gop_command->use_alt_ref; - assert(*coding_frame_count < rc.frames_to_key); + assert(gop_command->show_frame_count <= rc.frames_to_key); } else { *coding_frame_count = vp9_get_gop_coding_frame_count( &cpi->oxcf, &cpi->twopass, &cpi->frame_info, &rc, *first_show_idx, @@ -3855,12 +3866,19 @@ int vp9_get_gop_coding_frame_count(const VP9EncoderConfig *oxcf, 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 @@ int vp9_get_gop_coding_frame_count(const VP9EncoderConfig *oxcf, // 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; diff --git a/vp9/encoder/vp9_firstpass.h b/vp9/encoder/vp9_firstpass.h index ff0eb40c8..ddfc87d89 100644 --- a/vp9/encoder/vp9_firstpass.h +++ b/vp9/encoder/vp9_firstpass.h @@ -305,7 +305,7 @@ int vp9_get_gop_coding_frame_count(const struct VP9EncoderConfig *oxcf, 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); diff --git a/vp9/encoder/vp9_ratectrl.c b/vp9/encoder/vp9_ratectrl.c index 18ba04581..8c111166b 100644 --- a/vp9/encoder/vp9_ratectrl.c +++ b/vp9/encoder/vp9_ratectrl.c @@ -1717,10 +1717,12 @@ void vp9_rc_set_frame_target(VP9_COMP *cpi, int target) { } #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) / @@ -2533,26 +2535,25 @@ void vp9_rc_set_gf_interval_range(const VP9_COMP *const cpi, 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; diff --git a/vp9/simple_encode.cc b/vp9/simple_encode.cc index 8ff5ad3c9..6ba37a321 100644 --- a/vp9/simple_encode.cc +++ b/vp9/simple_encode.cc @@ -793,6 +793,7 @@ static VP9EncoderConfig GetEncodeConfig( if (enc_pass == VPX_RC_FIRST_PASS) { oxcf.lag_in_frames = 0; } + oxcf.use_simple_encode_api = 1; return oxcf; } @@ -1009,8 +1010,7 @@ T *GetVectorData(const std::vector<T> &v) { static GOP_COMMAND GetGopCommand(const std::vector<int> &gop_map, int start_show_index) { GOP_COMMAND gop_command; - if (gop_map.size() > 0) { - assert(static_cast<size_t>(start_show_index) < gop_map.size()); + if (static_cast<size_t>(start_show_index) < gop_map.size()) { assert((gop_map[start_show_index] & kGopMapFlagStart) != 0); int end_show_index = start_show_index + 1; // gop_map[end_show_index] & kGopMapFlagStart == 0 means this is diff --git a/vp9/vp9_cx_iface.c b/vp9/vp9_cx_iface.c index 438f9b5ed..7697806ce 100644 --- a/vp9/vp9_cx_iface.c +++ b/vp9/vp9_cx_iface.c @@ -652,6 +652,7 @@ static vpx_codec_err_t set_encoder_config( } 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 @@ void vp9_dump_encoder_config(const VP9EncoderConfig *oxcf, FILE *fp) { 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) { |