ref: fdf04093ecb87f9342aa3a17b7efaaf7cbb1808d
parent: 3bc58f13cc4ae0881ce483a8dcd7789a2d6f325d
author: angiebird <angiebird@google.com>
date: Sat May 23 12:28:40 EDT 2020
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
--- a/vp9/encoder/vp9_encoder.h
+++ b/vp9/encoder/vp9_encoder.h
@@ -532,12 +532,38 @@
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) {
@@ -544,12 +570,12 @@
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(
--- a/vp9/encoder/vp9_firstpass.c
+++ b/vp9/encoder/vp9_firstpass.c
@@ -2508,9 +2508,6 @@
* 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,25 +2523,7 @@
(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;
while (gop_coding_frames < rc->static_scene_max_gf_interval &&
@@ -2770,15 +2749,26 @@
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 @@
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 @@
*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 @@
}
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 @@
// 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 @@
}
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;
--- a/vp9/encoder/vp9_firstpass.h
+++ b/vp9/encoder/vp9_firstpass.h
@@ -264,7 +264,6 @@
/*!\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 @@
*
* \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 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);
--- a/vp9/simple_encode.cc
+++ b/vp9/simple_encode.cc
@@ -813,6 +813,29 @@
return const_cast<T *>(v.data());
}
+static GOP_COMMAND GetGopCommand(const std::vector<int> &gop_map,
+ int start_show_index) {
+ assert(static_cast<size_t>(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<size_t>(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<size_t>(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 @@
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 @@
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 @@
encode_command_reset_external_quantize_index(&impl_ptr_->cpi->encode_command);
}
+static int GetCodingFrameNumFromGopMap(const std::vector<int> &gop_map) {
+ int start_show_index = 0;
+ int coding_frame_count = 0;
+ while (static_cast<size_t>(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 @@
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);
}