From fdf04093ecb87f9342aa3a17b7efaaf7cbb1808d Mon Sep 17 00:00:00 2001 From: angiebird Date: Sat, 23 May 2020 16:28:40 -0700 Subject: [PATCH] Add GOP_COMMAND Send GOP_COMMAND to vp9 for setting gop decisions on the fly. GOP_COMMAND has three members. use: use this command to set gop or use vp9's gop decision. show_frame_count: number of show frames in this gop. use_alt_ref: use alt ref frame or not. Move the logic of processing external_arf_indexes_ from get_gop_coding_frame_num() to GetGopCommand() and GetCodingFrameNumFromGopMap(). Change-Id: Ic1942c7a4cf6eecdf3507864577688350c7ef0cf --- vp9/encoder/vp9_encoder.h | 40 ++++++++++++++++---- vp9/encoder/vp9_firstpass.c | 75 ++++++++++++++++--------------------- vp9/encoder/vp9_firstpass.h | 7 +--- vp9/simple_encode.cc | 51 ++++++++++++++++++++++--- 4 files changed, 113 insertions(+), 60 deletions(-) diff --git a/vp9/encoder/vp9_encoder.h b/vp9/encoder/vp9_encoder.h index 1a25a496e..7aa4bf7dc 100644 --- a/vp9/encoder/vp9_encoder.h +++ b/vp9/encoder/vp9_encoder.h @@ -532,24 +532,50 @@ typedef struct MOTION_VECTOR_INFO { int_mv mv[2]; } MOTION_VECTOR_INFO; +typedef struct GOP_COMMAND { + int use; // use this command to set gop or not. If not, use vp9's decision. + int show_frame_count; + int use_alt_ref; +} GOP_COMMAND; + +static INLINE void gop_command_on(GOP_COMMAND *gop_command, + int show_frame_count, int use_alt_ref) { + gop_command->use = 1; + gop_command->show_frame_count = show_frame_count; + gop_command->use_alt_ref = use_alt_ref; +} + +static INLINE void gop_command_off(GOP_COMMAND *gop_command) { + gop_command->use = 0; + gop_command->show_frame_count = 0; + gop_command->use_alt_ref = 0; +} + +static INLINE int gop_command_coding_frame_count( + const GOP_COMMAND *gop_command) { + if (gop_command->use == 0) { + assert(0); + return -1; + } + return gop_command->show_frame_count + gop_command->use_alt_ref; +} + typedef struct ENCODE_COMMAND { int use_external_quantize_index; int external_quantize_index; - // A list of binary flags set from the external controller. - // Each binary flag indicates whether the frame is an arf or not. - const int *external_arf_indexes; + GOP_COMMAND gop_command; } ENCODE_COMMAND; static INLINE void encode_command_init(ENCODE_COMMAND *encode_command) { vp9_zero(*encode_command); encode_command->use_external_quantize_index = 0; encode_command->external_quantize_index = -1; - encode_command->external_arf_indexes = NULL; + gop_command_off(&encode_command->gop_command); } -static INLINE void encode_command_set_external_arf_indexes( - ENCODE_COMMAND *encode_command, const int *external_arf_indexes) { - encode_command->external_arf_indexes = external_arf_indexes; +static INLINE void encode_command_set_gop_command( + ENCODE_COMMAND *encode_command, GOP_COMMAND gop_command) { + encode_command->gop_command = gop_command; } static INLINE void encode_command_set_external_quantize_index( diff --git a/vp9/encoder/vp9_firstpass.c b/vp9/encoder/vp9_firstpass.c index 3a48174c7..88c3e84bf 100644 --- a/vp9/encoder/vp9_firstpass.c +++ b/vp9/encoder/vp9_firstpass.c @@ -2508,9 +2508,6 @@ typedef struct RANGE { * structs. */ static int get_gop_coding_frame_num( -#if CONFIG_RATE_CTRL - const int *external_arf_indexes, -#endif int *use_alt_ref, const FRAME_INFO *frame_info, const FIRST_PASS_INFO *first_pass_info, const RATE_CONTROL *rc, int gf_start_show_idx, const RANGE *active_gf_interval, @@ -2526,24 +2523,6 @@ static int get_gop_coding_frame_num( (frame_info->frame_height + frame_info->frame_width) / 4.0; double zero_motion_accumulator = 1.0; int gop_coding_frames; -#if CONFIG_RATE_CTRL - (void)mv_ratio_accumulator_thresh; - (void)active_gf_interval; - (void)gop_intra_factor; - - if (external_arf_indexes != NULL && rc->frames_to_key > 1) { - // gop_coding_frames = 1 is necessary to filter out the overlay frame, - // since the arf is in this group of picture and its overlay is in the next. - gop_coding_frames = 1; - *use_alt_ref = 1; - while (gop_coding_frames < rc->frames_to_key) { - const int frame_index = gf_start_show_idx + gop_coding_frames; - ++gop_coding_frames; - if (external_arf_indexes[frame_index] == 1) break; - } - return gop_coding_frames; - } -#endif // CONFIG_RATE_CTRL *use_alt_ref = 1; gop_coding_frames = 0; @@ -2770,15 +2749,26 @@ 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( #if CONFIG_RATE_CTRL - cpi->encode_command.external_arf_indexes, -#endif - &use_alt_ref, frame_info, first_pass_info, rc, gf_start_show_idx, - &active_gf_interval, gop_intra_factor, cpi->oxcf.lag_in_frames); - use_alt_ref &= allow_alt_ref; + { + 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, first_pass_info, 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, first_pass_info, 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? rc->constrained_gf_group = (gop_coding_frames >= rc->frames_to_key) ? 1 : 0; @@ -3704,6 +3694,7 @@ void vp9_get_next_group_of_picture(const VP9_COMP *cpi, int *first_is_key_frame, int *use_alt_ref, int *coding_frame_count, int *first_show_idx, int *last_gop_use_alt_ref) { + const GOP_COMMAND *gop_command = &cpi->encode_command.gop_command; // We make a copy of rc here because we want to get information from the // encoder without changing its state. // TODO(angiebird): Avoid copying rc here. @@ -3726,14 +3717,19 @@ void vp9_get_next_group_of_picture(const VP9_COMP *cpi, int *first_is_key_frame, *first_is_key_frame = 1; } - *coding_frame_count = vp9_get_gop_coding_frame_count( - cpi->encode_command.external_arf_indexes, &cpi->oxcf, &cpi->frame_info, - &cpi->twopass.first_pass_info, &rc, *first_show_idx, multi_layer_arf, - allow_alt_ref, *first_is_key_frame, *last_gop_use_alt_ref, use_alt_ref); + 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); + } else { + *coding_frame_count = vp9_get_gop_coding_frame_count( + &cpi->oxcf, &cpi->frame_info, &cpi->twopass.first_pass_info, &rc, + *first_show_idx, multi_layer_arf, allow_alt_ref, *first_is_key_frame, + *last_gop_use_alt_ref, use_alt_ref); + } } -int vp9_get_gop_coding_frame_count(const int *external_arf_indexes, - const VP9EncoderConfig *oxcf, +int vp9_get_gop_coding_frame_count(const VP9EncoderConfig *oxcf, const FRAME_INFO *frame_info, const FIRST_PASS_INFO *first_pass_info, const RATE_CONTROL *rc, int show_idx, @@ -3756,9 +3752,6 @@ int vp9_get_gop_coding_frame_count(const int *external_arf_indexes, } frame_count = get_gop_coding_frame_num( -#if CONFIG_RATE_CTRL - external_arf_indexes, -#endif use_alt_ref, frame_info, first_pass_info, rc, show_idx, &active_gf_interval, gop_intra_factor, oxcf->lag_in_frames); *use_alt_ref &= allow_alt_ref; @@ -3767,8 +3760,7 @@ int vp9_get_gop_coding_frame_count(const int *external_arf_indexes, // 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 int *external_arf_indexes, - const VP9EncoderConfig *oxcf, +int vp9_get_coding_frame_num(const VP9EncoderConfig *oxcf, const FRAME_INFO *frame_info, const FIRST_PASS_INFO *first_pass_info, int multi_layer_arf, int allow_alt_ref) { @@ -3792,9 +3784,8 @@ int vp9_get_coding_frame_num(const int *external_arf_indexes, } gop_coding_frame_count = vp9_get_gop_coding_frame_count( - external_arf_indexes, oxcf, frame_info, first_pass_info, &rc, show_idx, - multi_layer_arf, allow_alt_ref, first_is_key_frame, - last_gop_use_alt_ref, &use_alt_ref); + oxcf, frame_info, first_pass_info, &rc, show_idx, multi_layer_arf, + allow_alt_ref, first_is_key_frame, last_gop_use_alt_ref, &use_alt_ref); rc.source_alt_ref_active = use_alt_ref; last_gop_use_alt_ref = use_alt_ref; diff --git a/vp9/encoder/vp9_firstpass.h b/vp9/encoder/vp9_firstpass.h index dcaf2eec6..51ffd0222 100644 --- a/vp9/encoder/vp9_firstpass.h +++ b/vp9/encoder/vp9_firstpass.h @@ -264,7 +264,6 @@ void vp9_get_next_group_of_picture(const struct VP9_COMP *cpi, /*!\brief Call this function before coding a new group of pictures to get * information about it. - * \param[in] external_arf_indexes External arf indexs passed in * \param[in] oxcf Encoder config * \param[in] frame_info Frame info * \param[in] first_pass_info First pass stats @@ -279,8 +278,7 @@ void vp9_get_next_group_of_picture(const struct VP9_COMP *cpi, * * \return Returns coding frame count */ -int vp9_get_gop_coding_frame_count(const int *external_arf_indexes, - const struct VP9EncoderConfig *oxcf, +int vp9_get_gop_coding_frame_count(const struct VP9EncoderConfig *oxcf, const FRAME_INFO *frame_info, const FIRST_PASS_INFO *first_pass_info, const RATE_CONTROL *rc, int show_idx, @@ -288,8 +286,7 @@ int vp9_get_gop_coding_frame_count(const int *external_arf_indexes, int first_is_key_frame, int last_gop_use_alt_ref, int *use_alt_ref); -int vp9_get_coding_frame_num(const int *external_arf_indexes, - const struct VP9EncoderConfig *oxcf, +int vp9_get_coding_frame_num(const struct VP9EncoderConfig *oxcf, const FRAME_INFO *frame_info, const FIRST_PASS_INFO *first_pass_info, int multi_layer_arf, int allow_alt_ref); diff --git a/vp9/simple_encode.cc b/vp9/simple_encode.cc index c417a2589..45d32c59d 100644 --- a/vp9/simple_encode.cc +++ b/vp9/simple_encode.cc @@ -813,6 +813,29 @@ T *GetVectorData(const std::vector &v) { return const_cast(v.data()); } +static GOP_COMMAND GetGopCommand(const std::vector &gop_map, + int start_show_index) { + assert(static_cast(start_show_index) < gop_map.size()); + GOP_COMMAND gop_command; + if (gop_map.size() > 0) { + int end_show_index = start_show_index + 1; + while (static_cast(end_show_index) < gop_map.size() && + gop_map[end_show_index] == 0) { + ++end_show_index; + } + const int show_frame_count = end_show_index - start_show_index; + int use_alt_ref = 1; + if (static_cast(end_show_index) == gop_map.size()) { + // This is the last gop group, there must be no altref. + use_alt_ref = 0; + } + gop_command_on(&gop_command, show_frame_count, use_alt_ref); + } else { + gop_command_off(&gop_command); + } + return gop_command; +} + void SimpleEncode::StartEncode() { assert(impl_ptr_->first_pass_stats.size() > 0); vpx_rational_t frame_rate = @@ -834,9 +857,6 @@ void SimpleEncode::StartEncode() { frame_coding_index_ = 0; show_frame_count_ = 0; - encode_command_set_external_arf_indexes(&impl_ptr_->cpi->encode_command, - GetVectorData(external_arf_indexes_)); - UpdateKeyFrameGroup(show_frame_count_); UpdateGroupOfPicture(impl_ptr_->cpi, frame_coding_index_, ref_frame_info_, @@ -914,6 +934,10 @@ void SimpleEncode::PostUpdateState( IncreaseGroupOfPictureIndex(&group_of_picture_); if (IsGroupOfPictureFinished(group_of_picture_)) { + const GOP_COMMAND gop_command = + GetGopCommand(external_arf_indexes_, show_frame_count_); + encode_command_set_gop_command(&impl_ptr_->cpi->encode_command, + gop_command); // This function needs to be called after ref_frame_info_ is updated // properly in PostUpdateRefFrameInfo() and UpdateKeyFrameGroup(). UpdateGroupOfPicture(impl_ptr_->cpi, frame_coding_index_, ref_frame_info_, @@ -1002,8 +1026,24 @@ void SimpleEncode::EncodeFrameWithQuantizeIndex( encode_command_reset_external_quantize_index(&impl_ptr_->cpi->encode_command); } +static int GetCodingFrameNumFromGopMap(const std::vector &gop_map) { + int start_show_index = 0; + int coding_frame_count = 0; + while (static_cast(start_show_index) < gop_map.size()) { + const GOP_COMMAND gop_command = GetGopCommand(gop_map, start_show_index); + start_show_index += gop_command.show_frame_count; + coding_frame_count += gop_command_coding_frame_count(&gop_command); + } + assert(start_show_index == gop_map.size()); + return coding_frame_count; +} + int SimpleEncode::GetCodingFrameNum() const { - assert(impl_ptr_->first_pass_stats.size() - 1 > 0); + assert(impl_ptr_->first_pass_stats.size() > 0); + if (external_arf_indexes_.size() > 0) { + return GetCodingFrameNumFromGopMap(external_arf_indexes_); + } + // These are the default settings for now. const int multi_layer_arf = 0; const int allow_alt_ref = 1; @@ -1017,8 +1057,7 @@ int SimpleEncode::GetCodingFrameNum() const { fps_init_first_pass_info(&first_pass_info, GetVectorData(impl_ptr_->first_pass_stats), num_frames_); - return vp9_get_coding_frame_num(external_arf_indexes_.data(), &oxcf, - &frame_info, &first_pass_info, + return vp9_get_coding_frame_num(&oxcf, &frame_info, &first_pass_info, multi_layer_arf, allow_alt_ref); } -- 2.40.0