Refactor AV1LevelParams from AV1_COMP
Grouped AV1 bitstream level related params from AV1_COMP
to new struct AV1LevelParams. Also added documentation
for the members, and cleaned up function interfaces.
BUG=aomedia:2610
Change-Id: Id28b5079243bbefed52959f9a35b919cf46bae8c
diff --git a/av1/av1_cx_iface.c b/av1/av1_cx_iface.c
index e13ed95..e701d35 100644
--- a/av1/av1_cx_iface.c
+++ b/av1/av1_cx_iface.c
@@ -2192,7 +2192,7 @@
}
const uint32_t obu_header_offset = 0;
obu_header_size = av1_write_obu_header(
- cpi, OBU_TEMPORAL_DELIMITER, 0,
+ &cpi->level_params, OBU_TEMPORAL_DELIMITER, 0,
(uint8_t *)(ctx->pending_cx_data + obu_header_offset));
// OBUs are preceded/succeeded by an unsigned leb128 coded integer.
@@ -2616,8 +2616,10 @@
static aom_codec_err_t ctrl_get_seq_level_idx(aom_codec_alg_priv_t *ctx,
va_list args) {
int *const arg = va_arg(args, int *);
+ const AV1_COMP *const cpi = ctx->cpi;
if (arg == NULL) return AOM_CODEC_INVALID_PARAM;
- return av1_get_seq_level_idx(ctx->cpi, arg);
+ return av1_get_seq_level_idx(&cpi->common.seq_params, &cpi->level_params,
+ arg);
}
static aom_codec_ctrl_fn_map_t encoder_ctrl_maps[] = {
diff --git a/av1/encoder/bitstream.c b/av1/encoder/bitstream.c
index edf6693..43c3d00 100644
--- a/av1/encoder/bitstream.c
+++ b/av1/encoder/bitstream.c
@@ -3249,11 +3249,12 @@
return wpos;
}
-uint32_t av1_write_obu_header(AV1_COMP *const cpi, OBU_TYPE obu_type,
- int obu_extension, uint8_t *const dst) {
- if (cpi->keep_level_stats &&
+uint32_t av1_write_obu_header(AV1LevelParams *const level_params,
+ OBU_TYPE obu_type, int obu_extension,
+ uint8_t *const dst) {
+ if (level_params->keep_level_stats &&
(obu_type == OBU_FRAME || obu_type == OBU_FRAME_HEADER))
- ++cpi->frame_header_count;
+ ++level_params->frame_header_count;
struct aom_write_bit_buffer wb = { dst, 0 };
uint32_t size = 0;
@@ -3432,6 +3433,7 @@
int *const largest_tile_id) {
AV1_COMMON *const cm = &cpi->common;
const CommonTileParams *const tiles = &cm->tiles;
+ AV1LevelParams *const level_params = &cpi->level_params;
aom_writer mode_bc;
int tile_row, tile_col;
// Store the location and size of each tile's data in the bitstream:
@@ -3462,7 +3464,8 @@
// For large_scale_tile case, we always have only one tile group, so it can
// be written as an OBU_FRAME.
const OBU_TYPE obu_type = OBU_FRAME;
- const uint32_t tg_hdr_size = av1_write_obu_header(cpi, obu_type, 0, data);
+ const uint32_t tg_hdr_size =
+ av1_write_obu_header(level_params, obu_type, 0, data);
data += tg_hdr_size;
const uint32_t frame_header_size =
@@ -3613,8 +3616,8 @@
// tile group header
const OBU_TYPE obu_type =
(num_tg_hdrs == 1) ? OBU_FRAME : OBU_TILE_GROUP;
- curr_tg_data_size =
- av1_write_obu_header(cpi, obu_type, obu_extension_header, data);
+ curr_tg_data_size = av1_write_obu_header(level_params, obu_type,
+ obu_extension_header, data);
obu_header_size = curr_tg_data_size;
if (num_tg_hdrs == 1) {
@@ -3700,7 +3703,7 @@
// Rewrite the OBU header to change the OBU type to Redundant Frame
// Header.
- av1_write_obu_header(cpi, OBU_REDUNDANT_FRAME_HEADER,
+ av1_write_obu_header(level_params, OBU_REDUNDANT_FRAME_HEADER,
obu_extension_header,
&data[fh_info->obu_header_byte_offset]);
@@ -3797,7 +3800,8 @@
(cm->current_frame.frame_type != KEY_FRAME &&
current_metadata->insert_flag == AOM_MIF_NON_KEY_FRAME) ||
current_metadata->insert_flag == AOM_MIF_ANY_FRAME) {
- obu_header_size = av1_write_obu_header(cpi, OBU_METADATA, 0, dst);
+ obu_header_size =
+ av1_write_obu_header(&cpi->level_params, OBU_METADATA, 0, dst);
obu_payload_size =
av1_write_metadata_obu(current_metadata, dst + obu_header_size);
length_field_size = obu_memmove(obu_header_size, obu_payload_size, dst);
@@ -3821,6 +3825,7 @@
uint8_t *data = dst;
uint32_t data_size;
AV1_COMMON *const cm = &cpi->common;
+ AV1LevelParams *const level_params = &cpi->level_params;
uint32_t obu_header_size = 0;
uint32_t obu_payload_size = 0;
FrameHeaderInfo fh_info = { NULL, 0, 0 };
@@ -3836,13 +3841,14 @@
bitstream_queue_reset_write();
#endif
- cpi->frame_header_count = 0;
+ level_params->frame_header_count = 0;
// The TD is now written outside the frame encode loop
// write sequence header obu if KEY_FRAME, preceded by 4-byte size
if (cm->current_frame.frame_type == KEY_FRAME && cm->show_frame) {
- obu_header_size = av1_write_obu_header(cpi, OBU_SEQUENCE_HEADER, 0, data);
+ obu_header_size =
+ av1_write_obu_header(level_params, OBU_SEQUENCE_HEADER, 0, data);
obu_payload_size =
av1_write_sequence_header_obu(&cm->seq_params, data + obu_header_size);
@@ -3865,8 +3871,8 @@
if (write_frame_header) {
// Write Frame Header OBU.
fh_info.frame_header = data;
- obu_header_size =
- av1_write_obu_header(cpi, OBU_FRAME_HEADER, obu_extension_header, data);
+ obu_header_size = av1_write_obu_header(level_params, OBU_FRAME_HEADER,
+ obu_extension_header, data);
obu_payload_size =
write_frame_header_obu(cpi, &saved_wb, data + obu_header_size, 1);
diff --git a/av1/encoder/bitstream.h b/av1/encoder/bitstream.h
index 51e0059..45151e2 100644
--- a/av1/encoder/bitstream.h
+++ b/av1/encoder/bitstream.h
@@ -28,8 +28,9 @@
// Writes the OBU header byte, and the OBU header extension byte when
// 'obu_extension' is non-zero. Returns number of bytes written to 'dst'.
-uint32_t av1_write_obu_header(AV1_COMP *const cpi, OBU_TYPE obu_type,
- int obu_extension, uint8_t *const dst);
+uint32_t av1_write_obu_header(AV1LevelParams *const level_params,
+ OBU_TYPE obu_type, int obu_extension,
+ uint8_t *const dst);
int av1_write_uleb_obu_size(size_t obu_header_size, size_t obu_payload_size,
uint8_t *dest);
diff --git a/av1/encoder/encoder.c b/av1/encoder/encoder.c
index 50b4409..fa504c7 100644
--- a/av1/encoder/encoder.c
+++ b/av1/encoder/encoder.c
@@ -894,7 +894,7 @@
}
for (int i = 0; i < MAX_NUM_OPERATING_POINTS; ++i) {
- aom_free(cpi->level_info[i]);
+ aom_free(cpi->level_params.level_info[i]);
}
if (cpi->use_svc) av1_free_svc_cyclic_refresh(cpi);
@@ -2770,6 +2770,7 @@
const int num_planes = av1_num_planes(cm);
RATE_CONTROL *const rc = &cpi->rc;
MACROBLOCK *const x = &cpi->td.mb;
+ AV1LevelParams *const level_params = &cpi->level_params;
if (seq_params->profile != oxcf->profile) seq_params->profile = oxcf->profile;
seq_params->bit_depth = oxcf->bit_depth;
@@ -2819,24 +2820,25 @@
x->e_mbd.bd = (int)seq_params->bit_depth;
x->e_mbd.global_motion = cm->global_motion;
- memcpy(cpi->target_seq_level_idx, cpi->oxcf.target_seq_level_idx,
- sizeof(cpi->target_seq_level_idx));
- cpi->keep_level_stats = 0;
+ memcpy(level_params->target_seq_level_idx, cpi->oxcf.target_seq_level_idx,
+ sizeof(level_params->target_seq_level_idx));
+ level_params->keep_level_stats = 0;
for (int i = 0; i < MAX_NUM_OPERATING_POINTS; ++i) {
- if (cpi->target_seq_level_idx[i] <= SEQ_LEVELS) {
- cpi->keep_level_stats |= 1u << i;
- if (!cpi->level_info[i]) {
- CHECK_MEM_ERROR(cm, cpi->level_info[i],
- aom_calloc(1, sizeof(*cpi->level_info[i])));
+ if (level_params->target_seq_level_idx[i] <= SEQ_LEVELS) {
+ level_params->keep_level_stats |= 1u << i;
+ if (!level_params->level_info[i]) {
+ CHECK_MEM_ERROR(cm, level_params->level_info[i],
+ aom_calloc(1, sizeof(*level_params->level_info[i])));
}
}
}
// TODO(huisu@): level targeting currently only works for the 0th operating
// point, so scalable coding is not supported yet.
- if (cpi->target_seq_level_idx[0] < SEQ_LEVELS) {
+ if (level_params->target_seq_level_idx[0] < SEQ_LEVELS) {
// Adjust encoder config in order to meet target level.
- config_target_level(cpi, cpi->target_seq_level_idx[0], seq_params->tier[0]);
+ config_target_level(cpi, level_params->target_seq_level_idx[0],
+ seq_params->tier[0]);
}
if ((has_no_stats_stage(cpi)) && (oxcf->rc_mode == AOM_Q)) {
@@ -6838,7 +6840,7 @@
}
#endif
- if (cpi->keep_level_stats && !is_stat_generation_stage(cpi)) {
+ if (cpi->level_params.keep_level_stats && !is_stat_generation_stage(cpi)) {
// Initialize level info. at the beginning of each sequence.
if (cm->current_frame.frame_type == KEY_FRAME && cm->show_frame) {
av1_init_level_info(cpi);
@@ -7110,8 +7112,8 @@
if (payload_offset + sequence_header_size > sizeof(header_buf)) return NULL;
memmove(&header_buf[payload_offset], &header_buf[0], sequence_header_size);
- if (av1_write_obu_header(cpi, OBU_SEQUENCE_HEADER, 0, &header_buf[0]) !=
- obu_header_size) {
+ if (av1_write_obu_header(&cpi->level_params, OBU_SEQUENCE_HEADER, 0,
+ &header_buf[0]) != obu_header_size) {
return NULL;
}
diff --git a/av1/encoder/encoder.h b/av1/encoder/encoder.h
index dd18779..89f2bff 100644
--- a/av1/encoder/encoder.h
+++ b/av1/encoder/encoder.h
@@ -1166,14 +1166,8 @@
uint64_t frame_component_time[kTimingComponents];
#endif
- // The following data are for AV1 bitstream levels.
- AV1_LEVEL target_seq_level_idx[MAX_NUM_OPERATING_POINTS];
- // Bit mask to indicate whether to keep level stats for corresponding
- // operating points.
- uint32_t keep_level_stats;
- AV1LevelInfo *level_info[MAX_NUM_OPERATING_POINTS];
- // Count the number of OBU_FRAME and OBU_FRAME_HEADER for level calculation.
- int frame_header_count;
+ // Parameters for AV1 bitstream levels.
+ AV1LevelParams level_params;
// whether any no-zero delta_q was actually used
int deltaq_used;
diff --git a/av1/encoder/level.c b/av1/encoder/level.c
index 47d647e..c6fd3e6 100644
--- a/av1/encoder/level.c
+++ b/av1/encoder/level.c
@@ -689,7 +689,8 @@
void av1_init_level_info(AV1_COMP *cpi) {
for (int op_index = 0; op_index < MAX_NUM_OPERATING_POINTS; ++op_index) {
- AV1LevelInfo *const this_level_info = cpi->level_info[op_index];
+ AV1LevelInfo *const this_level_info =
+ cpi->level_params.level_info[op_index];
if (!this_level_info) continue;
memset(this_level_info, 0, sizeof(*this_level_info));
AV1LevelSpec *const level_spec = &this_level_info->level_spec;
@@ -904,12 +905,12 @@
return fail_id;
}
-static void get_tile_stats(const AV1_COMP *const cpi, int *max_tile_size,
- int *max_superres_tile_width,
+static void get_tile_stats(const AV1_COMMON *const cm,
+ const TileDataEnc *const tile_data,
+ int *max_tile_size, int *max_superres_tile_width,
int *min_cropped_tile_width,
int *min_cropped_tile_height,
int *tile_width_valid) {
- const AV1_COMMON *const cm = &cpi->common;
const int tile_cols = cm->tiles.cols;
const int tile_rows = cm->tiles.rows;
const int superres_scale_denominator = cm->superres_scale_denominator;
@@ -923,7 +924,7 @@
for (int tile_row = 0; tile_row < tile_rows; ++tile_row) {
for (int tile_col = 0; tile_col < tile_cols; ++tile_col) {
const TileInfo *const tile_info =
- &cpi->tile_data[tile_row * cm->tiles.cols + tile_col].tile_info;
+ &tile_data[tile_row * cm->tiles.cols + tile_col].tile_info;
const int tile_width =
(tile_info->mi_col_end - tile_info->mi_col_start) * MI_SIZE;
const int tile_height =
@@ -1047,6 +1048,8 @@
void av1_update_level_info(AV1_COMP *cpi, size_t size, int64_t ts_start,
int64_t ts_end) {
AV1_COMMON *const cm = &cpi->common;
+ const AV1LevelParams *const level_params = &cpi->level_params;
+
const int upscaled_width = cm->superres_upscaled_width;
const int width = cm->width;
const int height = cm->height;
@@ -1054,7 +1057,7 @@
const int tile_rows = cm->tiles.rows;
const int tiles = tile_cols * tile_rows;
const int luma_pic_size = upscaled_width * height;
- const int frame_header_count = cpi->frame_header_count;
+ const int frame_header_count = level_params->frame_header_count;
const int show_frame = cm->show_frame;
const int show_existing_frame = cm->show_existing_frame;
@@ -1063,7 +1066,7 @@
int min_cropped_tile_height;
int max_superres_tile_width;
int tile_width_is_valid;
- get_tile_stats(cpi, &max_tile_size, &max_superres_tile_width,
+ get_tile_stats(cm, cpi->tile_data, &max_tile_size, &max_superres_tile_width,
&min_cropped_tile_width, &min_cropped_tile_height,
&tile_width_is_valid);
@@ -1083,11 +1086,11 @@
for (int i = 0; i < seq_params->operating_points_cnt_minus_1 + 1; ++i) {
if (!is_in_operating_point(seq_params->operating_point_idc[i],
temporal_layer_id, spatial_layer_id) ||
- !((cpi->keep_level_stats >> i) & 1)) {
+ !((level_params->keep_level_stats >> i) & 1)) {
continue;
}
- AV1LevelInfo *const level_info = cpi->level_info[i];
+ AV1LevelInfo *const level_info = level_params->level_info[i];
assert(level_info != NULL);
AV1LevelStats *const level_stats = &level_info->level_stats;
@@ -1137,7 +1140,7 @@
}
// Check whether target level is met.
- const AV1_LEVEL target_level = cpi->target_seq_level_idx[i];
+ const AV1_LEVEL target_level = level_params->target_seq_level_idx[i];
if (target_level < SEQ_LEVELS) {
assert(is_valid_seq_level_idx(target_level));
const int tier = seq_params->tier[i];
@@ -1155,15 +1158,16 @@
}
}
-aom_codec_err_t av1_get_seq_level_idx(const AV1_COMP *cpi, int *seq_level_idx) {
- const SequenceHeader *const seq_params = &cpi->common.seq_params;
+aom_codec_err_t av1_get_seq_level_idx(const SequenceHeader *seq_params,
+ const AV1LevelParams *level_params,
+ int *seq_level_idx) {
const int is_still_picture = seq_params->still_picture;
const BITSTREAM_PROFILE profile = seq_params->profile;
for (int op = 0; op < seq_params->operating_points_cnt_minus_1 + 1; ++op) {
seq_level_idx[op] = (int)SEQ_LEVEL_MAX;
- if (!((cpi->keep_level_stats >> op) & 1)) continue;
+ if (!((level_params->keep_level_stats >> op) & 1)) continue;
const int tier = seq_params->tier[op];
- const AV1LevelInfo *const level_info = cpi->level_info[op];
+ const AV1LevelInfo *const level_info = level_params->level_info[op];
assert(level_info != NULL);
for (int level = 0; level < SEQ_LEVELS; ++level) {
if (!is_valid_seq_level_idx(level)) continue;
diff --git a/av1/encoder/level.h b/av1/encoder/level.h
index 72118ec..5e0cce2 100644
--- a/av1/encoder/level.h
+++ b/av1/encoder/level.h
@@ -155,6 +155,19 @@
DECODER_MODEL decoder_models[SEQ_LEVELS];
} AV1LevelInfo;
+typedef struct AV1LevelParams {
+ // Specifies the level that the coded video sequence conforms to for each
+ // operating point.
+ AV1_LEVEL target_seq_level_idx[MAX_NUM_OPERATING_POINTS];
+ // Bit mask to indicate whether to keep level stats for corresponding
+ // operating points.
+ uint32_t keep_level_stats;
+ // Level information for each operating point.
+ AV1LevelInfo *level_info[MAX_NUM_OPERATING_POINTS];
+ // Count the number of OBU_FRAME and OBU_FRAME_HEADER for level calculation.
+ int frame_header_count;
+} AV1LevelParams;
+
static INLINE int is_in_operating_point(int operating_point,
int temporal_layer_id,
int spatial_layer_id) {
@@ -170,7 +183,8 @@
int64_t ts_end);
// Return sequence level indices in seq_level_idx[MAX_NUM_OPERATING_POINTS].
-aom_codec_err_t av1_get_seq_level_idx(const struct AV1_COMP *cpi,
+aom_codec_err_t av1_get_seq_level_idx(const SequenceHeader *seq_params,
+ const AV1LevelParams *level_params,
int *seq_level_idx);
// Print the status of the decoder model(for debugging).
diff --git a/av1/encoder/pass2_strategy.c b/av1/encoder/pass2_strategy.c
index 2f4654b..56c4d1a 100644
--- a/av1/encoder/pass2_strategy.c
+++ b/av1/encoder/pass2_strategy.c
@@ -777,7 +777,8 @@
continue;
}
- const AV1_LEVEL target_level = cpi->target_seq_level_idx[index];
+ const AV1_LEVEL target_level =
+ cpi->level_params.target_seq_level_idx[index];
if (target_level >= SEQ_LEVELS) continue;
assert(is_valid_seq_level_idx(target_level));