Angie Chiang | cea11f2 | 2017-02-24 12:30:40 -0800 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (c) 2017, Alliance for Open Media. All rights reserved |
| 3 | * |
| 4 | * This source code is subject to the terms of the BSD 2 Clause License and |
| 5 | * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License |
| 6 | * was not distributed with this source code in the LICENSE file, you can |
| 7 | * obtain it at www.aomedia.org/license/software. If the Alliance for Open |
| 8 | * Media Patent License 1.0 was not distributed with this source code in the |
| 9 | * PATENTS file, you can obtain it at www.aomedia.org/license/patent. |
| 10 | */ |
| 11 | |
Angie Chiang | 41220ab | 2018-02-14 17:48:23 -0800 | [diff] [blame] | 12 | #include "av1/decoder/decodetxb.h" |
| 13 | |
Linfeng Zhang | ae7b2f3 | 2017-11-08 15:46:57 -0800 | [diff] [blame] | 14 | #include "aom_ports/mem.h" |
Angie Chiang | 133733c | 2017-03-17 12:50:20 -0700 | [diff] [blame] | 15 | #include "av1/common/idct.h" |
Angie Chiang | 1b1c4a3 | 2018-02-13 16:36:54 -0800 | [diff] [blame] | 16 | #include "av1/common/scan.h" |
Angie Chiang | cea11f2 | 2017-02-24 12:30:40 -0800 | [diff] [blame] | 17 | #include "av1/common/txb_common.h" |
Angie Chiang | de58e49 | 2017-04-13 17:10:14 -0700 | [diff] [blame] | 18 | #include "av1/decoder/decodemv.h" |
Angie Chiang | cea11f2 | 2017-02-24 12:30:40 -0800 | [diff] [blame] | 19 | |
| 20 | #define ACCT_STR __func__ |
| 21 | |
Yunqing Wang | 1694a4f | 2018-01-30 16:40:55 -0800 | [diff] [blame] | 22 | static int read_golomb(MACROBLOCKD *xd, aom_reader *r) { |
Angie Chiang | cea11f2 | 2017-02-24 12:30:40 -0800 | [diff] [blame] | 23 | int x = 1; |
| 24 | int length = 0; |
| 25 | int i = 0; |
| 26 | |
| 27 | while (!i) { |
Yunqing Wang | 1694a4f | 2018-01-30 16:40:55 -0800 | [diff] [blame] | 28 | i = aom_read_bit(r, ACCT_STR); |
Angie Chiang | cea11f2 | 2017-02-24 12:30:40 -0800 | [diff] [blame] | 29 | ++length; |
Frank Bossen | 6940fc1 | 2018-05-16 09:03:52 -0400 | [diff] [blame] | 30 | if (length > 20) { |
Angie Chiang | f1880e1 | 2017-04-12 15:40:44 -0700 | [diff] [blame] | 31 | aom_internal_error(xd->error_info, AOM_CODEC_CORRUPT_FRAME, |
| 32 | "Invalid length in read_golomb"); |
| 33 | break; |
| 34 | } |
Angie Chiang | cea11f2 | 2017-02-24 12:30:40 -0800 | [diff] [blame] | 35 | } |
| 36 | |
| 37 | for (i = 0; i < length - 1; ++i) { |
| 38 | x <<= 1; |
Yunqing Wang | 1694a4f | 2018-01-30 16:40:55 -0800 | [diff] [blame] | 39 | x += aom_read_bit(r, ACCT_STR); |
Angie Chiang | cea11f2 | 2017-02-24 12:30:40 -0800 | [diff] [blame] | 40 | } |
| 41 | |
| 42 | return x - 1; |
| 43 | } |
| 44 | |
Linfeng Zhang | 0c72b2f | 2017-12-04 10:59:28 -0800 | [diff] [blame] | 45 | static INLINE int rec_eob_pos(const int eob_token, const int extra) { |
Yaowu Xu | 3a19b8a | 2019-05-01 08:40:42 -0700 | [diff] [blame] | 46 | int eob = av1_eob_group_start[eob_token]; |
Dake He | a47cd6c | 2017-10-13 18:09:58 -0700 | [diff] [blame] | 47 | if (eob > 2) { |
| 48 | eob += extra; |
| 49 | } |
| 50 | return eob; |
| 51 | } |
Dake He | a47cd6c | 2017-10-13 18:09:58 -0700 | [diff] [blame] | 52 | |
Angie Chiang | b3167a6 | 2018-01-30 19:37:57 -0800 | [diff] [blame] | 53 | static INLINE int get_dqv(const int16_t *dequant, int coeff_idx, |
| 54 | const qm_val_t *iqmatrix) { |
| 55 | int dqv = dequant[!!coeff_idx]; |
Angie Chiang | b3167a6 | 2018-01-30 19:37:57 -0800 | [diff] [blame] | 56 | if (iqmatrix != NULL) |
| 57 | dqv = |
| 58 | ((iqmatrix[coeff_idx] * dqv) + (1 << (AOM_QM_BITS - 1))) >> AOM_QM_BITS; |
Angie Chiang | b3167a6 | 2018-01-30 19:37:57 -0800 | [diff] [blame] | 59 | return dqv; |
| 60 | } |
Angie Chiang | b3167a6 | 2018-01-30 19:37:57 -0800 | [diff] [blame] | 61 | |
Angie Chiang | 6d5419c | 2018-02-20 15:12:15 -0800 | [diff] [blame] | 62 | static INLINE void read_coeffs_reverse_2d(aom_reader *r, TX_SIZE tx_size, |
| 63 | int start_si, int end_si, |
Kyle Siefring | 7bb4c54 | 2022-12-09 10:27:41 -0500 | [diff] [blame] | 64 | const int16_t *scan, int bhl, |
Angie Chiang | 6d5419c | 2018-02-20 15:12:15 -0800 | [diff] [blame] | 65 | uint8_t *levels, |
| 66 | base_cdf_arr base_cdf, |
| 67 | br_cdf_arr br_cdf) { |
Angie Chiang | a744030 | 2018-02-20 14:36:09 -0800 | [diff] [blame] | 68 | for (int c = end_si; c >= start_si; --c) { |
| 69 | const int pos = scan[c]; |
Kyle Siefring | 7bb4c54 | 2022-12-09 10:27:41 -0500 | [diff] [blame] | 70 | const int coeff_ctx = get_lower_levels_ctx_2d(levels, pos, bhl, tx_size); |
Angie Chiang | a744030 | 2018-02-20 14:36:09 -0800 | [diff] [blame] | 71 | const int nsymbs = 4; |
| 72 | int level = aom_read_symbol(r, base_cdf[coeff_ctx], nsymbs, ACCT_STR); |
| 73 | if (level > NUM_BASE_LEVELS) { |
Kyle Siefring | 7bb4c54 | 2022-12-09 10:27:41 -0500 | [diff] [blame] | 74 | const int br_ctx = get_br_ctx_2d(levels, pos, bhl); |
Angie Chiang | a744030 | 2018-02-20 14:36:09 -0800 | [diff] [blame] | 75 | aom_cdf_prob *cdf = br_cdf[br_ctx]; |
| 76 | for (int idx = 0; idx < COEFF_BASE_RANGE; idx += BR_CDF_SIZE - 1) { |
| 77 | const int k = aom_read_symbol(r, cdf, BR_CDF_SIZE, ACCT_STR); |
| 78 | level += k; |
| 79 | if (k < BR_CDF_SIZE - 1) break; |
| 80 | } |
Angie Chiang | a744030 | 2018-02-20 14:36:09 -0800 | [diff] [blame] | 81 | } |
Kyle Siefring | 7bb4c54 | 2022-12-09 10:27:41 -0500 | [diff] [blame] | 82 | levels[get_padded_idx(pos, bhl)] = level; |
Angie Chiang | a744030 | 2018-02-20 14:36:09 -0800 | [diff] [blame] | 83 | } |
| 84 | } |
| 85 | |
Angie Chiang | 6dea31e | 2018-02-16 17:47:20 -0800 | [diff] [blame] | 86 | static INLINE void read_coeffs_reverse(aom_reader *r, TX_SIZE tx_size, |
Katsuhisa Yuasa | 55c95f8 | 2018-04-03 00:51:22 +0900 | [diff] [blame] | 87 | TX_CLASS tx_class, int start_si, |
Kyle Siefring | 7bb4c54 | 2022-12-09 10:27:41 -0500 | [diff] [blame] | 88 | int end_si, const int16_t *scan, int bhl, |
Angie Chiang | 6dea31e | 2018-02-16 17:47:20 -0800 | [diff] [blame] | 89 | uint8_t *levels, base_cdf_arr base_cdf, |
Angie Chiang | 6d5419c | 2018-02-20 15:12:15 -0800 | [diff] [blame] | 90 | br_cdf_arr br_cdf) { |
Angie Chiang | 6dea31e | 2018-02-16 17:47:20 -0800 | [diff] [blame] | 91 | for (int c = end_si; c >= start_si; --c) { |
| 92 | const int pos = scan[c]; |
| 93 | const int coeff_ctx = |
Kyle Siefring | 7bb4c54 | 2022-12-09 10:27:41 -0500 | [diff] [blame] | 94 | get_lower_levels_ctx(levels, pos, bhl, tx_size, tx_class); |
Angie Chiang | 6dea31e | 2018-02-16 17:47:20 -0800 | [diff] [blame] | 95 | const int nsymbs = 4; |
| 96 | int level = aom_read_symbol(r, base_cdf[coeff_ctx], nsymbs, ACCT_STR); |
| 97 | if (level > NUM_BASE_LEVELS) { |
Kyle Siefring | 7bb4c54 | 2022-12-09 10:27:41 -0500 | [diff] [blame] | 98 | const int br_ctx = get_br_ctx(levels, pos, bhl, tx_class); |
Angie Chiang | 6dea31e | 2018-02-16 17:47:20 -0800 | [diff] [blame] | 99 | aom_cdf_prob *cdf = br_cdf[br_ctx]; |
| 100 | for (int idx = 0; idx < COEFF_BASE_RANGE; idx += BR_CDF_SIZE - 1) { |
| 101 | const int k = aom_read_symbol(r, cdf, BR_CDF_SIZE, ACCT_STR); |
| 102 | level += k; |
| 103 | if (k < BR_CDF_SIZE - 1) break; |
| 104 | } |
Angie Chiang | 6dea31e | 2018-02-16 17:47:20 -0800 | [diff] [blame] | 105 | } |
Kyle Siefring | 7bb4c54 | 2022-12-09 10:27:41 -0500 | [diff] [blame] | 106 | levels[get_padded_idx(pos, bhl)] = level; |
Angie Chiang | 6dea31e | 2018-02-16 17:47:20 -0800 | [diff] [blame] | 107 | } |
| 108 | } |
| 109 | |
Urvang Joshi | bac1dea | 2020-04-20 11:37:15 -0700 | [diff] [blame] | 110 | uint8_t av1_read_coeffs_txb(const AV1_COMMON *const cm, DecoderCodingBlock *dcb, |
Linfeng Zhang | 9a7cc0e | 2017-11-20 12:37:28 -0800 | [diff] [blame] | 111 | aom_reader *const r, const int blk_row, |
Luc Trudeau | 2eb9b84 | 2017-12-13 11:19:16 -0500 | [diff] [blame] | 112 | const int blk_col, const int plane, |
Deepa K G | 610c9b8 | 2018-06-19 12:47:01 +0530 | [diff] [blame] | 113 | const TXB_CTX *const txb_ctx, |
| 114 | const TX_SIZE tx_size) { |
Urvang Joshi | bac1dea | 2020-04-20 11:37:15 -0700 | [diff] [blame] | 115 | MACROBLOCKD *const xd = &dcb->xd; |
Linfeng Zhang | 9a7cc0e | 2017-11-20 12:37:28 -0800 | [diff] [blame] | 116 | FRAME_CONTEXT *const ec_ctx = xd->tile_ctx; |
Sebastien Alaiwan | c84e32f | 2018-01-11 15:50:18 +0100 | [diff] [blame] | 117 | const int32_t max_value = (1 << (7 + xd->bd)) - 1; |
| 118 | const int32_t min_value = -(1 << (7 + xd->bd)); |
Debargha Mukherjee | b3eda2f | 2017-11-28 16:00:20 -0800 | [diff] [blame] | 119 | const TX_SIZE txs_ctx = get_txsize_entropy_ctx(tx_size); |
Linfeng Zhang | 9a7cc0e | 2017-11-20 12:37:28 -0800 | [diff] [blame] | 120 | const PLANE_TYPE plane_type = get_plane_type(plane); |
Yue Chen | 53b53f0 | 2018-03-29 14:31:23 -0700 | [diff] [blame] | 121 | MB_MODE_INFO *const mbmi = xd->mi[0]; |
Linfeng Zhang | 0ff69c6 | 2017-12-04 10:35:38 -0800 | [diff] [blame] | 122 | struct macroblockd_plane *const pd = &xd->plane[plane]; |
| 123 | const int16_t *const dequant = pd->seg_dequant_QTX[mbmi->segment_id]; |
Urvang Joshi | bac1dea | 2020-04-20 11:37:15 -0700 | [diff] [blame] | 124 | tran_low_t *const tcoeffs = dcb->dqcoeff_block[plane] + dcb->cb_offset[plane]; |
Jingning Han | ff70545 | 2017-04-27 11:32:15 -0700 | [diff] [blame] | 125 | const int shift = av1_get_tx_scale(tx_size); |
Kyle Siefring | 7bb4c54 | 2022-12-09 10:27:41 -0500 | [diff] [blame] | 126 | const int bhl = get_txb_bhl(tx_size); |
Angie Chiang | a9ba58e | 2017-12-01 19:22:43 -0800 | [diff] [blame] | 127 | const int width = get_txb_wide(tx_size); |
| 128 | const int height = get_txb_high(tx_size); |
Angie Chiang | cea11f2 | 2017-02-24 12:30:40 -0800 | [diff] [blame] | 129 | int cul_level = 0; |
Matthieu Vaudano | 928c3795 | 2018-03-29 10:22:53 +0200 | [diff] [blame] | 130 | int dc_val = 0; |
Linfeng Zhang | 679d81e | 2017-10-31 15:27:42 -0700 | [diff] [blame] | 131 | uint8_t levels_buf[TX_PAD_2D]; |
Kyle Siefring | 7bb4c54 | 2022-12-09 10:27:41 -0500 | [diff] [blame] | 132 | uint8_t *const levels = set_levels(levels_buf, height); |
Hui Su | 41d6152 | 2018-01-23 10:47:55 -0800 | [diff] [blame] | 133 | const int all_zero = aom_read_symbol( |
| 134 | r, ec_ctx->txb_skip_cdf[txs_ctx][txb_ctx->txb_skip_ctx], 2, ACCT_STR); |
Urvang Joshi | bac1dea | 2020-04-20 11:37:15 -0700 | [diff] [blame] | 135 | eob_info *eob_data = dcb->eob_data[plane] + dcb->txb_offset[plane]; |
Deepa K G | 610c9b8 | 2018-06-19 12:47:01 +0530 | [diff] [blame] | 136 | uint16_t *const eob = &(eob_data->eob); |
| 137 | uint16_t *const max_scan_line = &(eob_data->max_scan_line); |
| 138 | *max_scan_line = 0; |
Angie Chiang | 29b0fad | 2017-03-20 16:18:45 -0700 | [diff] [blame] | 139 | *eob = 0; |
Jim Bankoski | c04ce61 | 2018-12-20 15:45:33 -0800 | [diff] [blame] | 140 | |
| 141 | #if CONFIG_INSPECTION |
| 142 | if (plane == 0) { |
| 143 | const int txk_type_idx = |
chiyotsai | 0f5cd05 | 2020-08-27 14:37:44 -0700 | [diff] [blame] | 144 | av1_get_txk_type_index(mbmi->bsize, blk_row, blk_col); |
Jim Bankoski | c04ce61 | 2018-12-20 15:45:33 -0800 | [diff] [blame] | 145 | mbmi->tx_skip[txk_type_idx] = all_zero; |
| 146 | } |
| 147 | #endif |
| 148 | |
Angie Chiang | 133733c | 2017-03-17 12:50:20 -0700 | [diff] [blame] | 149 | if (all_zero) { |
| 150 | *max_scan_line = 0; |
Hui Su | de1a5db | 2018-02-22 15:44:49 -0800 | [diff] [blame] | 151 | if (plane == 0) { |
Hui Su | 52b7ddc | 2019-10-10 16:27:16 -0700 | [diff] [blame] | 152 | xd->tx_type_map[blk_row * xd->tx_type_map_stride + blk_col] = DCT_DCT; |
Hui Su | de1a5db | 2018-02-22 15:44:49 -0800 | [diff] [blame] | 153 | } |
Angie Chiang | 133733c | 2017-03-17 12:50:20 -0700 | [diff] [blame] | 154 | return 0; |
| 155 | } |
| 156 | |
Luc Trudeau | 963dd9b | 2018-04-11 13:59:11 -0400 | [diff] [blame] | 157 | if (plane == AOM_PLANE_Y) { |
| 158 | // only y plane's tx_type is transmitted |
| 159 | av1_read_tx_type(cm, xd, blk_row, blk_col, tx_size, r); |
| 160 | } |
Urvang Joshi | b6409e9 | 2020-03-23 11:23:27 -0700 | [diff] [blame] | 161 | const TX_TYPE tx_type = |
| 162 | av1_get_tx_type(xd, plane_type, blk_row, blk_col, tx_size, |
| 163 | cm->features.reduced_tx_set_used); |
Jingning Han | e8bd3a0 | 2018-04-09 11:52:35 -0700 | [diff] [blame] | 164 | const TX_CLASS tx_class = tx_type_to_class[tx_type]; |
Angie Chiang | b3167a6 | 2018-01-30 19:37:57 -0800 | [diff] [blame] | 165 | const qm_val_t *iqmatrix = |
Urvang Joshi | f409a63 | 2020-03-28 01:03:50 -0700 | [diff] [blame] | 166 | av1_get_iqmatrix(&cm->quant_params, xd, plane, tx_size, tx_type); |
Yaowu Xu | f1e1293 | 2018-02-26 15:50:09 -0800 | [diff] [blame] | 167 | const SCAN_ORDER *const scan_order = get_scan(tx_size, tx_type); |
Linfeng Zhang | 9a7cc0e | 2017-11-20 12:37:28 -0800 | [diff] [blame] | 168 | const int16_t *const scan = scan_order->scan; |
Linfeng Zhang | 0c72b2f | 2017-12-04 10:59:28 -0800 | [diff] [blame] | 169 | int eob_extra = 0; |
| 170 | int eob_pt = 1; |
Angie Chiang | 133733c | 2017-03-17 12:50:20 -0700 | [diff] [blame] | 171 | |
Dake He | 0db7d0e | 2017-12-21 15:23:20 -0800 | [diff] [blame] | 172 | const int eob_multi_size = txsize_log2_minus4[tx_size]; |
Jingning Han | e8bd3a0 | 2018-04-09 11:52:35 -0700 | [diff] [blame] | 173 | const int eob_multi_ctx = (tx_class == TX_CLASS_2D) ? 0 : 1; |
Dake He | 0db7d0e | 2017-12-21 15:23:20 -0800 | [diff] [blame] | 174 | switch (eob_multi_size) { |
| 175 | case 0: |
Yunqing Wang | 1694a4f | 2018-01-30 16:40:55 -0800 | [diff] [blame] | 176 | eob_pt = |
| 177 | aom_read_symbol(r, ec_ctx->eob_flag_cdf16[plane_type][eob_multi_ctx], |
| 178 | 5, ACCT_STR) + |
| 179 | 1; |
Dake He | 0db7d0e | 2017-12-21 15:23:20 -0800 | [diff] [blame] | 180 | break; |
| 181 | case 1: |
Yunqing Wang | 1694a4f | 2018-01-30 16:40:55 -0800 | [diff] [blame] | 182 | eob_pt = |
| 183 | aom_read_symbol(r, ec_ctx->eob_flag_cdf32[plane_type][eob_multi_ctx], |
| 184 | 6, ACCT_STR) + |
| 185 | 1; |
Dake He | 0db7d0e | 2017-12-21 15:23:20 -0800 | [diff] [blame] | 186 | break; |
| 187 | case 2: |
Yunqing Wang | 1694a4f | 2018-01-30 16:40:55 -0800 | [diff] [blame] | 188 | eob_pt = |
| 189 | aom_read_symbol(r, ec_ctx->eob_flag_cdf64[plane_type][eob_multi_ctx], |
| 190 | 7, ACCT_STR) + |
| 191 | 1; |
Dake He | 0db7d0e | 2017-12-21 15:23:20 -0800 | [diff] [blame] | 192 | break; |
| 193 | case 3: |
| 194 | eob_pt = |
Yunqing Wang | 1694a4f | 2018-01-30 16:40:55 -0800 | [diff] [blame] | 195 | aom_read_symbol(r, ec_ctx->eob_flag_cdf128[plane_type][eob_multi_ctx], |
| 196 | 8, ACCT_STR) + |
Dake He | 0db7d0e | 2017-12-21 15:23:20 -0800 | [diff] [blame] | 197 | 1; |
| 198 | break; |
| 199 | case 4: |
| 200 | eob_pt = |
Yunqing Wang | 1694a4f | 2018-01-30 16:40:55 -0800 | [diff] [blame] | 201 | aom_read_symbol(r, ec_ctx->eob_flag_cdf256[plane_type][eob_multi_ctx], |
| 202 | 9, ACCT_STR) + |
Dake He | 0db7d0e | 2017-12-21 15:23:20 -0800 | [diff] [blame] | 203 | 1; |
| 204 | break; |
| 205 | case 5: |
| 206 | eob_pt = |
Yunqing Wang | 1694a4f | 2018-01-30 16:40:55 -0800 | [diff] [blame] | 207 | aom_read_symbol(r, ec_ctx->eob_flag_cdf512[plane_type][eob_multi_ctx], |
| 208 | 10, ACCT_STR) + |
Dake He | 0db7d0e | 2017-12-21 15:23:20 -0800 | [diff] [blame] | 209 | 1; |
| 210 | break; |
| 211 | case 6: |
| 212 | default: |
Yunqing Wang | 1694a4f | 2018-01-30 16:40:55 -0800 | [diff] [blame] | 213 | eob_pt = aom_read_symbol( |
| 214 | r, ec_ctx->eob_flag_cdf1024[plane_type][eob_multi_ctx], 11, |
| 215 | ACCT_STR) + |
| 216 | 1; |
Dake He | 0db7d0e | 2017-12-21 15:23:20 -0800 | [diff] [blame] | 217 | break; |
| 218 | } |
Dake He | a47cd6c | 2017-10-13 18:09:58 -0700 | [diff] [blame] | 219 | |
Yaowu Xu | 3a19b8a | 2019-05-01 08:40:42 -0700 | [diff] [blame] | 220 | const int eob_offset_bits = av1_eob_offset_bits[eob_pt]; |
wenyao.liu | 0be5901 | 2018-12-24 10:27:31 +0800 | [diff] [blame] | 221 | if (eob_offset_bits > 0) { |
Jingning Han | ff4a9f8 | 2018-06-08 10:48:45 -0700 | [diff] [blame] | 222 | const int eob_ctx = eob_pt - 3; |
Hui Su | 41d6152 | 2018-01-23 10:47:55 -0800 | [diff] [blame] | 223 | int bit = aom_read_symbol( |
Jingning Han | ff4a9f8 | 2018-06-08 10:48:45 -0700 | [diff] [blame] | 224 | r, ec_ctx->eob_extra_cdf[txs_ctx][plane_type][eob_ctx], 2, ACCT_STR); |
Angie Chiang | 7ab884e | 2017-10-18 15:57:12 -0700 | [diff] [blame] | 225 | if (bit) { |
wenyao.liu | 0be5901 | 2018-12-24 10:27:31 +0800 | [diff] [blame] | 226 | eob_extra += (1 << (eob_offset_bits - 1)); |
Angie Chiang | 7ab884e | 2017-10-18 15:57:12 -0700 | [diff] [blame] | 227 | } |
| 228 | |
wenyao.liu | 0be5901 | 2018-12-24 10:27:31 +0800 | [diff] [blame] | 229 | for (int i = 1; i < eob_offset_bits; i++) { |
Yunqing Wang | 1694a4f | 2018-01-30 16:40:55 -0800 | [diff] [blame] | 230 | bit = aom_read_bit(r, ACCT_STR); |
Dake He | a47cd6c | 2017-10-13 18:09:58 -0700 | [diff] [blame] | 231 | if (bit) { |
wenyao.liu | 0be5901 | 2018-12-24 10:27:31 +0800 | [diff] [blame] | 232 | eob_extra += (1 << (eob_offset_bits - 1 - i)); |
Dake He | a47cd6c | 2017-10-13 18:09:58 -0700 | [diff] [blame] | 233 | } |
Dake He | a47cd6c | 2017-10-13 18:09:58 -0700 | [diff] [blame] | 234 | } |
| 235 | } |
| 236 | *eob = rec_eob_pos(eob_pt, eob_extra); |
Dake He | a47cd6c | 2017-10-13 18:09:58 -0700 | [diff] [blame] | 237 | |
wenyao.liu | ebc72de | 2019-01-18 11:45:06 +0800 | [diff] [blame] | 238 | if (*eob > 1) { |
| 239 | memset(levels_buf, 0, |
| 240 | sizeof(*levels_buf) * |
Kyle Siefring | 7bb4c54 | 2022-12-09 10:27:41 -0500 | [diff] [blame] | 241 | ((height + TX_PAD_HOR) * (width + TX_PAD_VER) + TX_PAD_END)); |
wenyao.liu | ebc72de | 2019-01-18 11:45:06 +0800 | [diff] [blame] | 242 | } |
| 243 | |
Angie Chiang | da708cd | 2018-02-16 12:08:31 -0800 | [diff] [blame] | 244 | { |
Angie Chiang | f8a6822 | 2018-02-16 14:54:28 -0800 | [diff] [blame] | 245 | // Read the non-zero coefficient with scan index eob-1 |
Angie Chiang | da708cd | 2018-02-16 12:08:31 -0800 | [diff] [blame] | 246 | // TODO(angiebird): Put this into a function |
| 247 | const int c = *eob - 1; |
| 248 | const int pos = scan[c]; |
Kyle Siefring | 7bb4c54 | 2022-12-09 10:27:41 -0500 | [diff] [blame] | 249 | const int coeff_ctx = get_lower_levels_ctx_eob(bhl, width, c); |
Angie Chiang | da708cd | 2018-02-16 12:08:31 -0800 | [diff] [blame] | 250 | const int nsymbs = 3; |
| 251 | aom_cdf_prob *cdf = |
| 252 | ec_ctx->coeff_base_eob_cdf[txs_ctx][plane_type][coeff_ctx]; |
| 253 | int level = aom_read_symbol(r, cdf, nsymbs, ACCT_STR) + 1; |
| 254 | if (level > NUM_BASE_LEVELS) { |
Kyle Siefring | 7bb4c54 | 2022-12-09 10:27:41 -0500 | [diff] [blame] | 255 | const int br_ctx = get_br_ctx_eob(pos, bhl, tx_class); |
wenyao.liu | 0be5901 | 2018-12-24 10:27:31 +0800 | [diff] [blame] | 256 | cdf = ec_ctx->coeff_br_cdf[AOMMIN(txs_ctx, TX_32X32)][plane_type][br_ctx]; |
Angie Chiang | da708cd | 2018-02-16 12:08:31 -0800 | [diff] [blame] | 257 | for (int idx = 0; idx < COEFF_BASE_RANGE; idx += BR_CDF_SIZE - 1) { |
wenyao.liu | 0be5901 | 2018-12-24 10:27:31 +0800 | [diff] [blame] | 258 | const int k = aom_read_symbol(r, cdf, BR_CDF_SIZE, ACCT_STR); |
Angie Chiang | da708cd | 2018-02-16 12:08:31 -0800 | [diff] [blame] | 259 | level += k; |
| 260 | if (k < BR_CDF_SIZE - 1) break; |
| 261 | } |
Angie Chiang | da708cd | 2018-02-16 12:08:31 -0800 | [diff] [blame] | 262 | } |
Kyle Siefring | 7bb4c54 | 2022-12-09 10:27:41 -0500 | [diff] [blame] | 263 | levels[get_padded_idx(pos, bhl)] = level; |
Angie Chiang | da708cd | 2018-02-16 12:08:31 -0800 | [diff] [blame] | 264 | } |
Angie Chiang | 0975671 | 2018-02-21 12:18:11 -0800 | [diff] [blame] | 265 | if (*eob > 1) { |
| 266 | base_cdf_arr base_cdf = ec_ctx->coeff_base_cdf[txs_ctx][plane_type]; |
| 267 | br_cdf_arr br_cdf = |
| 268 | ec_ctx->coeff_br_cdf[AOMMIN(txs_ctx, TX_32X32)][plane_type]; |
Angie Chiang | 0975671 | 2018-02-21 12:18:11 -0800 | [diff] [blame] | 269 | if (tx_class == TX_CLASS_2D) { |
Kyle Siefring | 7bb4c54 | 2022-12-09 10:27:41 -0500 | [diff] [blame] | 270 | read_coeffs_reverse_2d(r, tx_size, 1, *eob - 1 - 1, scan, bhl, levels, |
Angie Chiang | 0975671 | 2018-02-21 12:18:11 -0800 | [diff] [blame] | 271 | base_cdf, br_cdf); |
Kyle Siefring | 7bb4c54 | 2022-12-09 10:27:41 -0500 | [diff] [blame] | 272 | read_coeffs_reverse(r, tx_size, tx_class, 0, 0, scan, bhl, levels, |
Angie Chiang | 0975671 | 2018-02-21 12:18:11 -0800 | [diff] [blame] | 273 | base_cdf, br_cdf); |
| 274 | } else { |
Kyle Siefring | 7bb4c54 | 2022-12-09 10:27:41 -0500 | [diff] [blame] | 275 | read_coeffs_reverse(r, tx_size, tx_class, 0, *eob - 1 - 1, scan, bhl, |
Angie Chiang | 0975671 | 2018-02-21 12:18:11 -0800 | [diff] [blame] | 276 | levels, base_cdf, br_cdf); |
| 277 | } |
Angie Chiang | 41220ab | 2018-02-14 17:48:23 -0800 | [diff] [blame] | 278 | } |
| 279 | |
Angie Chiang | 41220ab | 2018-02-14 17:48:23 -0800 | [diff] [blame] | 280 | for (int c = 0; c < *eob; ++c) { |
Angie Chiang | 1b1c4a3 | 2018-02-13 16:36:54 -0800 | [diff] [blame] | 281 | const int pos = scan[c]; |
Angie Chiang | 6d5419c | 2018-02-20 15:12:15 -0800 | [diff] [blame] | 282 | uint8_t sign; |
Kyle Siefring | 7bb4c54 | 2022-12-09 10:27:41 -0500 | [diff] [blame] | 283 | tran_low_t level = levels[get_padded_idx(pos, bhl)]; |
Linfeng Zhang | 9a7cc0e | 2017-11-20 12:37:28 -0800 | [diff] [blame] | 284 | if (level) { |
Linfeng Zhang | 9a7cc0e | 2017-11-20 12:37:28 -0800 | [diff] [blame] | 285 | *max_scan_line = AOMMAX(*max_scan_line, pos); |
Angie Chiang | 1b1c4a3 | 2018-02-13 16:36:54 -0800 | [diff] [blame] | 286 | if (c == 0) { |
| 287 | const int dc_sign_ctx = txb_ctx->dc_sign_ctx; |
Angie Chiang | 41220ab | 2018-02-14 17:48:23 -0800 | [diff] [blame] | 288 | sign = aom_read_symbol(r, ec_ctx->dc_sign_cdf[plane_type][dc_sign_ctx], |
| 289 | 2, ACCT_STR); |
Angie Chiang | 1b1c4a3 | 2018-02-13 16:36:54 -0800 | [diff] [blame] | 290 | } else { |
Angie Chiang | 41220ab | 2018-02-14 17:48:23 -0800 | [diff] [blame] | 291 | sign = aom_read_bit(r, ACCT_STR); |
Angie Chiang | 1b1c4a3 | 2018-02-13 16:36:54 -0800 | [diff] [blame] | 292 | } |
Angie Chiang | 4f5c352 | 2018-02-26 17:01:32 -0800 | [diff] [blame] | 293 | if (level >= MAX_BASE_BR_RANGE) { |
Angie Chiang | 83b9f11 | 2018-02-23 15:14:40 -0800 | [diff] [blame] | 294 | level += read_golomb(xd, r); |
Angie Chiang | 41220ab | 2018-02-14 17:48:23 -0800 | [diff] [blame] | 295 | } |
Matthieu Vaudano | 928c3795 | 2018-03-29 10:22:53 +0200 | [diff] [blame] | 296 | |
| 297 | if (c == 0) dc_val = sign ? -level : level; |
| 298 | |
Yaowu Xu | c0ff7a3 | 2018-03-09 10:44:38 -0800 | [diff] [blame] | 299 | // Bitmasking to clamp level to valid range: |
| 300 | // The valid range for 8/10/12 bit vdieo is at most 14/16/18 bit |
| 301 | level &= 0xfffff; |
Angie Chiang | 83b9f11 | 2018-02-23 15:14:40 -0800 | [diff] [blame] | 302 | cul_level += level; |
| 303 | tran_low_t dq_coeff; |
Yaowu Xu | c0ff7a3 | 2018-03-09 10:44:38 -0800 | [diff] [blame] | 304 | // Bitmasking to clamp dq_coeff to valid range: |
| 305 | // The valid range for 8/10/12 bit video is at most 17/19/21 bit |
Hui Su | 97f770a | 2018-05-09 11:31:32 -0700 | [diff] [blame] | 306 | dq_coeff = (tran_low_t)( |
| 307 | (int64_t)level * get_dqv(dequant, scan[c], iqmatrix) & 0xffffff); |
Angie Chiang | 83b9f11 | 2018-02-23 15:14:40 -0800 | [diff] [blame] | 308 | dq_coeff = dq_coeff >> shift; |
| 309 | if (sign) { |
| 310 | dq_coeff = -dq_coeff; |
| 311 | } |
| 312 | tcoeffs[pos] = clamp(dq_coeff, min_value, max_value); |
Jingning Han | 87b01b5 | 2017-08-31 12:07:20 -0700 | [diff] [blame] | 313 | } |
Angie Chiang | cea11f2 | 2017-02-24 12:30:40 -0800 | [diff] [blame] | 314 | } |
| 315 | |
Jingning Han | 258c13d | 2018-04-03 08:32:39 -0700 | [diff] [blame] | 316 | cul_level = AOMMIN(COEFF_CONTEXT_MASK, cul_level); |
Angie Chiang | cea11f2 | 2017-02-24 12:30:40 -0800 | [diff] [blame] | 317 | |
| 318 | // DC value |
Matthieu Vaudano | 928c3795 | 2018-03-29 10:22:53 +0200 | [diff] [blame] | 319 | set_dc_sign(&cul_level, dc_val); |
Angie Chiang | cea11f2 | 2017-02-24 12:30:40 -0800 | [diff] [blame] | 320 | |
| 321 | return cul_level; |
| 322 | } |
Angie Chiang | 133733c | 2017-03-17 12:50:20 -0700 | [diff] [blame] | 323 | |
Deepa K G | 3bc1f93 | 2018-06-21 14:25:03 +0530 | [diff] [blame] | 324 | void av1_read_coeffs_txb_facade(const AV1_COMMON *const cm, |
Urvang Joshi | bac1dea | 2020-04-20 11:37:15 -0700 | [diff] [blame] | 325 | DecoderCodingBlock *dcb, aom_reader *const r, |
Deepa K G | 1909dee | 2018-07-03 17:37:56 +0530 | [diff] [blame] | 326 | const int plane, const int row, const int col, |
Deepa K G | 3bc1f93 | 2018-06-21 14:25:03 +0530 | [diff] [blame] | 327 | const TX_SIZE tx_size) { |
| 328 | #if TXCOEFF_TIMER |
| 329 | struct aom_usec_timer timer; |
| 330 | aom_usec_timer_start(&timer); |
| 331 | #endif |
Urvang Joshi | bac1dea | 2020-04-20 11:37:15 -0700 | [diff] [blame] | 332 | MACROBLOCKD *const xd = &dcb->xd; |
Yue Chen | 53b53f0 | 2018-03-29 14:31:23 -0700 | [diff] [blame] | 333 | MB_MODE_INFO *const mbmi = xd->mi[0]; |
Linfeng Zhang | 0ff69c6 | 2017-12-04 10:35:38 -0800 | [diff] [blame] | 334 | struct macroblockd_plane *const pd = &xd->plane[plane]; |
Angie Chiang | 133733c | 2017-03-17 12:50:20 -0700 | [diff] [blame] | 335 | |
chiyotsai | 0f5cd05 | 2020-08-27 14:37:44 -0700 | [diff] [blame] | 336 | const BLOCK_SIZE bsize = mbmi->bsize; |
kyslov | 5859dca | 2019-04-08 12:13:11 -0700 | [diff] [blame] | 337 | assert(bsize < BLOCK_SIZES_ALL); |
Cheng Chen | 8ab1f44 | 2018-04-27 18:01:52 -0700 | [diff] [blame] | 338 | const BLOCK_SIZE plane_bsize = |
| 339 | get_plane_block_size(bsize, pd->subsampling_x, pd->subsampling_y); |
Angie Chiang | 133733c | 2017-03-17 12:50:20 -0700 | [diff] [blame] | 340 | |
Angie Chiang | 133733c | 2017-03-17 12:50:20 -0700 | [diff] [blame] | 341 | TXB_CTX txb_ctx; |
Urvang Joshi | 46ff552 | 2020-03-30 15:27:37 -0700 | [diff] [blame] | 342 | get_txb_ctx(plane_bsize, tx_size, plane, pd->above_entropy_context + col, |
| 343 | pd->left_entropy_context + row, &txb_ctx); |
Deepa K G | 610c9b8 | 2018-06-19 12:47:01 +0530 | [diff] [blame] | 344 | const uint8_t cul_level = |
Urvang Joshi | bac1dea | 2020-04-20 11:37:15 -0700 | [diff] [blame] | 345 | av1_read_coeffs_txb(cm, dcb, r, row, col, plane, &txb_ctx, tx_size); |
Urvang Joshi | 46ff552 | 2020-03-30 15:27:37 -0700 | [diff] [blame] | 346 | av1_set_entropy_contexts(xd, pd, plane, plane_bsize, tx_size, cul_level, col, |
| 347 | row); |
Deepa K G | 3bc1f93 | 2018-06-21 14:25:03 +0530 | [diff] [blame] | 348 | |
| 349 | if (is_inter_block(mbmi)) { |
Hui Su | 52b7ddc | 2019-10-10 16:27:16 -0700 | [diff] [blame] | 350 | const PLANE_TYPE plane_type = get_plane_type(plane); |
Deepa K G | 3bc1f93 | 2018-06-21 14:25:03 +0530 | [diff] [blame] | 351 | // tx_type will be read out in av1_read_coeffs_txb_facade |
Hui Su | 37980cc | 2019-10-09 10:16:35 -0700 | [diff] [blame] | 352 | const TX_TYPE tx_type = av1_get_tx_type(xd, plane_type, row, col, tx_size, |
Urvang Joshi | b6409e9 | 2020-03-23 11:23:27 -0700 | [diff] [blame] | 353 | cm->features.reduced_tx_set_used); |
Deepa K G | 3bc1f93 | 2018-06-21 14:25:03 +0530 | [diff] [blame] | 354 | |
Hui Su | 52b7ddc | 2019-10-10 16:27:16 -0700 | [diff] [blame] | 355 | if (plane == 0) { |
| 356 | const int txw = tx_size_wide_unit[tx_size]; |
| 357 | const int txh = tx_size_high_unit[tx_size]; |
| 358 | // The 16x16 unit is due to the constraint from tx_64x64 which sets the |
| 359 | // maximum tx size for chroma as 32x32. Coupled with 4x1 transform block |
| 360 | // size, the constraint takes effect in 32x16 / 16x32 size too. To solve |
| 361 | // the intricacy, cover all the 16x16 units inside a 64 level transform. |
| 362 | if (txw == tx_size_wide_unit[TX_64X64] || |
| 363 | txh == tx_size_high_unit[TX_64X64]) { |
| 364 | const int tx_unit = tx_size_wide_unit[TX_16X16]; |
| 365 | const int stride = xd->tx_type_map_stride; |
| 366 | for (int idy = 0; idy < txh; idy += tx_unit) { |
| 367 | for (int idx = 0; idx < txw; idx += tx_unit) { |
| 368 | xd->tx_type_map[(row + idy) * stride + col + idx] = tx_type; |
| 369 | } |
| 370 | } |
| 371 | } |
| 372 | } |
Deepa K G | 3bc1f93 | 2018-06-21 14:25:03 +0530 | [diff] [blame] | 373 | } |
| 374 | |
| 375 | #if TXCOEFF_TIMER |
| 376 | aom_usec_timer_mark(&timer); |
| 377 | const int64_t elapsed_time = aom_usec_timer_elapsed(&timer); |
| 378 | cm->txcoeff_timer += elapsed_time; |
| 379 | ++cm->txb_count; |
| 380 | #endif |
Angie Chiang | 133733c | 2017-03-17 12:50:20 -0700 | [diff] [blame] | 381 | } |