CONFIG_INSPECTION: Enable analysis of Non-Showable Frames

This patch replaces decoder_decode with decoder_inspect
so that every frame showable or not is iterated through.

Change-Id: Iaeca1a7ba4310d49a4502f9ac5aaf4b90e0c16b9
diff --git a/aom/aomdx.h b/aom/aomdx.h
index 765856a..e14ace4 100644
--- a/aom/aomdx.h
+++ b/aom/aomdx.h
@@ -45,6 +45,7 @@
 /** Callback that inspects decoder frame data.
  */
 typedef void (*aom_inspect_cb)(void *decoder, void *ctx);
+
 #endif
 
 /*!\brief Structure to hold inspection callback and context.
@@ -60,6 +61,19 @@
   void *inspect_ctx;
 } aom_inspect_init;
 
+/*!\brief Structure to collect a buffer index when inspecting.
+ *
+ * Defines a structure to hold the buffer and return an index
+ * when calling decode from inspect. This enables us to decode
+ * non showable sub frames.
+ */
+typedef struct {
+  /*! Pointer for new position in compressed buffer after decoding 1 OBU. */
+  const unsigned char *buf;
+  /*! Index into reference buffer array to see result of decoding 1 OBU. */
+  int idx;
+} Av1DecodeReturn;
+
 /*!\brief Structure to hold a tile's start address and size in the bitstream.
  *
  * Defines a structure to hold a tile's start address and size in the bitstream.
diff --git a/av1/av1_dx_iface.c b/av1/av1_dx_iface.c
index 904d12f..74b2627 100644
--- a/av1/av1_dx_iface.c
+++ b/av1/av1_dx_iface.c
@@ -452,6 +452,7 @@
     ctx->need_resync = 0;
 }
 
+#if !CONFIG_INSPECTION
 static aom_codec_err_t decode_one(aom_codec_alg_priv_t *ctx,
                                   const uint8_t **data, size_t data_sz,
                                   void *user_priv) {
@@ -477,11 +478,6 @@
   frame_worker_data->user_priv = user_priv;
   frame_worker_data->received_frame = 1;
 
-#if CONFIG_INSPECTION
-  frame_worker_data->pbi->inspect_cb = ctx->inspect_cb;
-  frame_worker_data->pbi->inspect_ctx = ctx->inspect_ctx;
-#endif
-
   frame_worker_data->pbi->common.large_scale_tile = ctx->tile_mode;
   frame_worker_data->pbi->dec_tile_row = ctx->decode_tile_row;
   frame_worker_data->pbi->dec_tile_col = ctx->decode_tile_col;
@@ -504,6 +500,36 @@
 
   return AOM_CODEC_OK;
 }
+#endif
+
+#if CONFIG_INSPECTION
+
+// This function enables the inspector to inspect non visible frames.
+static aom_codec_err_t decoder_inspect(aom_codec_alg_priv_t *ctx,
+                                       const uint8_t *data, size_t data_sz,
+                                       void *user_priv) {
+  aom_codec_err_t res = AOM_CODEC_OK;
+  Av1DecodeReturn *data2 = (Av1DecodeReturn *)user_priv;
+  if (ctx->frame_workers == NULL) {
+    res = init_decoder(ctx);
+    if (res != AOM_CODEC_OK) return res;
+  }
+  FrameWorkerData *const frame_worker_data =
+      (FrameWorkerData *)ctx->frame_workers[0].data1;
+  AV1Decoder *const pbi = frame_worker_data->pbi;
+  AV1_COMMON *const cm = &pbi->common;
+  frame_worker_data->pbi->inspect_cb = ctx->inspect_cb;
+  frame_worker_data->pbi->inspect_ctx = ctx->inspect_ctx;
+  res = av1_receive_compressed_data(frame_worker_data->pbi, data_sz, &data);
+  if (ctx->frame_workers->had_error)
+    return update_error_state(ctx, &frame_worker_data->pbi->common.error);
+
+  for (int i = 0; i < REF_FRAMES; ++i)
+    if (cm->ref_frame_map[i] == cm->new_fb_idx) data2->idx = i;
+  data2->buf = data;
+  return res;
+}
+#else
 
 static aom_codec_err_t decoder_decode(aom_codec_alg_priv_t *ctx,
                                       const uint8_t *data, size_t data_sz,
@@ -594,6 +620,7 @@
 
   return res;
 }
+#endif
 
 // If grain_params->apply_grain is false, returns img. Otherwise, adds film
 // grain to img, saves the result in *grain_img_ptr (allocating *grain_img_ptr
@@ -1287,9 +1314,13 @@
   decoder_ctrl_maps,                        // aom_codec_ctrl_fn_map_t
   {
       // NOLINT
-      decoder_peek_si,    // aom_codec_peek_si_fn_t
-      decoder_get_si,     // aom_codec_get_si_fn_t
-      decoder_decode,     // aom_codec_decode_fn_t
+      decoder_peek_si,  // aom_codec_peek_si_fn_t
+      decoder_get_si,   // aom_codec_get_si_fn_t
+#if CONFIG_INSPECTION
+      decoder_inspect,  // aom_codec_decode_fn_t
+#else
+      decoder_decode,  // aom_codec_decode_fn_t
+#endif
       decoder_get_frame,  // aom_codec_get_frame_fn_t
       decoder_set_fb_fn,  // aom_codec_set_fb_fn_t
   },
diff --git a/av1/decoder/inspection.h b/av1/decoder/inspection.h
index 7214a9b..ba1b8ac 100644
--- a/av1/decoder/inspection.h
+++ b/av1/decoder/inspection.h
@@ -20,7 +20,7 @@
 #include "av1/decoder/accounting.h"
 #endif
 
-#ifndef AOM_AOMDX_H_
+#ifndef AOM_AOM_AOMDX_H_
 typedef void (*aom_inspect_cb)(void *decoder, void *data);
 #endif
 
diff --git a/examples/inspect.c b/examples/inspect.c
index 9d5f0dc..6728f2c 100644
--- a/examples/inspect.c
+++ b/examples/inspect.c
@@ -618,21 +618,36 @@
   return EXIT_SUCCESS;
 }
 
+Av1DecodeReturn adr;
+int have_frame = 0;
+const unsigned char *frame;
+const unsigned char *end_frame;
+size_t frame_size = 0;
+
 EMSCRIPTEN_KEEPALIVE
 int read_frame() {
-  if (!aom_video_reader_read_frame(reader)) return EXIT_FAILURE;
   img = NULL;
-  aom_codec_iter_t iter = NULL;
-  size_t frame_size = 0;
-  const unsigned char *frame = aom_video_reader_get_frame(reader, &frame_size);
-  if (aom_codec_decode(&codec, frame, (unsigned int)frame_size, NULL) !=
+
+  if (!have_frame) {
+    if (!aom_video_reader_read_frame(reader)) return EXIT_FAILURE;
+    frame = aom_video_reader_get_frame(reader, &frame_size);
+    have_frame = 1;
+    end_frame = frame + frame_size;
+  }
+
+  if (aom_codec_decode(&codec, frame, (unsigned int)frame_size, &adr) !=
       AOM_CODEC_OK) {
     die_codec(&codec, "Failed to decode frame.");
   }
+  frame = adr.buf;
+  if (frame == end_frame) have_frame = 0;
+
   int got_any_frames = 0;
   aom_image_t *frame_img;
-  while ((frame_img = aom_codec_get_frame(&codec, &iter))) {
-    img = frame_img;
+  struct av1_ref_frame ref_dec;
+  ref_dec.idx = adr.idx;
+  if (!aom_codec_control(&codec, AV1_GET_REFERENCE, &ref_dec)) {
+    img = frame_img = &ref_dec.img;
     ++frame_count;
     got_any_frames = 1;
   }