Commit 2eada612 authored by Debargha Mukherjee's avatar Debargha Mukherjee

Add experiment to restrict compressed header

The compressed header is now used only when the refresh
type is set as forward, i.e. in error resilience and
frame parallel modes. As long as backward updates are
used the header is disabled thereby saving bits.

Change-Id: Iee9f66ffbd30ef3552ea41b75e4b51537cd9ff97
parent 8f4b2167
...@@ -1299,6 +1299,15 @@ static INLINE int all_lossless(const AV1_COMMON *cm, const MACROBLOCKD *xd) { ...@@ -1299,6 +1299,15 @@ static INLINE int all_lossless(const AV1_COMMON *cm, const MACROBLOCKD *xd) {
return all_lossless; return all_lossless;
} }
static INLINE int use_compressed_header(const AV1_COMMON *cm) {
(void)cm;
#if CONFIG_RESTRICT_COMPRESSED_HDR
return cm->refresh_frame_context == REFRESH_FRAME_CONTEXT_FORWARD;
#else
return 1;
#endif // CONFIG_RESTRICT_COMPRESSED_HDR
}
#ifdef __cplusplus #ifdef __cplusplus
} // extern "C" } // extern "C"
#endif #endif
......
...@@ -5071,11 +5071,14 @@ static size_t read_uncompressed_header(AV1Decoder *pbi, ...@@ -5071,11 +5071,14 @@ static size_t read_uncompressed_header(AV1Decoder *pbi,
#endif #endif
read_tile_info(pbi, rb); read_tile_info(pbi, rb);
sz = aom_rb_read_literal(rb, 16); if (use_compressed_header(cm)) {
sz = aom_rb_read_literal(rb, 16);
if (sz == 0) if (sz == 0)
aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME, aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME,
"Invalid header size"); "Invalid header size");
} else {
sz = 0;
}
return sz; return sz;
} }
...@@ -5194,6 +5197,7 @@ static int read_compressed_header(AV1Decoder *pbi, const uint8_t *data, ...@@ -5194,6 +5197,7 @@ static int read_compressed_header(AV1Decoder *pbi, const uint8_t *data,
return aom_reader_has_error(&r); return aom_reader_has_error(&r);
} }
#ifdef NDEBUG #ifdef NDEBUG
#define debug_check_frame_counts(cm) (void)0 #define debug_check_frame_counts(cm) (void)0
#else // !NDEBUG #else // !NDEBUG
...@@ -5419,16 +5423,17 @@ void av1_decode_frame(AV1Decoder *pbi, const uint8_t *data, ...@@ -5419,16 +5423,17 @@ void av1_decode_frame(AV1Decoder *pbi, const uint8_t *data,
#endif // CONFIG_HIGHBITDEPTH #endif // CONFIG_HIGHBITDEPTH
#endif // CONFIG_INTRABC #endif // CONFIG_INTRABC
if (!first_partition_size) { if (cm->show_existing_frame) {
// showing a frame directly // showing a frame directly
*p_data_end = data + aom_rb_bytes_read(&rb); *p_data_end = data + aom_rb_bytes_read(&rb);
return; return;
} }
data += aom_rb_bytes_read(&rb); data += aom_rb_bytes_read(&rb);
if (!read_is_valid(data, first_partition_size, data_end)) if (first_partition_size)
aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME, if (!read_is_valid(data, first_partition_size, data_end))
"Truncated packet or corrupt header length"); aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME,
"Truncated packet or corrupt header length");
cm->setup_mi(cm); cm->setup_mi(cm);
...@@ -5495,10 +5500,12 @@ void av1_decode_frame(AV1Decoder *pbi, const uint8_t *data, ...@@ -5495,10 +5500,12 @@ void av1_decode_frame(AV1Decoder *pbi, const uint8_t *data,
av1_zero(cm->counts); av1_zero(cm->counts);
xd->corrupted = 0; xd->corrupted = 0;
new_fb->corrupted = read_compressed_header(pbi, data, first_partition_size); if (first_partition_size) {
if (new_fb->corrupted) new_fb->corrupted = read_compressed_header(pbi, data, first_partition_size);
aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME, if (new_fb->corrupted)
"Decode failed. Frame data header is corrupted."); aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME,
"Decode failed. Frame data header is corrupted.");
}
#if CONFIG_LOOP_RESTORATION #if CONFIG_LOOP_RESTORATION
if (cm->rst_info[0].frame_restoration_type != RESTORE_NONE || if (cm->rst_info[0].frame_restoration_type != RESTORE_NONE ||
...@@ -5711,16 +5718,17 @@ size_t av1_decode_frame_headers_and_setup(AV1Decoder *pbi, const uint8_t *data, ...@@ -5711,16 +5718,17 @@ size_t av1_decode_frame_headers_and_setup(AV1Decoder *pbi, const uint8_t *data,
#endif // CONFIG_HIGHBITDEPTH #endif // CONFIG_HIGHBITDEPTH
#endif // CONFIG_INTRABC #endif // CONFIG_INTRABC
if (!first_partition_size) { if (cm->show_existing_frame) {
// showing a frame directly // showing a frame directly
*p_data_end = data + aom_rb_bytes_read(&rb); *p_data_end = data + aom_rb_bytes_read(&rb);
return 0; return 0;
} }
data += aom_rb_bytes_read(&rb); data += aom_rb_bytes_read(&rb);
if (!read_is_valid(data, first_partition_size, data_end)) if (first_partition_size)
aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME, if (!read_is_valid(data, first_partition_size, data_end))
"Truncated packet or corrupt header length"); aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME,
"Truncated packet or corrupt header length");
cm->setup_mi(cm); cm->setup_mi(cm);
...@@ -5787,11 +5795,12 @@ size_t av1_decode_frame_headers_and_setup(AV1Decoder *pbi, const uint8_t *data, ...@@ -5787,11 +5795,12 @@ size_t av1_decode_frame_headers_and_setup(AV1Decoder *pbi, const uint8_t *data,
av1_zero(cm->counts); av1_zero(cm->counts);
xd->corrupted = 0; xd->corrupted = 0;
new_fb->corrupted = read_compressed_header(pbi, data, first_partition_size); if (first_partition_size) {
if (new_fb->corrupted) new_fb->corrupted = read_compressed_header(pbi, data, first_partition_size);
aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME, if (new_fb->corrupted)
"Decode failed. Frame data header is corrupted."); aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME,
"Decode failed. Frame data header is corrupted.");
}
return first_partition_size; return first_partition_size;
} }
......
...@@ -383,7 +383,8 @@ int av1_receive_compressed_data(AV1Decoder *pbi, size_t size, ...@@ -383,7 +383,8 @@ int av1_receive_compressed_data(AV1Decoder *pbi, size_t size,
av1_decode_frame(pbi, source, source + size, psource); av1_decode_frame(pbi, source, source + size, psource);
#endif #endif
#if 1 #if 1
if (av1_decode_frame_headers_and_setup(pbi, source, source + size, psource)) { av1_decode_frame_headers_and_setup(pbi, source, source + size, psource);
if (!cm->show_existing_frame) {
av1_decode_tg_tiles_and_wrapup(pbi, source, source + size, psource, 0, av1_decode_tg_tiles_and_wrapup(pbi, source, source + size, psource, 0,
cm->tile_rows * cm->tile_cols - 1, 1); cm->tile_rows * cm->tile_cols - 1, 1);
} }
......
...@@ -105,6 +105,7 @@ static void write_uncompressed_header_frame(AV1_COMP *cpi, ...@@ -105,6 +105,7 @@ static void write_uncompressed_header_frame(AV1_COMP *cpi,
#endif #endif
static uint32_t write_compressed_header(AV1_COMP *cpi, uint8_t *data); static uint32_t write_compressed_header(AV1_COMP *cpi, uint8_t *data);
#if !CONFIG_OBU || CONFIG_EXT_TILE #if !CONFIG_OBU || CONFIG_EXT_TILE
static int remux_tiles(const AV1_COMMON *const cm, uint8_t *dst, static int remux_tiles(const AV1_COMMON *const cm, uint8_t *dst,
const uint32_t data_size, const uint32_t max_tile_size, const uint32_t data_size, const uint32_t max_tile_size,
...@@ -3888,7 +3889,7 @@ static uint32_t write_tiles(AV1_COMP *const cpi, uint8_t *const dst, ...@@ -3888,7 +3889,7 @@ static uint32_t write_tiles(AV1_COMP *const cpi, uint8_t *const dst,
const int have_tiles = tile_cols * tile_rows > 1; const int have_tiles = tile_cols * tile_rows > 1;
struct aom_write_bit_buffer wb = { dst, 0 }; struct aom_write_bit_buffer wb = { dst, 0 };
const int n_log2_tiles = cm->log2_tile_rows + cm->log2_tile_cols; const int n_log2_tiles = cm->log2_tile_rows + cm->log2_tile_cols;
uint32_t comp_hdr_size; uint32_t compressed_hdr_size;
// Fixed size tile groups for the moment // Fixed size tile groups for the moment
const int num_tg_hdrs = cm->num_tg; const int num_tg_hdrs = cm->num_tg;
const int tg_size = const int tg_size =
...@@ -3903,7 +3904,6 @@ static uint32_t write_tiles(AV1_COMP *const cpi, uint8_t *const dst, ...@@ -3903,7 +3904,6 @@ static uint32_t write_tiles(AV1_COMP *const cpi, uint8_t *const dst,
int tile_size_bytes = 4; int tile_size_bytes = 4;
int tile_col_size_bytes; int tile_col_size_bytes;
uint32_t uncompressed_hdr_size = 0; uint32_t uncompressed_hdr_size = 0;
struct aom_write_bit_buffer comp_hdr_len_wb;
struct aom_write_bit_buffer tg_params_wb; struct aom_write_bit_buffer tg_params_wb;
struct aom_write_bit_buffer tile_size_bytes_wb; struct aom_write_bit_buffer tile_size_bytes_wb;
uint32_t saved_offset; uint32_t saved_offset;
...@@ -4026,14 +4026,22 @@ static uint32_t write_tiles(AV1_COMP *const cpi, uint8_t *const dst, ...@@ -4026,14 +4026,22 @@ static uint32_t write_tiles(AV1_COMP *const cpi, uint8_t *const dst,
aom_wb_overwrite_literal(&wb, (1 << n_log2_tiles) - 1, n_log2_tiles); aom_wb_overwrite_literal(&wb, (1 << n_log2_tiles) - 1, n_log2_tiles);
} }
/* Write a placeholder for the compressed header length */ if (!use_compressed_header(cm)) {
comp_hdr_len_wb = wb; uncompressed_hdr_size = aom_wb_bytes_written(&wb);
aom_wb_write_literal(&wb, 0, 16); compressed_hdr_size = 0;
} else {
/* Write a placeholder for the compressed header length */
struct aom_write_bit_buffer comp_hdr_len_wb = wb;
aom_wb_write_literal(&wb, 0, 16);
uncompressed_hdr_size = aom_wb_bytes_written(&wb);
compressed_hdr_size =
write_compressed_header(cpi, dst + uncompressed_hdr_size);
aom_wb_overwrite_literal(&comp_hdr_len_wb, (int)(compressed_hdr_size),
16);
}
uncompressed_hdr_size = aom_wb_bytes_written(&wb); hdr_size = uncompressed_hdr_size + compressed_hdr_size;
comp_hdr_size = write_compressed_header(cpi, dst + uncompressed_hdr_size);
aom_wb_overwrite_literal(&comp_hdr_len_wb, (int)(comp_hdr_size), 16);
hdr_size = uncompressed_hdr_size + comp_hdr_size;
total_size += hdr_size; total_size += hdr_size;
for (tile_row = 0; tile_row < tile_rows; tile_row++) { for (tile_row = 0; tile_row < tile_rows; tile_row++) {
...@@ -4077,7 +4085,7 @@ static uint32_t write_tiles(AV1_COMP *const cpi, uint8_t *const dst, ...@@ -4077,7 +4085,7 @@ static uint32_t write_tiles(AV1_COMP *const cpi, uint8_t *const dst,
// Copy compressed header // Copy compressed header
memmove(dst + old_total_size + uncompressed_hdr_size, memmove(dst + old_total_size + uncompressed_hdr_size,
dst + uncompressed_hdr_size, dst + uncompressed_hdr_size,
comp_hdr_size * sizeof(uint8_t)); compressed_hdr_size * sizeof(uint8_t));
total_size += hdr_size; total_size += hdr_size;
tile_count = 1; tile_count = 1;
curr_tg_data_size = hdr_size + tile_size + 4; curr_tg_data_size = hdr_size + tile_size + 4;
...@@ -4096,7 +4104,7 @@ static uint32_t write_tiles(AV1_COMP *const cpi, uint8_t *const dst, ...@@ -4096,7 +4104,7 @@ static uint32_t write_tiles(AV1_COMP *const cpi, uint8_t *const dst,
// Copy compressed header // Copy compressed header
memmove(dst + total_size + uncompressed_hdr_size, memmove(dst + total_size + uncompressed_hdr_size,
dst + uncompressed_hdr_size, dst + uncompressed_hdr_size,
comp_hdr_size * sizeof(uint8_t)); compressed_hdr_size * sizeof(uint8_t));
total_size += hdr_size; total_size += hdr_size;
tile_count = 0; tile_count = 0;
curr_tg_data_size = hdr_size; curr_tg_data_size = hdr_size;
...@@ -4166,11 +4174,13 @@ static uint32_t write_tiles(AV1_COMP *const cpi, uint8_t *const dst, ...@@ -4166,11 +4174,13 @@ static uint32_t write_tiles(AV1_COMP *const cpi, uint8_t *const dst,
// Remux if possible. TODO (Thomas Davies): do this for more than one tile // Remux if possible. TODO (Thomas Davies): do this for more than one tile
// group // group
if (have_tiles && tg_count == 1) { if (have_tiles && tg_count == 1) {
int data_size = total_size - (uncompressed_hdr_size + comp_hdr_size); int data_size =
data_size = remux_tiles(cm, dst + uncompressed_hdr_size + comp_hdr_size, total_size - (uncompressed_hdr_size + compressed_hdr_size);
data_size, *max_tile_size, *max_tile_col_size, data_size =
&tile_size_bytes, &tile_col_size_bytes); remux_tiles(cm, dst + uncompressed_hdr_size + compressed_hdr_size,
total_size = data_size + uncompressed_hdr_size + comp_hdr_size; data_size, *max_tile_size, *max_tile_col_size,
&tile_size_bytes, &tile_col_size_bytes);
total_size = data_size + uncompressed_hdr_size + compressed_hdr_size;
aom_wb_overwrite_literal(&tile_size_bytes_wb, tile_size_bytes - 1, 2); aom_wb_overwrite_literal(&tile_size_bytes_wb, tile_size_bytes - 1, 2);
} }
...@@ -5457,9 +5467,8 @@ static uint32_t write_sequence_header_obu(AV1_COMP *cpi, uint8_t *const dst) { ...@@ -5457,9 +5467,8 @@ static uint32_t write_sequence_header_obu(AV1_COMP *cpi, uint8_t *const dst) {
static uint32_t write_frame_header_obu(AV1_COMP *cpi, uint8_t *const dst) { static uint32_t write_frame_header_obu(AV1_COMP *cpi, uint8_t *const dst) {
AV1_COMMON *const cm = &cpi->common; AV1_COMMON *const cm = &cpi->common;
struct aom_write_bit_buffer wb = { dst, 0 }; struct aom_write_bit_buffer wb = { dst, 0 };
struct aom_write_bit_buffer compr_hdr_len_wb;
uint32_t total_size = 0; uint32_t total_size = 0;
uint32_t compr_hdr_size, uncompressed_hdr_size; uint32_t compressed_hdr_size, uncompressed_hdr_size;
write_uncompressed_header_obu(cpi, &wb); write_uncompressed_header_obu(cpi, &wb);
...@@ -5471,15 +5480,21 @@ static uint32_t write_frame_header_obu(AV1_COMP *cpi, uint8_t *const dst) { ...@@ -5471,15 +5480,21 @@ static uint32_t write_frame_header_obu(AV1_COMP *cpi, uint8_t *const dst) {
// write the tile length code (Always 4 bytes for now) // write the tile length code (Always 4 bytes for now)
aom_wb_write_literal(&wb, 3, 2); aom_wb_write_literal(&wb, 3, 2);
// placeholder for the compressed header length if (!use_compressed_header(cm)) {
compr_hdr_len_wb = wb; uncompressed_hdr_size = aom_wb_bytes_written(&wb);
aom_wb_write_literal(&wb, 0, 16); compressed_hdr_size = 0;
} else {
// placeholder for the compressed header length
struct aom_write_bit_buffer compr_hdr_len_wb = wb;
aom_wb_write_literal(&wb, 0, 16);
uncompressed_hdr_size = aom_wb_bytes_written(&wb); uncompressed_hdr_size = aom_wb_bytes_written(&wb);
compr_hdr_size = write_compressed_header(cpi, dst + uncompressed_hdr_size); compressed_hdr_size =
aom_wb_overwrite_literal(&compr_hdr_len_wb, (int)(compr_hdr_size), 16); write_compressed_header(cpi, dst + uncompressed_hdr_size);
aom_wb_overwrite_literal(&compr_hdr_len_wb, (int)(compressed_hdr_size), 16);
}
total_size = uncompressed_hdr_size + compr_hdr_size; total_size = uncompressed_hdr_size + compressed_hdr_size;
return total_size; return total_size;
} }
...@@ -5728,8 +5743,8 @@ void av1_pack_bitstream(AV1_COMP *const cpi, uint8_t *dst, size_t *size) { ...@@ -5728,8 +5743,8 @@ void av1_pack_bitstream(AV1_COMP *const cpi, uint8_t *dst, size_t *size) {
uint32_t data_size; uint32_t data_size;
#if CONFIG_EXT_TILE #if CONFIG_EXT_TILE
AV1_COMMON *const cm = &cpi->common; AV1_COMMON *const cm = &cpi->common;
uint32_t compressed_header_size = 0; uint32_t compressed_hdr_size = 0;
uint32_t uncompressed_header_size; uint32_t uncompressed_hdr_size;
struct aom_write_bit_buffer saved_wb; struct aom_write_bit_buffer saved_wb;
struct aom_write_bit_buffer wb = { data, 0 }; struct aom_write_bit_buffer wb = { data, 0 };
const int have_tiles = cm->tile_cols * cm->tile_rows > 1; const int have_tiles = cm->tile_cols * cm->tile_rows > 1;
...@@ -5811,17 +5826,21 @@ void av1_pack_bitstream(AV1_COMP *const cpi, uint8_t *dst, size_t *size) { ...@@ -5811,17 +5826,21 @@ void av1_pack_bitstream(AV1_COMP *const cpi, uint8_t *dst, size_t *size) {
// Number of bytes in tile size - 1 // Number of bytes in tile size - 1
aom_wb_write_literal(&wb, 0, 2); aom_wb_write_literal(&wb, 0, 2);
} }
// Size of compressed header
aom_wb_write_literal(&wb, 0, 16);
uncompressed_header_size = (uint32_t)aom_wb_bytes_written(&wb); if (!use_compressed_header(cm)) {
data += uncompressed_header_size; uncompressed_hdr_size = (uint32_t)aom_wb_bytes_written(&wb);
aom_clear_system_state();
aom_clear_system_state(); compressed_hdr_size = 0;
} else {
// Write the compressed header // Size of compressed header
compressed_header_size = write_compressed_header(cpi, data); aom_wb_write_literal(&wb, 0, 16);
data += compressed_header_size; uncompressed_hdr_size = (uint32_t)aom_wb_bytes_written(&wb);
aom_clear_system_state();
// Write the compressed header
compressed_hdr_size =
write_compressed_header(cpi, data + uncompressed_hdr_size);
}
data += uncompressed_hdr_size + compressed_hdr_size;
// Write the encoded tile data // Write the encoded tile data
data_size = write_tiles(cpi, data, &max_tile_size, &max_tile_col_size); data_size = write_tiles(cpi, data, &max_tile_size, &max_tile_col_size);
...@@ -5851,9 +5870,9 @@ void av1_pack_bitstream(AV1_COMP *const cpi, uint8_t *dst, size_t *size) { ...@@ -5851,9 +5870,9 @@ void av1_pack_bitstream(AV1_COMP *const cpi, uint8_t *dst, size_t *size) {
assert(tile_size_bytes >= 1 && tile_size_bytes <= 4); assert(tile_size_bytes >= 1 && tile_size_bytes <= 4);
aom_wb_write_literal(&saved_wb, tile_size_bytes - 1, 2); aom_wb_write_literal(&saved_wb, tile_size_bytes - 1, 2);
} }
// TODO(jbb): Figure out what to do if compressed_header_size > 16 bits. // TODO(jbb): Figure out what to do if compressed_hdr_size > 16 bits.
assert(compressed_header_size <= 0xffff); assert(compressed_hdr_size <= 0xffff);
aom_wb_write_literal(&saved_wb, compressed_header_size, 16); aom_wb_write_literal(&saved_wb, compressed_hdr_size, 16);
} else { } else {
#endif // CONFIG_EXT_TILE #endif // CONFIG_EXT_TILE
data += data_size; data += data_size;
......
...@@ -192,6 +192,7 @@ set(CONFIG_RECT_TX 1 CACHE NUMBER "AV1 experiment flag.") ...@@ -192,6 +192,7 @@ set(CONFIG_RECT_TX 1 CACHE NUMBER "AV1 experiment flag.")
set(CONFIG_RECT_TX_EXT 0 CACHE NUMBER "AV1 experiment flag.") set(CONFIG_RECT_TX_EXT 0 CACHE NUMBER "AV1 experiment flag.")
set(CONFIG_REFERENCE_BUFFER 1 CACHE NUMBER "AV1 experiment flag.") set(CONFIG_REFERENCE_BUFFER 1 CACHE NUMBER "AV1 experiment flag.")
set(CONFIG_REF_ADAPT 0 CACHE NUMBER "AV1 experiment flag.") set(CONFIG_REF_ADAPT 0 CACHE NUMBER "AV1 experiment flag.")
set(CONFIG_RESTRICT_COMPRESSED_HDR 0 CACHE NUMBER "AV1 experiment flag.")
set(CONFIG_SBL_SYMBOL 0 CACHE NUMBER "AV1 experiment flag.") set(CONFIG_SBL_SYMBOL 0 CACHE NUMBER "AV1 experiment flag.")
set(CONFIG_SMOOTH_HV 1 CACHE NUMBER "AV1 experiment flag.") set(CONFIG_SMOOTH_HV 1 CACHE NUMBER "AV1 experiment flag.")
set(CONFIG_SPEED_REFS 0 CACHE NUMBER "AV1 experiment flag.") set(CONFIG_SPEED_REFS 0 CACHE NUMBER "AV1 experiment flag.")
......
...@@ -352,6 +352,7 @@ EXPERIMENT_LIST=" ...@@ -352,6 +352,7 @@ EXPERIMENT_LIST="
amvr amvr
lpf_sb lpf_sb
opt_ref_mv opt_ref_mv
restrict_compressed_hdr
" "
CONFIG_LIST=" CONFIG_LIST="
dependency_tracking dependency_tracking
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment