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;