modify scalability info according to operating point
The way scalability-related info is set/derived has changed with
the introduction of operating points. This patch addresses these
changes
- enhancement layers are renamed spatial layers
- number of temporal/spatial layers is set/derived from
operating_point_idc
- some code cleanup
Change-Id: I698fbe751980ab3a5d4d3109a950fd8a7a8d9433
diff --git a/aom/aom_decoder.h b/aom/aom_decoder.h
index 3973c50..458e3bb 100644
--- a/aom/aom_decoder.h
+++ b/aom/aom_decoder.h
@@ -84,7 +84,8 @@
unsigned int w; /**< Width (or 0 for unknown/default) */
unsigned int h; /**< Height (or 0 for unknown/default) */
unsigned int is_kf; /**< Current frame is a keyframe */
- unsigned int enhancement_layers_cnt; /**< Enhancement layers */
+ unsigned int number_spatial_layers; /**< Number of spatial layers */
+ unsigned int number_temporal_layers; /**< Number of temporal layers */
unsigned int is_annexb; /**< Is Bitstream in Annex-B format */
} aom_codec_stream_info_t;
diff --git a/aom/aom_image.h b/aom/aom_image.h
index 6f72d2d..439cfdc 100644
--- a/aom/aom_image.h
+++ b/aom/aom_image.h
@@ -173,8 +173,8 @@
int bps; /**< bits per sample (for packed formats) */
- int temporal_id; /**< Temporal layer Id of image */
- int enhancement_id; /**< Spatial layer Id of image */
+ int temporal_id; /**< Temporal layer Id of image */
+ int spatial_id; /**< Spatial layer Id of image */
/*!\brief The following member may be set by the application to associate
* data with this image.
diff --git a/aom/aomcx.h b/aom/aomcx.h
index fe9f106..544e2b5 100644
--- a/aom/aomcx.h
+++ b/aom/aomcx.h
@@ -167,9 +167,9 @@
*/
AOME_SET_SCALEMODE = 11,
- /*!\brief Codec control function to set encoder enhancement layer id.
+ /*!\brief Codec control function to set encoder spatial layer id.
*/
- AOME_SET_ENHANCEMENT_LAYER_ID = 12,
+ AOME_SET_SPATIAL_LAYER_ID = 12,
/*!\brief Codec control function to set encoder internal speed settings.
*
@@ -960,8 +960,8 @@
AOM_CTRL_USE_TYPE(AOME_SET_SCALEMODE, aom_scaling_mode_t *)
#define AOM_CTRL_AOME_SET_SCALEMODE
-AOM_CTRL_USE_TYPE(AOME_SET_ENHANCEMENT_LAYER_ID, int)
-#define AOM_CTRL_AOME_SET_ENHANCEMENT_LAYER_ID
+AOM_CTRL_USE_TYPE(AOME_SET_SPATIAL_LAYER_ID, int)
+#define AOM_CTRL_AOME_SET_SPATIAL_LAYER_ID
AOM_CTRL_USE_TYPE(AOME_SET_CPUUSED, int)
#define AOM_CTRL_AOME_SET_CPUUSED
diff --git a/aom_dsp/grain_synthesis.c b/aom_dsp/grain_synthesis.c
index 8ee9640..ed349e2 100644
--- a/aom_dsp/grain_synthesis.c
+++ b/aom_dsp/grain_synthesis.c
@@ -961,7 +961,7 @@
dst->y_chroma_shift = src->y_chroma_shift;
dst->temporal_id = src->temporal_id;
- dst->enhancement_id = src->enhancement_id;
+ dst->spatial_id = src->spatial_id;
width = src->d_w % 2 ? src->d_w + 1 : src->d_w;
height = src->d_h % 2 ? src->d_h + 1 : src->d_h;
diff --git a/av1/av1_cx_iface.c b/av1/av1_cx_iface.c
index c813cc7..e75e57e 100644
--- a/av1/av1_cx_iface.c
+++ b/av1/av1_cx_iface.c
@@ -25,7 +25,7 @@
#include "aom_ports/mem_ops.h"
#define MAG_SIZE (4)
-#define MAX_NUM_ENHANCEMENT_LAYERS 128
+#define MAX_NUM_ENHANCEMENT_LAYERS 3
struct av1_extracfg {
int cpu_used; // available cpu percentage in 1/16
@@ -1337,7 +1337,7 @@
if (ctx->pending_cx_data == 0) ctx->pending_cx_data = cx_data;
const int write_temporal_delimiter =
- !cpi->common.enhancement_layer_id && !ctx->pending_frame_count;
+ !cpi->common.spatial_layer_id && !ctx->pending_frame_count;
if (write_temporal_delimiter) {
uint32_t obu_header_size = 1;
@@ -1587,12 +1587,12 @@
}
}
-static aom_codec_err_t ctrl_set_enhancement_layer_id(aom_codec_alg_priv_t *ctx,
- va_list args) {
- const int enhancement_layer_id = va_arg(args, int);
- if (enhancement_layer_id > MAX_NUM_ENHANCEMENT_LAYERS)
+static aom_codec_err_t ctrl_set_spatial_layer_id(aom_codec_alg_priv_t *ctx,
+ va_list args) {
+ const int spatial_layer_id = va_arg(args, int);
+ if (spatial_layer_id > MAX_NUM_ENHANCEMENT_LAYERS)
return AOM_CODEC_INVALID_PARAM;
- ctx->cpi->common.enhancement_layer_id = enhancement_layer_id;
+ ctx->cpi->common.spatial_layer_id = spatial_layer_id;
return AOM_CODEC_OK;
}
@@ -1601,7 +1601,7 @@
const int number_spatial_layers = va_arg(args, int);
if (number_spatial_layers > MAX_NUM_ENHANCEMENT_LAYERS)
return AOM_CODEC_INVALID_PARAM;
- ctx->cpi->common.enhancement_layers_cnt = number_spatial_layers - 1;
+ ctx->cpi->common.number_spatial_layers = number_spatial_layers;
return AOM_CODEC_OK;
}
@@ -1682,7 +1682,7 @@
{ AOME_SET_ROI_MAP, ctrl_set_roi_map },
{ AOME_SET_ACTIVEMAP, ctrl_set_active_map },
{ AOME_SET_SCALEMODE, ctrl_set_scale_mode },
- { AOME_SET_ENHANCEMENT_LAYER_ID, ctrl_set_enhancement_layer_id },
+ { AOME_SET_SPATIAL_LAYER_ID, ctrl_set_spatial_layer_id },
{ AOME_SET_CPUUSED, ctrl_set_cpuused },
{ AOME_SET_DEVSF, ctrl_set_devsf },
{ AOME_SET_ENABLEAUTOALTREF, ctrl_set_enable_auto_alt_ref },
diff --git a/av1/av1_dx_iface.c b/av1/av1_dx_iface.c
index 4a9a1e3..80f3da4 100644
--- a/av1/av1_dx_iface.c
+++ b/av1/av1_dx_iface.c
@@ -172,10 +172,12 @@
} else {
const uint8_t operating_points_minus1_cnt =
aom_rb_read_literal(rb, OP_POINTS_MINUS1_BITS);
- si->enhancement_layers_cnt = operating_points_minus1_cnt;
+ int operating_point_idc0 = 0;
for (int i = 0; i < operating_points_minus1_cnt + 1; i++) {
- aom_rb_read_literal(rb, OP_POINTS_IDC_BITS); // idc
- aom_rb_read_literal(rb, LEVEL_BITS); // level
+ int operating_point_idc;
+ operating_point_idc = aom_rb_read_literal(rb, OP_POINTS_IDC_BITS);
+ if (i == 0) operating_point_idc0 = operating_point_idc;
+ aom_rb_read_literal(rb, LEVEL_BITS); // level
#if !CONFIG_BUFFER_MODEL
if (aom_rb_read_literal(rb,
1)) { // decoder_rate_model_param_present_flag
@@ -185,6 +187,19 @@
}
#endif // !CONFIG_BUFFER_MODEL
}
+
+ // derive number of spatial/temporal layers from operating_point_idc0
+ if (operating_point_idc0 == 0) {
+ si->number_temporal_layers = 1;
+ si->number_spatial_layers = 1;
+ } else {
+ si->number_spatial_layers = 0;
+ si->number_temporal_layers = 0;
+ for (int j = 0; j < 8; j++) {
+ si->number_spatial_layers += (operating_point_idc0 >> (j + 8)) & 0x1;
+ si->number_temporal_layers += (operating_point_idc0 >> j) & 0x1;
+ }
+ }
}
}
@@ -676,7 +691,7 @@
ctx->img.fb_priv = frame_bufs[cm->new_fb_idx].raw_frame_buffer.priv;
img = &ctx->img;
img->temporal_id = cm->temporal_layer_id;
- img->enhancement_id = cm->enhancement_layer_id;
+ img->spatial_id = cm->spatial_layer_id;
return add_grain_if_needed(
img, ctx->image_with_grain,
&frame_worker_data->pbi->common.film_grain_params);
diff --git a/av1/common/onyxc_int.h b/av1/common/onyxc_int.h
index 85e4936..761f6af 100644
--- a/av1/common/onyxc_int.h
+++ b/av1/common/onyxc_int.h
@@ -544,8 +544,8 @@
int frame_refs_short_signaling;
int temporal_layer_id;
- int enhancement_layer_id;
- int enhancement_layers_cnt;
+ int spatial_layer_id;
+ int number_spatial_layers;
int num_allocated_above_context_mi_col;
int num_allocated_above_contexts;
int num_allocated_above_context_planes;
diff --git a/av1/decoder/decodeframe.c b/av1/decoder/decodeframe.c
index 7661995..300e0ea 100644
--- a/av1/decoder/decodeframe.c
+++ b/av1/decoder/decodeframe.c
@@ -3438,7 +3438,7 @@
cm->temporal_layer_id) &
0x1) &&
((cm->op_params[op_num].decoder_model_operating_point_idc >>
- (cm->enhancement_layer_id + 8)) &
+ (cm->spatial_layer_id + 8)) &
0x1)) ||
cm->op_params[op_num].decoder_model_operating_point_idc == 0) {
cm->op_frame_timing[op_num].buffer_removal_delay =
diff --git a/av1/decoder/obu.c b/av1/decoder/obu.c
index c08d4d5..d99e7dd 100644
--- a/av1/decoder/obu.c
+++ b/av1/decoder/obu.c
@@ -92,7 +92,7 @@
header->size += 1;
header->temporal_layer_id = aom_rb_read_literal(rb, 3);
- header->enhancement_layer_id = aom_rb_read_literal(rb, 2);
+ header->spatial_layer_id = aom_rb_read_literal(rb, 2);
aom_rb_read_literal(rb, 3); // reserved
}
@@ -120,7 +120,7 @@
}
if ((pbi->current_operating_point >> obu_header.temporal_layer_id) & 0x1 &&
- (pbi->current_operating_point >> (obu_header.enhancement_layer_id + 8)) &
+ (pbi->current_operating_point >> (obu_header.spatial_layer_id + 8)) &
0x1) {
return 1;
}
@@ -155,7 +155,6 @@
}
if (seq_params->reduced_still_picture_hdr) {
- pbi->common.enhancement_layers_cnt = 1;
seq_params->operating_point_idc[0] = 0;
seq_params->level[0] = read_bitstream_level(rb);
if (seq_params->level[0].major > LEVEL_MAJOR_MAX)
@@ -164,7 +163,6 @@
} else {
uint8_t operating_points_minus1_cnt =
aom_rb_read_literal(rb, OP_POINTS_MINUS1_BITS);
- pbi->common.enhancement_layers_cnt = operating_points_minus1_cnt + 1;
for (int i = 0; i < operating_points_minus1_cnt + 1; i++) {
seq_params->operating_point_idc[i] =
aom_rb_read_literal(rb, OP_POINTS_IDC_BITS);
@@ -544,7 +542,7 @@
data += bytes_read;
cm->temporal_layer_id = obu_header.temporal_layer_id;
- cm->enhancement_layer_id = obu_header.enhancement_layer_id;
+ cm->spatial_layer_id = obu_header.spatial_layer_id;
if (obu_header.type != OBU_TEMPORAL_DELIMITER &&
obu_header.type != OBU_SEQUENCE_HEADER &&
diff --git a/av1/decoder/obu.h b/av1/decoder/obu.h
index 8922cb7..7c46bca 100644
--- a/av1/decoder/obu.h
+++ b/av1/decoder/obu.h
@@ -21,7 +21,7 @@
int has_length_field;
int has_extension;
int temporal_layer_id;
- int enhancement_layer_id;
+ int spatial_layer_id;
} ObuHeader;
aom_codec_err_t aom_read_obu_header(uint8_t *buffer, size_t buffer_length,
diff --git a/av1/encoder/bitstream.c b/av1/encoder/bitstream.c
index 4d9bdf0..394ecfe 100644
--- a/av1/encoder/bitstream.c
+++ b/av1/encoder/bitstream.c
@@ -3100,7 +3100,7 @@
cm->temporal_layer_id) &
0x1 &&
(cm->op_params[op_num].decoder_model_operating_point_idc >>
- (cm->enhancement_layer_id + 8)) &
+ (cm->spatial_layer_id + 8)) &
0x1) ||
cm->op_params[op_num].decoder_model_operating_point_idc == 0) {
aom_wb_write_literal(
@@ -3539,7 +3539,7 @@
}
static uint32_t write_sequence_header_obu(AV1_COMP *cpi, uint8_t *const dst,
- uint8_t enhancement_layers_cnt) {
+ uint8_t number_spatial_layers) {
AV1_COMMON *const cm = &cpi->common;
struct aom_write_bit_buffer wb = { dst, 0 };
uint32_t size = 0;
@@ -3556,7 +3556,8 @@
if (cm->seq_params.reduced_still_picture_hdr) {
write_bitstream_level(cm->seq_params.level[0], &wb);
} else {
- uint8_t operating_points_minus1_cnt = enhancement_layers_cnt;
+ uint8_t operating_points_minus1_cnt =
+ number_spatial_layers > 1 ? number_spatial_layers - 1 : 0;
aom_wb_write_literal(&wb, operating_points_minus1_cnt,
OP_POINTS_MINUS1_BITS);
int i;
@@ -4009,9 +4010,9 @@
uint32_t obu_header_size = 0;
uint32_t obu_payload_size = 0;
FrameHeaderInfo fh_info = { NULL, 0, 0 };
- const uint8_t enhancement_layers_cnt = cm->enhancement_layers_cnt;
+ const uint8_t number_spatial_layers = cm->number_spatial_layers;
const uint8_t obu_extension_header =
- cm->temporal_layer_id << 5 | cm->enhancement_layer_id << 3 | 0;
+ cm->temporal_layer_id << 5 | cm->spatial_layer_id << 3 | 0;
#if CONFIG_BITSTREAM_DEBUG
bitstream_queue_reset_write();
@@ -4024,7 +4025,7 @@
obu_header_size = write_obu_header(OBU_SEQUENCE_HEADER, 0, data);
obu_payload_size = write_sequence_header_obu(cpi, data + obu_header_size,
- enhancement_layers_cnt);
+ number_spatial_layers);
const size_t length_field_size =
obu_memmove(obu_header_size, obu_payload_size, data);
if (write_uleb_obu_size(obu_header_size, obu_payload_size, data) !=
diff --git a/examples/scalable_decoder.c b/examples/scalable_decoder.c
index d5f11f1..3be406b 100644
--- a/examples/scalable_decoder.c
+++ b/examples/scalable_decoder.c
@@ -121,7 +121,7 @@
if (aom_codec_dec_init(&codec, decoder->codec_interface(), NULL, 0))
die_codec(&codec, "Failed to initialize decoder.");
- // peak sequence header OBU to get enhancement layer count, if any
+ // peak sequence header OBU to get number of spatial layers
const size_t ret = fread(tmpbuf, 1, 32, inputfile);
if (ret != 32) die_codec(&codec, "Input is not a valid obu file");
si.is_annexb = 0;
@@ -133,8 +133,13 @@
if (!file_is_obu(&obu_ctx))
die_codec(&codec, "Input is not a valid obu file");
- // open output yuv files
- for (i = 0; i <= si.enhancement_layers_cnt; i++) {
+ // open base layer output yuv file
+ snprintf(filename, sizeof(filename), "out_lyr%d.yuv", 0);
+ if (!(outfile[0] = fopen(filename, "wb")))
+ die("Failed top open output for writing.");
+
+ // open any enhancement layer output yuv files
+ for (i = 1; i < si.number_spatial_layers; i++) {
snprintf(filename, sizeof(filename), "out_lyr%d.yuv", i);
if (!(outfile[i] = fopen(filename, "wb")))
die("Failed to open output for writing.");
@@ -153,29 +158,28 @@
img_shifted->bit_depth = 8;
aom_img_downshift(img_shifted, img,
img->bit_depth - img_shifted->bit_depth);
- if (img->enhancement_id == 0) {
+ if (img->spatial_id == 0) {
printf("Writing base layer 0 %d\n", frame_cnt);
aom_img_write(img_shifted, outfile[0]);
obu_ctx.last_layer_id++;
- } else if (img->enhancement_id <= (int)si.enhancement_layers_cnt) {
- printf("Writing enhancemnt layer %d %d\n", img->enhancement_id,
- frame_cnt);
- aom_img_write(img_shifted, outfile[img->enhancement_id]);
- if (img->enhancement_id == (int)si.enhancement_layers_cnt)
+ } else if (img->spatial_id <= (int)(si.number_spatial_layers - 1)) {
+ printf("Writing enhancemnt layer %d %d\n", img->spatial_id, frame_cnt);
+ aom_img_write(img_shifted, outfile[img->spatial_id]);
+ if (img->spatial_id == (int)(si.number_spatial_layers - 1))
obu_ctx.last_layer_id = 0;
else
obu_ctx.last_layer_id++;
} else {
die_codec(&codec, "Invalid bitstream. Layer id exceeds layer count");
}
- if (img->enhancement_id == (int)si.enhancement_layers_cnt) ++frame_cnt;
+ if (img->spatial_id == (int)(si.number_spatial_layers - 1)) ++frame_cnt;
}
}
printf("Processed %d frames.\n", frame_cnt);
if (aom_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec");
- for (i = 0; i <= si.enhancement_layers_cnt; i++) fclose(outfile[i]);
+ for (i = 0; i < si.number_spatial_layers; i++) fclose(outfile[i]);
fclose(inputfile);
diff --git a/examples/scalable_encoder.c b/examples/scalable_encoder.c
index 12306b2..10d647e 100644
--- a/examples/scalable_encoder.c
+++ b/examples/scalable_encoder.c
@@ -213,6 +213,11 @@
if (aom_codec_control(&codec, AOME_SET_CPUUSED, 8))
die_codec(&codec, "Failed to set cpu to 8");
+ if (aom_codec_control(&codec, AV1E_SET_TILE_COLUMNS, 2))
+ die_codec(&codec, "Failed to set tile columns to 2");
+ if (aom_codec_control(&codec, AV1E_SET_NUM_TG, 3))
+ die_codec(&codec, "Failed to set num of tile groups to 3");
+
if (aom_codec_control(&codec, AOME_SET_NUMBER_SPATIAL_LAYERS, 2))
die_codec(&codec, "Failed to set number of spatial layers to 2");
@@ -237,7 +242,7 @@
cfg.g_h = info.frame_height;
if (aom_codec_enc_config_set(&codec, &cfg))
die_codec(&codec, "Failed to set enc cfg for layer 0");
- if (aom_codec_control(&codec, AOME_SET_ENHANCEMENT_LAYER_ID, 0))
+ if (aom_codec_control(&codec, AOME_SET_SPATIAL_LAYER_ID, 0))
die_codec(&codec, "Failed to set layer id to 0");
if (aom_codec_control(&codec, AOME_SET_CQ_LEVEL, 62))
die_codec(&codec, "Failed to set cq level");
@@ -256,7 +261,7 @@
aom_img_read(&raw1, infile1);
if (aom_codec_enc_config_set(&codec, &cfg))
die_codec(&codec, "Failed to set enc cfg for layer 1");
- if (aom_codec_control(&codec, AOME_SET_ENHANCEMENT_LAYER_ID, 1))
+ if (aom_codec_control(&codec, AOME_SET_SPATIAL_LAYER_ID, 1))
die_codec(&codec, "Failed to set layer id to 1");
if (aom_codec_control(&codec, AOME_SET_CQ_LEVEL, 10))
die_codec(&codec, "Failed to set cq level");
diff --git a/obudec.c b/obudec.c
index 902a210..f381fa4 100644
--- a/obudec.c
+++ b/obudec.c
@@ -390,7 +390,7 @@
if (obu_header.type == OBU_TEMPORAL_DELIMITER || obu_size == 0 ||
(obu_header.has_extension &&
- obu_header.enhancement_layer_id > obu_ctx->last_layer_id)) {
+ obu_header.spatial_layer_id > obu_ctx->last_layer_id)) {
tu_size = obu_ctx->bytes_buffered;
break;
} else {
diff --git a/test/scalability_test.cc b/test/scalability_test.cc
index 7f90404..b399188 100644
--- a/test/scalability_test.cc
+++ b/test/scalability_test.cc
@@ -45,7 +45,7 @@
AOM_EFLAG_NO_REF_BWD | AOM_EFLAG_NO_REF_ARF2 |
AOM_EFLAG_NO_UPD_LAST | AOM_EFLAG_NO_UPD_GF |
AOM_EFLAG_NO_UPD_ARF | AOM_EFLAG_NO_UPD_ENTROPY;
- encoder->Control(AOME_SET_ENHANCEMENT_LAYER_ID, 1);
+ encoder->Control(AOME_SET_SPATIAL_LAYER_ID, 1);
encoder->Control(AOME_SET_CQ_LEVEL, kEnhancementLayerQp);
} else {
frame_flags_ = AOM_EFLAG_NO_REF_LAST2 | AOM_EFLAG_NO_REF_LAST3 |
@@ -53,7 +53,7 @@
AOM_EFLAG_NO_REF_BWD | AOM_EFLAG_NO_REF_ARF2 |
AOM_EFLAG_NO_UPD_GF | AOM_EFLAG_NO_UPD_ARF |
AOM_EFLAG_NO_UPD_ENTROPY;
- encoder->Control(AOME_SET_ENHANCEMENT_LAYER_ID, 0);
+ encoder->Control(AOME_SET_SPATIAL_LAYER_ID, 0);
encoder->Control(AOME_SET_CQ_LEVEL, kBaseLayerQp);
}
}
diff --git a/tools/obu_parser.cc b/tools/obu_parser.cc
index 1c24c4c..e07763c 100644
--- a/tools/obu_parser.cc
+++ b/tools/obu_parser.cc
@@ -101,7 +101,7 @@
obu_header->temporal_layer_id =
(ext_header_byte >> kObuExtTemporalIdBitsShift) &
kObuExtTemporalIdBitsMask;
- obu_header->enhancement_layer_id =
+ obu_header->spatial_layer_id =
(ext_header_byte >> kObuExtSpatialIdBitsShift) & kObuExtSpatialIdBitsMask;
return true;