[NORMATIVE] ext_tile: set external references at the tile level
This patch implemented the external reference setting before decoding
decode a tile in the tile list OBU.
BUG=aomedia:1938
Change-Id: I4dcad505dc365b26acaeaf6efdda8ea227c309a2
diff --git a/aom/aomdx.h b/aom/aomdx.h
index 8e0284b..f463b62 100644
--- a/aom/aomdx.h
+++ b/aom/aomdx.h
@@ -71,6 +71,17 @@
const void *coded_tile_data;
} aom_tile_data;
+/*!\brief Structure to hold the external reference frame pointer.
+ *
+ * Define a structure to hold the external reference frame pointer.
+ */
+typedef struct av1_ext_ref_frame {
+ /*! Start pointer of external references. */
+ aom_image_t *img;
+ /*! Number of available external references. */
+ int num;
+} av1_ext_ref_frame_t;
+
/*!\enum aom_dec_control_id
* \brief AOM decoder control functions
*
@@ -160,6 +171,11 @@
* bitstream. This provides a way to access a specific tile's bitstream data.
*/
AV1D_GET_TILE_DATA,
+ /** control function to set the external references' pointers in the decoder.
+ * This is used while decoding the tile list OBU in large-scale tile coding
+ * mode.
+ */
+ AV1D_SET_EXT_REF_PTR,
/** control function to enable the ext-tile software debug and testing code in
* the decoder.
*/
@@ -219,6 +235,8 @@
#define AOM_CTRL_AV1_SET_TILE_MODE
AOM_CTRL_USE_TYPE(AV1D_GET_TILE_DATA, aom_tile_data *)
#define AOM_CTRL_AV1D_GET_TILE_DATA
+AOM_CTRL_USE_TYPE(AV1D_SET_EXT_REF_PTR, av1_ext_ref_frame_t *)
+#define AOM_CTRL_AV1D_SET_EXT_REF_PTR
AOM_CTRL_USE_TYPE(AV1D_EXT_TILE_DEBUG, unsigned int)
#define AOM_CTRL_AV1D_EXT_TILE_DEBUG
AOM_CTRL_USE_TYPE(AV1D_SET_IS_ANNEXB, unsigned int)
diff --git a/av1/av1_dx_iface.c b/av1/av1_dx_iface.c
index f99dacf..c440fed 100644
--- a/av1/av1_dx_iface.c
+++ b/av1/av1_dx_iface.c
@@ -59,9 +59,10 @@
int decode_tile_row;
int decode_tile_col;
unsigned int tile_mode;
+ unsigned int ext_tile_debug;
+ EXTERNAL_REFERENCES ext_refs;
unsigned int is_annexb;
int operating_point;
- unsigned int ext_tile_debug;
AVxWorker *frame_workers;
int num_frame_workers;
@@ -480,6 +481,8 @@
frame_worker_data->pbi->dec_tile_row = ctx->decode_tile_row;
frame_worker_data->pbi->dec_tile_col = ctx->decode_tile_col;
frame_worker_data->pbi->ext_tile_debug = ctx->ext_tile_debug;
+ frame_worker_data->pbi->ext_refs = ctx->ext_refs;
+
frame_worker_data->pbi->common.is_annexb = ctx->is_annexb;
worker->had_error = 0;
@@ -896,6 +899,22 @@
return AOM_CODEC_INVALID_PARAM;
}
+static aom_codec_err_t ctrl_set_ext_ref_ptr(aom_codec_alg_priv_t *ctx,
+ va_list args) {
+ av1_ext_ref_frame_t *const data = va_arg(args, av1_ext_ref_frame_t *);
+
+ if (data) {
+ av1_ext_ref_frame_t *const ext_frames = data;
+ ctx->ext_refs.num = ext_frames->num;
+ for (int i = 0; i < ctx->ext_refs.num; i++) {
+ image2yuvconfig(ext_frames->img++, &ctx->ext_refs.refs[i]);
+ }
+ return AOM_CODEC_OK;
+ } else {
+ return AOM_CODEC_INVALID_PARAM;
+ }
+}
+
static aom_codec_err_t ctrl_get_render_size(aom_codec_alg_priv_t *ctx,
va_list args) {
int *const render_size = va_arg(args, int *);
@@ -1066,6 +1085,7 @@
{ AV1D_SET_OPERATING_POINT, ctrl_set_operating_point },
{ AV1_SET_INSPECTION_CALLBACK, ctrl_set_inspection_callback },
{ AV1D_EXT_TILE_DEBUG, ctrl_ext_tile_debug },
+ { AV1D_SET_EXT_REF_PTR, ctrl_set_ext_ref_ptr },
// Getters
{ AOMD_GET_FRAME_CORRUPTED, ctrl_get_frame_corrupted },
diff --git a/av1/common/enums.h b/av1/common/enums.h
index e1feec4..6e0fc55 100644
--- a/av1/common/enums.h
+++ b/av1/common/enums.h
@@ -606,6 +606,9 @@
#define SUPERRES_SCALE_BITS 3
#define SUPERRES_SCALE_DENOMINATOR_MIN (SCALE_NUMERATOR + 1)
+// In large_scale_tile coding, external references are used.
+#define MAX_EXTERNAL_REFERENCES 128
+
#ifdef __cplusplus
} // extern "C"
#endif
diff --git a/av1/decoder/decoder.h b/av1/decoder/decoder.h
index 4d7b5fa..d85b3d5 100644
--- a/av1/decoder/decoder.h
+++ b/av1/decoder/decoder.h
@@ -52,6 +52,11 @@
size_t size;
} TileBufferDec;
+typedef struct EXTERNAL_REFERENCES {
+ YV12_BUFFER_CONFIG refs[MAX_EXTERNAL_REFERENCES];
+ int num;
+} EXTERNAL_REFERENCES;
+
typedef struct AV1Decoder {
DECLARE_ALIGNED(32, MACROBLOCKD, mb);
@@ -115,7 +120,8 @@
int output_frame_height_in_tiles_minus_1;
int tile_count_minus_1;
uint32_t coded_tile_data_size;
- int ext_tile_debug; // for ext-tile software debug & testing
+ unsigned int ext_tile_debug; // for ext-tile software debug & testing
+ EXTERNAL_REFERENCES ext_refs;
} AV1Decoder;
int av1_receive_compressed_data(struct AV1Decoder *pbi, size_t size,
diff --git a/av1/decoder/obu.c b/av1/decoder/obu.c
index cb17925..42c92cc 100644
--- a/av1/decoder/obu.c
+++ b/av1/decoder/obu.c
@@ -394,13 +394,13 @@
// Read out the tile info.
uint32_t tile_info_bytes = 5;
- // TODO(yunqing): set reference here.
+ // Set reference for each tile.
int ref_idx = aom_rb_read_literal(rb, 8);
if (ref_idx > 127) {
cm->error.error_code = AOM_CODEC_CORRUPT_FRAME;
return 0;
}
- (void)ref_idx;
+ av1_set_reference_dec(cm, 0, 1, &pbi->ext_refs.refs[ref_idx]);
pbi->dec_tile_row = aom_rb_read_literal(rb, 8);
pbi->dec_tile_col = aom_rb_read_literal(rb, 8);
diff --git a/av1/encoder/encoder.c b/av1/encoder/encoder.c
index 61a3058..bb2767d 100644
--- a/av1/encoder/encoder.c
+++ b/av1/encoder/encoder.c
@@ -6036,8 +6036,9 @@
(b->flags & YV12_FLAG_HIGHBITDEPTH);
}
-int av1_copy_new_frame_enc(AV1_COMMON *cm, YV12_BUFFER_CONFIG *new_frame,
- YV12_BUFFER_CONFIG *sd) {
+aom_codec_err_t av1_copy_new_frame_enc(AV1_COMMON *cm,
+ YV12_BUFFER_CONFIG *new_frame,
+ YV12_BUFFER_CONFIG *sd) {
const int num_planes = av1_num_planes(cm);
if (!equal_dimensions_and_border(new_frame, sd))
aom_internal_error(&cm->error, AOM_CODEC_ERROR,
diff --git a/av1/encoder/encoder.h b/av1/encoder/encoder.h
index 0b818fc..42752d0 100644
--- a/av1/encoder/encoder.h
+++ b/av1/encoder/encoder.h
@@ -712,8 +712,9 @@
int av1_get_last_show_frame(AV1_COMP *cpi, YV12_BUFFER_CONFIG *frame);
-int av1_copy_new_frame_enc(AV1_COMMON *cm, YV12_BUFFER_CONFIG *new_frame,
- YV12_BUFFER_CONFIG *sd);
+aom_codec_err_t av1_copy_new_frame_enc(AV1_COMMON *cm,
+ YV12_BUFFER_CONFIG *new_frame,
+ YV12_BUFFER_CONFIG *sd);
int av1_use_as_reference(AV1_COMP *cpi, int ref_frame_flags);
diff --git a/examples/lightfield_bitstream_parsing.c b/examples/lightfield_bitstream_parsing.c
index 8ca630e..8ecc0ee 100644
--- a/examples/lightfield_bitstream_parsing.c
+++ b/examples/lightfield_bitstream_parsing.c
@@ -259,7 +259,7 @@
aom_wb_write_literal(&wb, tr, 8);
aom_wb_write_literal(&wb, tc, 8);
aom_wb_write_literal(&wb, tile_data.coded_tile_data_size - 1, 16);
- tl += 5;
+ tl += tile_info_bytes;
memcpy(tl, (uint8_t *)tile_data.coded_tile_data,
tile_data.coded_tile_data_size);
@@ -269,13 +269,10 @@
tile_info_bytes + (uint32_t)tile_data.coded_tile_data_size;
}
- printf("\n tile_list_obu_size: %d\n", tile_list_obu_size);
-
// Write tile list OBU size.
size_t bytes_written = 0;
- aom_uleb_encode_fixed_size(tile_list_obu_size, 4, 4, saved_obu_size_loc,
- &bytes_written);
- if (bytes_written != 4)
+ if (aom_uleb_encode_fixed_size(tile_list_obu_size, 4, 4, saved_obu_size_loc,
+ &bytes_written))
die_codec(&codec, "Failed to encode the tile list obu size.");
// Copy camera frame bitstream directly to get the header.
diff --git a/examples/lightfield_decoder.c b/examples/lightfield_decoder.c
index 4f5da22..ed61923 100644
--- a/examples/lightfield_decoder.c
+++ b/examples/lightfield_decoder.c
@@ -32,6 +32,7 @@
#include "common/tools_common.h"
#include "common/video_reader.h"
+#define MAX_EXTERNAL_REFERENCES 128
#define AOM_BORDER_IN_PIXELS 288
static const char *exec_name;
@@ -63,7 +64,7 @@
int lf_blocksize;
int u_blocks;
int v_blocks;
- aom_image_t reference_images[128];
+ aom_image_t reference_images[MAX_EXTERNAL_REFERENCES];
size_t frame_size = 0;
const unsigned char *frame = NULL;
int i;
diff --git a/examples/lightfield_encoder.c b/examples/lightfield_encoder.c
index d182c94..edcdff9 100644
--- a/examples/lightfield_encoder.c
+++ b/examples/lightfield_encoder.c
@@ -42,6 +42,7 @@
#include "common/tools_common.h"
#include "common/video_writer.h"
+#define MAX_EXTERNAL_REFERENCES 128
#define AOM_BORDER_IN_PIXELS 288
static const char *exec_name;
@@ -247,7 +248,7 @@
int bu, bv;
int u_blocks, v_blocks;
aom_image_t *frame_to_encode;
- aom_image_t reference_images[128];
+ aom_image_t reference_images[MAX_EXTERNAL_REFERENCES];
int reference_image_num = 0;
int i;
diff --git a/examples/lightfield_tile_list_decoder.c b/examples/lightfield_tile_list_decoder.c
index 3ce01e6..1b48fa1 100644
--- a/examples/lightfield_tile_list_decoder.c
+++ b/examples/lightfield_tile_list_decoder.c
@@ -33,6 +33,7 @@
#include "common/tools_common.h"
#include "common/video_reader.h"
+#define MAX_EXTERNAL_REFERENCES 128
#define AOM_BORDER_IN_PIXELS 288
static const char *exec_name;
@@ -58,7 +59,7 @@
int lf_width, lf_height, lf_blocksize;
int u_blocks, v_blocks;
int num_tile_lists;
- aom_image_t reference_images[128];
+ aom_image_t reference_images[MAX_EXTERNAL_REFERENCES];
size_t frame_size = 0;
const unsigned char *frame = NULL;
int i, n;
@@ -138,27 +139,21 @@
// Decode the lightfield.
aom_codec_control_(&codec, AV1_SET_TILE_MODE, 1);
+ // Set external references.
+ av1_ext_ref_frame_t set_ext_ref = { &reference_images[0], num_references };
+ aom_codec_control_(&codec, AV1D_SET_EXT_REF_PTR, &set_ext_ref);
+
// Must decode the camera frame header first.
aom_video_reader_read_frame(reader);
frame = aom_video_reader_get_frame(reader, &frame_size);
if (aom_codec_decode(&codec, frame, frame_size, NULL))
die_codec(&codec, "Failed to decode the frame.");
- printf("\nCamera frame header is decoded.\n");
-
// Decode tile lists one by one.
for (n = 0; n < num_tile_lists; n++) {
aom_video_reader_read_frame(reader);
frame = aom_video_reader_get_frame(reader, &frame_size);
- // TODO(yunqing): need to implement this at tile level.
- av1_ref_frame_t ref;
- ref.idx = 0;
- ref.use_external_ref = 1;
- ref.img = reference_images[0]; // hard-coded for now.
- if (aom_codec_control(&codec, AV1_SET_REFERENCE, &ref))
- die_codec(&codec, "Failed to set reference frame");
-
if (aom_codec_decode(&codec, frame, frame_size, NULL))
die_codec(&codec, "Failed to decode the tile list.");