From: angiebird Date: Fri, 28 Feb 2020 04:03:11 +0000 (-0800) Subject: Add ref_frame_info to encode_frame_result X-Git-Tag: v1.9.0-rc1~58^2~2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=fc898231f126a38db8c789be16c5d9e8dc72c293;p=platform%2Fupstream%2Flibvpx.git Add ref_frame_info to encode_frame_result Change-Id: If41a1ea6ce0a2b8db3811f2fa8efcf16f97fa0bd --- diff --git a/vp9/common/vp9_blockd.h b/vp9/common/vp9_blockd.h index 6ef8127..d7de46c 100644 --- a/vp9/common/vp9_blockd.h +++ b/vp9/common/vp9_blockd.h @@ -64,6 +64,12 @@ typedef struct { typedef int8_t MV_REFERENCE_FRAME; +static INLINE int mv_ref_frame_to_inter_ref_idx( + MV_REFERENCE_FRAME mv_ref_frame) { + assert(mv_ref_frame >= LAST_FRAME && mv_ref_frame < MAX_REF_FRAMES); + return mv_ref_frame - 1; +} + // This structure now relates to 8x8 block regions. typedef struct MODE_INFO { // Common for both INTER and INTRA blocks diff --git a/vp9/common/vp9_onyxc_int.h b/vp9/common/vp9_onyxc_int.h index 60759f3..cc4267a 100644 --- a/vp9/common/vp9_onyxc_int.h +++ b/vp9/common/vp9_onyxc_int.h @@ -69,7 +69,18 @@ typedef struct { int mi_rows; int mi_cols; uint8_t released; - int frame_index; + + // Note that frame_index/frame_coding_index are only set by set_frame_index() + // on the encoder side. + + // TODO(angiebird): Set frame_index/frame_coding_index on the decoder side + // properly. + int frame_index; // Display order in the video, it's equivalent to the + // show_idx defined in EncodeFrameInfo. +#if CONFIG_RATE_CTRL + int frame_coding_index; // The coding order (starting from zero) of this + // frame. +#endif // CONFIG_RATE_CTRL vpx_codec_frame_buffer_t raw_frame_buffer; YV12_BUFFER_CONFIG buf; } RefCntBuffer; diff --git a/vp9/encoder/vp9_encoder.c b/vp9/encoder/vp9_encoder.c index a35b4af..44747db 100644 --- a/vp9/encoder/vp9_encoder.c +++ b/vp9/encoder/vp9_encoder.c @@ -4887,6 +4887,9 @@ static void set_frame_index(VP9_COMP *cpi, VP9_COMMON *cm) { const GF_GROUP *const gf_group = &cpi->twopass.gf_group; ref_buffer->frame_index = cm->current_video_frame + gf_group->arf_src_offset[gf_group->index]; +#if CONFIG_RATE_CTRL + ref_buffer->frame_coding_index = cm->current_frame_coding_index; +#endif // CONFIG_RATE_CTRL } } @@ -5080,9 +5083,22 @@ static void set_mb_wiener_variance(VP9_COMP *cpi) { cpi->norm_wiener_variance = VPXMAX(1, cpi->norm_wiener_variance); } -static void encode_frame_to_data_rate(VP9_COMP *cpi, size_t *size, - uint8_t *dest, - unsigned int *frame_flags) { +#if !CONFIG_REALTIME_ONLY +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_buf[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, +#endif // CONFIG_RATE_CTRL + ENCODE_FRAME_RESULT *encode_frame_result); +#endif // !CONFIG_REALTIME_ONLY + +static void encode_frame_to_data_rate( + VP9_COMP *cpi, size_t *size, uint8_t *dest, unsigned int *frame_flags, + ENCODE_FRAME_RESULT *encode_frame_result) { VP9_COMMON *const cm = &cpi->common; const VP9EncoderConfig *const oxcf = &cpi->oxcf; struct segmentation *const seg = &cm->seg; @@ -5247,6 +5263,44 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi, size_t *size, // build the bitstream vp9_pack_bitstream(cpi, dest, size); +#if CONFIG_REALTIME_ONLY + (void)encode_frame_result; + 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]; + 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 + // cpi->alt_fb_idx are updated for current frame and have + // not been updated for the next frame yet. + // The update locations are as follows. + // 1) twopass.gf_group.index is initialized at define_gf_group by vp9_zero() + // for the first frame in the gf_group and is updated for the next frame at + // vp9_twopass_postencode_update(). + // 2) cpi->Source is updated at the beginning of vp9_get_compressed_data() + // 3) cm->new_fb_idx is updated at the beginning of + // vp9_get_compressed_data() by get_free_fb(cm). + // 4) cpi->lst_fb_idx/gld_fb_idx/alt_fb_idx will be updated for the next + // frame at vp9_update_reference_frames(). + // 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), + cpi->oxcf.input_bit_depth, cm->bit_depth, cpi->td.counts, +#if CONFIG_RATE_CTRL + cpi->partition_info, cpi->motion_vector_info, +#endif // CONFIG_RATE_CTRL + encode_frame_result); + } +#endif // CONFIG_REALTIME_ONLY + if (cpi->rc.use_post_encode_drop && cm->base_qindex < cpi->rc.worst_quality && cpi->svc.spatial_layer_id == 0 && post_encode_drop_cbr(cpi, size)) { restore_coding_context(cpi); @@ -5370,7 +5424,8 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi, size_t *size, static void SvcEncode(VP9_COMP *cpi, size_t *size, uint8_t *dest, unsigned int *frame_flags) { vp9_rc_get_svc_params(cpi); - encode_frame_to_data_rate(cpi, size, dest, frame_flags); + encode_frame_to_data_rate(cpi, size, dest, frame_flags, + /*encode_frame_result = */ NULL); } static void Pass0Encode(VP9_COMP *cpi, size_t *size, uint8_t *dest, @@ -5380,17 +5435,19 @@ static void Pass0Encode(VP9_COMP *cpi, size_t *size, uint8_t *dest, } else { vp9_rc_get_one_pass_vbr_params(cpi); } - encode_frame_to_data_rate(cpi, size, dest, frame_flags); + encode_frame_to_data_rate(cpi, size, dest, frame_flags, + /*encode_frame_result = */ NULL); } #if !CONFIG_REALTIME_ONLY static void Pass2Encode(VP9_COMP *cpi, size_t *size, uint8_t *dest, - unsigned int *frame_flags) { + unsigned int *frame_flags, + ENCODE_FRAME_RESULT *encode_frame_result) { cpi->allow_encode_breakout = ENCODE_BREAKOUT_ENABLED; #if CONFIG_MISMATCH_DEBUG mismatch_move_frame_idx_w(); #endif - encode_frame_to_data_rate(cpi, size, dest, frame_flags); + encode_frame_to_data_rate(cpi, size, dest, frame_flags, encode_frame_result); } #endif // !CONFIG_REALTIME_ONLY @@ -7249,11 +7306,10 @@ static void yv12_buffer_to_image_buffer(const YV12_BUFFER_CONFIG *yv12_buffer, } } #endif // CONFIG_RATE_CTRL - static void update_encode_frame_result( - int show_idx, FRAME_UPDATE_TYPE update_type, - const YV12_BUFFER_CONFIG *source_frame, - const YV12_BUFFER_CONFIG *coded_frame, int quantize_index, + 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, @@ -7263,29 +7319,54 @@ static void update_encode_frame_result( #if CONFIG_RATE_CTRL PSNR_STATS psnr; #if CONFIG_VP9_HIGHBITDEPTH - vpx_calc_highbd_psnr(source_frame, coded_frame, &psnr, bit_depth, + 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, &psnr); + 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; + + if (update_type != KF_UPDATE) { + const VP9_REFFRAME inter_ref_flags[MAX_INTER_REF_FRAMES] = { VP9_LAST_FLAG, + VP9_GOLD_FLAG, + VP9_ALT_FLAG }; + int i; + for (i = 0; i < MAX_INTER_REF_FRAMES; ++i) { + assert(ref_frame_bufs[i] != NULL); + encode_frame_result->ref_frame_coding_indexes[i] = + ref_frame_bufs[i]->frame_coding_index; + encode_frame_result->ref_frame_valid_list[i] = + !(ref_frame_flags & inter_ref_flags[i]); + } + } else { + // No reference frame is available when this is a key frame. + int i; + for (i = 0; i < MAX_INTER_REF_FRAMES; ++i) { + encode_frame_result->ref_frame_coding_indexes[i] = -1; + encode_frame_result->ref_frame_valid_list[i] = 0; + } + } 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; if (encode_frame_result->coded_frame.allocated) { - yv12_buffer_to_image_buffer(coded_frame, &encode_frame_result->coded_frame); + 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; + (void)coded_frame_buf; + (void)ref_frame_bufs; (void)counts; #endif // CONFIG_RATE_CTRL - encode_frame_result->show_idx = show_idx; + encode_frame_result->show_idx = coded_frame_buf->frame_index; encode_frame_result->update_type = update_type; encode_frame_result->quantize_index = quantize_index; } @@ -7294,6 +7375,7 @@ static void update_encode_frame_result( 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 + encode_frame_result->frame_coding_index = -1; vp9_zero(encode_frame_result->coded_frame); encode_frame_result->coded_frame.allocated = 0; #endif // CONFIG_RATE_CTRL @@ -7575,29 +7657,7 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags, cpi->td.mb.inv_txfm_add = lossless ? vp9_iwht4x4_add : vp9_idct4x4_add; vp9_first_pass(cpi, source); } else if (oxcf->pass == 2 && !cpi->use_svc) { - Pass2Encode(cpi, size, dest, frame_flags); - // update_encode_frame_result() depends on twopass.gf_group.index and - // cm->new_fb_idx and cpi->Source are updated for current properly and have - // not been updated for the next frame yet. - // The update locations are as follows. - // 1) twopass.gf_group.index is initialized at define_gf_group by vp9_zero() - // for the first frame in the gf_group and is updated for the next frame at - // vp9_twopass_postencode_update(). - // 2) cpi->Source is updated at the beginning of this function, i.e. - // vp9_get_compressed_data() - // 3) cm->new_fb_idx is updated at the beginning of this function by - // get_free_fb(cm) - // TODO(angiebird): Improve the codebase to make the update of frame - // dependent variables more robust. - update_encode_frame_result( - source->show_idx, - cpi->twopass.gf_group.update_type[cpi->twopass.gf_group.index], - cpi->Source, get_frame_new_buffer(cm), vp9_get_quantizer(cpi), - cpi->oxcf.input_bit_depth, cm->bit_depth, cpi->td.counts, -#if CONFIG_RATE_CTRL - cpi->partition_info, cpi->motion_vector_info, -#endif // CONFIG_RATE_CTRL - encode_frame_result); + Pass2Encode(cpi, size, dest, frame_flags, encode_frame_result); vp9_twopass_postencode_update(cpi); } else if (cpi->use_svc) { SvcEncode(cpi, size, dest, frame_flags); diff --git a/vp9/encoder/vp9_encoder.h b/vp9/encoder/vp9_encoder.h index 8b4c6a5..a237b74 100644 --- a/vp9/encoder/vp9_encoder.h +++ b/vp9/encoder/vp9_encoder.h @@ -936,6 +936,9 @@ typedef struct ENCODE_FRAME_RESULT { int show_idx; FRAME_UPDATE_TYPE update_type; #if CONFIG_RATE_CTRL + int frame_coding_index; + int ref_frame_coding_indexes[MAX_INTER_REF_FRAMES]; + int ref_frame_valid_list[MAX_INTER_REF_FRAMES]; double psnr; uint64_t sse; FRAME_COUNTS frame_counts; @@ -1043,10 +1046,22 @@ static INLINE int get_ref_frame_buf_idx(const VP9_COMP *const cpi, return (map_idx != INVALID_IDX) ? cm->ref_frame_map[map_idx] : INVALID_IDX; } -static INLINE RefCntBuffer *get_ref_cnt_buffer(VP9_COMMON *cm, int fb_idx) { +static INLINE RefCntBuffer *get_ref_cnt_buffer(const VP9_COMMON *cm, + int fb_idx) { return fb_idx != INVALID_IDX ? &cm->buffer_pool->frame_bufs[fb_idx] : NULL; } +static INLINE void get_ref_frame_bufs( + const VP9_COMP *cpi, RefCntBuffer *ref_frame_bufs[MAX_INTER_REF_FRAMES]) { + const VP9_COMMON *const cm = &cpi->common; + MV_REFERENCE_FRAME ref_frame; + for (ref_frame = LAST_FRAME; ref_frame < MAX_REF_FRAMES; ++ref_frame) { + int ref_frame_buf_idx = get_ref_frame_buf_idx(cpi, ref_frame); + int inter_ref_idx = mv_ref_frame_to_inter_ref_idx(ref_frame); + ref_frame_bufs[inter_ref_idx] = get_ref_cnt_buffer(cm, ref_frame_buf_idx); + } +} + static INLINE YV12_BUFFER_CONFIG *get_ref_frame_buffer( const VP9_COMP *const cpi, MV_REFERENCE_FRAME ref_frame) { const VP9_COMMON *const cm = &cpi->common; diff --git a/vp9/simple_encode.cc b/vp9/simple_encode.cc index d5e6fb5..31e2089 100644 --- a/vp9/simple_encode.cc +++ b/vp9/simple_encode.cc @@ -498,6 +498,14 @@ static void update_encode_frame_result( encode_frame_result->coding_data_bit_size = encode_frame_result->coding_data_byte_size * 8; encode_frame_result->show_idx = encode_frame_info->show_idx; + encode_frame_result->coding_idx = encode_frame_info->frame_coding_index; + for (int i = 0; i < kRefFrameTypeMax; ++i) { + assert(kRefFrameTypeMax == MAX_INTER_REF_FRAMES); + encode_frame_result->ref_frame_info.coding_indexes[i] = + encode_frame_info->ref_frame_coding_indexes[i]; + encode_frame_result->ref_frame_info.valid_list[i] = + encode_frame_info->ref_frame_valid_list[i]; + } encode_frame_result->frame_type = get_frame_type_from_update_type(encode_frame_info->update_type); encode_frame_result->psnr = encode_frame_info->psnr; diff --git a/vp9/simple_encode.h b/vp9/simple_encode.h index 821bb92..1a064c8 100644 --- a/vp9/simple_encode.h +++ b/vp9/simple_encode.h @@ -199,6 +199,8 @@ void output_image_buffer(const ImageBuffer &image_buffer, std::FILE *out_file); struct EncodeFrameResult { int show_idx; FrameType frame_type; + int coding_idx; + RefFrameInfo ref_frame_info; size_t coding_data_bit_size; size_t coding_data_byte_size; // The EncodeFrame will allocate a buffer, write the coding data into the