diff options
Diffstat (limited to 'third_party/aom/av1/decoder')
-rw-r--r-- | third_party/aom/av1/decoder/accounting.h | 6 | ||||
-rw-r--r-- | third_party/aom/av1/decoder/decodeframe.c | 555 | ||||
-rw-r--r-- | third_party/aom/av1/decoder/decodeframe.h | 8 | ||||
-rw-r--r-- | third_party/aom/av1/decoder/decodemv.c | 179 | ||||
-rw-r--r-- | third_party/aom/av1/decoder/decodemv.h | 6 | ||||
-rw-r--r-- | third_party/aom/av1/decoder/decoder.c | 21 | ||||
-rw-r--r-- | third_party/aom/av1/decoder/decoder.h | 12 | ||||
-rw-r--r-- | third_party/aom/av1/decoder/decodetxb.h | 6 | ||||
-rw-r--r-- | third_party/aom/av1/decoder/detokenize.h | 6 | ||||
-rw-r--r-- | third_party/aom/av1/decoder/dthread.h | 6 | ||||
-rw-r--r-- | third_party/aom/av1/decoder/inspection.h | 6 | ||||
-rw-r--r-- | third_party/aom/av1/decoder/obu.c | 176 | ||||
-rw-r--r-- | third_party/aom/av1/decoder/obu.h | 29 |
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_ |