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;
}