summaryrefslogtreecommitdiffstats
path: root/third_party/aom/av1/decoder
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/aom/av1/decoder')
-rw-r--r--third_party/aom/av1/decoder/accounting.h6
-rw-r--r--third_party/aom/av1/decoder/decodeframe.c555
-rw-r--r--third_party/aom/av1/decoder/decodeframe.h8
-rw-r--r--third_party/aom/av1/decoder/decodemv.c179
-rw-r--r--third_party/aom/av1/decoder/decodemv.h6
-rw-r--r--third_party/aom/av1/decoder/decoder.c21
-rw-r--r--third_party/aom/av1/decoder/decoder.h12
-rw-r--r--third_party/aom/av1/decoder/decodetxb.h6
-rw-r--r--third_party/aom/av1/decoder/detokenize.h6
-rw-r--r--third_party/aom/av1/decoder/dthread.h6
-rw-r--r--third_party/aom/av1/decoder/inspection.h6
-rw-r--r--third_party/aom/av1/decoder/obu.c176
-rw-r--r--third_party/aom/av1/decoder/obu.h29
13 files changed, 556 insertions, 460 deletions
diff --git a/third_party/aom/av1/decoder/accounting.h b/third_party/aom/av1/decoder/accounting.h
index 9099d081b..288e5e63e 100644
--- a/third_party/aom/av1/decoder/accounting.h
+++ b/third_party/aom/av1/decoder/accounting.h
@@ -8,8 +8,8 @@
* Media Patent License 1.0 was not distributed with this source code in the
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
*/
-#ifndef AOM_ACCOUNTING_H_
-#define AOM_ACCOUNTING_H_
+#ifndef AOM_AV1_DECODER_ACCOUNTING_H_
+#define AOM_AV1_DECODER_ACCOUNTING_H_
#include <stdlib.h>
#include "aom/aomdx.h"
@@ -79,4 +79,4 @@ void aom_accounting_dump(Accounting *accounting);
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus
-#endif // AOM_ACCOUNTING_H_
+#endif // AOM_AV1_DECODER_ACCOUNTING_H_
diff --git a/third_party/aom/av1/decoder/decodeframe.c b/third_party/aom/av1/decoder/decodeframe.c
index 6dbc4f3eb..31f14b531 100644
--- a/third_party/aom/av1/decoder/decodeframe.c
+++ b/third_party/aom/av1/decoder/decodeframe.c
@@ -43,6 +43,7 @@
#include "av1/common/entropy.h"
#include "av1/common/entropymode.h"
#include "av1/common/entropymv.h"
+#include "av1/common/frame_buffers.h"
#include "av1/common/idct.h"
#include "av1/common/mvref_common.h"
#include "av1/common/pred_common.h"
@@ -87,18 +88,25 @@ int av1_check_trailing_bits(AV1Decoder *pbi, struct aom_read_bit_buffer *rb) {
static void set_planes_to_neutral_grey(const SequenceHeader *const seq_params,
const YV12_BUFFER_CONFIG *const buf,
int only_chroma) {
- const int val = 1 << (seq_params->bit_depth - 1);
-
- for (int plane = only_chroma; plane < MAX_MB_PLANE; plane++) {
- const int is_uv = plane > 0;
- for (int row_idx = 0; row_idx < buf->crop_heights[is_uv]; row_idx++) {
- if (seq_params->use_highbitdepth) {
- // TODO(yaowu): replace this with aom_memset16() for speed
- for (int col_idx = 0; col_idx < buf->crop_widths[is_uv]; col_idx++) {
- uint16_t *base = CONVERT_TO_SHORTPTR(buf->buffers[plane]);
- base[row_idx * buf->strides[is_uv] + col_idx] = val;
+ if (seq_params->use_highbitdepth) {
+ const int val = 1 << (seq_params->bit_depth - 1);
+ for (int plane = only_chroma; plane < MAX_MB_PLANE; plane++) {
+ const int is_uv = plane > 0;
+ uint16_t *const base = CONVERT_TO_SHORTPTR(buf->buffers[plane]);
+ // Set the first row to neutral grey. Then copy the first row to all
+ // subsequent rows.
+ if (buf->crop_heights[is_uv] > 0) {
+ aom_memset16(base, val, buf->crop_widths[is_uv]);
+ for (int row_idx = 1; row_idx < buf->crop_heights[is_uv]; row_idx++) {
+ memcpy(&base[row_idx * buf->strides[is_uv]], base,
+ sizeof(*base) * buf->crop_widths[is_uv]);
}
- } else {
+ }
+ }
+ } else {
+ for (int plane = only_chroma; plane < MAX_MB_PLANE; plane++) {
+ const int is_uv = plane > 0;
+ for (int row_idx = 0; row_idx < buf->crop_heights[is_uv]; row_idx++) {
memset(&buf->buffers[plane][row_idx * buf->uv_stride], 1 << 7,
buf->crop_widths[is_uv]);
}
@@ -687,11 +695,10 @@ static INLINE void dec_build_inter_predictors(const AV1_COMMON *cm,
for (int x = 0; x < b8_w; x += b4_w) {
MB_MODE_INFO *this_mbmi = xd->mi[row * xd->mi_stride + col];
is_compound = has_second_ref(this_mbmi);
- DECLARE_ALIGNED(32, CONV_BUF_TYPE, tmp_dst[8 * 8]);
int tmp_dst_stride = 8;
assert(bw < 8 || bh < 8);
ConvolveParams conv_params = get_conv_params_no_round(
- 0, 0, plane, tmp_dst, tmp_dst_stride, is_compound, xd->bd);
+ 0, plane, xd->tmp_conv_dst, tmp_dst_stride, is_compound, xd->bd);
conv_params.use_jnt_comp_avg = 0;
struct buf_2d *const dst_buf = &pd->dst;
uint8_t *dst = dst_buf->buf + dst_buf->stride * y + x;
@@ -735,7 +742,6 @@ static INLINE void dec_build_inter_predictors(const AV1_COMMON *cm,
extend_mc_border(sf, pre_buf, scaled_mv, block, subpel_x_mv,
subpel_y_mv, 0, is_intrabc, highbd, xd->mc_buf[ref],
&pre, &src_stride);
- conv_params.ref = ref;
conv_params.do_average = ref;
if (is_masked_compound_type(mi->interinter_comp.type)) {
// masked compound type has its own average mechanism
@@ -762,7 +768,6 @@ static INLINE void dec_build_inter_predictors(const AV1_COMMON *cm,
uint8_t *const dst = dst_buf->buf;
uint8_t *pre[2];
SubpelParams subpel_params[2];
- DECLARE_ALIGNED(32, uint16_t, tmp_dst[MAX_SB_SIZE * MAX_SB_SIZE]);
int src_stride[2];
for (ref = 0; ref < 1 + is_compound; ++ref) {
const struct scale_factors *const sf =
@@ -797,7 +802,7 @@ static INLINE void dec_build_inter_predictors(const AV1_COMMON *cm,
}
ConvolveParams conv_params = get_conv_params_no_round(
- 0, 0, plane, tmp_dst, MAX_SB_SIZE, is_compound, xd->bd);
+ 0, plane, xd->tmp_conv_dst, MAX_SB_SIZE, is_compound, xd->bd);
av1_jnt_comp_weight_assign(cm, mi, 0, &conv_params.fwd_offset,
&conv_params.bck_offset,
&conv_params.use_jnt_comp_avg, is_compound);
@@ -808,7 +813,6 @@ static INLINE void dec_build_inter_predictors(const AV1_COMMON *cm,
WarpTypesAllowed warp_types;
warp_types.global_warp_allowed = is_global[ref];
warp_types.local_warp_allowed = mi->motion_mode == WARPED_CAUSAL;
- conv_params.ref = ref;
conv_params.do_average = ref;
if (is_masked_compound_type(mi->interinter_comp.type)) {
// masked compound type has its own average mechanism
@@ -931,7 +935,7 @@ static void dec_build_prediction_by_above_preds(
// Adjust mb_to_bottom_edge to have the correct value for the OBMC
// prediction block. This is half the height of the original block,
// except for 128-wide blocks, where we only use a height of 32.
- int this_height = xd->n8_h * MI_SIZE;
+ int this_height = xd->n4_h * MI_SIZE;
int pred_height = AOMMIN(this_height / 2, 32);
xd->mb_to_bottom_edge += (this_height - pred_height) * 8;
@@ -984,7 +988,7 @@ static void dec_build_prediction_by_left_preds(
// Adjust mb_to_right_edge to have the correct value for the OBMC
// prediction block. This is half the width of the original block,
// except for 128-wide blocks, where we only use a width of 32.
- int this_width = xd->n8_w * MI_SIZE;
+ int this_width = xd->n4_w * MI_SIZE;
int pred_width = AOMMIN(this_width / 2, 32);
xd->mb_to_right_edge += (this_width - pred_width) * 8;
@@ -1006,8 +1010,6 @@ static void dec_build_obmc_inter_predictors_sb(const AV1_COMMON *cm,
MACROBLOCKD *xd, int mi_row,
int mi_col) {
const int num_planes = av1_num_planes(cm);
- DECLARE_ALIGNED(16, uint8_t, tmp_buf1[2 * MAX_MB_PLANE * MAX_SB_SQUARE]);
- DECLARE_ALIGNED(16, uint8_t, tmp_buf2[2 * MAX_MB_PLANE * MAX_SB_SQUARE]);
uint8_t *dst_buf1[MAX_MB_PLANE], *dst_buf2[MAX_MB_PLANE];
int dst_stride1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
int dst_stride2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
@@ -1018,19 +1020,23 @@ static void dec_build_obmc_inter_predictors_sb(const AV1_COMMON *cm,
if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
int len = sizeof(uint16_t);
- dst_buf1[0] = CONVERT_TO_BYTEPTR(tmp_buf1);
- dst_buf1[1] = CONVERT_TO_BYTEPTR(tmp_buf1 + MAX_SB_SQUARE * len);
- dst_buf1[2] = CONVERT_TO_BYTEPTR(tmp_buf1 + MAX_SB_SQUARE * 2 * len);
- dst_buf2[0] = CONVERT_TO_BYTEPTR(tmp_buf2);
- dst_buf2[1] = CONVERT_TO_BYTEPTR(tmp_buf2 + MAX_SB_SQUARE * len);
- dst_buf2[2] = CONVERT_TO_BYTEPTR(tmp_buf2 + MAX_SB_SQUARE * 2 * len);
+ dst_buf1[0] = CONVERT_TO_BYTEPTR(xd->tmp_obmc_bufs[0]);
+ dst_buf1[1] =
+ CONVERT_TO_BYTEPTR(xd->tmp_obmc_bufs[0] + MAX_SB_SQUARE * len);
+ dst_buf1[2] =
+ CONVERT_TO_BYTEPTR(xd->tmp_obmc_bufs[0] + MAX_SB_SQUARE * 2 * len);
+ dst_buf2[0] = CONVERT_TO_BYTEPTR(xd->tmp_obmc_bufs[1]);
+ dst_buf2[1] =
+ CONVERT_TO_BYTEPTR(xd->tmp_obmc_bufs[1] + MAX_SB_SQUARE * len);
+ dst_buf2[2] =
+ CONVERT_TO_BYTEPTR(xd->tmp_obmc_bufs[1] + MAX_SB_SQUARE * 2 * len);
} else {
- dst_buf1[0] = tmp_buf1;
- dst_buf1[1] = tmp_buf1 + MAX_SB_SQUARE;
- dst_buf1[2] = tmp_buf1 + MAX_SB_SQUARE * 2;
- dst_buf2[0] = tmp_buf2;
- dst_buf2[1] = tmp_buf2 + MAX_SB_SQUARE;
- dst_buf2[2] = tmp_buf2 + MAX_SB_SQUARE * 2;
+ dst_buf1[0] = xd->tmp_obmc_bufs[0];
+ dst_buf1[1] = xd->tmp_obmc_bufs[0] + MAX_SB_SQUARE;
+ dst_buf1[2] = xd->tmp_obmc_bufs[0] + MAX_SB_SQUARE * 2;
+ dst_buf2[0] = xd->tmp_obmc_bufs[1];
+ dst_buf2[1] = xd->tmp_obmc_bufs[1] + MAX_SB_SQUARE;
+ dst_buf2[2] = xd->tmp_obmc_bufs[1] + MAX_SB_SQUARE * 2;
}
dec_build_prediction_by_above_preds(cm, xd, mi_row, mi_col, dst_buf1,
dst_width1, dst_height1, dst_stride1);
@@ -1069,8 +1075,9 @@ static void predict_inter_block(AV1_COMMON *const cm, MACROBLOCKD *const xd,
}
dec_build_inter_predictors_sb(cm, xd, mi_row, mi_col, NULL, bsize);
- if (mbmi->motion_mode == OBMC_CAUSAL)
+ if (mbmi->motion_mode == OBMC_CAUSAL) {
dec_build_obmc_inter_predictors_sb(cm, xd, mi_row, mi_col);
+ }
#if CONFIG_MISMATCH_DEBUG
for (int plane = 0; plane < num_planes; ++plane) {
const struct macroblockd_plane *pd = &xd->plane[plane];
@@ -1225,9 +1232,18 @@ static void decode_token_recon_block(AV1Decoder *const pbi,
set_color_index_map_offset);
}
+#if LOOP_FILTER_BITMASK
+static void store_bitmask_vartx(AV1_COMMON *cm, int mi_row, int mi_col,
+ BLOCK_SIZE bsize, TX_SIZE tx_size,
+ MB_MODE_INFO *mbmi);
+#endif
+
static void read_tx_size_vartx(MACROBLOCKD *xd, MB_MODE_INFO *mbmi,
- TX_SIZE tx_size, int depth, int blk_row,
- int blk_col, aom_reader *r) {
+ TX_SIZE tx_size, int depth,
+#if LOOP_FILTER_BITMASK
+ AV1_COMMON *cm, int mi_row, int mi_col,
+#endif
+ int blk_row, int blk_col, aom_reader *r) {
FRAME_CONTEXT *ec_ctx = xd->tile_ctx;
int is_split = 0;
const BLOCK_SIZE bsize = mbmi->sb_type;
@@ -1271,15 +1287,29 @@ static void read_tx_size_vartx(MACROBLOCKD *xd, MB_MODE_INFO *mbmi,
mbmi->tx_size = sub_txs;
txfm_partition_update(xd->above_txfm_context + blk_col,
xd->left_txfm_context + blk_row, sub_txs, tx_size);
+#if LOOP_FILTER_BITMASK
+ store_bitmask_vartx(cm, mi_row + blk_row, mi_col + blk_col, BLOCK_8X8,
+ TX_4X4, mbmi);
+#endif
return;
}
+#if LOOP_FILTER_BITMASK
+ if (depth + 1 == MAX_VARTX_DEPTH) {
+ store_bitmask_vartx(cm, mi_row + blk_row, mi_col + blk_col,
+ txsize_to_bsize[tx_size], sub_txs, mbmi);
+ }
+#endif
assert(bsw > 0 && bsh > 0);
for (int row = 0; row < tx_size_high_unit[tx_size]; row += bsh) {
for (int col = 0; col < tx_size_wide_unit[tx_size]; col += bsw) {
int offsetr = blk_row + row;
int offsetc = blk_col + col;
- read_tx_size_vartx(xd, mbmi, sub_txs, depth + 1, offsetr, offsetc, r);
+ read_tx_size_vartx(xd, mbmi, sub_txs, depth + 1,
+#if LOOP_FILTER_BITMASK
+ cm, mi_row, mi_col,
+#endif
+ offsetr, offsetc, r);
}
}
} else {
@@ -1293,6 +1323,10 @@ static void read_tx_size_vartx(MACROBLOCKD *xd, MB_MODE_INFO *mbmi,
mbmi->tx_size = tx_size;
txfm_partition_update(xd->above_txfm_context + blk_col,
xd->left_txfm_context + blk_row, tx_size, tx_size);
+#if LOOP_FILTER_BITMASK
+ store_bitmask_vartx(cm, mi_row + blk_row, mi_col + blk_col,
+ txsize_to_bsize[tx_size], tx_size, mbmi);
+#endif
}
}
@@ -1330,6 +1364,191 @@ static TX_SIZE read_tx_size(AV1_COMMON *cm, MACROBLOCKD *xd, int is_inter,
}
}
+#if LOOP_FILTER_BITMASK
+static void store_bitmask_vartx(AV1_COMMON *cm, int mi_row, int mi_col,
+ BLOCK_SIZE bsize, TX_SIZE tx_size,
+ MB_MODE_INFO *mbmi) {
+ LoopFilterMask *lfm = get_loop_filter_mask(cm, mi_row, mi_col);
+ const TX_SIZE tx_size_y_vert = txsize_vert_map[tx_size];
+ const TX_SIZE tx_size_y_horz = txsize_horz_map[tx_size];
+ const TX_SIZE tx_size_uv_vert = txsize_vert_map[av1_get_max_uv_txsize(
+ mbmi->sb_type, cm->seq_params.subsampling_x,
+ cm->seq_params.subsampling_y)];
+ const TX_SIZE tx_size_uv_horz = txsize_horz_map[av1_get_max_uv_txsize(
+ mbmi->sb_type, cm->seq_params.subsampling_x,
+ cm->seq_params.subsampling_y)];
+ const int is_square_transform_size = tx_size <= TX_64X64;
+ int mask_id = 0;
+ int offset = 0;
+ const int half_ratio_tx_size_max32 =
+ (tx_size > TX_64X64) & (tx_size <= TX_32X16);
+ if (is_square_transform_size) {
+ switch (tx_size) {
+ case TX_4X4: mask_id = mask_id_table_tx_4x4[bsize]; break;
+ case TX_8X8:
+ mask_id = mask_id_table_tx_8x8[bsize];
+ offset = 19;
+ break;
+ case TX_16X16:
+ mask_id = mask_id_table_tx_16x16[bsize];
+ offset = 33;
+ break;
+ case TX_32X32:
+ mask_id = mask_id_table_tx_32x32[bsize];
+ offset = 42;
+ break;
+ case TX_64X64: mask_id = 46; break;
+ default: assert(!is_square_transform_size); return;
+ }
+ mask_id += offset;
+ } else if (half_ratio_tx_size_max32) {
+ int tx_size_equal_block_size = bsize == txsize_to_bsize[tx_size];
+ mask_id = 47 + 2 * (tx_size - TX_4X8) + (tx_size_equal_block_size ? 0 : 1);
+ } else if (tx_size == TX_32X64) {
+ mask_id = 59;
+ } else if (tx_size == TX_64X32) {
+ mask_id = 60;
+ } else { // quarter ratio tx size
+ mask_id = 61 + (tx_size - TX_4X16);
+ }
+ int index = 0;
+ const int row = mi_row % MI_SIZE_64X64;
+ const int col = mi_col % MI_SIZE_64X64;
+ const int shift = get_index_shift(col, row, &index);
+ const int vert_shift = tx_size_y_vert <= TX_8X8 ? shift : col;
+ for (int i = 0; i + index < 4; ++i) {
+ // y vertical.
+ lfm->tx_size_ver[0][tx_size_y_horz].bits[i + index] |=
+ (left_mask_univariant_reordered[mask_id].bits[i] << vert_shift);
+ // y horizontal.
+ lfm->tx_size_hor[0][tx_size_y_vert].bits[i + index] |=
+ (above_mask_univariant_reordered[mask_id].bits[i] << shift);
+ // u/v vertical.
+ lfm->tx_size_ver[1][tx_size_uv_horz].bits[i + index] |=
+ (left_mask_univariant_reordered[mask_id].bits[i] << vert_shift);
+ // u/v horizontal.
+ lfm->tx_size_hor[1][tx_size_uv_vert].bits[i + index] |=
+ (above_mask_univariant_reordered[mask_id].bits[i] << shift);
+ }
+}
+
+static void store_bitmask_univariant_tx(AV1_COMMON *cm, int mi_row, int mi_col,
+ BLOCK_SIZE bsize, MB_MODE_INFO *mbmi) {
+ // Use a lookup table that provides one bitmask for a given block size and
+ // a univariant transform size.
+ int index;
+ int shift;
+ int row;
+ int col;
+ LoopFilterMask *lfm = get_loop_filter_mask(cm, mi_row, mi_col);
+ const TX_SIZE tx_size_y_vert = txsize_vert_map[mbmi->tx_size];
+ const TX_SIZE tx_size_y_horz = txsize_horz_map[mbmi->tx_size];
+ const TX_SIZE tx_size_uv_vert = txsize_vert_map[av1_get_max_uv_txsize(
+ mbmi->sb_type, cm->seq_params.subsampling_x,
+ cm->seq_params.subsampling_y)];
+ const TX_SIZE tx_size_uv_horz = txsize_horz_map[av1_get_max_uv_txsize(
+ mbmi->sb_type, cm->seq_params.subsampling_x,
+ cm->seq_params.subsampling_y)];
+ const int is_square_transform_size = mbmi->tx_size <= TX_64X64;
+ int mask_id = 0;
+ int offset = 0;
+ const int half_ratio_tx_size_max32 =
+ (mbmi->tx_size > TX_64X64) & (mbmi->tx_size <= TX_32X16);
+ if (is_square_transform_size) {
+ switch (mbmi->tx_size) {
+ case TX_4X4: mask_id = mask_id_table_tx_4x4[bsize]; break;
+ case TX_8X8:
+ mask_id = mask_id_table_tx_8x8[bsize];
+ offset = 19;
+ break;
+ case TX_16X16:
+ mask_id = mask_id_table_tx_16x16[bsize];
+ offset = 33;
+ break;
+ case TX_32X32:
+ mask_id = mask_id_table_tx_32x32[bsize];
+ offset = 42;
+ break;
+ case TX_64X64: mask_id = 46; break;
+ default: assert(!is_square_transform_size); return;
+ }
+ mask_id += offset;
+ } else if (half_ratio_tx_size_max32) {
+ int tx_size_equal_block_size = bsize == txsize_to_bsize[mbmi->tx_size];
+ mask_id =
+ 47 + 2 * (mbmi->tx_size - TX_4X8) + (tx_size_equal_block_size ? 0 : 1);
+ } else if (mbmi->tx_size == TX_32X64) {
+ mask_id = 59;
+ } else if (mbmi->tx_size == TX_64X32) {
+ mask_id = 60;
+ } else { // quarter ratio tx size
+ mask_id = 61 + (mbmi->tx_size - TX_4X16);
+ }
+ row = mi_row % MI_SIZE_64X64;
+ col = mi_col % MI_SIZE_64X64;
+ shift = get_index_shift(col, row, &index);
+ const int vert_shift = tx_size_y_vert <= TX_8X8 ? shift : col;
+ for (int i = 0; i + index < 4; ++i) {
+ // y vertical.
+ lfm->tx_size_ver[0][tx_size_y_horz].bits[i + index] |=
+ (left_mask_univariant_reordered[mask_id].bits[i] << vert_shift);
+ // y horizontal.
+ lfm->tx_size_hor[0][tx_size_y_vert].bits[i + index] |=
+ (above_mask_univariant_reordered[mask_id].bits[i] << shift);
+ // u/v vertical.
+ lfm->tx_size_ver[1][tx_size_uv_horz].bits[i + index] |=
+ (left_mask_univariant_reordered[mask_id].bits[i] << vert_shift);
+ // u/v horizontal.
+ lfm->tx_size_hor[1][tx_size_uv_vert].bits[i + index] |=
+ (above_mask_univariant_reordered[mask_id].bits[i] << shift);
+ }
+}
+
+static void store_bitmask_other_info(AV1_COMMON *cm, int mi_row, int mi_col,
+ BLOCK_SIZE bsize, MB_MODE_INFO *mbmi) {
+ int index;
+ int shift;
+ int row;
+ LoopFilterMask *lfm = get_loop_filter_mask(cm, mi_row, mi_col);
+ const int row_start = mi_row % MI_SIZE_64X64;
+ const int col_start = mi_col % MI_SIZE_64X64;
+ shift = get_index_shift(col_start, row_start, &index);
+ const uint64_t top_edge_mask =
+ ((uint64_t)1 << (shift + mi_size_wide[bsize])) - ((uint64_t)1 << shift);
+ lfm->is_horz_border.bits[index] |= top_edge_mask;
+ const int is_vert_border = mask_id_table_vert_border[bsize];
+ const int vert_shift = block_size_high[bsize] <= 8 ? shift : col_start;
+ for (int i = 0; i + index < 4; ++i) {
+ lfm->is_vert_border.bits[i + index] |=
+ (left_mask_univariant_reordered[is_vert_border].bits[i] << vert_shift);
+ }
+ const int is_skip = mbmi->skip && is_inter_block(mbmi);
+ if (is_skip) {
+ const int is_skip_mask = mask_id_table_tx_4x4[bsize];
+ for (int i = 0; i + index < 4; ++i) {
+ lfm->skip.bits[i + index] |=
+ (above_mask_univariant_reordered[is_skip_mask].bits[i] << shift);
+ }
+ }
+ const uint8_t level_vert_y = get_filter_level(cm, &cm->lf_info, 0, 0, mbmi);
+ const uint8_t level_horz_y = get_filter_level(cm, &cm->lf_info, 1, 0, mbmi);
+ const uint8_t level_u = get_filter_level(cm, &cm->lf_info, 0, 1, mbmi);
+ const uint8_t level_v = get_filter_level(cm, &cm->lf_info, 0, 2, mbmi);
+ for (int r = mi_row; r < mi_row + mi_size_high[bsize]; r++) {
+ index = 0;
+ row = r % MI_SIZE_64X64;
+ memset(&lfm->lfl_y_ver[row][col_start], level_vert_y,
+ sizeof(uint8_t) * mi_size_wide[bsize]);
+ memset(&lfm->lfl_y_hor[row][col_start], level_horz_y,
+ sizeof(uint8_t) * mi_size_wide[bsize]);
+ memset(&lfm->lfl_u[row][col_start], level_u,
+ sizeof(uint8_t) * mi_size_wide[bsize]);
+ memset(&lfm->lfl_v[row][col_start], level_v,
+ sizeof(uint8_t) * mi_size_wide[bsize]);
+ }
+}
+#endif
+
static void parse_decode_block(AV1Decoder *const pbi, ThreadData *const td,
int mi_row, int mi_col, aom_reader *r,
PARTITION_TYPE partition, BLOCK_SIZE bsize) {
@@ -1353,14 +1572,46 @@ static void parse_decode_block(AV1Decoder *const pbi, ThreadData *const td,
for (int idy = 0; idy < height; idy += bh)
for (int idx = 0; idx < width; idx += bw)
- read_tx_size_vartx(xd, mbmi, max_tx_size, 0, idy, idx, r);
+ read_tx_size_vartx(xd, mbmi, max_tx_size, 0,
+#if LOOP_FILTER_BITMASK
+ cm, mi_row, mi_col,
+#endif
+ idy, idx, r);
} else {
mbmi->tx_size = read_tx_size(cm, xd, inter_block_tx, !mbmi->skip, r);
if (inter_block_tx)
memset(mbmi->inter_tx_size, mbmi->tx_size, sizeof(mbmi->inter_tx_size));
- set_txfm_ctxs(mbmi->tx_size, xd->n8_w, xd->n8_h,
+ set_txfm_ctxs(mbmi->tx_size, xd->n4_w, xd->n4_h,
mbmi->skip && is_inter_block(mbmi), xd);
+#if LOOP_FILTER_BITMASK
+ const int w = mi_size_wide[bsize];
+ const int h = mi_size_high[bsize];
+ if (w <= mi_size_wide[BLOCK_64X64] && h <= mi_size_high[BLOCK_64X64]) {
+ store_bitmask_univariant_tx(cm, mi_row, mi_col, bsize, mbmi);
+ } else {
+ for (int row = 0; row < h; row += mi_size_high[BLOCK_64X64]) {
+ for (int col = 0; col < w; col += mi_size_wide[BLOCK_64X64]) {
+ store_bitmask_univariant_tx(cm, mi_row + row, mi_col + col,
+ BLOCK_64X64, mbmi);
+ }
+ }
+ }
+#endif
+ }
+#if LOOP_FILTER_BITMASK
+ const int w = mi_size_wide[bsize];
+ const int h = mi_size_high[bsize];
+ if (w <= mi_size_wide[BLOCK_64X64] && h <= mi_size_high[BLOCK_64X64]) {
+ store_bitmask_other_info(cm, mi_row, mi_col, bsize, mbmi);
+ } else {
+ for (int row = 0; row < h; row += mi_size_high[BLOCK_64X64]) {
+ for (int col = 0; col < w; col += mi_size_wide[BLOCK_64X64]) {
+ store_bitmask_other_info(cm, mi_row + row, mi_col + col, BLOCK_64X64,
+ mbmi);
+ }
+ }
}
+#endif
if (cm->delta_q_present_flag) {
for (int i = 0; i < MAX_SEGMENTS; i++) {
@@ -1952,6 +2203,11 @@ static void setup_quantization(AV1_COMMON *const cm,
cm->v_dc_delta_q = cm->u_dc_delta_q;
cm->v_ac_delta_q = cm->u_ac_delta_q;
}
+ } else {
+ cm->u_dc_delta_q = 0;
+ cm->u_ac_delta_q = 0;
+ cm->v_dc_delta_q = 0;
+ cm->v_ac_delta_q = 0;
}
cm->dequant_bit_depth = seq_params->bit_depth;
cm->using_qmatrix = aom_rb_read_bit(rb);
@@ -2082,29 +2338,9 @@ static void resize_context_buffers(AV1_COMMON *cm, int width, int height) {
cm->cur_frame->height = cm->height;
}
-static void setup_frame_size(AV1_COMMON *cm, int frame_size_override_flag,
- struct aom_read_bit_buffer *rb) {
- const SequenceHeader *const seq_params = &cm->seq_params;
- int width, height;
+static void setup_buffer_pool(AV1_COMMON *cm) {
BufferPool *const pool = cm->buffer_pool;
-
- if (frame_size_override_flag) {
- int num_bits_width = seq_params->num_bits_width;
- int num_bits_height = seq_params->num_bits_height;
- av1_read_frame_size(rb, num_bits_width, num_bits_height, &width, &height);
- if (width > seq_params->max_frame_width ||
- height > seq_params->max_frame_height) {
- aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME,
- "Frame dimensions are larger than the maximum values");
- }
- } else {
- width = seq_params->max_frame_width;
- height = seq_params->max_frame_height;
- }
-
- setup_superres(cm, rb, &width, &height);
- resize_context_buffers(cm, width, height);
- setup_render_size(cm, rb);
+ const SequenceHeader *const seq_params = &cm->seq_params;
lock_buffer_pool(pool);
if (aom_realloc_frame_buffer(
@@ -2140,6 +2376,31 @@ static void setup_frame_size(AV1_COMMON *cm, int frame_size_override_flag,
pool->frame_bufs[cm->new_fb_idx].buf.render_height = cm->render_height;
}
+static void setup_frame_size(AV1_COMMON *cm, int frame_size_override_flag,
+ struct aom_read_bit_buffer *rb) {
+ const SequenceHeader *const seq_params = &cm->seq_params;
+ int width, height;
+
+ if (frame_size_override_flag) {
+ int num_bits_width = seq_params->num_bits_width;
+ int num_bits_height = seq_params->num_bits_height;
+ av1_read_frame_size(rb, num_bits_width, num_bits_height, &width, &height);
+ if (width > seq_params->max_frame_width ||
+ height > seq_params->max_frame_height) {
+ aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME,
+ "Frame dimensions are larger than the maximum values");
+ }
+ } else {
+ width = seq_params->max_frame_width;
+ height = seq_params->max_frame_height;
+ }
+
+ setup_superres(cm, rb, &width, &height);
+ resize_context_buffers(cm, width, height);
+ setup_render_size(cm, rb);
+ setup_buffer_pool(cm);
+}
+
static void setup_sb_size(SequenceHeader *seq_params,
struct aom_read_bit_buffer *rb) {
set_sb_size(seq_params, aom_rb_read_bit(rb) ? BLOCK_128X128 : BLOCK_64X64);
@@ -2158,7 +2419,6 @@ static void setup_frame_size_with_refs(AV1_COMMON *cm,
int width, height;
int found = 0;
int has_valid_ref_frame = 0;
- BufferPool *const pool = cm->buffer_pool;
for (int i = 0; i < INTER_REFS_PER_FRAME; ++i) {
if (aom_rb_read_bit(rb)) {
YV12_BUFFER_CONFIG *const buf = cm->frame_refs[i].buf;
@@ -2208,39 +2468,7 @@ static void setup_frame_size_with_refs(AV1_COMMON *cm,
aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME,
"Referenced frame has incompatible color format");
}
-
- lock_buffer_pool(pool);
- if (aom_realloc_frame_buffer(
- get_frame_new_buffer(cm), cm->width, cm->height,
- seq_params->subsampling_x, seq_params->subsampling_y,
- seq_params->use_highbitdepth, AOM_BORDER_IN_PIXELS,
- cm->byte_alignment,
- &pool->frame_bufs[cm->new_fb_idx].raw_frame_buffer, pool->get_fb_cb,
- pool->cb_priv)) {
- unlock_buffer_pool(pool);
- aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
- "Failed to allocate frame buffer");
- }
- unlock_buffer_pool(pool);
-
- pool->frame_bufs[cm->new_fb_idx].buf.subsampling_x =
- seq_params->subsampling_x;
- pool->frame_bufs[cm->new_fb_idx].buf.subsampling_y =
- seq_params->subsampling_y;
- pool->frame_bufs[cm->new_fb_idx].buf.bit_depth =
- (unsigned int)seq_params->bit_depth;
- pool->frame_bufs[cm->new_fb_idx].buf.color_primaries =
- seq_params->color_primaries;
- pool->frame_bufs[cm->new_fb_idx].buf.transfer_characteristics =
- seq_params->transfer_characteristics;
- pool->frame_bufs[cm->new_fb_idx].buf.matrix_coefficients =
- seq_params->matrix_coefficients;
- pool->frame_bufs[cm->new_fb_idx].buf.monochrome = seq_params->monochrome;
- pool->frame_bufs[cm->new_fb_idx].buf.chroma_sample_position =
- seq_params->chroma_sample_position;
- pool->frame_bufs[cm->new_fb_idx].buf.color_range = seq_params->color_range;
- pool->frame_bufs[cm->new_fb_idx].buf.render_width = cm->render_width;
- pool->frame_bufs[cm->new_fb_idx].buf.render_height = cm->render_height;
+ setup_buffer_pool(cm);
}
// Same function as av1_read_uniform but reading from uncompresses header wb
@@ -2252,7 +2480,7 @@ static int rb_read_uniform(struct aom_read_bit_buffer *const rb, int n) {
if (v < m)
return v;
else
- return (v << 1) - m + aom_rb_read_literal(rb, 1);
+ return (v << 1) - m + aom_rb_read_bit(rb);
}
static void read_tile_info_max_tile(AV1_COMMON *const cm,
@@ -2344,6 +2572,10 @@ static void read_tile_info(AV1Decoder *const pbi,
// tile to use for cdf update
cm->context_update_tile_id =
aom_rb_read_literal(rb, cm->log2_tile_rows + cm->log2_tile_cols);
+ if (cm->context_update_tile_id >= cm->tile_rows * cm->tile_cols) {
+ aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME,
+ "Invalid context_update_tile_id");
+ }
// tile size magnitude
pbi->tile_size_bytes = aom_rb_read_literal(rb, 2) + 1;
}
@@ -2746,31 +2978,13 @@ static INLINE void sync_write(AV1DecRowMTSync *const dec_row_mt_sync, int r,
#endif // CONFIG_MULTITHREAD
}
-static INLINE int get_sb_rows_in_tile(AV1Decoder *pbi, TileInfo tile) {
- AV1_COMMON *cm = &pbi->common;
- int mi_rows_aligned_to_sb = ALIGN_POWER_OF_TWO(
- tile.mi_row_end - tile.mi_row_start, cm->seq_params.mib_size_log2);
- int sb_rows = mi_rows_aligned_to_sb >> cm->seq_params.mib_size_log2;
-
- return sb_rows;
-}
-
-static INLINE int get_sb_cols_in_tile(AV1Decoder *pbi, TileInfo tile) {
- AV1_COMMON *cm = &pbi->common;
- int mi_cols_aligned_to_sb = ALIGN_POWER_OF_TWO(
- tile.mi_col_end - tile.mi_col_start, cm->seq_params.mib_size_log2);
- int sb_cols = mi_cols_aligned_to_sb >> cm->seq_params.mib_size_log2;
-
- return sb_cols;
-}
-
static void decode_tile_sb_row(AV1Decoder *pbi, ThreadData *const td,
TileInfo tile_info, const int mi_row) {
AV1_COMMON *const cm = &pbi->common;
const int num_planes = av1_num_planes(cm);
TileDataDec *const tile_data =
pbi->tile_data + tile_info.tile_row * cm->tile_cols + tile_info.tile_col;
- const int sb_cols_in_tile = get_sb_cols_in_tile(pbi, tile_info);
+ const int sb_cols_in_tile = av1_get_sb_cols_in_tile(cm, tile_info);
const int sb_row_in_tile =
(mi_row - tile_info.mi_row_start) >> cm->seq_params.mib_size_log2;
int sb_col_in_tile = 0;
@@ -2792,15 +3006,11 @@ static void decode_tile_sb_row(AV1Decoder *pbi, ThreadData *const td,
}
static int check_trailing_bits_after_symbol_coder(aom_reader *r) {
+ if (aom_reader_has_overflowed(r)) return -1;
+
uint32_t nb_bits = aom_reader_tell(r);
uint32_t nb_bytes = (nb_bits + 7) >> 3;
-
- const uint8_t *p_begin = aom_reader_find_begin(r);
- const uint8_t *p_end = aom_reader_find_end(r);
-
- // It is legal to have no padding bytes (nb_bytes == p_end - p_begin).
- if ((ptrdiff_t)nb_bytes > p_end - p_begin) return -1;
- const uint8_t *p = p_begin + nb_bytes;
+ const uint8_t *p = aom_reader_find_begin(r) + nb_bytes;
// aom_reader_tell() returns 1 for a newly initialized decoder, and the
// return value only increases as values are decoded. So nb_bits > 0, and
@@ -2810,6 +3020,7 @@ static int check_trailing_bits_after_symbol_coder(aom_reader *r) {
if ((last_byte & (2 * pattern - 1)) != pattern) return -1;
// Make sure that all padding bytes are zero as required by the spec.
+ const uint8_t *p_end = aom_reader_find_end(r);
while (p < p_end) {
if (*p != 0) return -1;
p++;
@@ -2863,6 +3074,11 @@ static void decode_tile(AV1Decoder *pbi, ThreadData *const td, int tile_row,
// Bit-stream parsing and decoding of the superblock
decode_partition(pbi, td, mi_row, mi_col, td->bit_reader,
cm->seq_params.sb_size, 0x3);
+
+ if (aom_reader_has_overflowed(td->bit_reader)) {
+ aom_merge_corrupted_flag(&td->xd.corrupted, 1);
+ return;
+ }
}
}
@@ -2950,6 +3166,11 @@ static const uint8_t *decode_tiles(AV1Decoder *pbi, const uint8_t *data,
td->xd.corrupted = 0;
td->xd.mc_buf[0] = td->mc_buf[0];
td->xd.mc_buf[1] = td->mc_buf[1];
+ td->xd.tmp_conv_dst = td->tmp_conv_dst;
+ for (int j = 0; j < 2; ++j) {
+ td->xd.tmp_obmc_bufs[j] = td->tmp_obmc_bufs[j];
+ }
+
for (tile_row = tile_rows_start; tile_row < tile_rows_end; ++tile_row) {
const int row = inv_row_order ? tile_rows - 1 - tile_row : tile_row;
@@ -3236,6 +3457,7 @@ static int row_mt_worker_hook(void *arg1, void *arg2) {
#endif
frame_row_mt_info->row_mt_exit = 1;
#if CONFIG_MULTITHREAD
+ pthread_cond_broadcast(pbi->row_mt_cond_);
pthread_mutex_unlock(pbi->row_mt_mutex_);
#endif
return 0;
@@ -3386,16 +3608,24 @@ static void alloc_dec_jobs(AV1DecTileMT *tile_mt_info, AV1_COMMON *cm,
aom_malloc(sizeof(*tile_mt_info->job_queue) * num_tiles));
}
-void av1_free_mc_tmp_buf(ThreadData *thread_data, int use_highbd) {
+void av1_free_mc_tmp_buf(ThreadData *thread_data) {
int ref;
for (ref = 0; ref < 2; ref++) {
- if (use_highbd)
+ if (thread_data->mc_buf_use_highbd)
aom_free(CONVERT_TO_SHORTPTR(thread_data->mc_buf[ref]));
else
aom_free(thread_data->mc_buf[ref]);
thread_data->mc_buf[ref] = NULL;
}
thread_data->mc_buf_size = 0;
+ thread_data->mc_buf_use_highbd = 0;
+
+ aom_free(thread_data->tmp_conv_dst);
+ thread_data->tmp_conv_dst = NULL;
+ for (int i = 0; i < 2; ++i) {
+ aom_free(thread_data->tmp_obmc_bufs[i]);
+ thread_data->tmp_obmc_bufs[i] = NULL;
+ }
}
static void allocate_mc_tmp_buf(AV1_COMMON *const cm, ThreadData *thread_data,
@@ -3411,6 +3641,17 @@ static void allocate_mc_tmp_buf(AV1_COMMON *const cm, ThreadData *thread_data,
}
}
thread_data->mc_buf_size = buf_size;
+ thread_data->mc_buf_use_highbd = use_highbd;
+
+ CHECK_MEM_ERROR(cm, thread_data->tmp_conv_dst,
+ aom_memalign(32, MAX_SB_SIZE * MAX_SB_SIZE *
+ sizeof(*thread_data->tmp_conv_dst)));
+ for (int i = 0; i < 2; ++i) {
+ CHECK_MEM_ERROR(
+ cm, thread_data->tmp_obmc_bufs[i],
+ aom_memalign(16, 2 * MAX_MB_PLANE * MAX_SB_SQUARE *
+ sizeof(*thread_data->tmp_obmc_bufs[i])));
+ }
}
static void reset_dec_workers(AV1Decoder *pbi, AVxWorkerHook worker_hook,
@@ -3425,6 +3666,10 @@ static void reset_dec_workers(AV1Decoder *pbi, AVxWorkerHook worker_hook,
thread_data->td->xd.corrupted = 0;
thread_data->td->xd.mc_buf[0] = thread_data->td->mc_buf[0];
thread_data->td->xd.mc_buf[1] = thread_data->td->mc_buf[1];
+ thread_data->td->xd.tmp_conv_dst = thread_data->td->tmp_conv_dst;
+ for (int j = 0; j < 2; ++j) {
+ thread_data->td->xd.tmp_obmc_bufs[j] = thread_data->td->tmp_obmc_bufs[j];
+ }
winterface->sync(worker);
worker->hook = worker_hook;
@@ -3511,7 +3756,7 @@ static void decode_mt_init(AV1Decoder *pbi) {
for (worker_idx = 0; worker_idx < pbi->max_threads - 1; ++worker_idx) {
DecWorkerData *const thread_data = pbi->thread_data + worker_idx;
if (thread_data->td->mc_buf_size != buf_size) {
- av1_free_mc_tmp_buf(thread_data->td, use_highbd);
+ av1_free_mc_tmp_buf(thread_data->td);
allocate_mc_tmp_buf(cm, thread_data->td, buf_size, use_highbd);
}
}
@@ -3783,8 +4028,8 @@ static const uint8_t *decode_tiles_row_mt(AV1Decoder *pbi, const uint8_t *data,
TileDataDec *tile_data = pbi->tile_data + row * cm->tile_cols + col;
av1_tile_init(&tile_data->tile_info, cm, row, col);
- max_sb_rows =
- AOMMAX(max_sb_rows, get_sb_rows_in_tile(pbi, tile_data->tile_info));
+ max_sb_rows = AOMMAX(max_sb_rows,
+ av1_get_sb_rows_in_tile(cm, tile_data->tile_info));
}
}
@@ -3905,6 +4150,8 @@ void av1_read_film_grain_params(AV1_COMMON *cm,
if (!seq_params->monochrome)
pars->chroma_scaling_from_luma = aom_rb_read_bit(rb);
+ else
+ pars->chroma_scaling_from_luma = 0;
if (seq_params->monochrome || pars->chroma_scaling_from_luma ||
((seq_params->subsampling_x == 1) && (seq_params->subsampling_y == 1) &&
@@ -4412,6 +4659,29 @@ static void show_existing_frame_reset(AV1Decoder *const pbi,
*cm->fc = cm->frame_contexts[existing_frame_idx];
}
+static INLINE void reset_frame_buffers(AV1_COMMON *cm) {
+ RefCntBuffer *const frame_bufs = cm->buffer_pool->frame_bufs;
+ int i;
+
+ memset(&cm->ref_frame_map, -1, sizeof(cm->ref_frame_map));
+ memset(&cm->next_ref_frame_map, -1, sizeof(cm->next_ref_frame_map));
+
+ lock_buffer_pool(cm->buffer_pool);
+ for (i = 0; i < FRAME_BUFFERS; ++i) {
+ if (i != cm->new_fb_idx) {
+ frame_bufs[i].ref_count = 0;
+ cm->buffer_pool->release_fb_cb(cm->buffer_pool->cb_priv,
+ &frame_bufs[i].raw_frame_buffer);
+ } else {
+ assert(frame_bufs[i].ref_count == 1);
+ }
+ frame_bufs[i].cur_frame_offset = 0;
+ av1_zero(frame_bufs[i].ref_frame_offset);
+ }
+ av1_zero_unused_internal_frame_buffers(&cm->buffer_pool->int_frame_buffers);
+ unlock_buffer_pool(cm->buffer_pool);
+}
+
// On success, returns 0. On failure, calls aom_internal_error and does not
// return.
static int read_uncompressed_header(AV1Decoder *pbi,
@@ -4443,6 +4713,11 @@ static int read_uncompressed_header(AV1Decoder *pbi,
cm->reset_decoder_state = 0;
if (cm->show_existing_frame) {
+ if (pbi->sequence_header_changed) {
+ aom_internal_error(
+ &cm->error, AOM_CODEC_CORRUPT_FRAME,
+ "New sequence header starts with a show_existing_frame.");
+ }
// Show an existing frame directly.
const int existing_frame_idx = aom_rb_read_literal(rb, 3);
const int frame_to_show = cm->ref_frame_map[existing_frame_idx];
@@ -4493,6 +4768,18 @@ static int read_uncompressed_header(AV1Decoder *pbi,
}
cm->frame_type = (FRAME_TYPE)aom_rb_read_literal(rb, 2); // 2 bits
+ if (pbi->sequence_header_changed) {
+ if (pbi->common.frame_type == KEY_FRAME) {
+ // This is the start of a new coded video sequence.
+ pbi->sequence_header_changed = 0;
+ pbi->decoding_first_frame = 1;
+ reset_frame_buffers(&pbi->common);
+ } else {
+ aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME,
+ "Sequence header has changed without a keyframe.");
+ }
+ }
+
cm->show_frame = aom_rb_read_bit(rb);
if (seq_params->still_picture &&
(cm->frame_type != KEY_FRAME || !cm->show_frame)) {
@@ -4582,8 +4869,7 @@ static int read_uncompressed_header(AV1Decoder *pbi,
}
}
- frame_size_override_flag =
- frame_is_sframe(cm) ? 1 : aom_rb_read_literal(rb, 1);
+ frame_size_override_flag = frame_is_sframe(cm) ? 1 : aom_rb_read_bit(rb);
cm->frame_offset =
aom_rb_read_literal(rb, seq_params->order_hint_bits_minus_1 + 1);
@@ -5152,7 +5438,7 @@ static void setup_frame_info(AV1Decoder *pbi) {
const int use_highbd = cm->seq_params.use_highbitdepth ? 1 : 0;
const int buf_size = MC_TEMP_BUF_PELS << use_highbd;
if (pbi->td.mc_buf_size != buf_size) {
- av1_free_mc_tmp_buf(&pbi->td, use_highbd);
+ av1_free_mc_tmp_buf(&pbi->td);
allocate_mc_tmp_buf(cm, &pbi->td, buf_size, use_highbd);
}
}
@@ -5166,6 +5452,11 @@ void av1_decode_tg_tiles_and_wrapup(AV1Decoder *pbi, const uint8_t *data,
const int tile_count_tg = end_tile - start_tile + 1;
if (initialize_flag) setup_frame_info(pbi);
+ const int num_planes = av1_num_planes(cm);
+#if LOOP_FILTER_BITMASK
+ av1_loop_filter_frame_init(cm, 0, num_planes);
+ av1_zero_array(cm->lf.lfm, cm->lf.lfm_num);
+#endif
if (pbi->max_threads > 1 && !(cm->large_scale_tile && !pbi->ext_tile_debug) &&
pbi->row_mt)
@@ -5177,7 +5468,6 @@ void av1_decode_tg_tiles_and_wrapup(AV1Decoder *pbi, const uint8_t *data,
else
*p_data_end = decode_tiles(pbi, data, data_end, start_tile, end_tile);
- const int num_planes = av1_num_planes(cm);
// If the bit stream is monochrome, set the U and V buffers to a constant.
if (num_planes < 3) {
set_planes_to_neutral_grey(&cm->seq_params, xd->cur_buf, 1);
@@ -5190,7 +5480,7 @@ void av1_decode_tg_tiles_and_wrapup(AV1Decoder *pbi, const uint8_t *data,
if (!cm->allow_intrabc && !cm->single_tile_decoding) {
if (cm->lf.filter_level[0] || cm->lf.filter_level[1]) {
#if LOOP_FILTER_BITMASK
- av1_loop_filter_frame(get_frame_new_buffer(cm), cm, &pbi->mb, 0,
+ av1_loop_filter_frame(get_frame_new_buffer(cm), cm, &pbi->mb, 1, 0,
num_planes, 0);
#else
if (pbi->num_workers > 1) {
@@ -5255,6 +5545,7 @@ void av1_decode_tg_tiles_and_wrapup(AV1Decoder *pbi, const uint8_t *data,
if (!xd->corrupted) {
if (cm->refresh_frame_context == REFRESH_FRAME_CONTEXT_BACKWARD) {
+ assert(cm->context_update_tile_id < pbi->allocated_tiles);
*cm->fc = pbi->tile_data[cm->context_update_tile_id].tctx;
av1_reset_cdf_symbol_counters(cm->fc);
}
diff --git a/third_party/aom/av1/decoder/decodeframe.h b/third_party/aom/av1/decoder/decodeframe.h
index d289b31f2..ddad273f1 100644
--- a/third_party/aom/av1/decoder/decodeframe.h
+++ b/third_party/aom/av1/decoder/decodeframe.h
@@ -9,8 +9,8 @@
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
*/
-#ifndef AV1_DECODER_DECODEFRAME_H_
-#define AV1_DECODER_DECODEFRAME_H_
+#ifndef AOM_AV1_DECODER_DECODEFRAME_H_
+#define AOM_AV1_DECODER_DECODEFRAME_H_
#ifdef __cplusplus
extern "C" {
@@ -74,7 +74,7 @@ struct aom_read_bit_buffer *av1_init_read_bit_buffer(
struct AV1Decoder *pbi, struct aom_read_bit_buffer *rb, const uint8_t *data,
const uint8_t *data_end);
-void av1_free_mc_tmp_buf(struct ThreadData *thread_data, int use_highbd);
+void av1_free_mc_tmp_buf(struct ThreadData *thread_data);
void av1_set_single_tile_decoding_mode(AV1_COMMON *const cm);
@@ -82,4 +82,4 @@ void av1_set_single_tile_decoding_mode(AV1_COMMON *const cm);
} // extern "C"
#endif
-#endif // AV1_DECODER_DECODEFRAME_H_
+#endif // AOM_AV1_DECODER_DECODEFRAME_H_
diff --git a/third_party/aom/av1/decoder/decodemv.c b/third_party/aom/av1/decoder/decodemv.c
index 5e920b18d..551e4d543 100644
--- a/third_party/aom/av1/decoder/decodemv.c
+++ b/third_party/aom/av1/decoder/decodemv.c
@@ -94,42 +94,26 @@ static int read_delta_qindex(AV1_COMMON *cm, const MACROBLOCKD *xd,
}
return reduced_delta_qindex;
}
-static int read_delta_lflevel(AV1_COMMON *cm, const MACROBLOCKD *xd,
- aom_reader *r, int lf_id,
- MB_MODE_INFO *const mbmi, int mi_col,
+static int read_delta_lflevel(const AV1_COMMON *const cm, aom_reader *r,
+ aom_cdf_prob *const cdf,
+ const MB_MODE_INFO *const mbmi, int mi_col,
int mi_row) {
- int sign, abs, reduced_delta_lflevel = 0;
- BLOCK_SIZE bsize = mbmi->sb_type;
+ int reduced_delta_lflevel = 0;
+ const BLOCK_SIZE bsize = mbmi->sb_type;
const int b_col = mi_col & (cm->seq_params.mib_size - 1);
const int b_row = mi_row & (cm->seq_params.mib_size - 1);
const int read_delta_lf_flag = (b_col == 0 && b_row == 0);
- FRAME_CONTEXT *ec_ctx = xd->tile_ctx;
if ((bsize != cm->seq_params.sb_size || mbmi->skip == 0) &&
read_delta_lf_flag) {
- if (cm->delta_lf_multi) {
- assert(lf_id >= 0 &&
- lf_id < (av1_num_planes(cm) > 1 ? FRAME_LF_COUNT
- : FRAME_LF_COUNT - 2));
- abs = aom_read_symbol(r, ec_ctx->delta_lf_multi_cdf[lf_id],
- DELTA_LF_PROBS + 1, ACCT_STR);
- } else {
- abs = aom_read_symbol(r, ec_ctx->delta_lf_cdf, DELTA_LF_PROBS + 1,
- ACCT_STR);
- }
+ int abs = aom_read_symbol(r, cdf, DELTA_LF_PROBS + 1, ACCT_STR);
const int smallval = (abs < DELTA_LF_SMALL);
if (!smallval) {
const int rem_bits = aom_read_literal(r, 3, ACCT_STR) + 1;
const int thr = (1 << rem_bits) + 1;
abs = aom_read_literal(r, rem_bits, ACCT_STR) + thr;
}
-
- if (abs) {
- sign = aom_read_bit(r, ACCT_STR);
- } else {
- sign = 1;
- }
-
+ const int sign = abs ? aom_read_bit(r, ACCT_STR) : 1;
reduced_delta_lflevel = sign ? -abs : abs;
}
return reduced_delta_lflevel;
@@ -618,19 +602,22 @@ static void read_filter_intra_mode_info(const AV1_COMMON *const cm,
void av1_read_tx_type(const AV1_COMMON *const cm, MACROBLOCKD *xd, int blk_row,
int blk_col, TX_SIZE tx_size, aom_reader *r) {
MB_MODE_INFO *mbmi = xd->mi[0];
- const int inter_block = is_inter_block(mbmi);
- FRAME_CONTEXT *ec_ctx = xd->tile_ctx;
-
const int txk_type_idx =
av1_get_txk_type_index(mbmi->sb_type, blk_row, blk_col);
TX_TYPE *tx_type = &mbmi->txk_type[txk_type_idx];
+ *tx_type = DCT_DCT;
+
+ // No need to read transform type if block is skipped.
+ if (mbmi->skip || segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP))
+ return;
+
+ // No need to read transform type for lossless mode(qindex==0).
+ const int qindex =
+ cm->seg.enabled ? xd->qindex[mbmi->segment_id] : cm->base_qindex;
+ if (qindex <= 0) return;
- const TX_SIZE square_tx_size = txsize_sqr_map[tx_size];
- if (get_ext_tx_types(tx_size, inter_block, cm->reduced_tx_set_used) > 1 &&
- ((!cm->seg.enabled && cm->base_qindex > 0) ||
- (cm->seg.enabled && xd->qindex[mbmi->segment_id] > 0)) &&
- !mbmi->skip &&
- !segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
+ const int inter_block = is_inter_block(mbmi);
+ if (get_ext_tx_types(tx_size, inter_block, cm->reduced_tx_set_used) > 1) {
const TxSetType tx_set_type =
av1_get_ext_tx_set_type(tx_size, inter_block, cm->reduced_tx_set_used);
const int eset =
@@ -639,23 +626,22 @@ void av1_read_tx_type(const AV1_COMMON *const cm, MACROBLOCKD *xd, int blk_row,
// there is no need to read the tx_type
assert(eset != 0);
+ const TX_SIZE square_tx_size = txsize_sqr_map[tx_size];
+ FRAME_CONTEXT *ec_ctx = xd->tile_ctx;
if (inter_block) {
*tx_type = av1_ext_tx_inv[tx_set_type][aom_read_symbol(
r, ec_ctx->inter_ext_tx_cdf[eset][square_tx_size],
av1_num_ext_tx_set[tx_set_type], ACCT_STR)];
} else {
- PREDICTION_MODE intra_dir;
- if (mbmi->filter_intra_mode_info.use_filter_intra)
- intra_dir =
- fimode_to_intradir[mbmi->filter_intra_mode_info.filter_intra_mode];
- else
- intra_dir = mbmi->mode;
+ const PREDICTION_MODE intra_mode =
+ mbmi->filter_intra_mode_info.use_filter_intra
+ ? fimode_to_intradir[mbmi->filter_intra_mode_info
+ .filter_intra_mode]
+ : mbmi->mode;
*tx_type = av1_ext_tx_inv[tx_set_type][aom_read_symbol(
- r, ec_ctx->intra_ext_tx_cdf[eset][square_tx_size][intra_dir],
+ r, ec_ctx->intra_ext_tx_cdf[eset][square_tx_size][intra_mode],
av1_num_ext_tx_set[tx_set_type], ACCT_STR)];
}
- } else {
- *tx_type = DCT_DCT;
}
}
@@ -720,6 +706,43 @@ static void read_intrabc_info(AV1_COMMON *const cm, MACROBLOCKD *const xd,
}
}
+// If delta q is present, reads delta_q index.
+// Also reads delta_q loop filter levels, if present.
+static void read_delta_q_params(AV1_COMMON *const cm, MACROBLOCKD *const xd,
+ const int mi_row, const int mi_col,
+ aom_reader *r) {
+ if (cm->delta_q_present_flag) {
+ MB_MODE_INFO *const mbmi = xd->mi[0];
+ xd->current_qindex +=
+ read_delta_qindex(cm, xd, r, mbmi, mi_col, mi_row) * cm->delta_q_res;
+ /* Normative: Clamp to [1,MAXQ] to not interfere with lossless mode */
+ xd->current_qindex = clamp(xd->current_qindex, 1, MAXQ);
+ FRAME_CONTEXT *const ec_ctx = xd->tile_ctx;
+ if (cm->delta_lf_present_flag) {
+ if (cm->delta_lf_multi) {
+ const int frame_lf_count =
+ av1_num_planes(cm) > 1 ? FRAME_LF_COUNT : FRAME_LF_COUNT - 2;
+ for (int lf_id = 0; lf_id < frame_lf_count; ++lf_id) {
+ const int tmp_lvl =
+ xd->delta_lf[lf_id] +
+ read_delta_lflevel(cm, r, ec_ctx->delta_lf_multi_cdf[lf_id], mbmi,
+ mi_col, mi_row) *
+ cm->delta_lf_res;
+ mbmi->delta_lf[lf_id] = xd->delta_lf[lf_id] =
+ clamp(tmp_lvl, -MAX_LOOP_FILTER, MAX_LOOP_FILTER);
+ }
+ } else {
+ const int tmp_lvl = xd->delta_lf_from_base +
+ read_delta_lflevel(cm, r, ec_ctx->delta_lf_cdf,
+ mbmi, mi_col, mi_row) *
+ cm->delta_lf_res;
+ mbmi->delta_lf_from_base = xd->delta_lf_from_base =
+ clamp(tmp_lvl, -MAX_LOOP_FILTER, MAX_LOOP_FILTER);
+ }
+ }
+ }
+}
+
static void read_intra_frame_mode_info(AV1_COMMON *const cm,
MACROBLOCKD *const xd, int mi_row,
int mi_col, aom_reader *r) {
@@ -743,33 +766,7 @@ static void read_intra_frame_mode_info(AV1_COMMON *const cm,
read_cdef(cm, r, xd, mi_col, mi_row);
- if (cm->delta_q_present_flag) {
- xd->current_qindex +=
- read_delta_qindex(cm, xd, r, mbmi, mi_col, mi_row) * cm->delta_q_res;
- /* Normative: Clamp to [1,MAXQ] to not interfere with lossless mode */
- xd->current_qindex = clamp(xd->current_qindex, 1, MAXQ);
- if (cm->delta_lf_present_flag) {
- if (cm->delta_lf_multi) {
- const int frame_lf_count =
- av1_num_planes(cm) > 1 ? FRAME_LF_COUNT : FRAME_LF_COUNT - 2;
- for (int lf_id = 0; lf_id < frame_lf_count; ++lf_id) {
- const int tmp_lvl =
- xd->delta_lf[lf_id] +
- read_delta_lflevel(cm, xd, r, lf_id, mbmi, mi_col, mi_row) *
- cm->delta_lf_res;
- mbmi->delta_lf[lf_id] = xd->delta_lf[lf_id] =
- clamp(tmp_lvl, -MAX_LOOP_FILTER, MAX_LOOP_FILTER);
- }
- } else {
- const int tmp_lvl =
- xd->delta_lf_from_base +
- read_delta_lflevel(cm, xd, r, -1, mbmi, mi_col, mi_row) *
- cm->delta_lf_res;
- mbmi->delta_lf_from_base = xd->delta_lf_from_base =
- clamp(tmp_lvl, -MAX_LOOP_FILTER, MAX_LOOP_FILTER);
- }
- }
- }
+ read_delta_q_params(cm, xd, mi_row, mi_col, r);
mbmi->current_qindex = xd->current_qindex;
@@ -1402,7 +1399,7 @@ static void read_inter_block_mode_info(AV1Decoder *const pbi,
mbmi->motion_mode = SIMPLE_TRANSLATION;
if (is_motion_variation_allowed_bsize(mbmi->sb_type) && !mbmi->skip_mode &&
!has_second_ref(mbmi))
- mbmi->num_proj_ref[0] = findSamples(cm, xd, mi_row, mi_col, pts, pts_inref);
+ mbmi->num_proj_ref = findSamples(cm, xd, mi_row, mi_col, pts, pts_inref);
av1_count_overlappable_neighbors(cm, xd, mi_row, mi_col);
if (mbmi->ref_frame[1] != INTRA_FRAME)
@@ -1463,20 +1460,20 @@ static void read_inter_block_mode_info(AV1Decoder *const pbi,
read_mb_interp_filter(cm, xd, mbmi, r);
if (mbmi->motion_mode == WARPED_CAUSAL) {
- mbmi->wm_params[0].wmtype = DEFAULT_WMTYPE;
- mbmi->wm_params[0].invalid = 0;
+ mbmi->wm_params.wmtype = DEFAULT_WMTYPE;
+ mbmi->wm_params.invalid = 0;
- if (mbmi->num_proj_ref[0] > 1)
- mbmi->num_proj_ref[0] = selectSamples(&mbmi->mv[0].as_mv, pts, pts_inref,
- mbmi->num_proj_ref[0], bsize);
+ if (mbmi->num_proj_ref > 1)
+ mbmi->num_proj_ref = selectSamples(&mbmi->mv[0].as_mv, pts, pts_inref,
+ mbmi->num_proj_ref, bsize);
- if (find_projection(mbmi->num_proj_ref[0], pts, pts_inref, bsize,
+ if (find_projection(mbmi->num_proj_ref, pts, pts_inref, bsize,
mbmi->mv[0].as_mv.row, mbmi->mv[0].as_mv.col,
- &mbmi->wm_params[0], mi_row, mi_col)) {
+ &mbmi->wm_params, mi_row, mi_col)) {
#if WARPED_MOTION_DEBUG
printf("Warning: unexpected warped model from aomenc\n");
#endif
- mbmi->wm_params[0].invalid = 1;
+ mbmi->wm_params.invalid = 1;
}
}
@@ -1512,33 +1509,7 @@ static void read_inter_frame_mode_info(AV1Decoder *const pbi,
read_cdef(cm, r, xd, mi_col, mi_row);
- if (cm->delta_q_present_flag) {
- xd->current_qindex +=
- read_delta_qindex(cm, xd, r, mbmi, mi_col, mi_row) * cm->delta_q_res;
- /* Normative: Clamp to [1,MAXQ] to not interfere with lossless mode */
- xd->current_qindex = clamp(xd->current_qindex, 1, MAXQ);
- if (cm->delta_lf_present_flag) {
- if (cm->delta_lf_multi) {
- const int frame_lf_count =
- av1_num_planes(cm) > 1 ? FRAME_LF_COUNT : FRAME_LF_COUNT - 2;
- for (int lf_id = 0; lf_id < frame_lf_count; ++lf_id) {
- const int tmp_lvl =
- xd->delta_lf[lf_id] +
- read_delta_lflevel(cm, xd, r, lf_id, mbmi, mi_col, mi_row) *
- cm->delta_lf_res;
- mbmi->delta_lf[lf_id] = xd->delta_lf[lf_id] =
- clamp(tmp_lvl, -MAX_LOOP_FILTER, MAX_LOOP_FILTER);
- }
- } else {
- const int tmp_lvl =
- xd->delta_lf_from_base +
- read_delta_lflevel(cm, xd, r, -1, mbmi, mi_col, mi_row) *
- cm->delta_lf_res;
- mbmi->delta_lf_from_base = xd->delta_lf_from_base =
- clamp(tmp_lvl, -MAX_LOOP_FILTER, MAX_LOOP_FILTER);
- }
- }
- }
+ read_delta_q_params(cm, xd, mi_row, mi_col, r);
if (!mbmi->skip_mode)
inter_block = read_is_inter_block(cm, xd, mbmi->segment_id, r);
diff --git a/third_party/aom/av1/decoder/decodemv.h b/third_party/aom/av1/decoder/decodemv.h
index 6243bb168..1625e5bd2 100644
--- a/third_party/aom/av1/decoder/decodemv.h
+++ b/third_party/aom/av1/decoder/decodemv.h
@@ -9,8 +9,8 @@
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
*/
-#ifndef AV1_DECODER_DECODEMV_H_
-#define AV1_DECODER_DECODEMV_H_
+#ifndef AOM_AV1_DECODER_DECODEMV_H_
+#define AOM_AV1_DECODER_DECODEMV_H_
#include "aom_dsp/bitreader.h"
@@ -32,4 +32,4 @@ void av1_read_mode_info(AV1Decoder *const pbi, MACROBLOCKD *xd,
void av1_read_tx_type(const AV1_COMMON *const cm, MACROBLOCKD *xd, int blk_row,
int blk_col, TX_SIZE tx_size, aom_reader *r);
-#endif // AV1_DECODER_DECODEMV_H_
+#endif // AOM_AV1_DECODER_DECODEMV_H_
diff --git a/third_party/aom/av1/decoder/decoder.c b/third_party/aom/av1/decoder/decoder.c
index e978fad6c..a5f4fd67f 100644
--- a/third_party/aom/av1/decoder/decoder.c
+++ b/third_party/aom/av1/decoder/decoder.c
@@ -37,16 +37,11 @@
#include "av1/decoder/obu.h"
static void initialize_dec(void) {
- static volatile int init_done = 0;
-
- if (!init_done) {
- av1_rtcd();
- aom_dsp_rtcd();
- aom_scale_rtcd();
- av1_init_intra_predictors();
- av1_init_wedge_masks();
- init_done = 1;
- }
+ av1_rtcd();
+ aom_dsp_rtcd();
+ aom_scale_rtcd();
+ av1_init_intra_predictors();
+ av1_init_wedge_masks();
}
static void dec_setup_mi(AV1_COMMON *cm) {
@@ -171,8 +166,7 @@ void av1_decoder_remove(AV1Decoder *pbi) {
if (pbi->thread_data) {
for (int worker_idx = 0; worker_idx < pbi->max_threads - 1; worker_idx++) {
DecWorkerData *const thread_data = pbi->thread_data + worker_idx;
- const int use_highbd = pbi->common.seq_params.use_highbitdepth ? 1 : 0;
- av1_free_mc_tmp_buf(thread_data->td, use_highbd);
+ av1_free_mc_tmp_buf(thread_data->td);
aom_free(thread_data->td);
}
aom_free(pbi->thread_data);
@@ -209,8 +203,7 @@ void av1_decoder_remove(AV1Decoder *pbi) {
#if CONFIG_ACCOUNTING
aom_accounting_clear(&pbi->accounting);
#endif
- const int use_highbd = pbi->common.seq_params.use_highbitdepth ? 1 : 0;
- av1_free_mc_tmp_buf(&pbi->td, use_highbd);
+ av1_free_mc_tmp_buf(&pbi->td);
aom_free(pbi);
}
diff --git a/third_party/aom/av1/decoder/decoder.h b/third_party/aom/av1/decoder/decoder.h
index 610b98d95..5ca939c24 100644
--- a/third_party/aom/av1/decoder/decoder.h
+++ b/third_party/aom/av1/decoder/decoder.h
@@ -9,8 +9,8 @@
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
*/
-#ifndef AV1_DECODER_DECODER_H_
-#define AV1_DECODER_DECODER_H_
+#ifndef AOM_AV1_DECODER_DECODER_H_
+#define AOM_AV1_DECODER_DECODER_H_
#include "config/aom_config.h"
@@ -55,6 +55,11 @@ typedef struct ThreadData {
CB_BUFFER cb_buffer_base;
uint8_t *mc_buf[2];
int32_t mc_buf_size;
+ int mc_buf_use_highbd; // Boolean: whether the byte pointers stored in
+ // mc_buf were converted from highbd pointers.
+
+ CONV_BUF_TYPE *tmp_conv_dst;
+ uint8_t *tmp_obmc_bufs[2];
decode_block_visitor_fn_t read_coeffs_tx_intra_block_visit;
decode_block_visitor_fn_t predict_and_recon_intra_block_visit;
@@ -199,6 +204,7 @@ typedef struct AV1Decoder {
int tg_start; // First tile in the current tilegroup
int tg_size_bit_offset;
int sequence_header_ready;
+ int sequence_header_changed;
#if CONFIG_INSPECTION
aom_inspect_cb inspect_cb;
void *inspect_ctx;
@@ -308,4 +314,4 @@ typedef void (*block_visitor_fn_t)(AV1Decoder *const pbi, ThreadData *const td,
} // extern "C"
#endif
-#endif // AV1_DECODER_DECODER_H_
+#endif // AOM_AV1_DECODER_DECODER_H_
diff --git a/third_party/aom/av1/decoder/decodetxb.h b/third_party/aom/av1/decoder/decodetxb.h
index 687bba958..fe04f6abd 100644
--- a/third_party/aom/av1/decoder/decodetxb.h
+++ b/third_party/aom/av1/decoder/decodetxb.h
@@ -9,8 +9,8 @@
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
*/
-#ifndef DECODETXB_H_
-#define DECODETXB_H_
+#ifndef AOM_AV1_DECODER_DECODETXB_H_
+#define AOM_AV1_DECODER_DECODETXB_H_
#include "config/aom_config.h"
@@ -29,4 +29,4 @@ void av1_read_coeffs_txb_facade(const AV1_COMMON *const cm,
MACROBLOCKD *const xd, aom_reader *const r,
const int plane, const int row, const int col,
const TX_SIZE tx_size);
-#endif // DECODETXB_H_
+#endif // AOM_AV1_DECODER_DECODETXB_H_
diff --git a/third_party/aom/av1/decoder/detokenize.h b/third_party/aom/av1/decoder/detokenize.h
index ec85bf7ea..173b437a9 100644
--- a/third_party/aom/av1/decoder/detokenize.h
+++ b/third_party/aom/av1/decoder/detokenize.h
@@ -9,8 +9,8 @@
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
*/
-#ifndef AV1_DECODER_DETOKENIZE_H_
-#define AV1_DECODER_DETOKENIZE_H_
+#ifndef AOM_AV1_DECODER_DETOKENIZE_H_
+#define AOM_AV1_DECODER_DETOKENIZE_H_
#include "config/aom_config.h"
@@ -26,4 +26,4 @@ void av1_decode_palette_tokens(MACROBLOCKD *const xd, int plane, aom_reader *r);
#ifdef __cplusplus
} // extern "C"
#endif
-#endif // AV1_DECODER_DETOKENIZE_H_
+#endif // AOM_AV1_DECODER_DETOKENIZE_H_
diff --git a/third_party/aom/av1/decoder/dthread.h b/third_party/aom/av1/decoder/dthread.h
index 9f854e015..1d264b07e 100644
--- a/third_party/aom/av1/decoder/dthread.h
+++ b/third_party/aom/av1/decoder/dthread.h
@@ -9,8 +9,8 @@
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
*/
-#ifndef AV1_DECODER_DTHREAD_H_
-#define AV1_DECODER_DTHREAD_H_
+#ifndef AOM_AV1_DECODER_DTHREAD_H_
+#define AOM_AV1_DECODER_DTHREAD_H_
#include "config/aom_config.h"
@@ -79,4 +79,4 @@ void av1_frameworker_copy_context(AVxWorker *const dst_worker,
} // extern "C"
#endif
-#endif // AV1_DECODER_DTHREAD_H_
+#endif // AOM_AV1_DECODER_DTHREAD_H_
diff --git a/third_party/aom/av1/decoder/inspection.h b/third_party/aom/av1/decoder/inspection.h
index bb604f684..7214a9bed 100644
--- a/third_party/aom/av1/decoder/inspection.h
+++ b/third_party/aom/av1/decoder/inspection.h
@@ -8,8 +8,8 @@
* Media Patent License 1.0 was not distributed with this source code in the
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
*/
-#ifndef AOM_INSPECTION_H_
-#define AOM_INSPECTION_H_
+#ifndef AOM_AV1_DECODER_INSPECTION_H_
+#define AOM_AV1_DECODER_INSPECTION_H_
#ifdef __cplusplus
extern "C" {
@@ -81,4 +81,4 @@ int ifd_inspect(insp_frame_data *fd, void *decoder);
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus
-#endif // AOM_INSPECTION_H_
+#endif // AOM_AV1_DECODER_INSPECTION_H_
diff --git a/third_party/aom/av1/decoder/obu.c b/third_party/aom/av1/decoder/obu.c
index 715bc6837..44ecf818e 100644
--- a/third_party/aom/av1/decoder/obu.c
+++ b/third_party/aom/av1/decoder/obu.c
@@ -18,6 +18,7 @@
#include "aom_ports/mem_ops.h"
#include "av1/common/common.h"
+#include "av1/common/obu_util.h"
#include "av1/common/timing.h"
#include "av1/decoder/decoder.h"
#include "av1/decoder/decodeframe.h"
@@ -42,85 +43,6 @@ typedef enum {
SCALABILITY_SS = 14
} SCALABILITY_STRUCTURES;
-// Returns 1 when OBU type is valid, and 0 otherwise.
-static int valid_obu_type(int obu_type) {
- int valid_type = 0;
- switch (obu_type) {
- case OBU_SEQUENCE_HEADER:
- case OBU_TEMPORAL_DELIMITER:
- case OBU_FRAME_HEADER:
- case OBU_TILE_GROUP:
- case OBU_METADATA:
- case OBU_FRAME:
- case OBU_REDUNDANT_FRAME_HEADER:
- case OBU_TILE_LIST:
- case OBU_PADDING: valid_type = 1; break;
- default: break;
- }
- return valid_type;
-}
-
-// Parses OBU header and stores values in 'header'.
-static aom_codec_err_t read_obu_header(struct aom_read_bit_buffer *rb,
- int is_annexb, ObuHeader *header) {
- if (!rb || !header) return AOM_CODEC_INVALID_PARAM;
-
- const ptrdiff_t bit_buffer_byte_length = rb->bit_buffer_end - rb->bit_buffer;
- if (bit_buffer_byte_length < 1) return AOM_CODEC_CORRUPT_FRAME;
-
- header->size = 1;
-
- if (aom_rb_read_bit(rb) != 0) {
- // Forbidden bit. Must not be set.
- return AOM_CODEC_CORRUPT_FRAME;
- }
-
- header->type = (OBU_TYPE)aom_rb_read_literal(rb, 4);
-
- if (!valid_obu_type(header->type)) return AOM_CODEC_CORRUPT_FRAME;
-
- header->has_extension = aom_rb_read_bit(rb);
- header->has_size_field = aom_rb_read_bit(rb);
-
- if (!header->has_size_field && !is_annexb) {
- // section 5 obu streams must have obu_size field set.
- return AOM_CODEC_UNSUP_BITSTREAM;
- }
-
- if (aom_rb_read_bit(rb) != 0) {
- // obu_reserved_1bit must be set to 0.
- return AOM_CODEC_CORRUPT_FRAME;
- }
-
- if (header->has_extension) {
- if (bit_buffer_byte_length == 1) return AOM_CODEC_CORRUPT_FRAME;
-
- header->size += 1;
- header->temporal_layer_id = aom_rb_read_literal(rb, 3);
- header->spatial_layer_id = aom_rb_read_literal(rb, 2);
- if (aom_rb_read_literal(rb, 3) != 0) {
- // extension_header_reserved_3bits must be set to 0.
- return AOM_CODEC_CORRUPT_FRAME;
- }
- }
-
- return AOM_CODEC_OK;
-}
-
-aom_codec_err_t aom_read_obu_header(uint8_t *buffer, size_t buffer_length,
- size_t *consumed, ObuHeader *header,
- int is_annexb) {
- if (buffer_length < 1 || !consumed || !header) return AOM_CODEC_INVALID_PARAM;
-
- // TODO(tomfinegan): Set the error handler here and throughout this file, and
- // confirm parsing work done via aom_read_bit_buffer is successful.
- struct aom_read_bit_buffer rb = { buffer, buffer + buffer_length, 0, NULL,
- NULL };
- aom_codec_err_t parse_result = read_obu_header(&rb, is_annexb, header);
- if (parse_result == AOM_CODEC_OK) *consumed = header->size;
- return parse_result;
-}
-
aom_codec_err_t aom_get_num_layers_from_operating_point_idc(
int operating_point_idc, unsigned int *number_spatial_layers,
unsigned int *number_temporal_layers) {
@@ -208,7 +130,7 @@ static uint32_t read_sequence_header_obu(AV1Decoder *pbi,
SequenceHeader *const seq_params = &sh;
seq_params->profile = av1_read_profile(rb);
- if (seq_params->profile > PROFILE_2) {
+ if (seq_params->profile > CONFIG_MAX_DECODE_PROFILE) {
cm->error.error_code = AOM_CODEC_UNSUP_BITSTREAM;
return 0;
}
@@ -349,10 +271,8 @@ static uint32_t read_sequence_header_obu(AV1Decoder *pbi,
// If a sequence header has been decoded before, we check if the new
// one is consistent with the old one.
if (pbi->sequence_header_ready) {
- if (!are_seq_headers_consistent(&cm->seq_params, seq_params)) {
- aom_internal_error(&cm->error, AOM_CODEC_UNSUP_BITSTREAM,
- "Inconsistent sequence headers received.");
- }
+ if (!are_seq_headers_consistent(&cm->seq_params, seq_params))
+ pbi->sequence_header_changed = 1;
}
cm->seq_params = *seq_params;
@@ -620,9 +540,9 @@ static void read_metadata_hdr_mdcv(const uint8_t *data, size_t sz) {
static void scalability_structure(struct aom_read_bit_buffer *rb) {
int spatial_layers_cnt = aom_rb_read_literal(rb, 2);
- int spatial_layer_dimensions_present_flag = aom_rb_read_literal(rb, 1);
- int spatial_layer_description_present_flag = aom_rb_read_literal(rb, 1);
- int temporal_group_description_present_flag = aom_rb_read_literal(rb, 1);
+ int spatial_layer_dimensions_present_flag = aom_rb_read_bit(rb);
+ int spatial_layer_description_present_flag = aom_rb_read_bit(rb);
+ int temporal_group_description_present_flag = aom_rb_read_bit(rb);
aom_rb_read_literal(rb, 3); // reserved
if (spatial_layer_dimensions_present_flag) {
@@ -643,8 +563,8 @@ static void scalability_structure(struct aom_read_bit_buffer *rb) {
temporal_group_size = aom_rb_read_literal(rb, 8);
for (i = 0; i < temporal_group_size; i++) {
aom_rb_read_literal(rb, 3);
- aom_rb_read_literal(rb, 1);
- aom_rb_read_literal(rb, 1);
+ aom_rb_read_bit(rb);
+ aom_rb_read_bit(rb);
int temporal_group_ref_cnt = aom_rb_read_literal(rb, 3);
for (j = 0; j < temporal_group_ref_cnt; j++) {
aom_rb_read_literal(rb, 8);
@@ -716,61 +636,6 @@ static size_t read_metadata(const uint8_t *data, size_t sz) {
return sz;
}
-static aom_codec_err_t read_obu_size(const uint8_t *data,
- size_t bytes_available,
- size_t *const obu_size,
- size_t *const length_field_size) {
- uint64_t u_obu_size = 0;
- if (aom_uleb_decode(data, bytes_available, &u_obu_size, length_field_size) !=
- 0) {
- return AOM_CODEC_CORRUPT_FRAME;
- }
-
- if (u_obu_size > UINT32_MAX) return AOM_CODEC_CORRUPT_FRAME;
- *obu_size = (size_t)u_obu_size;
- return AOM_CODEC_OK;
-}
-
-aom_codec_err_t aom_read_obu_header_and_size(const uint8_t *data,
- size_t bytes_available,
- int is_annexb,
- ObuHeader *obu_header,
- size_t *const payload_size,
- size_t *const bytes_read) {
- size_t length_field_size = 0, obu_size = 0;
- aom_codec_err_t status;
-
- if (is_annexb) {
- // Size field comes before the OBU header, and includes the OBU header
- status =
- read_obu_size(data, bytes_available, &obu_size, &length_field_size);
-
- if (status != AOM_CODEC_OK) return status;
- }
-
- struct aom_read_bit_buffer rb = { data + length_field_size,
- data + bytes_available, 0, NULL, NULL };
-
- status = read_obu_header(&rb, is_annexb, obu_header);
- if (status != AOM_CODEC_OK) return status;
-
- if (is_annexb) {
- // Derive the payload size from the data we've already read
- if (obu_size < obu_header->size) return AOM_CODEC_CORRUPT_FRAME;
-
- *payload_size = obu_size - obu_header->size;
- } else {
- // Size field comes after the OBU header, and is just the payload size
- status = read_obu_size(data + obu_header->size,
- bytes_available - obu_header->size, payload_size,
- &length_field_size);
- if (status != AOM_CODEC_OK) return status;
- }
-
- *bytes_read = length_field_size + obu_header->size;
- return AOM_CODEC_OK;
-}
-
// On success, returns a boolean that indicates whether the decoding of the
// current frame is finished. On failure, sets cm->error.error_code and
// returns -1.
@@ -781,8 +646,6 @@ int aom_decode_frame_from_obus(struct AV1Decoder *pbi, const uint8_t *data,
int frame_decoding_finished = 0;
int is_first_tg_obu_received = 1;
uint32_t frame_header_size = 0;
- int seq_header_received = 0;
- size_t seq_header_size = 0;
ObuHeader obu_header;
memset(&obu_header, 0, sizeof(obu_header));
pbi->seen_frame_header = 0;
@@ -853,19 +716,8 @@ int aom_decode_frame_from_obus(struct AV1Decoder *pbi, const uint8_t *data,
pbi->seen_frame_header = 0;
break;
case OBU_SEQUENCE_HEADER:
- if (!seq_header_received) {
- decoded_payload_size = read_sequence_header_obu(pbi, &rb);
- if (cm->error.error_code != AOM_CODEC_OK) return -1;
-
- seq_header_size = decoded_payload_size;
- seq_header_received = 1;
- } else {
- // Seeing another sequence header, skip as all sequence headers are
- // required to be identical except for the contents of
- // operating_parameters_info and the amount of trailing bits.
- // TODO(yaowu): verifying redundant sequence headers are identical.
- decoded_payload_size = seq_header_size;
- }
+ decoded_payload_size = read_sequence_header_obu(pbi, &rb);
+ if (cm->error.error_code != AOM_CODEC_OK) return -1;
break;
case OBU_FRAME_HEADER:
case OBU_REDUNDANT_FRAME_HEADER:
@@ -889,6 +741,7 @@ int aom_decode_frame_from_obus(struct AV1Decoder *pbi, const uint8_t *data,
assert(rb.bit_offset == 0);
rb.bit_offset = 8 * frame_header_size;
}
+
decoded_payload_size = frame_header_size;
pbi->frame_header_size = frame_header_size;
@@ -938,6 +791,11 @@ int aom_decode_frame_from_obus(struct AV1Decoder *pbi, const uint8_t *data,
decoded_payload_size = read_metadata(data, payload_size);
break;
case OBU_TILE_LIST:
+ if (CONFIG_NORMAL_TILE_MODE) {
+ cm->error.error_code = AOM_CODEC_UNSUP_BITSTREAM;
+ return -1;
+ }
+
// This OBU type is purely for the large scale tile coding mode.
// The common camera frame header has to be already decoded.
if (!pbi->camera_frame_header_ready) {
diff --git a/third_party/aom/av1/decoder/obu.h b/third_party/aom/av1/decoder/obu.h
index 5f2197058..5ab243fc9 100644
--- a/third_party/aom/av1/decoder/obu.h
+++ b/third_party/aom/av1/decoder/obu.h
@@ -9,35 +9,12 @@
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
*/
-#ifndef AV1_DECODER_OBU_H
-#define AV1_DECODER_OBU_H
+#ifndef AOM_AV1_DECODER_OBU_H_
+#define AOM_AV1_DECODER_OBU_H_
#include "aom/aom_codec.h"
#include "av1/decoder/decoder.h"
-typedef struct {
- size_t size; // Size (1 or 2 bytes) of the OBU header (including the
- // optional OBU extension header) in the bitstream.
- OBU_TYPE type;
- int has_size_field;
- int has_extension;
- // The following fields come from the OBU extension header and therefore are
- // only used if has_extension is true.
- int temporal_layer_id;
- int spatial_layer_id;
-} ObuHeader;
-
-aom_codec_err_t aom_read_obu_header(uint8_t *buffer, size_t buffer_length,
- size_t *consumed, ObuHeader *header,
- int is_annexb);
-
-aom_codec_err_t aom_read_obu_header_and_size(const uint8_t *data,
- size_t bytes_available,
- int is_annexb,
- ObuHeader *obu_header,
- size_t *const payload_size,
- size_t *const bytes_read);
-
// Try to decode one frame from a buffer.
// Returns 1 if we decoded a frame,
// 0 if we didn't decode a frame but that's okay
@@ -51,4 +28,4 @@ aom_codec_err_t aom_get_num_layers_from_operating_point_idc(
int operating_point_idc, unsigned int *num_spatial_layers,
unsigned int *num_temporal_layers);
-#endif
+#endif // AOM_AV1_DECODER_OBU_H_