[NORMATIVE] add code for operating_points experiment
Normative changes only in the sequence header
BUG=aomedia:1615
Change-Id: I6f8f87c3834998f15b89dec8c5d7f60ab0900851
diff --git a/av1/common/onyxc_int.h b/av1/common/onyxc_int.h
index 652a9cd..0a5c504 100644
--- a/av1/common/onyxc_int.h
+++ b/av1/common/onyxc_int.h
@@ -77,6 +77,17 @@
#define NUM_PING_PONG_BUFFERS 2
+#if CONFIG_OPERATING_POINTS
+#if CONFIG_SCALABILITY
+#define MAX_NUM_TEMPORAL_LAYERS 8
+#define MAX_NUM_SPATIAL_LAYERS 4
+#define MAX_NUM_OPERATING_POINTS \
+ MAX_NUM_TEMPORAL_LAYERS + MAX_NUM_SPATIAL_LAYERS
+#else
+#define MAX_NUM_OPERATING_POINTS 1
+#endif
+#endif
+
// TODO(jingning): Turning this on to set up transform coefficient
// processing timer.
#define TXCOEFF_TIMER 0
@@ -225,6 +236,14 @@
// 1 - Enable superres for the sequence, and also
// enable per-frame flag to denote if superres is
// enabled for that frame.
+#if CONFIG_OPERATING_POINTS
+ int operating_point_idc[MAX_NUM_OPERATING_POINTS];
+ int level[MAX_NUM_OPERATING_POINTS];
+ int decoder_rate_model_param_present_flag[MAX_NUM_OPERATING_POINTS];
+ int decode_to_display_rate_ratio[MAX_NUM_OPERATING_POINTS];
+ int initial_display_delay[MAX_NUM_OPERATING_POINTS];
+ int extra_frame_buffers[MAX_NUM_OPERATING_POINTS];
+#endif // CONFIG_OPERATING_POINTS
} SequenceHeader;
typedef struct AV1Common {
diff --git a/av1/decoder/decoder.h b/av1/decoder/decoder.h
index 1626645..e9fa260 100644
--- a/av1/decoder/decoder.h
+++ b/av1/decoder/decoder.h
@@ -97,6 +97,9 @@
aom_inspect_cb inspect_cb;
void *inspect_ctx;
#endif
+#if CONFIG_OPERATING_POINTS
+ int current_operating_point;
+#endif
} AV1Decoder;
int av1_receive_compressed_data(struct AV1Decoder *pbi, size_t size,
diff --git a/av1/decoder/obu.c b/av1/decoder/obu.c
index 1f46d6c..6dbe328 100644
--- a/av1/decoder/obu.c
+++ b/av1/decoder/obu.c
@@ -149,6 +149,22 @@
}
#endif
+#if CONFIG_OPERATING_POINTS
+static int is_obu_in_current_operating_point(AV1Decoder *pbi,
+ ObuHeader obu_header) {
+ if (!pbi->current_operating_point) {
+ return 1;
+ }
+
+ if ((pbi->current_operating_point >> obu_header.temporal_layer_id) & 0x1 &&
+ (pbi->current_operating_point >> (obu_header.enhancement_layer_id + 8)) &
+ 0x1) {
+ return 1;
+ }
+ return 0;
+}
+#endif
+
static uint32_t read_temporal_delimiter_obu() { return 0; }
static uint32_t read_sequence_header_obu(AV1Decoder *pbi,
@@ -157,6 +173,8 @@
uint32_t saved_bit_offset = rb->bit_offset;
cm->profile = av1_read_profile(rb);
+
+#if !CONFIG_OPERATING_POINTS
#if !CONFIG_SCALABILITY
aom_rb_read_literal(rb, 4); // level
#else
@@ -166,6 +184,29 @@
aom_rb_read_literal(rb, 4); // level for each enhancement layer
}
#endif
+#else // CONFIG_OPERATING_POINTS
+#if CONFIG_SCALABILITY
+ uint8_t operating_points_minus1_cnt = aom_rb_read_literal(rb, 5);
+ pbi->common.enhancement_layers_cnt = operating_points_minus1_cnt + 1;
+#else
+ uint8_t operating_points_minus1_cnt = 0;
+#endif
+ int i;
+ SequenceHeader *seq_params = &cm->seq_params;
+ for (i = 0; i < operating_points_minus1_cnt + 1; i++) {
+ seq_params->operating_point_idc[i] = aom_rb_read_literal(rb, 12);
+ seq_params->level[i] = aom_rb_read_literal(rb, 4);
+ seq_params->decoder_rate_model_param_present_flag[i] =
+ aom_rb_read_literal(rb, 1);
+ if (seq_params->decoder_rate_model_param_present_flag[i]) {
+ seq_params->decode_to_display_rate_ratio[i] = aom_rb_read_literal(rb, 12);
+ seq_params->initial_display_delay[i] = aom_rb_read_literal(rb, 24);
+ seq_params->extra_frame_buffers[i] = aom_rb_read_literal(rb, 4);
+ }
+ }
+ // This decoder supports all levels. Choose the first operating point
+ pbi->current_operating_point = seq_params->operating_point_idc[0];
+#endif // CONFIG_OPERATING_POINTS
read_sequence_header(cm, rb);
@@ -445,6 +486,13 @@
#if CONFIG_OBU_FRAME
case OBU_FRAME:
#endif // CONFIG_OBU_FRAME
+#if CONFIG_OPERATING_POINTS
+ // don't decode obu if it's not in current operating mode
+ if (!is_obu_in_current_operating_point(pbi, obu_header)) {
+ decoded_payload_size = payload_size;
+ break;
+ }
+#endif
// Only decode first frame header received
if (!frame_header_received) {
#if CONFIG_TRAILING_BITS
@@ -486,12 +534,26 @@
cm->error.error_code = AOM_CODEC_CORRUPT_FRAME;
return;
}
+#if CONFIG_OPERATING_POINTS
+ // don't decode obu if it's not in current operating mode
+ if (!is_obu_in_current_operating_point(pbi, obu_header)) {
+ decoded_payload_size = payload_size;
+ break;
+ }
+#endif
decoded_payload_size += read_one_tile_group_obu(
pbi, &rb, is_first_tg_obu_received, data + obu_payload_offset,
data + payload_size, p_data_end, &frame_decoding_finished);
is_first_tg_obu_received = 0;
break;
case OBU_METADATA:
+#if CONFIG_OPERATING_POINTS
+ // don't decode obu if it's not in current operating mode
+ if (!is_obu_in_current_operating_point(pbi, obu_header)) {
+ decoded_payload_size = payload_size;
+ break;
+ }
+#endif
decoded_payload_size = read_metadata(data, payload_size);
break;
case OBU_PADDING:
diff --git a/av1/encoder/bitstream.c b/av1/encoder/bitstream.c
index bf93c48..8d273e2 100644
--- a/av1/encoder/bitstream.c
+++ b/av1/encoder/bitstream.c
@@ -3495,6 +3495,8 @@
uint32_t size = 0;
write_profile(cm->profile, &wb);
+
+#if !CONFIG_OPERATING_POINTS
#if !CONFIG_SCALABILITY
aom_wb_write_literal(&wb, 0, 4);
#else
@@ -3504,6 +3506,20 @@
aom_wb_write_literal(&wb, 0, 4);
}
#endif
+#else // CONFIG_OPERATING_POINTS
+#if !CONFIG_SCALABILITY
+ uint8_t operating_points_minus1_cnt = 0;
+#else
+ uint8_t operating_points_minus1_cnt = enhancement_layers_cnt;
+#endif
+ aom_wb_write_literal(&wb, operating_points_minus1_cnt, 5);
+ int i;
+ for (i = 0; i < operating_points_minus1_cnt + 1; i++) {
+ aom_wb_write_literal(&wb, 0, 12); // operating_point_idc[i]
+ aom_wb_write_literal(&wb, 0, 4); // level[i]
+ aom_wb_write_literal(&wb, 0, 1); // decoder_rate_model_present_flag[i]
+ }
+#endif // CONFIG_OPERATING_POINTS
write_sequence_header(cpi, &wb);
diff --git a/build/cmake/aom_config_defaults.cmake b/build/cmake/aom_config_defaults.cmake
index b497aee..6ba1430 100644
--- a/build/cmake/aom_config_defaults.cmake
+++ b/build/cmake/aom_config_defaults.cmake
@@ -106,6 +106,7 @@
set(CONFIG_OBU_FRAME 1 CACHE NUMBER "AV1 experiment flag.")
set(CONFIG_OBU_NO_IVF 0 CACHE NUMBER "AV1 experiment flag.")
set(CONFIG_OBU_REDUNDANT_FRAME_HEADER 0 CACHE NUMBER "AV1 experiment flag.")
+set(CONFIG_OPERATING_POINTS 0 CACHE NUMBER "AV1 experiment flag.")
set(CONFIG_RD_DEBUG 0 CACHE NUMBER "AV1 experiment flag.")
set(CONFIG_SCALABILITY 1 CACHE NUMBER "AV1 experiment flag.")
set(CONFIG_SHORT_FILTER 1 CACHE NUMBER "AV1 experiment flag.")