obu: Merge FH and TG if there is only 1 TG
Guarded by CONFIG_OBU_FRAME flag.
Change-Id: I331cf5ae93beb9aba299159ba2af28c0ffd31df5
diff --git a/aom/aom_codec.h b/aom/aom_codec.h
index ff9647a..7838008 100644
--- a/aom/aom_codec.h
+++ b/aom/aom_codec.h
@@ -488,6 +488,7 @@
OBU_FRAME_HEADER = 3,
OBU_TILE_GROUP = 4,
OBU_METADATA = 5,
+ OBU_FRAME = 6,
OBU_PADDING = 15,
} OBU_TYPE;
diff --git a/av1/decoder/obu.c b/av1/decoder/obu.c
index afd589d..addcf61 100644
--- a/av1/decoder/obu.c
+++ b/av1/decoder/obu.c
@@ -72,6 +72,7 @@
case OBU_TEMPORAL_DELIMITER:
case OBU_FRAME_HEADER:
case OBU_TILE_GROUP:
+ case OBU_FRAME:
case OBU_METADATA:
case OBU_PADDING: valid_type = 1; break;
default: break;
@@ -323,6 +324,7 @@
struct aom_read_bit_buffer rb;
size_t payload_size = 0;
size_t decoded_payload_size = 0;
+ size_t obu_payload_offset = 0;
const size_t bytes_available = data_end - data;
if (bytes_available < 1) {
@@ -401,6 +403,9 @@
decoded_payload_size = seq_header_size;
}
break;
+#if CONFIG_OBU_FRAME
+ case OBU_FRAME:
+#endif // CONFIG_OBU_FRAME
case OBU_FRAME_HEADER:
// Only decode first frame header received
if (!frame_header_received) {
@@ -409,16 +414,25 @@
frame_header_received = 1;
}
decoded_payload_size = frame_header_size;
- if (cm->show_existing_frame) frame_decoding_finished = 1;
+ if (cm->show_existing_frame) {
+ frame_decoding_finished = 1;
+ break;
+ }
+#if CONFIG_OBU_FRAME
+ if (obu_header.type == OBU_FRAME_HEADER) break;
+ obu_payload_offset = frame_header_size;
+ AOM_FALLTHROUGH_INTENDED; // fall through to read tile group.
+#else
break;
+#endif // CONFIG_OBU_FRAME
case OBU_TILE_GROUP:
if (!frame_header_received) {
cm->error.error_code = AOM_CODEC_CORRUPT_FRAME;
return;
}
- decoded_payload_size = read_one_tile_group_obu(
- pbi, &rb, is_first_tg_obu_received, data, data + payload_size,
- p_data_end, &frame_decoding_finished);
+ decoded_payload_size += read_one_tile_group_obu(
+ pbi, &rb, is_first_tg_obu_received, data + obu_payload_offset,
+ data + payload_size, p_data_end, &frame_decoding_finished);
is_first_tg_obu_received = 0;
break;
case OBU_METADATA:
diff --git a/av1/encoder/bitstream.c b/av1/encoder/bitstream.c
index c6dc82e..e8a16e9 100644
--- a/av1/encoder/bitstream.c
+++ b/av1/encoder/bitstream.c
@@ -3680,11 +3680,22 @@
*max_tile_col_size = 0;
if (cm->large_scale_tile) {
+#if CONFIG_OBU_FRAME
+ // For large_scale_tile case, we always have only one tile group, so it can
+ // be written as an OBU_FRAME.
+ const OBU_TYPE obu_type = OBU_FRAME;
+#else
+ const OBU_TYPE obu_type = OBU_TILE_GROUP;
+#endif // CONFIG_OBU_FRAME
uint32_t tg_hdr_size =
- write_obu_header(OBU_TILE_GROUP, 0, data + PRE_OBU_SIZE_BYTES);
+ write_obu_header(obu_type, 0, data + PRE_OBU_SIZE_BYTES);
tg_hdr_size += PRE_OBU_SIZE_BYTES;
data += tg_hdr_size;
+#if CONFIG_OBU_FRAME
+ total_size += write_frame_header_obu(cpi, saved_wb, data);
+#endif // CONFIG_OBU_FRAME
+
int tile_size_bytes = 0;
int tile_col_size_bytes = 0;
@@ -3829,11 +3840,23 @@
// A new tile group begins at this tile. Write the obu header and
// tile group header
- curr_tg_data_size = write_obu_header(
- OBU_TILE_GROUP, obu_extension_header, data + PRE_OBU_SIZE_BYTES);
+#if CONFIG_OBU_FRAME
+ const OBU_TYPE obu_type =
+ (num_tg_hdrs == 1) ? OBU_FRAME : OBU_TILE_GROUP;
+#else
+ const OBU_TYPE obu_type = OBU_TILE_GROUP;
+#endif
+ curr_tg_data_size = write_obu_header(obu_type, obu_extension_header,
+ data + PRE_OBU_SIZE_BYTES);
#if CONFIG_OBU_SIZING
obu_header_size = curr_tg_data_size;
#endif // CONFIG_OBU_SIZING
+#if CONFIG_OBU_FRAME
+ if (num_tg_hdrs == 1) {
+ curr_tg_data_size += write_frame_header_obu(
+ cpi, saved_wb, data + curr_tg_data_size + PRE_OBU_SIZE_BYTES);
+ }
+#endif
curr_tg_data_size += write_tile_group_header(
data + curr_tg_data_size + PRE_OBU_SIZE_BYTES, tile_idx,
AOMMIN(tile_idx + tg_size - 1, tile_cols * tile_rows - 1),
@@ -3957,7 +3980,7 @@
AV1_COMMON *const cm = &cpi->common;
uint32_t obu_header_size = 0;
uint32_t obu_payload_size = 0;
- FrameHeaderInfo fh_info;
+ FrameHeaderInfo fh_info = { NULL, 0 };
#if CONFIG_SCALABILITY
const uint8_t enhancement_layers_cnt = cm->enhancement_layers_cnt;
const uint8_t obu_extension_header =
@@ -4000,33 +4023,41 @@
data += obu_header_size + obu_payload_size + length_field_size;
}
- struct aom_write_bit_buffer saved_wb;
+#if CONFIG_OBU_FRAME
+ const int write_frame_header = (cm->num_tg > 1 || cm->show_existing_frame);
+#else
+ const int write_frame_header = 1;
+#endif // CONFIG_OBU_FRAME
- // Write Frame Header OBU.
- fh_info.frame_header = data;
- obu_header_size = write_obu_header(OBU_FRAME_HEADER, obu_extension_header,
- data + PRE_OBU_SIZE_BYTES);
- obu_payload_size = write_frame_header_obu(
- cpi, &saved_wb, data + PRE_OBU_SIZE_BYTES + obu_header_size);
+ struct aom_write_bit_buffer saved_wb;
+ if (write_frame_header) {
+ // Write Frame Header OBU.
+ fh_info.frame_header = data;
+ obu_header_size = write_obu_header(OBU_FRAME_HEADER, obu_extension_header,
+ data + PRE_OBU_SIZE_BYTES);
+ obu_payload_size = write_frame_header_obu(
+ cpi, &saved_wb, data + PRE_OBU_SIZE_BYTES + obu_header_size);
#if CONFIG_OBU_SIZING
- 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) !=
- AOM_CODEC_OK) {
- return AOM_CODEC_ERROR;
- }
+ 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) !=
+ AOM_CODEC_OK) {
+ return AOM_CODEC_ERROR;
+ }
#else
- const size_t length_field_size = PRE_OBU_SIZE_BYTES;
- mem_put_le32(data, obu_header_size + obu_payload_size);
+ const size_t length_field_size = PRE_OBU_SIZE_BYTES;
+ mem_put_le32(data, obu_header_size + obu_payload_size);
#endif // CONFIG_OBU_SIZING
- fh_info.total_length = obu_header_size + obu_payload_size + length_field_size;
- data += fh_info.total_length;
+ fh_info.total_length =
+ obu_header_size + obu_payload_size + length_field_size;
+ data += fh_info.total_length;
- // Since length_field_size is determined adaptively after frame header
- // encoding, saved_wb must be adjusted accordingly.
- saved_wb.bit_buffer += length_field_size;
+ // Since length_field_size is determined adaptively after frame header
+ // encoding, saved_wb must be adjusted accordingly.
+ saved_wb.bit_buffer += length_field_size;
+ }
#define EXT_TILE_DEBUG 0
#if EXT_TILE_DEBUG
diff --git a/build/cmake/aom_config_defaults.cmake b/build/cmake/aom_config_defaults.cmake
index 5d76ce5..a447ed5 100644
--- a/build/cmake/aom_config_defaults.cmake
+++ b/build/cmake/aom_config_defaults.cmake
@@ -113,6 +113,7 @@
set(CONFIG_MAX_TILE 1 CACHE NUMBER "AV1 experiment flag.")
set(CONFIG_MONO_VIDEO 1 CACHE NUMBER "AV1 experiment flag.")
set(CONFIG_NO_FRAME_CONTEXT_SIGNALING 0 CACHE NUMBER "AV1 experiment flag.")
+set(CONFIG_OBU_FRAME 0 CACHE NUMBER "AV1 experiment flag.")
set(CONFIG_OBU_NO_IVF 0 CACHE NUMBER "AV1 experiment flag.")
set(CONFIG_OBU_SIZE_AFTER_HEADER 0 CACHE NUMBER "AV1 experiment flag.")
set(CONFIG_OBU_SIZING 1 CACHE NUMBER "AV1 experiment flag.")