From c2aa1520a4610fb5cc640f55c117805fb0047502 Mon Sep 17 00:00:00 2001 From: angiebird Date: Tue, 25 Feb 2020 17:30:14 -0800 Subject: [PATCH] Add RefFrameInfo RefFrameInfo contains the coding_indexes and valid_list of three reference frame types. Note that I will add unit test in the follow-up CLs. Change-Id: Ia055df1f8a5537b2bdd02c78991df9bbf48e951a --- vp9/simple_encode.cc | 58 +++++++++++++++++++++++++++++++++----------- vp9/simple_encode.h | 37 +++++++++++++++------------- 2 files changed, 64 insertions(+), 31 deletions(-) diff --git a/vp9/simple_encode.cc b/vp9/simple_encode.cc index 214d33cc8..25d02518d 100644 --- a/vp9/simple_encode.cc +++ b/vp9/simple_encode.cc @@ -524,12 +524,20 @@ static int IsGroupOfPictureFinished(const GroupOfPicture &group_of_picture) { group_of_picture.encode_frame_list.size(); } -static void UpdateRefFrameCodingIndexes(FrameType frame_type, - int frame_coding_index, - int *ref_frame_coding_indexes, - int *ref_frame_valid_list) { +static void InitRefFrameInfo(RefFrameInfo *ref_frame_info) { + for (int i = 0; i < kRefFrameTypeMax; ++i) { + ref_frame_info->coding_indexes[i] = 0; + ref_frame_info->valid_list[i] = 0; + } +} + +// After finishing coding a frame, this function will update the coded frame +// into the ref_frame_info based on the frame_type and the coding_index. +static void PostUpdateRefFrameInfo(FrameType frame_type, int frame_coding_index, + RefFrameInfo *ref_frame_info) { // This part is written based on the logics in vp9_configure_buffer_updates() // and update_ref_frames() + int *ref_frame_coding_indexes = ref_frame_info->coding_indexes; switch (frame_type) { case kFrameTypeKey: ref_frame_coding_indexes[kRefFrameTypeLast] = frame_coding_index; @@ -564,6 +572,7 @@ static void UpdateRefFrameCodingIndexes(FrameType frame_type, const int past_index = ref_frame_coding_indexes[kRefFrameTypePast]; const int future_index = ref_frame_coding_indexes[kRefFrameTypeFuture]; + int *ref_frame_valid_list = ref_frame_info->valid_list; for (int ref_frame_idx = 0; ref_frame_idx < kRefFrameTypeMax; ++ref_frame_idx) { ref_frame_valid_list[ref_frame_idx] = 1; @@ -585,6 +594,7 @@ static void UpdateRefFrameCodingIndexes(FrameType frame_type, static void SetGroupOfPicture(int first_is_key_frame, int use_alt_ref, int coding_frame_count, int first_show_idx, int last_gop_use_alt_ref, int start_coding_index, + const RefFrameInfo &start_ref_frame_info, GroupOfPicture *group_of_picture) { // Clean up the state of previous group of picture. group_of_picture->encode_frame_list.clear(); @@ -592,10 +602,16 @@ static void SetGroupOfPicture(int first_is_key_frame, int use_alt_ref, group_of_picture->show_frame_count = coding_frame_count - use_alt_ref; group_of_picture->start_show_index = first_show_idx; group_of_picture->start_coding_index = start_coding_index; + + // We need to make a copy of start reference frame info because we + // use it to simulate the ref frame update. + RefFrameInfo ref_frame_info = start_ref_frame_info; + { // First frame in the group of pictures. It's either key frame or show inter // frame. EncodeFrameInfo encode_frame_info; + // Set frame_type if (first_is_key_frame) { encode_frame_info.frame_type = kFrameTypeKey; } else { @@ -605,8 +621,14 @@ static void SetGroupOfPicture(int first_is_key_frame, int use_alt_ref, encode_frame_info.frame_type = kFrameTypeGolden; } } + encode_frame_info.show_idx = first_show_idx; encode_frame_info.coding_index = start_coding_index; + + encode_frame_info.ref_frame_info = ref_frame_info; + PostUpdateRefFrameInfo(encode_frame_info.frame_type, + encode_frame_info.coding_index, &ref_frame_info); + group_of_picture->encode_frame_list.push_back(encode_frame_info); } @@ -618,6 +640,11 @@ static void SetGroupOfPicture(int first_is_key_frame, int use_alt_ref, encode_frame_info.frame_type = kFrameTypeAltRef; encode_frame_info.show_idx = first_show_idx + show_frame_count; encode_frame_info.coding_index = start_coding_index + 1; + + encode_frame_info.ref_frame_info = ref_frame_info; + PostUpdateRefFrameInfo(encode_frame_info.frame_type, + encode_frame_info.coding_index, &ref_frame_info); + group_of_picture->encode_frame_list.push_back(encode_frame_info); } @@ -627,6 +654,11 @@ static void SetGroupOfPicture(int first_is_key_frame, int use_alt_ref, encode_frame_info.frame_type = kFrameTypeInter; encode_frame_info.show_idx = first_show_idx + i; encode_frame_info.coding_index = start_coding_index + use_alt_ref + i; + + encode_frame_info.ref_frame_info = ref_frame_info; + PostUpdateRefFrameInfo(encode_frame_info.frame_type, + encode_frame_info.coding_index, &ref_frame_info); + group_of_picture->encode_frame_list.push_back(encode_frame_info); } } @@ -635,6 +667,7 @@ static void SetGroupOfPicture(int first_is_key_frame, int use_alt_ref, // |group_of_picture| accordingly. // This is called at the starting of encoding of each group of picture. static void UpdateGroupOfPicture(const VP9_COMP *cpi, int start_coding_index, + const RefFrameInfo &start_ref_frame_info, GroupOfPicture *group_of_picture) { int first_is_key_frame; int use_alt_ref; @@ -646,7 +679,7 @@ static void UpdateGroupOfPicture(const VP9_COMP *cpi, int start_coding_index, &last_gop_use_alt_ref); SetGroupOfPicture(first_is_key_frame, use_alt_ref, coding_frame_count, first_show_idx, last_gop_use_alt_ref, start_coding_index, - group_of_picture); + start_ref_frame_info, group_of_picture); } SimpleEncode::SimpleEncode(int frame_width, int frame_height, @@ -672,10 +705,7 @@ SimpleEncode::SimpleEncode(int frame_width, int frame_height, impl_ptr_->cpi = nullptr; impl_ptr_->img_fmt = VPX_IMG_FMT_I420; - for (int i = 0; i < kRefFrameTypeMax; ++i) { - ref_frame_coding_indexes_[i] = 0; - ref_frame_valid_list_[i] = 0; - } + InitRefFrameInfo(&ref_frame_info_); } void SimpleEncode::ComputeFirstPassStats() { @@ -779,7 +809,8 @@ void SimpleEncode::StartEncode() { frame_coding_index_ = 0; encode_command_set_external_arf_indexes(&impl_ptr_->cpi->encode_command, external_arf_indexes_.data()); - UpdateGroupOfPicture(impl_ptr_->cpi, frame_coding_index_, &group_of_picture_); + UpdateGroupOfPicture(impl_ptr_->cpi, frame_coding_index_, ref_frame_info_, + &group_of_picture_); rewind(in_file_); if (out_file_ != nullptr) { @@ -818,13 +849,12 @@ void SimpleEncode::PostUpdateState( const EncodeFrameResult &encode_frame_result) { // This function needs to be called before the increament of // frame_coding_index_ - UpdateRefFrameCodingIndexes(encode_frame_result.frame_type, - frame_coding_index_, ref_frame_coding_indexes_, - ref_frame_valid_list_); + PostUpdateRefFrameInfo(encode_frame_result.frame_type, frame_coding_index_, + &ref_frame_info_); ++frame_coding_index_; IncreaseGroupOfPictureIndex(&group_of_picture_); if (IsGroupOfPictureFinished(group_of_picture_)) { - UpdateGroupOfPicture(impl_ptr_->cpi, frame_coding_index_, + UpdateGroupOfPicture(impl_ptr_->cpi, frame_coding_index_, ref_frame_info_, &group_of_picture_); } } diff --git a/vp9/simple_encode.h b/vp9/simple_encode.h index 6e70e993e..821bb928f 100644 --- a/vp9/simple_encode.h +++ b/vp9/simple_encode.h @@ -71,6 +71,21 @@ struct MotionVectorInfo { double mv_column[2]; }; +struct RefFrameInfo { + int coding_indexes[kRefFrameTypeMax]; + + // Indicate whether the reference frames are available or not. + // When the reference frame type is not valid, it means either the to-be-coded + // frame is a key frame or the reference frame already appears in other + // reference frame type. vp9 always keeps three types of reference frame + // available. However, the duplicated reference frames will not be + // chosen by the encoder. The priorities of choosing reference frames are + // kRefFrameTypeLast > kRefFrameTypePast > kRefFrameTypeFuture. + // For example, if kRefFrameTypeLast and kRefFrameTypePast both point to the + // same frame, kRefFrameTypePast will be set to invalid. + int valid_list[kRefFrameTypeMax]; +}; + struct EncodeFrameInfo { int show_idx; @@ -78,6 +93,7 @@ struct EncodeFrameInfo { // coding order (starting from zero) in the coding process of the entire // video. The coding index for each frame is unique. int coding_index; + RefFrameInfo ref_frame_info; FrameType frame_type; }; @@ -342,23 +358,10 @@ class SimpleEncode { // video. The coding index of the to-be-coded frame. int frame_coding_index_; - // Coding indexes of reference frames of to-be-coded-frame. - int ref_frame_coding_indexes_[kRefFrameTypeMax]; - - // Indicate whether the reference frames are available or not. - // When the reference frame type is not valid, it means either the to-be-coded - // frame is a key frame or the reference frame already appears in other - // reference frame type. vp9 always keeps three types of reference frame - // available. However, the duplicated reference frames will not be - // chosen by the encoder. The priorities of choosing reference frames are - // kRefFrameTypeLast > kRefFrameTypePast > kRefFrameTypeFuture. - // For example, if kRefFrameTypeLast and kRefFrameTypePast both point to the - // same frame, kRefFrameTypePast will be set to invalid. - - // TODO(angiebird): Do we need to reset ref_frame_valid_list_ and - // ref_frame_valid_list_ when nex key frame appears? - - int ref_frame_valid_list_[kRefFrameTypeMax]; + // TODO(angiebird): Do we need to reset ref_frames_info_ when the next key + // frame appears? + // Reference frames info of the to-be-coded frame. + RefFrameInfo ref_frame_info_; void PostUpdateState(const EncodeFrameResult &encode_frame_result); }; -- 2.40.0