ext_tile: add image format support in example

Added the image format support in lightfield decoder example.

BUG=aomedia:2008

Change-Id: I0178347bd0091c2207eeb29cd882fa9a7e143381
diff --git a/aom/aomdx.h b/aom/aomdx.h
index 5a6da21..398d5ce 100644
--- a/aom/aomdx.h
+++ b/aom/aomdx.h
@@ -119,6 +119,9 @@
   /** control function to get the bit depth of the stream. */
   AV1D_GET_BIT_DEPTH,
 
+  /** control function to get the image format of the stream. */
+  AV1D_GET_IMG_FORMAT,
+
   /** control function to set the byte alignment of the planes in the reference
    * buffers. Valid values are power of 2, from 32 to 1024. A value of 0 sets
    * legacy alignment. I.e. Y plane is aligned to 32 bytes, U plane directly
@@ -244,6 +247,8 @@
 #define AOM_CTRL_AV1D_GET_DISPLAY_SIZE
 AOM_CTRL_USE_TYPE(AV1D_GET_BIT_DEPTH, unsigned int *)
 #define AOM_CTRL_AV1D_GET_BIT_DEPTH
+AOM_CTRL_USE_TYPE(AV1D_GET_IMG_FORMAT, aom_img_fmt_t *)
+#define AOM_CTRL_AV1D_GET_IMG_FORMAT
 AOM_CTRL_USE_TYPE(AV1D_GET_FRAME_SIZE, int *)
 #define AOM_CTRL_AV1D_GET_FRAME_SIZE
 AOM_CTRL_USE_TYPE(AV1_INVERT_TILE_DECODE_ORDER, int)
diff --git a/av1/av1_dx_iface.c b/av1/av1_dx_iface.c
index c4abf65..3860a15 100644
--- a/av1/av1_dx_iface.c
+++ b/av1/av1_dx_iface.c
@@ -1029,6 +1029,43 @@
   return AOM_CODEC_INVALID_PARAM;
 }
 
+static aom_img_fmt_t get_img_format(int subsampling_x, int subsampling_y,
+                                    int use_highbitdepth) {
+  aom_img_fmt_t fmt = 0;
+
+  if (subsampling_x == 0 && subsampling_y == 0)
+    fmt = AOM_IMG_FMT_I444;
+  else if (subsampling_x == 1 && subsampling_y == 0)
+    fmt = AOM_IMG_FMT_I422;
+  else if (subsampling_x == 1 && subsampling_y == 1)
+    fmt = AOM_IMG_FMT_I420;
+
+  if (use_highbitdepth) fmt |= AOM_IMG_FMT_HIGHBITDEPTH;
+  return fmt;
+}
+
+static aom_codec_err_t ctrl_get_img_format(aom_codec_alg_priv_t *ctx,
+                                           va_list args) {
+  aom_img_fmt_t *const img_fmt = va_arg(args, aom_img_fmt_t *);
+  AVxWorker *const worker = &ctx->frame_workers[ctx->next_output_worker_id];
+
+  if (img_fmt) {
+    if (worker) {
+      FrameWorkerData *const frame_worker_data =
+          (FrameWorkerData *)worker->data1;
+      const AV1_COMMON *const cm = &frame_worker_data->pbi->common;
+
+      *img_fmt = get_img_format(cm->subsampling_x, cm->subsampling_y,
+                                cm->use_highbitdepth);
+      return AOM_CODEC_OK;
+    } else {
+      return AOM_CODEC_ERROR;
+    }
+  }
+
+  return AOM_CODEC_INVALID_PARAM;
+}
+
 static aom_codec_err_t ctrl_set_invert_tile_order(aom_codec_alg_priv_t *ctx,
                                                   va_list args) {
   ctx->invert_tile_order = va_arg(args, int);
@@ -1179,6 +1216,7 @@
   { AOMD_GET_LAST_QUANTIZER, ctrl_get_last_quantizer },
   { AOMD_GET_LAST_REF_UPDATES, ctrl_get_last_ref_updates },
   { AV1D_GET_BIT_DEPTH, ctrl_get_bit_depth },
+  { AV1D_GET_IMG_FORMAT, ctrl_get_img_format },
   { AV1D_GET_DISPLAY_SIZE, ctrl_get_render_size },
   { AV1D_GET_FRAME_SIZE, ctrl_get_frame_size },
   { AV1_GET_ACCOUNTING, ctrl_get_accounting },
diff --git a/av1/decoder/obu.c b/av1/decoder/obu.c
index 45b3aa2..2c2e9a1 100644
--- a/av1/decoder/obu.c
+++ b/av1/decoder/obu.c
@@ -315,8 +315,8 @@
       !(cm->subsampling_x == 1 && cm->subsampling_y == 1) &&
       !(cm->subsampling_x == 1 && cm->subsampling_y == 0)) {
     aom_internal_error(&cm->error, AOM_CODEC_UNSUP_BITSTREAM,
-                       "Only 4:4:4, 4:2:2 and 4:2:0 are currently supported by "
-                       "CfL, %d %d subsampling is not supported.\n",
+                       "Only 4:4:4, 4:2:2 and 4:2:0 are currently supported, "
+                       "%d %d subsampling is not supported.\n",
                        cm->subsampling_x, cm->subsampling_y);
   }
 
diff --git a/examples/lightfield_decoder.c b/examples/lightfield_decoder.c
index 79cbaee..4200ae7 100644
--- a/examples/lightfield_decoder.c
+++ b/examples/lightfield_decoder.c
@@ -83,7 +83,7 @@
   aom_image_t reference_images[MAX_EXTERNAL_REFERENCES];
   size_t frame_size = 0;
   const unsigned char *frame = NULL;
-  int n, i;
+  int n, i, j;
   exec_name = argv[0];
 
   if (argc != 4) die("Invalid number of arguments.");
@@ -106,17 +106,7 @@
 
   if (aom_codec_dec_init(&codec, decoder->codec_interface(), NULL, 0))
     die_codec(&codec, "Failed to initialize decoder.");
-  // Allocate memory to store decoded references.
-  aom_img_fmt_t ref_fmt = AOM_IMG_FMT_I420;
-  if (!CONFIG_LOWBITDEPTH) ref_fmt |= AOM_IMG_FMT_HIGHBITDEPTH;
-  // Allocate memory with the border so that it can be used as a reference.
-  for (i = 0; i < num_references; i++) {
-    unsigned int border = AOM_BORDER_IN_PIXELS;
-    if (!aom_img_alloc_with_border(&reference_images[i], ref_fmt, width, height,
-                                   32, 8, border)) {
-      die("Failed to allocate references.");
-    }
-  }
+
   // Decode anchor frames.
   aom_codec_control_(&codec, AV1_SET_TILE_MODE, 0);
   for (i = 0; i < num_references; ++i) {
@@ -125,6 +115,22 @@
     if (aom_codec_decode(&codec, frame, frame_size, NULL))
       die_codec(&codec, "Failed to decode frame.");
 
+    if (i == 0) {
+      aom_img_fmt_t ref_fmt = 0;
+      if (aom_codec_control(&codec, AV1D_GET_IMG_FORMAT, &ref_fmt))
+        die_codec(&codec, "Failed to get the image format");
+
+      // Allocate memory to store decoded references. Allocate memory with the
+      // border so that it can be used as a reference.
+      for (j = 0; j < num_references; j++) {
+        unsigned int border = AOM_BORDER_IN_PIXELS;
+        if (!aom_img_alloc_with_border(&reference_images[j], ref_fmt, width,
+                                       height, 32, 8, border)) {
+          die("Failed to allocate references.");
+        }
+      }
+    }
+
     if (aom_codec_control(&codec, AV1_COPY_NEW_FRAME_IMAGE,
                           &reference_images[i]))
       die_codec(&codec, "Failed to copy decoded reference frame");
diff --git a/examples/lightfield_tile_list_decoder.c b/examples/lightfield_tile_list_decoder.c
index f6d0110..48e42b0 100644
--- a/examples/lightfield_tile_list_decoder.c
+++ b/examples/lightfield_tile_list_decoder.c
@@ -57,7 +57,7 @@
   aom_image_t reference_images[MAX_EXTERNAL_REFERENCES];
   size_t frame_size = 0;
   const unsigned char *frame = NULL;
-  int i, n;
+  int i, j, n;
 
   exec_name = argv[0];
 
@@ -83,18 +83,6 @@
   if (aom_codec_dec_init(&codec, decoder->codec_interface(), NULL, 0))
     die_codec(&codec, "Failed to initialize decoder.");
 
-  // Allocate memory to store decoded references.
-  aom_img_fmt_t ref_fmt = AOM_IMG_FMT_I420;
-  if (!CONFIG_LOWBITDEPTH) ref_fmt |= AOM_IMG_FMT_HIGHBITDEPTH;
-  // Allocate memory with the border so that it can be used as a reference.
-  for (i = 0; i < num_references; i++) {
-    unsigned int border = AOM_BORDER_IN_PIXELS;
-    if (!aom_img_alloc_with_border(&reference_images[i], ref_fmt, width, height,
-                                   32, 8, border)) {
-      die("Failed to allocate references.");
-    }
-  }
-
   // Decode anchor frames.
   aom_codec_control_(&codec, AV1_SET_TILE_MODE, 0);
 
@@ -104,6 +92,22 @@
     if (aom_codec_decode(&codec, frame, frame_size, NULL))
       die_codec(&codec, "Failed to decode frame.");
 
+    if (i == 0) {
+      aom_img_fmt_t ref_fmt = 0;
+      if (aom_codec_control(&codec, AV1D_GET_IMG_FORMAT, &ref_fmt))
+        die_codec(&codec, "Failed to get the image format");
+
+      // Allocate memory to store decoded references. Allocate memory with the
+      // border so that it can be used as a reference.
+      for (j = 0; j < num_references; j++) {
+        unsigned int border = AOM_BORDER_IN_PIXELS;
+        if (!aom_img_alloc_with_border(&reference_images[j], ref_fmt, width,
+                                       height, 32, 8, border)) {
+          die("Failed to allocate references.");
+        }
+      }
+    }
+
     if (aom_codec_control(&codec, AV1_COPY_NEW_FRAME_IMAGE,
                           &reference_images[i]))
       die_codec(&codec, "Failed to copy decoded reference frame");