Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1 | /* |
Yaowu Xu | 2ab7ff0 | 2016-09-02 12:04:54 -0700 | [diff] [blame] | 2 | * Copyright (c) 2016, Alliance for Open Media. All rights reserved |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 3 | * |
Yaowu Xu | 2ab7ff0 | 2016-09-02 12:04:54 -0700 | [diff] [blame] | 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. |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 10 | */ |
| 11 | |
| 12 | #include <assert.h> |
| 13 | #include <limits.h> |
| 14 | #include <stdio.h> |
| 15 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 16 | #include "aom/aom_encoder.h" |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 17 | #include "aom_dsp/aom_dsp_common.h" |
Debargha Mukherjee | 47748b5 | 2017-03-24 12:20:49 -0700 | [diff] [blame] | 18 | #include "aom_dsp/binary_codes_writer.h" |
Cheng Chen | c7855b1 | 2017-09-05 10:49:08 -0700 | [diff] [blame] | 19 | #include "aom_dsp/bitwriter_buffer.h" |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 20 | #include "aom_mem/aom_mem.h" |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 21 | #include "aom_ports/mem_ops.h" |
| 22 | #include "aom_ports/system_state.h" |
Angie Chiang | 6062a8b | 2016-09-21 16:01:04 -0700 | [diff] [blame] | 23 | #if CONFIG_BITSTREAM_DEBUG |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 24 | #include "aom_util/debug_util.h" |
Angie Chiang | 6062a8b | 2016-09-21 16:01:04 -0700 | [diff] [blame] | 25 | #endif // CONFIG_BITSTREAM_DEBUG |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 26 | |
Steinar Midtskogen | a9d41e8 | 2017-03-17 12:48:15 +0100 | [diff] [blame] | 27 | #include "av1/common/cdef.h" |
Luc Trudeau | d183b64 | 2017-11-28 11:42:37 -0500 | [diff] [blame] | 28 | #include "av1/common/cfl.h" |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 29 | #include "av1/common/entropy.h" |
| 30 | #include "av1/common/entropymode.h" |
| 31 | #include "av1/common/entropymv.h" |
| 32 | #include "av1/common/mvref_common.h" |
Thomas Davies | f693610 | 2016-09-05 16:51:31 +0100 | [diff] [blame] | 33 | #include "av1/common/odintrin.h" |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 34 | #include "av1/common/pred_common.h" |
| 35 | #include "av1/common/reconinter.h" |
hui su | 45dc597 | 2016-12-08 17:42:50 -0800 | [diff] [blame] | 36 | #include "av1/common/reconintra.h" |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 37 | #include "av1/common/seg_common.h" |
| 38 | #include "av1/common/tile_common.h" |
| 39 | |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 40 | #include "av1/encoder/bitstream.h" |
| 41 | #include "av1/encoder/cost.h" |
| 42 | #include "av1/encoder/encodemv.h" |
Hui Su | ec73b44 | 2018-01-04 12:47:53 -0800 | [diff] [blame] | 43 | #include "av1/encoder/encodetxb.h" |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 44 | #include "av1/encoder/mcomp.h" |
hui su | d13c24a | 2017-04-07 16:13:07 -0700 | [diff] [blame] | 45 | #include "av1/encoder/palette.h" |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 46 | #include "av1/encoder/segmentation.h" |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 47 | #include "av1/encoder/tokenize.h" |
| 48 | |
Di Chen | 5658662 | 2017-06-09 13:49:44 -0700 | [diff] [blame] | 49 | #define ENC_MISMATCH_DEBUG 0 |
Zoe Liu | 85b6646 | 2017-04-20 14:28:19 -0700 | [diff] [blame] | 50 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 51 | static INLINE void write_uniform(aom_writer *w, int n, int v) { |
hui su | 3749929 | 2017-04-26 09:49:53 -0700 | [diff] [blame] | 52 | const int l = get_unsigned_bits(n); |
| 53 | const int m = (1 << l) - n; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 54 | if (l == 0) return; |
| 55 | if (v < m) { |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 56 | aom_write_literal(w, v, l - 1); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 57 | } else { |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 58 | aom_write_literal(w, m + ((v - m) >> 1), l - 1); |
| 59 | aom_write_literal(w, (v - m) & 1, 1); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 60 | } |
| 61 | } |
| 62 | |
Rupert Swarbrick | 6c54521 | 2017-09-01 17:17:25 +0100 | [diff] [blame] | 63 | static void loop_restoration_write_sb_coeffs(const AV1_COMMON *const cm, |
| 64 | MACROBLOCKD *xd, |
Rupert Swarbrick | dd6f09a | 2017-10-19 16:10:23 +0100 | [diff] [blame] | 65 | const RestorationUnitInfo *rui, |
Yue Chen | 4439151 | 2018-03-13 15:37:26 -0700 | [diff] [blame] | 66 | aom_writer *const w, int plane, |
| 67 | FRAME_COUNTS *counts); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 68 | |
Jingning Han | 3e4c6a6 | 2017-12-14 14:50:57 -0800 | [diff] [blame] | 69 | static void write_intra_mode_kf(FRAME_CONTEXT *frame_ctx, const MODE_INFO *mi, |
| 70 | const MODE_INFO *above_mi, |
| 71 | const MODE_INFO *left_mi, PREDICTION_MODE mode, |
| 72 | aom_writer *w) { |
Alex Converse | 2874430 | 2017-04-13 14:46:22 -0700 | [diff] [blame] | 73 | assert(!is_intrabc_block(&mi->mbmi)); |
Jingning Han | 9010e20 | 2017-12-14 14:48:09 -0800 | [diff] [blame] | 74 | (void)mi; |
Jingning Han | 9010e20 | 2017-12-14 14:48:09 -0800 | [diff] [blame] | 75 | aom_write_symbol(w, mode, get_y_mode_cdf(frame_ctx, above_mi, left_mi), |
Jingning Han | f04254f | 2017-03-08 10:51:35 -0800 | [diff] [blame] | 76 | INTRA_MODES); |
Jingning Han | f04254f | 2017-03-08 10:51:35 -0800 | [diff] [blame] | 77 | } |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 78 | |
Thomas Davies | 1de6c88 | 2017-01-11 17:47:49 +0000 | [diff] [blame] | 79 | static void write_inter_mode(aom_writer *w, PREDICTION_MODE mode, |
Zoe Liu | 7f24e1b | 2017-03-17 17:42:05 -0700 | [diff] [blame] | 80 | FRAME_CONTEXT *ec_ctx, const int16_t mode_ctx) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 81 | const int16_t newmv_ctx = mode_ctx & NEWMV_CTX_MASK; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 82 | |
Thomas Davies | 149eda5 | 2017-06-12 18:11:55 +0100 | [diff] [blame] | 83 | aom_write_symbol(w, mode != NEWMV, ec_ctx->newmv_cdf[newmv_ctx], 2); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 84 | |
Jingning Han | f2b87bd | 2017-05-18 16:27:30 -0700 | [diff] [blame] | 85 | if (mode != NEWMV) { |
Sarah Parker | 2b9ec2e | 2017-10-30 17:34:08 -0700 | [diff] [blame] | 86 | const int16_t zeromv_ctx = |
| 87 | (mode_ctx >> GLOBALMV_OFFSET) & GLOBALMV_CTX_MASK; |
Sarah Parker | 2b9ec2e | 2017-10-30 17:34:08 -0700 | [diff] [blame] | 88 | aom_write_symbol(w, mode != GLOBALMV, ec_ctx->zeromv_cdf[zeromv_ctx], 2); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 89 | |
Sarah Parker | 2b9ec2e | 2017-10-30 17:34:08 -0700 | [diff] [blame] | 90 | if (mode != GLOBALMV) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 91 | int16_t refmv_ctx = (mode_ctx >> REFMV_OFFSET) & REFMV_CTX_MASK; |
Thomas Davies | 149eda5 | 2017-06-12 18:11:55 +0100 | [diff] [blame] | 92 | aom_write_symbol(w, mode != NEARESTMV, ec_ctx->refmv_cdf[refmv_ctx], 2); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 93 | } |
| 94 | } |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 95 | } |
| 96 | |
Thomas Davies | 149eda5 | 2017-06-12 18:11:55 +0100 | [diff] [blame] | 97 | static void write_drl_idx(FRAME_CONTEXT *ec_ctx, const MB_MODE_INFO *mbmi, |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 98 | const MB_MODE_INFO_EXT *mbmi_ext, aom_writer *w) { |
| 99 | uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 100 | |
| 101 | assert(mbmi->ref_mv_idx < 3); |
| 102 | |
Sebastien Alaiwan | 34d5566 | 2017-11-15 09:36:03 +0100 | [diff] [blame] | 103 | const int new_mv = mbmi->mode == NEWMV || mbmi->mode == NEW_NEWMV; |
Rupert Swarbrick | cf77276 | 2017-11-03 16:41:07 +0000 | [diff] [blame] | 104 | if (new_mv) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 105 | int idx; |
| 106 | for (idx = 0; idx < 2; ++idx) { |
Jingning Han | b4fc74d | 2017-12-21 14:34:03 -0800 | [diff] [blame] | 107 | if (mbmi_ext->ref_mv_count[ref_frame_type] > idx + 1) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 108 | uint8_t drl_ctx = |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 109 | av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], idx); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 110 | |
Thomas Davies | 149eda5 | 2017-06-12 18:11:55 +0100 | [diff] [blame] | 111 | aom_write_symbol(w, mbmi->ref_mv_idx != idx, ec_ctx->drl_cdf[drl_ctx], |
| 112 | 2); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 113 | if (mbmi->ref_mv_idx == idx) return; |
| 114 | } |
| 115 | } |
| 116 | return; |
| 117 | } |
| 118 | |
David Barker | 3dfba99 | 2017-04-03 16:10:09 +0100 | [diff] [blame] | 119 | if (have_nearmv_in_inter_mode(mbmi->mode)) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 120 | int idx; |
| 121 | // TODO(jingning): Temporary solution to compensate the NEARESTMV offset. |
| 122 | for (idx = 1; idx < 3; ++idx) { |
Jingning Han | b4fc74d | 2017-12-21 14:34:03 -0800 | [diff] [blame] | 123 | if (mbmi_ext->ref_mv_count[ref_frame_type] > idx + 1) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 124 | uint8_t drl_ctx = |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 125 | av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], idx); |
Thomas Davies | 149eda5 | 2017-06-12 18:11:55 +0100 | [diff] [blame] | 126 | aom_write_symbol(w, mbmi->ref_mv_idx != (idx - 1), |
| 127 | ec_ctx->drl_cdf[drl_ctx], 2); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 128 | if (mbmi->ref_mv_idx == (idx - 1)) return; |
| 129 | } |
| 130 | } |
| 131 | return; |
| 132 | } |
| 133 | } |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 134 | |
Thomas Davies | 8c08a33 | 2017-06-26 17:30:34 +0100 | [diff] [blame] | 135 | static void write_inter_compound_mode(AV1_COMMON *cm, MACROBLOCKD *xd, |
| 136 | aom_writer *w, PREDICTION_MODE mode, |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 137 | const int16_t mode_ctx) { |
Thomas Davies | 8c08a33 | 2017-06-26 17:30:34 +0100 | [diff] [blame] | 138 | assert(is_inter_compound_mode(mode)); |
Thomas Davies | 8c08a33 | 2017-06-26 17:30:34 +0100 | [diff] [blame] | 139 | (void)cm; |
| 140 | aom_write_symbol(w, INTER_COMPOUND_OFFSET(mode), |
| 141 | xd->tile_ctx->inter_compound_mode_cdf[mode_ctx], |
| 142 | INTER_COMPOUND_MODES); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 143 | } |
Zoe Liu | 85b6646 | 2017-04-20 14:28:19 -0700 | [diff] [blame] | 144 | |
Thomas Davies | 985bfc3 | 2017-06-27 16:51:26 +0100 | [diff] [blame] | 145 | static void write_tx_size_vartx(const AV1_COMMON *cm, MACROBLOCKD *xd, |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 146 | const MB_MODE_INFO *mbmi, TX_SIZE tx_size, |
Jingning Han | 94d5bfc | 2016-10-21 10:14:36 -0700 | [diff] [blame] | 147 | int depth, int blk_row, int blk_col, |
| 148 | aom_writer *w) { |
Thomas Davies | 985bfc3 | 2017-06-27 16:51:26 +0100 | [diff] [blame] | 149 | FRAME_CONTEXT *ec_ctx = xd->tile_ctx; |
| 150 | (void)cm; |
Jingning Han | f65b870 | 2016-10-31 12:13:20 -0700 | [diff] [blame] | 151 | const int max_blocks_high = max_block_high(xd, mbmi->sb_type, 0); |
| 152 | const int max_blocks_wide = max_block_wide(xd, mbmi->sb_type, 0); |
| 153 | |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 154 | if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return; |
| 155 | |
Jingning Han | 571189c | 2016-10-24 10:38:43 -0700 | [diff] [blame] | 156 | if (depth == MAX_VARTX_DEPTH) { |
Jingning Han | 331662e | 2017-05-30 17:03:32 -0700 | [diff] [blame] | 157 | txfm_partition_update(xd->above_txfm_context + blk_col, |
| 158 | xd->left_txfm_context + blk_row, tx_size, tx_size); |
Jingning Han | 94d5bfc | 2016-10-21 10:14:36 -0700 | [diff] [blame] | 159 | return; |
| 160 | } |
| 161 | |
Hui Su | 7167d95 | 2018-02-01 16:33:12 -0800 | [diff] [blame] | 162 | const int ctx = txfm_partition_context(xd->above_txfm_context + blk_col, |
| 163 | xd->left_txfm_context + blk_row, |
| 164 | mbmi->sb_type, tx_size); |
| 165 | const int txb_size_index = |
| 166 | av1_get_txb_size_index(mbmi->sb_type, blk_row, blk_col); |
Rupert Swarbrick | cf77276 | 2017-11-03 16:41:07 +0000 | [diff] [blame] | 167 | const int write_txfm_partition = |
Hui Su | 7167d95 | 2018-02-01 16:33:12 -0800 | [diff] [blame] | 168 | tx_size == mbmi->inter_tx_size[txb_size_index]; |
Rupert Swarbrick | cf77276 | 2017-11-03 16:41:07 +0000 | [diff] [blame] | 169 | if (write_txfm_partition) { |
Thomas Davies | 985bfc3 | 2017-06-27 16:51:26 +0100 | [diff] [blame] | 170 | aom_write_symbol(w, 0, ec_ctx->txfm_partition_cdf[ctx], 2); |
Thomas Davies | 985bfc3 | 2017-06-27 16:51:26 +0100 | [diff] [blame] | 171 | |
Jingning Han | 331662e | 2017-05-30 17:03:32 -0700 | [diff] [blame] | 172 | txfm_partition_update(xd->above_txfm_context + blk_col, |
| 173 | xd->left_txfm_context + blk_row, tx_size, tx_size); |
Yue Chen | d6bdd46 | 2017-07-19 16:05:43 -0700 | [diff] [blame] | 174 | // TODO(yuec): set correct txfm partition update for qttx |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 175 | } else { |
Debargha Mukherjee | e4e18fc | 2017-12-06 23:43:24 -0800 | [diff] [blame] | 176 | const TX_SIZE sub_txs = sub_tx_size_map[1][tx_size]; |
Yue Chen | 0797a20 | 2017-10-27 17:24:56 -0700 | [diff] [blame] | 177 | const int bsw = tx_size_wide_unit[sub_txs]; |
| 178 | const int bsh = tx_size_high_unit[sub_txs]; |
Jingning Han | f64062f | 2016-11-02 16:22:18 -0700 | [diff] [blame] | 179 | |
Thomas Davies | 985bfc3 | 2017-06-27 16:51:26 +0100 | [diff] [blame] | 180 | aom_write_symbol(w, 1, ec_ctx->txfm_partition_cdf[ctx], 2); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 181 | |
David Barker | 16c64e3 | 2017-08-23 16:54:59 +0100 | [diff] [blame] | 182 | if (sub_txs == TX_4X4) { |
Jingning Han | 331662e | 2017-05-30 17:03:32 -0700 | [diff] [blame] | 183 | txfm_partition_update(xd->above_txfm_context + blk_col, |
| 184 | xd->left_txfm_context + blk_row, sub_txs, tx_size); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 185 | return; |
| 186 | } |
| 187 | |
Yue Chen | 0797a20 | 2017-10-27 17:24:56 -0700 | [diff] [blame] | 188 | assert(bsw > 0 && bsh > 0); |
| 189 | for (int row = 0; row < tx_size_high_unit[tx_size]; row += bsh) |
| 190 | for (int col = 0; col < tx_size_wide_unit[tx_size]; col += bsw) { |
| 191 | int offsetr = blk_row + row; |
| 192 | int offsetc = blk_col + col; |
| 193 | write_tx_size_vartx(cm, xd, mbmi, sub_txs, depth + 1, offsetr, offsetc, |
| 194 | w); |
| 195 | } |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 196 | } |
| 197 | } |
| 198 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 199 | static void write_selected_tx_size(const AV1_COMMON *cm, const MACROBLOCKD *xd, |
| 200 | aom_writer *w) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 201 | const MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi; |
| 202 | const BLOCK_SIZE bsize = mbmi->sb_type; |
Thomas Davies | 15580c5 | 2017-03-09 13:53:42 +0000 | [diff] [blame] | 203 | FRAME_CONTEXT *ec_ctx = xd->tile_ctx; |
| 204 | (void)cm; |
Rupert Swarbrick | fcff0b2 | 2017-10-05 09:26:04 +0100 | [diff] [blame] | 205 | if (block_signals_txsize(bsize)) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 206 | const TX_SIZE tx_size = mbmi->tx_size; |
Yaowu Xu | 25ff26a | 2018-02-26 11:20:10 -0800 | [diff] [blame] | 207 | const int tx_size_ctx = get_tx_size_context(xd); |
Debargha Mukherjee | 0fa057f | 2017-12-06 17:06:29 -0800 | [diff] [blame] | 208 | const int depth = tx_size_to_depth(tx_size, bsize, 0); |
| 209 | const int max_depths = bsize_to_max_depth(bsize, 0); |
Debargha Mukherjee | e4e18fc | 2017-12-06 23:43:24 -0800 | [diff] [blame] | 210 | const int32_t tx_size_cat = bsize_to_tx_size_cat(bsize, 0); |
Debargha Mukherjee | 6147b1b | 2017-11-08 08:31:09 -0800 | [diff] [blame] | 211 | |
Debargha Mukherjee | 6147b1b | 2017-11-08 08:31:09 -0800 | [diff] [blame] | 212 | assert(depth >= 0 && depth <= max_depths); |
Debargha Mukherjee | 6147b1b | 2017-11-08 08:31:09 -0800 | [diff] [blame] | 213 | assert(!is_inter_block(mbmi)); |
Yue Chen | 49587a7 | 2016-09-28 17:09:47 -0700 | [diff] [blame] | 214 | assert(IMPLIES(is_rect_tx(tx_size), is_rect_tx_allowed(xd, mbmi))); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 215 | |
Thomas Davies | 15580c5 | 2017-03-09 13:53:42 +0000 | [diff] [blame] | 216 | aom_write_symbol(w, depth, ec_ctx->tx_size_cdf[tx_size_cat][tx_size_ctx], |
Debargha Mukherjee | 6147b1b | 2017-11-08 08:31:09 -0800 | [diff] [blame] | 217 | max_depths + 1); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 218 | } |
| 219 | } |
| 220 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 221 | static int write_skip(const AV1_COMMON *cm, const MACROBLOCKD *xd, |
| 222 | int segment_id, const MODE_INFO *mi, aom_writer *w) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 223 | if (segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP)) { |
| 224 | return 1; |
| 225 | } else { |
| 226 | const int skip = mi->mbmi.skip; |
Zoe Liu | e646daa | 2017-10-17 15:28:46 -0700 | [diff] [blame] | 227 | const int ctx = av1_get_skip_context(xd); |
Thomas Davies | 61e3e37 | 2017-04-04 16:10:23 +0100 | [diff] [blame] | 228 | FRAME_CONTEXT *ec_ctx = xd->tile_ctx; |
Thomas Davies | 61e3e37 | 2017-04-04 16:10:23 +0100 | [diff] [blame] | 229 | aom_write_symbol(w, skip, ec_ctx->skip_cdfs[ctx], 2); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 230 | return skip; |
| 231 | } |
| 232 | } |
| 233 | |
Zoe Liu | f40a957 | 2017-10-13 12:37:19 -0700 | [diff] [blame] | 234 | static int write_skip_mode(const AV1_COMMON *cm, const MACROBLOCKD *xd, |
| 235 | int segment_id, const MODE_INFO *mi, aom_writer *w) { |
| 236 | if (!cm->skip_mode_flag) return 0; |
| 237 | if (segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP)) { |
| 238 | return 0; |
| 239 | } |
| 240 | const int skip_mode = mi->mbmi.skip_mode; |
| 241 | if (!is_comp_ref_allowed(mi->mbmi.sb_type)) { |
| 242 | assert(!skip_mode); |
| 243 | return 0; |
| 244 | } |
| 245 | const int ctx = av1_get_skip_mode_context(xd); |
| 246 | aom_write_symbol(w, skip_mode, xd->tile_ctx->skip_mode_cdfs[ctx], 2); |
| 247 | return skip_mode; |
| 248 | } |
Zoe Liu | f40a957 | 2017-10-13 12:37:19 -0700 | [diff] [blame] | 249 | |
Thomas Davies | f6ad935 | 2017-04-19 11:38:06 +0100 | [diff] [blame] | 250 | static void write_is_inter(const AV1_COMMON *cm, const MACROBLOCKD *xd, |
| 251 | int segment_id, aom_writer *w, const int is_inter) { |
| 252 | if (!segfeature_active(&cm->seg, segment_id, SEG_LVL_REF_FRAME)) { |
Frederic Barbier | 5e91142 | 2017-12-12 17:17:07 +0100 | [diff] [blame] | 253 | if (segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP) |
| 254 | #if CONFIG_SEGMENT_GLOBALMV |
| 255 | || segfeature_active(&cm->seg, segment_id, SEG_LVL_GLOBALMV) |
| 256 | #endif |
Johann | b0ef6ff | 2018-02-08 14:32:21 -0800 | [diff] [blame] | 257 | ) |
Frederic Barbier | 5e91142 | 2017-12-12 17:17:07 +0100 | [diff] [blame] | 258 | if (!av1_is_valid_scale(&cm->frame_refs[0].sf)) |
| 259 | return; // LAST_FRAME not valid for reference |
| 260 | |
Yue Chen | 170678a | 2017-10-17 13:43:10 -0700 | [diff] [blame] | 261 | const int ctx = av1_get_intra_inter_context(xd); |
Thomas Davies | f6ad935 | 2017-04-19 11:38:06 +0100 | [diff] [blame] | 262 | FRAME_CONTEXT *ec_ctx = xd->tile_ctx; |
Thomas Davies | f6ad935 | 2017-04-19 11:38:06 +0100 | [diff] [blame] | 263 | aom_write_symbol(w, is_inter, ec_ctx->intra_inter_cdf[ctx], 2); |
Thomas Davies | f6ad935 | 2017-04-19 11:38:06 +0100 | [diff] [blame] | 264 | } |
| 265 | } |
| 266 | |
Thomas Davies | d9b5726 | 2017-06-27 17:43:25 +0100 | [diff] [blame] | 267 | static void write_motion_mode(const AV1_COMMON *cm, MACROBLOCKD *xd, |
| 268 | const MODE_INFO *mi, aom_writer *w) { |
Sarah Parker | 19234cc | 2017-03-10 16:43:25 -0800 | [diff] [blame] | 269 | const MB_MODE_INFO *mbmi = &mi->mbmi; |
Thomas Davies | d9b5726 | 2017-06-27 17:43:25 +0100 | [diff] [blame] | 270 | |
Sebastien Alaiwan | 4879580 | 2017-10-30 12:07:13 +0100 | [diff] [blame] | 271 | MOTION_MODE last_motion_mode_allowed = |
Yue Chen | 5380cb5 | 2018-02-23 15:33:21 -0800 | [diff] [blame] | 272 | cm->switchable_motion_mode |
| 273 | ? motion_mode_allowed(cm->global_motion, xd, mi) |
| 274 | : SIMPLE_TRANSLATION; |
| 275 | assert(mbmi->motion_mode <= last_motion_mode_allowed); |
Rupert Swarbrick | cf77276 | 2017-11-03 16:41:07 +0000 | [diff] [blame] | 276 | switch (last_motion_mode_allowed) { |
| 277 | case SIMPLE_TRANSLATION: break; |
Rupert Swarbrick | cf77276 | 2017-11-03 16:41:07 +0000 | [diff] [blame] | 278 | case OBMC_CAUSAL: |
Rupert Swarbrick | cf77276 | 2017-11-03 16:41:07 +0000 | [diff] [blame] | 279 | aom_write_symbol(w, mbmi->motion_mode == OBMC_CAUSAL, |
| 280 | xd->tile_ctx->obmc_cdf[mbmi->sb_type], 2); |
Rupert Swarbrick | cf77276 | 2017-11-03 16:41:07 +0000 | [diff] [blame] | 281 | break; |
Rupert Swarbrick | cf77276 | 2017-11-03 16:41:07 +0000 | [diff] [blame] | 282 | default: |
| 283 | aom_write_symbol(w, mbmi->motion_mode, |
| 284 | xd->tile_ctx->motion_mode_cdf[mbmi->sb_type], |
| 285 | MOTION_MODES); |
Yue Chen | 69f18e1 | 2016-09-08 14:48:15 -0700 | [diff] [blame] | 286 | } |
Yue Chen | 69f18e1 | 2016-09-08 14:48:15 -0700 | [diff] [blame] | 287 | } |
Wei-Ting Lin | 85a8f70 | 2017-06-22 13:55:15 -0700 | [diff] [blame] | 288 | |
Thomas Davies | d6ee8a8 | 2017-03-02 14:42:50 +0000 | [diff] [blame] | 289 | static void write_delta_qindex(const AV1_COMMON *cm, const MACROBLOCKD *xd, |
| 290 | int delta_qindex, aom_writer *w) { |
Arild Fuldseth | 0744116 | 2016-08-15 15:07:52 +0200 | [diff] [blame] | 291 | int sign = delta_qindex < 0; |
| 292 | int abs = sign ? -delta_qindex : delta_qindex; |
Thomas Davies | d6ee8a8 | 2017-03-02 14:42:50 +0000 | [diff] [blame] | 293 | int rem_bits, thr; |
Thomas Davies | f693610 | 2016-09-05 16:51:31 +0100 | [diff] [blame] | 294 | int smallval = abs < DELTA_Q_SMALL ? 1 : 0; |
Thomas Davies | d6ee8a8 | 2017-03-02 14:42:50 +0000 | [diff] [blame] | 295 | FRAME_CONTEXT *ec_ctx = xd->tile_ctx; |
| 296 | (void)cm; |
Thomas Davies | f693610 | 2016-09-05 16:51:31 +0100 | [diff] [blame] | 297 | |
Thomas Davies | d6ee8a8 | 2017-03-02 14:42:50 +0000 | [diff] [blame] | 298 | aom_write_symbol(w, AOMMIN(abs, DELTA_Q_SMALL), ec_ctx->delta_q_cdf, |
| 299 | DELTA_Q_PROBS + 1); |
Thomas Davies | f693610 | 2016-09-05 16:51:31 +0100 | [diff] [blame] | 300 | |
| 301 | if (!smallval) { |
| 302 | rem_bits = OD_ILOG_NZ(abs - 1) - 1; |
| 303 | thr = (1 << rem_bits) + 1; |
Thomas Davies | 3b93e8e | 2017-09-20 09:59:07 +0100 | [diff] [blame] | 304 | aom_write_literal(w, rem_bits - 1, 3); |
Thomas Davies | f693610 | 2016-09-05 16:51:31 +0100 | [diff] [blame] | 305 | aom_write_literal(w, abs - thr, rem_bits); |
Arild Fuldseth | 0744116 | 2016-08-15 15:07:52 +0200 | [diff] [blame] | 306 | } |
| 307 | if (abs > 0) { |
| 308 | aom_write_bit(w, sign); |
| 309 | } |
| 310 | } |
Thomas Davies | f693610 | 2016-09-05 16:51:31 +0100 | [diff] [blame] | 311 | |
Fangwen Fu | 231fe42 | 2017-04-24 17:52:29 -0700 | [diff] [blame] | 312 | #if CONFIG_EXT_DELTA_Q |
| 313 | static void write_delta_lflevel(const AV1_COMMON *cm, const MACROBLOCKD *xd, |
Debargha Mukherjee | 2382b14 | 2018-02-26 14:31:32 -0800 | [diff] [blame] | 314 | int lf_id, int delta_lflevel, aom_writer *w) { |
Fangwen Fu | 231fe42 | 2017-04-24 17:52:29 -0700 | [diff] [blame] | 315 | int sign = delta_lflevel < 0; |
| 316 | int abs = sign ? -delta_lflevel : delta_lflevel; |
| 317 | int rem_bits, thr; |
| 318 | int smallval = abs < DELTA_LF_SMALL ? 1 : 0; |
Fangwen Fu | 231fe42 | 2017-04-24 17:52:29 -0700 | [diff] [blame] | 319 | FRAME_CONTEXT *ec_ctx = xd->tile_ctx; |
| 320 | (void)cm; |
Fangwen Fu | 231fe42 | 2017-04-24 17:52:29 -0700 | [diff] [blame] | 321 | |
Cheng Chen | 880166a | 2017-10-02 17:48:48 -0700 | [diff] [blame] | 322 | if (cm->delta_lf_multi) { |
Imdad Sardharwalla | f74b4ab | 2018-02-20 17:22:42 +0000 | [diff] [blame] | 323 | assert(lf_id >= 0 && lf_id < (av1_num_planes(cm) > 1 ? FRAME_LF_COUNT |
| 324 | : FRAME_LF_COUNT - 2)); |
Cheng Chen | 880166a | 2017-10-02 17:48:48 -0700 | [diff] [blame] | 325 | aom_write_symbol(w, AOMMIN(abs, DELTA_LF_SMALL), |
| 326 | ec_ctx->delta_lf_multi_cdf[lf_id], DELTA_LF_PROBS + 1); |
| 327 | } else { |
| 328 | aom_write_symbol(w, AOMMIN(abs, DELTA_LF_SMALL), ec_ctx->delta_lf_cdf, |
| 329 | DELTA_LF_PROBS + 1); |
| 330 | } |
Fangwen Fu | 231fe42 | 2017-04-24 17:52:29 -0700 | [diff] [blame] | 331 | |
| 332 | if (!smallval) { |
| 333 | rem_bits = OD_ILOG_NZ(abs - 1) - 1; |
| 334 | thr = (1 << rem_bits) + 1; |
Thomas Davies | 3b93e8e | 2017-09-20 09:59:07 +0100 | [diff] [blame] | 335 | aom_write_literal(w, rem_bits - 1, 3); |
Fangwen Fu | 231fe42 | 2017-04-24 17:52:29 -0700 | [diff] [blame] | 336 | aom_write_literal(w, abs - thr, rem_bits); |
| 337 | } |
| 338 | if (abs > 0) { |
| 339 | aom_write_bit(w, sign); |
| 340 | } |
| 341 | } |
Fangwen Fu | 231fe42 | 2017-04-24 17:52:29 -0700 | [diff] [blame] | 342 | #endif // CONFIG_EXT_DELTA_Q |
Arild Fuldseth | 0744116 | 2016-08-15 15:07:52 +0200 | [diff] [blame] | 343 | |
Sarah Parker | 99e7daa | 2017-08-29 10:30:13 -0700 | [diff] [blame] | 344 | static void pack_map_tokens(aom_writer *w, const TOKENEXTRA **tp, int n, |
| 345 | int num) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 346 | const TOKENEXTRA *p = *tp; |
hui su | 40b9e7f | 2017-07-13 18:15:56 -0700 | [diff] [blame] | 347 | write_uniform(w, n, p->token); // The first color index. |
| 348 | ++p; |
| 349 | --num; |
| 350 | for (int i = 0; i < num; ++i) { |
Sarah Parker | 0cf4d9f | 2017-08-18 13:09:14 -0700 | [diff] [blame] | 351 | aom_write_symbol(w, p->token, p->color_map_cdf, n); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 352 | ++p; |
| 353 | } |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 354 | *tp = p; |
| 355 | } |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 356 | |
Jingning Han | a228569 | 2017-10-25 15:14:31 -0700 | [diff] [blame] | 357 | static void pack_txb_tokens(aom_writer *w, AV1_COMMON *cm, MACROBLOCK *const x, |
Jingning Han | 4fe5f67 | 2017-05-19 15:46:07 -0700 | [diff] [blame] | 358 | const TOKENEXTRA **tp, |
Jingning Han | a228569 | 2017-10-25 15:14:31 -0700 | [diff] [blame] | 359 | const TOKENEXTRA *const tok_end, MACROBLOCKD *xd, |
| 360 | MB_MODE_INFO *mbmi, int plane, |
Jingning Han | 4fe5f67 | 2017-05-19 15:46:07 -0700 | [diff] [blame] | 361 | BLOCK_SIZE plane_bsize, aom_bit_depth_t bit_depth, |
| 362 | int block, int blk_row, int blk_col, |
| 363 | TX_SIZE tx_size, TOKEN_STATS *token_stats) { |
| 364 | const struct macroblockd_plane *const pd = &xd->plane[plane]; |
Jingning Han | 4fe5f67 | 2017-05-19 15:46:07 -0700 | [diff] [blame] | 365 | const int max_blocks_high = max_block_high(xd, plane_bsize, plane); |
| 366 | const int max_blocks_wide = max_block_wide(xd, plane_bsize, plane); |
| 367 | |
| 368 | if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return; |
| 369 | |
Debargha Mukherjee | 8aec7f3 | 2017-12-20 15:48:49 -0800 | [diff] [blame] | 370 | const TX_SIZE plane_tx_size = |
Debargha Mukherjee | 6396d3a | 2017-12-21 00:12:38 -0800 | [diff] [blame] | 371 | plane ? av1_get_uv_tx_size(mbmi, pd->subsampling_x, pd->subsampling_y) |
Hui Su | 7167d95 | 2018-02-01 16:33:12 -0800 | [diff] [blame] | 372 | : mbmi->inter_tx_size[av1_get_txb_size_index(plane_bsize, blk_row, |
| 373 | blk_col)]; |
Jingning Han | 4fe5f67 | 2017-05-19 15:46:07 -0700 | [diff] [blame] | 374 | |
Debargha Mukherjee | 6396d3a | 2017-12-21 00:12:38 -0800 | [diff] [blame] | 375 | if (tx_size == plane_tx_size || plane) { |
Jingning Han | 4fe5f67 | 2017-05-19 15:46:07 -0700 | [diff] [blame] | 376 | TOKEN_STATS tmp_token_stats; |
| 377 | init_token_stats(&tmp_token_stats); |
| 378 | |
Jingning Han | 4fe5f67 | 2017-05-19 15:46:07 -0700 | [diff] [blame] | 379 | tran_low_t *tcoeff = BLOCK_OFFSET(x->mbmi_ext->tcoeff[plane], block); |
| 380 | uint16_t eob = x->mbmi_ext->eobs[plane][block]; |
| 381 | TXB_CTX txb_ctx = { x->mbmi_ext->txb_skip_ctx[plane][block], |
| 382 | x->mbmi_ext->dc_sign_ctx[plane][block] }; |
Luc Trudeau | 2eb9b84 | 2017-12-13 11:19:16 -0500 | [diff] [blame] | 383 | av1_write_coeffs_txb(cm, xd, w, blk_row, blk_col, plane, tx_size, tcoeff, |
| 384 | eob, &txb_ctx); |
Jingning Han | 4fe5f67 | 2017-05-19 15:46:07 -0700 | [diff] [blame] | 385 | #if CONFIG_RD_DEBUG |
| 386 | token_stats->txb_coeff_cost_map[blk_row][blk_col] = tmp_token_stats.cost; |
| 387 | token_stats->cost += tmp_token_stats.cost; |
| 388 | #endif |
| 389 | } else { |
Debargha Mukherjee | e4e18fc | 2017-12-06 23:43:24 -0800 | [diff] [blame] | 390 | const TX_SIZE sub_txs = sub_tx_size_map[1][tx_size]; |
Yue Chen | 0797a20 | 2017-10-27 17:24:56 -0700 | [diff] [blame] | 391 | const int bsw = tx_size_wide_unit[sub_txs]; |
| 392 | const int bsh = tx_size_high_unit[sub_txs]; |
Jingning Han | 4fe5f67 | 2017-05-19 15:46:07 -0700 | [diff] [blame] | 393 | |
Yue Chen | 0797a20 | 2017-10-27 17:24:56 -0700 | [diff] [blame] | 394 | assert(bsw > 0 && bsh > 0); |
Jingning Han | 4fe5f67 | 2017-05-19 15:46:07 -0700 | [diff] [blame] | 395 | |
Yue Chen | 0797a20 | 2017-10-27 17:24:56 -0700 | [diff] [blame] | 396 | for (int r = 0; r < tx_size_high_unit[tx_size]; r += bsh) { |
| 397 | for (int c = 0; c < tx_size_wide_unit[tx_size]; c += bsw) { |
| 398 | const int offsetr = blk_row + r; |
| 399 | const int offsetc = blk_col + c; |
| 400 | const int step = bsh * bsw; |
Jingning Han | 4fe5f67 | 2017-05-19 15:46:07 -0700 | [diff] [blame] | 401 | |
Yue Chen | 0797a20 | 2017-10-27 17:24:56 -0700 | [diff] [blame] | 402 | if (offsetr >= max_blocks_high || offsetc >= max_blocks_wide) continue; |
Jingning Han | 4fe5f67 | 2017-05-19 15:46:07 -0700 | [diff] [blame] | 403 | |
Yue Chen | 0797a20 | 2017-10-27 17:24:56 -0700 | [diff] [blame] | 404 | pack_txb_tokens(w, cm, x, tp, tok_end, xd, mbmi, plane, plane_bsize, |
| 405 | bit_depth, block, offsetr, offsetc, sub_txs, |
| 406 | token_stats); |
| 407 | block += step; |
| 408 | } |
Jingning Han | 4fe5f67 | 2017-05-19 15:46:07 -0700 | [diff] [blame] | 409 | } |
| 410 | } |
| 411 | } |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 412 | |
Rostislav Pehlivanov | 938710c | 2017-11-28 02:26:21 +0000 | [diff] [blame] | 413 | #if CONFIG_SPATIAL_SEGMENTATION |
Frederic Barbier | 0c4a632 | 2018-02-22 10:14:00 +0100 | [diff] [blame] | 414 | static INLINE void set_spatial_segment_id(const AV1_COMMON *const cm, |
| 415 | uint8_t *segment_ids, |
| 416 | BLOCK_SIZE bsize, int mi_row, |
| 417 | int mi_col, int segment_id) { |
| 418 | const int mi_offset = mi_row * cm->mi_cols + mi_col; |
| 419 | const int bw = mi_size_wide[bsize]; |
| 420 | const int bh = mi_size_high[bsize]; |
| 421 | const int xmis = AOMMIN(cm->mi_cols - mi_col, bw); |
| 422 | const int ymis = AOMMIN(cm->mi_rows - mi_row, bh); |
| 423 | int x, y; |
| 424 | |
| 425 | for (y = 0; y < ymis; ++y) |
| 426 | for (x = 0; x < xmis; ++x) |
| 427 | segment_ids[mi_offset + y * cm->mi_cols + x] = segment_id; |
| 428 | } |
| 429 | |
Frederic Barbier | 19f0a23 | 2018-03-07 12:28:20 +0100 | [diff] [blame] | 430 | int av1_neg_interleave(int x, int ref, int max) { |
Rostislav Pehlivanov | f624dd5 | 2017-10-24 16:46:09 +0100 | [diff] [blame] | 431 | const int diff = x - ref; |
| 432 | if (!ref) return x; |
Frederic Barbier | 541429a | 2018-03-07 14:33:42 +0100 | [diff] [blame] | 433 | if (ref >= (max - 1)) return -x + max - 1; |
Rostislav Pehlivanov | f624dd5 | 2017-10-24 16:46:09 +0100 | [diff] [blame] | 434 | if (2 * ref < max) { |
| 435 | if (abs(diff) <= ref) { |
| 436 | if (diff > 0) |
| 437 | return (diff << 1) - 1; |
| 438 | else |
| 439 | return ((-diff) << 1); |
| 440 | } |
| 441 | return x; |
| 442 | } else { |
| 443 | if (abs(diff) < (max - ref)) { |
| 444 | if (diff > 0) |
| 445 | return (diff << 1) - 1; |
| 446 | else |
| 447 | return ((-diff) << 1); |
| 448 | } |
| 449 | return (max - x) - 1; |
| 450 | } |
| 451 | } |
| 452 | |
Rostislav Pehlivanov | 938710c | 2017-11-28 02:26:21 +0000 | [diff] [blame] | 453 | static void write_segment_id(AV1_COMP *cpi, const MB_MODE_INFO *const mbmi, |
| 454 | aom_writer *w, const struct segmentation *seg, |
| 455 | struct segmentation_probs *segp, int mi_row, |
| 456 | int mi_col, int skip) { |
Rostislav Pehlivanov | 938710c | 2017-11-28 02:26:21 +0000 | [diff] [blame] | 457 | if (!seg->enabled || !seg->update_map) return; |
Rostislav Pehlivanov | f624dd5 | 2017-10-24 16:46:09 +0100 | [diff] [blame] | 458 | |
Hui Su | cff20b9 | 2018-03-13 15:35:52 -0700 | [diff] [blame] | 459 | AV1_COMMON *const cm = &cpi->common; |
| 460 | MACROBLOCKD *const xd = &cpi->td.mb.e_mbd; |
| 461 | int cdf_num; |
| 462 | const int pred = av1_get_spatial_seg_pred(cm, xd, mi_row, mi_col, &cdf_num); |
Rostislav Pehlivanov | f624dd5 | 2017-10-24 16:46:09 +0100 | [diff] [blame] | 463 | |
| 464 | if (skip) { |
Hui Su | ad7551e | 2018-03-14 11:13:31 -0700 | [diff] [blame] | 465 | // Still need to transmit tx size for intra blocks even if skip is |
| 466 | // true. Changing segment_id may make the tx size become invalid, e.g |
| 467 | // changing from lossless to lossy. |
| 468 | assert(is_inter_block(mbmi) || !cpi->has_lossless_segment); |
| 469 | |
Rostislav Pehlivanov | 938710c | 2017-11-28 02:26:21 +0000 | [diff] [blame] | 470 | set_spatial_segment_id(cm, cm->current_frame_seg_map, mbmi->sb_type, mi_row, |
| 471 | mi_col, pred); |
| 472 | set_spatial_segment_id(cm, cpi->segmentation_map, mbmi->sb_type, mi_row, |
| 473 | mi_col, pred); |
| 474 | /* mbmi is read only but we need to update segment_id */ |
| 475 | ((MB_MODE_INFO *)mbmi)->segment_id = pred; |
Rostislav Pehlivanov | f624dd5 | 2017-10-24 16:46:09 +0100 | [diff] [blame] | 476 | return; |
| 477 | } |
| 478 | |
Hui Su | cff20b9 | 2018-03-13 15:35:52 -0700 | [diff] [blame] | 479 | const int coded_id = |
Frederic Barbier | 19f0a23 | 2018-03-07 12:28:20 +0100 | [diff] [blame] | 480 | av1_neg_interleave(mbmi->segment_id, pred, seg->last_active_segid + 1); |
Rostislav Pehlivanov | 938710c | 2017-11-28 02:26:21 +0000 | [diff] [blame] | 481 | aom_cdf_prob *pred_cdf = segp->spatial_pred_seg_cdf[cdf_num]; |
Rostislav Pehlivanov | f624dd5 | 2017-10-24 16:46:09 +0100 | [diff] [blame] | 482 | aom_write_symbol(w, coded_id, pred_cdf, 8); |
Rostislav Pehlivanov | 938710c | 2017-11-28 02:26:21 +0000 | [diff] [blame] | 483 | set_spatial_segment_id(cm, cm->current_frame_seg_map, mbmi->sb_type, mi_row, |
| 484 | mi_col, mbmi->segment_id); |
Rostislav Pehlivanov | f624dd5 | 2017-10-24 16:46:09 +0100 | [diff] [blame] | 485 | } |
Rostislav Pehlivanov | 938710c | 2017-11-28 02:26:21 +0000 | [diff] [blame] | 486 | #else |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 487 | static void write_segment_id(aom_writer *w, const struct segmentation *seg, |
Thomas | 9ac5508 | 2016-09-23 18:04:17 +0100 | [diff] [blame] | 488 | struct segmentation_probs *segp, int segment_id) { |
Nathan E. Egge | f627e58 | 2016-08-19 20:06:51 -0400 | [diff] [blame] | 489 | if (seg->enabled && seg->update_map) { |
Nathan E. Egge | f627e58 | 2016-08-19 20:06:51 -0400 | [diff] [blame] | 490 | aom_write_symbol(w, segment_id, segp->tree_cdf, MAX_SEGMENTS); |
Nathan E. Egge | f627e58 | 2016-08-19 20:06:51 -0400 | [diff] [blame] | 491 | } |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 492 | } |
Rostislav Pehlivanov | 938710c | 2017-11-28 02:26:21 +0000 | [diff] [blame] | 493 | #endif |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 494 | |
Thomas Davies | 315f578 | 2017-06-14 15:14:55 +0100 | [diff] [blame] | 495 | #define WRITE_REF_BIT(bname, pname) \ |
Thomas Davies | 0fbd2b7 | 2017-09-12 10:49:45 +0100 | [diff] [blame] | 496 | aom_write_symbol(w, bname, av1_get_pred_cdf_##pname(xd), 2) |
Thomas Davies | 315f578 | 2017-06-14 15:14:55 +0100 | [diff] [blame] | 497 | |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 498 | // This function encodes the reference frame |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 499 | static void write_ref_frames(const AV1_COMMON *cm, const MACROBLOCKD *xd, |
| 500 | aom_writer *w) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 501 | const MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi; |
| 502 | const int is_compound = has_second_ref(mbmi); |
| 503 | const int segment_id = mbmi->segment_id; |
| 504 | |
| 505 | // If segment level coding of this signal is disabled... |
| 506 | // or the segment allows multiple reference frame options |
| 507 | if (segfeature_active(&cm->seg, segment_id, SEG_LVL_REF_FRAME)) { |
| 508 | assert(!is_compound); |
| 509 | assert(mbmi->ref_frame[0] == |
| 510 | get_segdata(&cm->seg, segment_id, SEG_LVL_REF_FRAME)); |
David Barker | d92f356 | 2017-10-09 17:46:23 +0100 | [diff] [blame] | 511 | } |
Sarah Parker | 2b9ec2e | 2017-10-30 17:34:08 -0700 | [diff] [blame] | 512 | #if CONFIG_SEGMENT_GLOBALMV |
David Barker | d92f356 | 2017-10-09 17:46:23 +0100 | [diff] [blame] | 513 | else if (segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP) || |
Sarah Parker | 2b9ec2e | 2017-10-30 17:34:08 -0700 | [diff] [blame] | 514 | segfeature_active(&cm->seg, segment_id, SEG_LVL_GLOBALMV)) |
David Barker | d92f356 | 2017-10-09 17:46:23 +0100 | [diff] [blame] | 515 | #else |
| 516 | else if (segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP)) |
| 517 | #endif |
| 518 | { |
| 519 | assert(!is_compound); |
| 520 | assert(mbmi->ref_frame[0] == LAST_FRAME); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 521 | } else { |
| 522 | // does the feature use compound prediction or not |
| 523 | // (if not specified at the frame/segment level) |
| 524 | if (cm->reference_mode == REFERENCE_MODE_SELECT) { |
Debargha Mukherjee | 0f248c4 | 2017-09-07 12:40:18 -0700 | [diff] [blame] | 525 | if (is_comp_ref_allowed(mbmi->sb_type)) |
Thomas Davies | 860def6 | 2017-06-14 10:00:03 +0100 | [diff] [blame] | 526 | aom_write_symbol(w, is_compound, av1_get_reference_mode_cdf(cm, xd), 2); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 527 | } else { |
| 528 | assert((!is_compound) == (cm->reference_mode == SINGLE_REFERENCE)); |
| 529 | } |
| 530 | |
| 531 | if (is_compound) { |
Zoe Liu | c082bbc | 2017-05-17 13:31:37 -0700 | [diff] [blame] | 532 | const COMP_REFERENCE_TYPE comp_ref_type = has_uni_comp_refs(mbmi) |
| 533 | ? UNIDIR_COMP_REFERENCE |
| 534 | : BIDIR_COMP_REFERENCE; |
Sebastien Alaiwan | 4be6cb3 | 2017-11-02 18:04:11 +0100 | [diff] [blame] | 535 | aom_write_symbol(w, comp_ref_type, av1_get_comp_reference_type_cdf(xd), |
| 536 | 2); |
Zoe Liu | c082bbc | 2017-05-17 13:31:37 -0700 | [diff] [blame] | 537 | |
| 538 | if (comp_ref_type == UNIDIR_COMP_REFERENCE) { |
| 539 | const int bit = mbmi->ref_frame[0] == BWDREF_FRAME; |
Zoe Liu | 4917295 | 2018-01-23 14:32:31 -0800 | [diff] [blame] | 540 | WRITE_REF_BIT(bit, uni_comp_ref_p); |
Zoe Liu | fcf5fa2 | 2017-06-26 16:00:38 -0700 | [diff] [blame] | 541 | |
Zoe Liu | c082bbc | 2017-05-17 13:31:37 -0700 | [diff] [blame] | 542 | if (!bit) { |
Zoe Liu | fcf5fa2 | 2017-06-26 16:00:38 -0700 | [diff] [blame] | 543 | assert(mbmi->ref_frame[0] == LAST_FRAME); |
Sebastien Alaiwan | 4be6cb3 | 2017-11-02 18:04:11 +0100 | [diff] [blame] | 544 | const int bit1 = mbmi->ref_frame[1] == LAST3_FRAME || |
| 545 | mbmi->ref_frame[1] == GOLDEN_FRAME; |
Zoe Liu | 4917295 | 2018-01-23 14:32:31 -0800 | [diff] [blame] | 546 | WRITE_REF_BIT(bit1, uni_comp_ref_p1); |
Sebastien Alaiwan | 4be6cb3 | 2017-11-02 18:04:11 +0100 | [diff] [blame] | 547 | if (bit1) { |
| 548 | const int bit2 = mbmi->ref_frame[1] == GOLDEN_FRAME; |
Zoe Liu | 4917295 | 2018-01-23 14:32:31 -0800 | [diff] [blame] | 549 | WRITE_REF_BIT(bit2, uni_comp_ref_p2); |
Zoe Liu | fcf5fa2 | 2017-06-26 16:00:38 -0700 | [diff] [blame] | 550 | } |
Zoe Liu | fcf5fa2 | 2017-06-26 16:00:38 -0700 | [diff] [blame] | 551 | } else { |
| 552 | assert(mbmi->ref_frame[1] == ALTREF_FRAME); |
Zoe Liu | c082bbc | 2017-05-17 13:31:37 -0700 | [diff] [blame] | 553 | } |
| 554 | |
| 555 | return; |
| 556 | } |
Zoe Liu | fcf5fa2 | 2017-06-26 16:00:38 -0700 | [diff] [blame] | 557 | |
| 558 | assert(comp_ref_type == BIDIR_COMP_REFERENCE); |
Zoe Liu | c082bbc | 2017-05-17 13:31:37 -0700 | [diff] [blame] | 559 | |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 560 | const int bit = (mbmi->ref_frame[0] == GOLDEN_FRAME || |
| 561 | mbmi->ref_frame[0] == LAST3_FRAME); |
Sebastien Alaiwan | 4be6cb3 | 2017-11-02 18:04:11 +0100 | [diff] [blame] | 562 | WRITE_REF_BIT(bit, comp_ref_p); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 563 | |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 564 | if (!bit) { |
Zoe Liu | 8781828 | 2017-11-26 17:09:59 -0800 | [diff] [blame] | 565 | const int bit1 = mbmi->ref_frame[0] == LAST2_FRAME; |
Sebastien Alaiwan | 4be6cb3 | 2017-11-02 18:04:11 +0100 | [diff] [blame] | 566 | WRITE_REF_BIT(bit1, comp_ref_p1); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 567 | } else { |
Sebastien Alaiwan | 4be6cb3 | 2017-11-02 18:04:11 +0100 | [diff] [blame] | 568 | const int bit2 = mbmi->ref_frame[0] == GOLDEN_FRAME; |
| 569 | WRITE_REF_BIT(bit2, comp_ref_p2); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 570 | } |
Zoe Liu | 7b1ec7a | 2017-05-24 22:28:24 -0700 | [diff] [blame] | 571 | |
Sebastien Alaiwan | 4be6cb3 | 2017-11-02 18:04:11 +0100 | [diff] [blame] | 572 | const int bit_bwd = mbmi->ref_frame[1] == ALTREF_FRAME; |
Zoe Liu | 4917295 | 2018-01-23 14:32:31 -0800 | [diff] [blame] | 573 | WRITE_REF_BIT(bit_bwd, comp_bwdref_p); |
Zoe Liu | e9b15e2 | 2017-07-19 15:53:01 -0700 | [diff] [blame] | 574 | |
Sebastien Alaiwan | 4be6cb3 | 2017-11-02 18:04:11 +0100 | [diff] [blame] | 575 | if (!bit_bwd) { |
Zoe Liu | 4917295 | 2018-01-23 14:32:31 -0800 | [diff] [blame] | 576 | WRITE_REF_BIT(mbmi->ref_frame[1] == ALTREF2_FRAME, comp_bwdref_p1); |
Zoe Liu | e9b15e2 | 2017-07-19 15:53:01 -0700 | [diff] [blame] | 577 | } |
Zoe Liu | e9b15e2 | 2017-07-19 15:53:01 -0700 | [diff] [blame] | 578 | |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 579 | } else { |
Zoe Liu | e9b15e2 | 2017-07-19 15:53:01 -0700 | [diff] [blame] | 580 | const int bit0 = (mbmi->ref_frame[0] <= ALTREF_FRAME && |
| 581 | mbmi->ref_frame[0] >= BWDREF_FRAME); |
Zoe Liu | 4917295 | 2018-01-23 14:32:31 -0800 | [diff] [blame] | 582 | WRITE_REF_BIT(bit0, single_ref_p1); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 583 | |
| 584 | if (bit0) { |
Sebastien Alaiwan | 4be6cb3 | 2017-11-02 18:04:11 +0100 | [diff] [blame] | 585 | const int bit1 = mbmi->ref_frame[0] == ALTREF_FRAME; |
Zoe Liu | 4917295 | 2018-01-23 14:32:31 -0800 | [diff] [blame] | 586 | WRITE_REF_BIT(bit1, single_ref_p2); |
Zoe Liu | e9b15e2 | 2017-07-19 15:53:01 -0700 | [diff] [blame] | 587 | |
Sebastien Alaiwan | 4be6cb3 | 2017-11-02 18:04:11 +0100 | [diff] [blame] | 588 | if (!bit1) { |
Zoe Liu | 4917295 | 2018-01-23 14:32:31 -0800 | [diff] [blame] | 589 | WRITE_REF_BIT(mbmi->ref_frame[0] == ALTREF2_FRAME, single_ref_p6); |
Zoe Liu | e9b15e2 | 2017-07-19 15:53:01 -0700 | [diff] [blame] | 590 | } |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 591 | } else { |
| 592 | const int bit2 = (mbmi->ref_frame[0] == LAST3_FRAME || |
| 593 | mbmi->ref_frame[0] == GOLDEN_FRAME); |
Zoe Liu | 4917295 | 2018-01-23 14:32:31 -0800 | [diff] [blame] | 594 | WRITE_REF_BIT(bit2, single_ref_p3); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 595 | |
| 596 | if (!bit2) { |
Sebastien Alaiwan | 4be6cb3 | 2017-11-02 18:04:11 +0100 | [diff] [blame] | 597 | const int bit3 = mbmi->ref_frame[0] != LAST_FRAME; |
Zoe Liu | 4917295 | 2018-01-23 14:32:31 -0800 | [diff] [blame] | 598 | WRITE_REF_BIT(bit3, single_ref_p4); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 599 | } else { |
Sebastien Alaiwan | 4be6cb3 | 2017-11-02 18:04:11 +0100 | [diff] [blame] | 600 | const int bit4 = mbmi->ref_frame[0] != LAST3_FRAME; |
Zoe Liu | 4917295 | 2018-01-23 14:32:31 -0800 | [diff] [blame] | 601 | WRITE_REF_BIT(bit4, single_ref_p5); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 602 | } |
| 603 | } |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 604 | } |
| 605 | } |
| 606 | } |
| 607 | |
Yue Chen | a938362 | 2018-03-08 14:37:09 -0800 | [diff] [blame] | 608 | static void write_filter_intra_mode_info(const AV1_COMMON *cm, |
| 609 | const MACROBLOCKD *xd, |
hui su | 5db9743 | 2016-10-14 16:10:14 -0700 | [diff] [blame] | 610 | const MB_MODE_INFO *const mbmi, |
| 611 | aom_writer *w) { |
Yue Chen | a938362 | 2018-03-08 14:37:09 -0800 | [diff] [blame] | 612 | if (av1_filter_intra_allowed(cm, mbmi)) { |
Yue Chen | b057187 | 2017-12-18 18:12:59 -0800 | [diff] [blame] | 613 | aom_write_symbol(w, mbmi->filter_intra_mode_info.use_filter_intra, |
Yue Chen | 45dfb79 | 2018-03-01 13:02:40 -0800 | [diff] [blame] | 614 | xd->tile_ctx->filter_intra_cdfs[mbmi->sb_type], 2); |
Yue Chen | b057187 | 2017-12-18 18:12:59 -0800 | [diff] [blame] | 615 | if (mbmi->filter_intra_mode_info.use_filter_intra) { |
hui su | 5db9743 | 2016-10-14 16:10:14 -0700 | [diff] [blame] | 616 | const FILTER_INTRA_MODE mode = |
Yue Chen | b057187 | 2017-12-18 18:12:59 -0800 | [diff] [blame] | 617 | mbmi->filter_intra_mode_info.filter_intra_mode; |
Yue Chen | 994dba2 | 2017-12-19 15:27:26 -0800 | [diff] [blame] | 618 | aom_write_symbol(w, mode, xd->tile_ctx->filter_intra_mode_cdf, |
Yue Chen | 63ce36f | 2017-10-10 23:37:31 -0700 | [diff] [blame] | 619 | FILTER_INTRA_MODES); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 620 | } |
| 621 | } |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 622 | } |
| 623 | |
Luc Trudeau | 866da79 | 2018-02-12 11:13:34 -0500 | [diff] [blame] | 624 | static void write_angle_delta(aom_writer *w, int angle_delta, |
| 625 | aom_cdf_prob *cdf) { |
Luc Trudeau | 866da79 | 2018-02-12 11:13:34 -0500 | [diff] [blame] | 626 | aom_write_symbol(w, angle_delta + MAX_ANGLE_DELTA, cdf, |
| 627 | 2 * MAX_ANGLE_DELTA + 1); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 628 | } |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 629 | |
Angie Chiang | 5678ad9 | 2016-11-21 09:38:40 -0800 | [diff] [blame] | 630 | static void write_mb_interp_filter(AV1_COMP *cpi, const MACROBLOCKD *xd, |
| 631 | aom_writer *w) { |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 632 | AV1_COMMON *const cm = &cpi->common; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 633 | const MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi; |
Thomas Davies | 77c7c40 | 2017-01-11 17:58:54 +0000 | [diff] [blame] | 634 | FRAME_CONTEXT *ec_ctx = xd->tile_ctx; |
Jingning Han | 203b1d3 | 2017-01-12 16:00:13 -0800 | [diff] [blame] | 635 | |
Debargha Mukherjee | 0df711f | 2017-05-02 16:00:20 -0700 | [diff] [blame] | 636 | if (!av1_is_interp_needed(xd)) { |
Rupert Swarbrick | 27e9029 | 2017-09-28 17:46:50 +0100 | [diff] [blame] | 637 | assert(mbmi->interp_filters == |
| 638 | av1_broadcast_interp_filter( |
| 639 | av1_unswitchable_filter(cm->interp_filter))); |
Debargha Mukherjee | 0df711f | 2017-05-02 16:00:20 -0700 | [diff] [blame] | 640 | return; |
| 641 | } |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 642 | if (cm->interp_filter == SWITCHABLE) { |
Jingning Han | 203b1d3 | 2017-01-12 16:00:13 -0800 | [diff] [blame] | 643 | int dir; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 644 | for (dir = 0; dir < 2; ++dir) { |
Jingning Han | 4a17335 | 2018-03-01 17:54:07 -0800 | [diff] [blame] | 645 | const int ctx = av1_get_pred_context_switchable_interp(xd, dir); |
| 646 | InterpFilter filter = |
| 647 | av1_extract_interp_filter(mbmi->interp_filters, dir); |
| 648 | aom_write_symbol(w, filter, ec_ctx->switchable_interp_cdf[ctx], |
| 649 | SWITCHABLE_FILTERS); |
| 650 | ++cpi->interp_filter_selected[0][filter]; |
Jingning Han | 127c823 | 2018-02-22 16:54:13 -0800 | [diff] [blame] | 651 | if (cm->seq_params.enable_dual_filter == 0) return; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 652 | } |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 653 | } |
| 654 | } |
| 655 | |
hui su | 33567b2 | 2017-04-30 16:40:19 -0700 | [diff] [blame] | 656 | // Transmit color values with delta encoding. Write the first value as |
| 657 | // literal, and the deltas between each value and the previous one. "min_val" is |
| 658 | // the smallest possible value of the deltas. |
| 659 | static void delta_encode_palette_colors(const int *colors, int num, |
| 660 | int bit_depth, int min_val, |
| 661 | aom_writer *w) { |
| 662 | if (num <= 0) return; |
hui su | fa4ff85 | 2017-05-15 12:20:50 -0700 | [diff] [blame] | 663 | assert(colors[0] < (1 << bit_depth)); |
hui su | 33567b2 | 2017-04-30 16:40:19 -0700 | [diff] [blame] | 664 | aom_write_literal(w, colors[0], bit_depth); |
| 665 | if (num == 1) return; |
| 666 | int max_delta = 0; |
| 667 | int deltas[PALETTE_MAX_SIZE]; |
| 668 | memset(deltas, 0, sizeof(deltas)); |
| 669 | for (int i = 1; i < num; ++i) { |
hui su | fa4ff85 | 2017-05-15 12:20:50 -0700 | [diff] [blame] | 670 | assert(colors[i] < (1 << bit_depth)); |
hui su | 33567b2 | 2017-04-30 16:40:19 -0700 | [diff] [blame] | 671 | const int delta = colors[i] - colors[i - 1]; |
| 672 | deltas[i - 1] = delta; |
| 673 | assert(delta >= min_val); |
| 674 | if (delta > max_delta) max_delta = delta; |
| 675 | } |
| 676 | const int min_bits = bit_depth - 3; |
| 677 | int bits = AOMMAX(av1_ceil_log2(max_delta + 1 - min_val), min_bits); |
hui su | fa4ff85 | 2017-05-15 12:20:50 -0700 | [diff] [blame] | 678 | assert(bits <= bit_depth); |
hui su | 33567b2 | 2017-04-30 16:40:19 -0700 | [diff] [blame] | 679 | int range = (1 << bit_depth) - colors[0] - min_val; |
hui su | d13c24a | 2017-04-07 16:13:07 -0700 | [diff] [blame] | 680 | aom_write_literal(w, bits - min_bits, 2); |
hui su | 33567b2 | 2017-04-30 16:40:19 -0700 | [diff] [blame] | 681 | for (int i = 0; i < num - 1; ++i) { |
| 682 | aom_write_literal(w, deltas[i] - min_val, bits); |
| 683 | range -= deltas[i]; |
| 684 | bits = AOMMIN(bits, av1_ceil_log2(range)); |
hui su | d13c24a | 2017-04-07 16:13:07 -0700 | [diff] [blame] | 685 | } |
| 686 | } |
| 687 | |
hui su | 33567b2 | 2017-04-30 16:40:19 -0700 | [diff] [blame] | 688 | // Transmit luma palette color values. First signal if each color in the color |
| 689 | // cache is used. Those colors that are not in the cache are transmitted with |
| 690 | // delta encoding. |
| 691 | static void write_palette_colors_y(const MACROBLOCKD *const xd, |
| 692 | const PALETTE_MODE_INFO *const pmi, |
| 693 | int bit_depth, aom_writer *w) { |
| 694 | const int n = pmi->palette_size[0]; |
hui su | 33567b2 | 2017-04-30 16:40:19 -0700 | [diff] [blame] | 695 | uint16_t color_cache[2 * PALETTE_MAX_SIZE]; |
Hui Su | 3748bc2 | 2017-08-23 11:30:41 -0700 | [diff] [blame] | 696 | const int n_cache = av1_get_palette_cache(xd, 0, color_cache); |
hui su | 33567b2 | 2017-04-30 16:40:19 -0700 | [diff] [blame] | 697 | int out_cache_colors[PALETTE_MAX_SIZE]; |
| 698 | uint8_t cache_color_found[2 * PALETTE_MAX_SIZE]; |
| 699 | const int n_out_cache = |
| 700 | av1_index_color_cache(color_cache, n_cache, pmi->palette_colors, n, |
| 701 | cache_color_found, out_cache_colors); |
| 702 | int n_in_cache = 0; |
| 703 | for (int i = 0; i < n_cache && n_in_cache < n; ++i) { |
| 704 | const int found = cache_color_found[i]; |
| 705 | aom_write_bit(w, found); |
| 706 | n_in_cache += found; |
| 707 | } |
| 708 | assert(n_in_cache + n_out_cache == n); |
| 709 | delta_encode_palette_colors(out_cache_colors, n_out_cache, bit_depth, 1, w); |
| 710 | } |
| 711 | |
| 712 | // Write chroma palette color values. U channel is handled similarly to the luma |
| 713 | // channel. For v channel, either use delta encoding or transmit raw values |
| 714 | // directly, whichever costs less. |
| 715 | static void write_palette_colors_uv(const MACROBLOCKD *const xd, |
| 716 | const PALETTE_MODE_INFO *const pmi, |
hui su | d13c24a | 2017-04-07 16:13:07 -0700 | [diff] [blame] | 717 | int bit_depth, aom_writer *w) { |
hui su | d13c24a | 2017-04-07 16:13:07 -0700 | [diff] [blame] | 718 | const int n = pmi->palette_size[1]; |
hui su | d13c24a | 2017-04-07 16:13:07 -0700 | [diff] [blame] | 719 | const uint16_t *colors_u = pmi->palette_colors + PALETTE_MAX_SIZE; |
| 720 | const uint16_t *colors_v = pmi->palette_colors + 2 * PALETTE_MAX_SIZE; |
hui su | d13c24a | 2017-04-07 16:13:07 -0700 | [diff] [blame] | 721 | // U channel colors. |
hui su | 33567b2 | 2017-04-30 16:40:19 -0700 | [diff] [blame] | 722 | uint16_t color_cache[2 * PALETTE_MAX_SIZE]; |
Hui Su | 3748bc2 | 2017-08-23 11:30:41 -0700 | [diff] [blame] | 723 | const int n_cache = av1_get_palette_cache(xd, 1, color_cache); |
hui su | 33567b2 | 2017-04-30 16:40:19 -0700 | [diff] [blame] | 724 | int out_cache_colors[PALETTE_MAX_SIZE]; |
| 725 | uint8_t cache_color_found[2 * PALETTE_MAX_SIZE]; |
| 726 | const int n_out_cache = av1_index_color_cache( |
| 727 | color_cache, n_cache, colors_u, n, cache_color_found, out_cache_colors); |
| 728 | int n_in_cache = 0; |
| 729 | for (int i = 0; i < n_cache && n_in_cache < n; ++i) { |
| 730 | const int found = cache_color_found[i]; |
| 731 | aom_write_bit(w, found); |
| 732 | n_in_cache += found; |
hui su | d13c24a | 2017-04-07 16:13:07 -0700 | [diff] [blame] | 733 | } |
hui su | 33567b2 | 2017-04-30 16:40:19 -0700 | [diff] [blame] | 734 | delta_encode_palette_colors(out_cache_colors, n_out_cache, bit_depth, 0, w); |
| 735 | |
| 736 | // V channel colors. Don't use color cache as the colors are not sorted. |
hui su | d13c24a | 2017-04-07 16:13:07 -0700 | [diff] [blame] | 737 | const int max_val = 1 << bit_depth; |
| 738 | int zero_count = 0, min_bits_v = 0; |
| 739 | int bits_v = |
| 740 | av1_get_palette_delta_bits_v(pmi, bit_depth, &zero_count, &min_bits_v); |
| 741 | const int rate_using_delta = |
| 742 | 2 + bit_depth + (bits_v + 1) * (n - 1) - zero_count; |
| 743 | const int rate_using_raw = bit_depth * n; |
| 744 | if (rate_using_delta < rate_using_raw) { // delta encoding |
hui su | fa4ff85 | 2017-05-15 12:20:50 -0700 | [diff] [blame] | 745 | assert(colors_v[0] < (1 << bit_depth)); |
hui su | d13c24a | 2017-04-07 16:13:07 -0700 | [diff] [blame] | 746 | aom_write_bit(w, 1); |
| 747 | aom_write_literal(w, bits_v - min_bits_v, 2); |
| 748 | aom_write_literal(w, colors_v[0], bit_depth); |
hui su | 33567b2 | 2017-04-30 16:40:19 -0700 | [diff] [blame] | 749 | for (int i = 1; i < n; ++i) { |
hui su | fa4ff85 | 2017-05-15 12:20:50 -0700 | [diff] [blame] | 750 | assert(colors_v[i] < (1 << bit_depth)); |
hui su | d13c24a | 2017-04-07 16:13:07 -0700 | [diff] [blame] | 751 | if (colors_v[i] == colors_v[i - 1]) { // No need to signal sign bit. |
| 752 | aom_write_literal(w, 0, bits_v); |
| 753 | continue; |
| 754 | } |
| 755 | const int delta = abs((int)colors_v[i] - colors_v[i - 1]); |
| 756 | const int sign_bit = colors_v[i] < colors_v[i - 1]; |
| 757 | if (delta <= max_val - delta) { |
| 758 | aom_write_literal(w, delta, bits_v); |
| 759 | aom_write_bit(w, sign_bit); |
| 760 | } else { |
| 761 | aom_write_literal(w, max_val - delta, bits_v); |
| 762 | aom_write_bit(w, !sign_bit); |
| 763 | } |
| 764 | } |
| 765 | } else { // Transmit raw values. |
| 766 | aom_write_bit(w, 0); |
hui su | fa4ff85 | 2017-05-15 12:20:50 -0700 | [diff] [blame] | 767 | for (int i = 0; i < n; ++i) { |
| 768 | assert(colors_v[i] < (1 << bit_depth)); |
| 769 | aom_write_literal(w, colors_v[i], bit_depth); |
| 770 | } |
hui su | d13c24a | 2017-04-07 16:13:07 -0700 | [diff] [blame] | 771 | } |
| 772 | } |
hui su | d13c24a | 2017-04-07 16:13:07 -0700 | [diff] [blame] | 773 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 774 | static void write_palette_mode_info(const AV1_COMMON *cm, const MACROBLOCKD *xd, |
Hui Su | 8b618f6 | 2017-12-20 12:03:35 -0800 | [diff] [blame] | 775 | const MODE_INFO *const mi, int mi_row, |
| 776 | int mi_col, aom_writer *w) { |
Imdad Sardharwalla | af8e264 | 2018-01-19 11:46:34 +0000 | [diff] [blame] | 777 | const int num_planes = av1_num_planes(cm); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 778 | const MB_MODE_INFO *const mbmi = &mi->mbmi; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 779 | const BLOCK_SIZE bsize = mbmi->sb_type; |
Hui Su | 473cf89 | 2017-11-08 18:14:31 -0800 | [diff] [blame] | 780 | assert(av1_allow_palette(cm->allow_screen_content_tools, bsize)); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 781 | const PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info; |
Hui Su | c1f411b | 2017-12-19 15:58:28 -0800 | [diff] [blame] | 782 | const int bsize_ctx = av1_get_palette_bsize_ctx(bsize); |
Rupert Swarbrick | 6f9cd94 | 2017-08-02 15:57:18 +0100 | [diff] [blame] | 783 | |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 784 | if (mbmi->mode == DC_PRED) { |
Urvang Joshi | 23a6111 | 2017-01-30 14:59:27 -0800 | [diff] [blame] | 785 | const int n = pmi->palette_size[0]; |
Hui Su | db68555 | 2018-01-12 16:38:33 -0800 | [diff] [blame] | 786 | const int palette_y_mode_ctx = av1_get_palette_mode_ctx(xd); |
Thomas Davies | 59f9231 | 2017-08-23 00:33:12 +0100 | [diff] [blame] | 787 | aom_write_symbol( |
| 788 | w, n > 0, |
Hui Su | c1f411b | 2017-12-19 15:58:28 -0800 | [diff] [blame] | 789 | xd->tile_ctx->palette_y_mode_cdf[bsize_ctx][palette_y_mode_ctx], 2); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 790 | if (n > 0) { |
Thomas Davies | ce7272d | 2017-07-04 16:11:08 +0100 | [diff] [blame] | 791 | aom_write_symbol(w, n - PALETTE_MIN_SIZE, |
Hui Su | c1f411b | 2017-12-19 15:58:28 -0800 | [diff] [blame] | 792 | xd->tile_ctx->palette_y_size_cdf[bsize_ctx], |
Thomas Davies | ce7272d | 2017-07-04 16:11:08 +0100 | [diff] [blame] | 793 | PALETTE_SIZES); |
hui su | 33567b2 | 2017-04-30 16:40:19 -0700 | [diff] [blame] | 794 | write_palette_colors_y(xd, pmi, cm->bit_depth, w); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 795 | } |
| 796 | } |
| 797 | |
Rupert Swarbrick | dcb3cff | 2017-11-09 15:58:33 +0000 | [diff] [blame] | 798 | const int uv_dc_pred = |
Imdad Sardharwalla | af8e264 | 2018-01-19 11:46:34 +0000 | [diff] [blame] | 799 | num_planes > 1 && mbmi->uv_mode == UV_DC_PRED && |
Hui Su | 8b618f6 | 2017-12-20 12:03:35 -0800 | [diff] [blame] | 800 | is_chroma_reference(mi_row, mi_col, bsize, xd->plane[1].subsampling_x, |
| 801 | xd->plane[1].subsampling_y); |
Rupert Swarbrick | dcb3cff | 2017-11-09 15:58:33 +0000 | [diff] [blame] | 802 | if (uv_dc_pred) { |
Urvang Joshi | 23a6111 | 2017-01-30 14:59:27 -0800 | [diff] [blame] | 803 | const int n = pmi->palette_size[1]; |
| 804 | const int palette_uv_mode_ctx = (pmi->palette_size[0] > 0); |
Thomas Davies | 59f9231 | 2017-08-23 00:33:12 +0100 | [diff] [blame] | 805 | aom_write_symbol(w, n > 0, |
| 806 | xd->tile_ctx->palette_uv_mode_cdf[palette_uv_mode_ctx], 2); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 807 | if (n > 0) { |
Thomas Davies | ce7272d | 2017-07-04 16:11:08 +0100 | [diff] [blame] | 808 | aom_write_symbol(w, n - PALETTE_MIN_SIZE, |
Hui Su | c1f411b | 2017-12-19 15:58:28 -0800 | [diff] [blame] | 809 | xd->tile_ctx->palette_uv_size_cdf[bsize_ctx], |
Thomas Davies | ce7272d | 2017-07-04 16:11:08 +0100 | [diff] [blame] | 810 | PALETTE_SIZES); |
hui su | 33567b2 | 2017-04-30 16:40:19 -0700 | [diff] [blame] | 811 | write_palette_colors_uv(xd, pmi, cm->bit_depth, w); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 812 | } |
| 813 | } |
| 814 | } |
| 815 | |
Angie Chiang | c31ea68 | 2017-04-13 16:20:54 -0700 | [diff] [blame] | 816 | void av1_write_tx_type(const AV1_COMMON *const cm, const MACROBLOCKD *xd, |
Luc Trudeau | 2eb9b84 | 2017-12-13 11:19:16 -0500 | [diff] [blame] | 817 | int blk_row, int blk_col, int plane, TX_SIZE tx_size, |
Angie Chiang | c31ea68 | 2017-04-13 16:20:54 -0700 | [diff] [blame] | 818 | aom_writer *w) { |
| 819 | MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi; |
Jingning Han | 2a4da94 | 2016-11-03 18:31:30 -0700 | [diff] [blame] | 820 | const int is_inter = is_inter_block(mbmi); |
Thomas Davies | cef0962 | 2017-01-11 17:27:12 +0000 | [diff] [blame] | 821 | FRAME_CONTEXT *ec_ctx = xd->tile_ctx; |
Thomas Davies | cef0962 | 2017-01-11 17:27:12 +0000 | [diff] [blame] | 822 | |
Angie Chiang | c31ea68 | 2017-04-13 16:20:54 -0700 | [diff] [blame] | 823 | // Only y plane's tx_type is transmitted |
Angie Chiang | 39b06eb | 2017-04-14 09:52:29 -0700 | [diff] [blame] | 824 | if (plane > 0) return; |
| 825 | PLANE_TYPE plane_type = get_plane_type(plane); |
Sarah Parker | 7c71cc0 | 2018-01-29 12:27:58 -0800 | [diff] [blame] | 826 | TX_TYPE tx_type = av1_get_tx_type(plane_type, xd, blk_row, blk_col, tx_size, |
| 827 | cm->reduced_tx_set_used); |
Angie Chiang | c31ea68 | 2017-04-13 16:20:54 -0700 | [diff] [blame] | 828 | |
Hui Su | 99350a6 | 2018-01-11 16:41:09 -0800 | [diff] [blame] | 829 | const TX_SIZE square_tx_size = txsize_sqr_map[tx_size]; |
| 830 | const BLOCK_SIZE bsize = mbmi->sb_type; |
| 831 | if (get_ext_tx_types(tx_size, bsize, is_inter, cm->reduced_tx_set_used) > 1 && |
| 832 | ((!cm->seg.enabled && cm->base_qindex > 0) || |
| 833 | (cm->seg.enabled && xd->qindex[mbmi->segment_id] > 0)) && |
| 834 | !mbmi->skip && |
| 835 | !segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) { |
| 836 | const TxSetType tx_set_type = |
| 837 | get_ext_tx_set_type(tx_size, bsize, is_inter, cm->reduced_tx_set_used); |
| 838 | const int eset = |
| 839 | get_ext_tx_set(tx_size, bsize, is_inter, cm->reduced_tx_set_used); |
| 840 | // eset == 0 should correspond to a set with only DCT_DCT and there |
| 841 | // is no need to send the tx_type |
| 842 | assert(eset > 0); |
| 843 | assert(av1_ext_tx_used[tx_set_type][tx_type]); |
| 844 | if (is_inter) { |
| 845 | aom_write_symbol(w, av1_ext_tx_ind[tx_set_type][tx_type], |
| 846 | ec_ctx->inter_ext_tx_cdf[eset][square_tx_size], |
| 847 | av1_num_ext_tx_set[tx_set_type]); |
| 848 | } else { |
Hui Su | 99350a6 | 2018-01-11 16:41:09 -0800 | [diff] [blame] | 849 | PREDICTION_MODE intra_dir; |
| 850 | if (mbmi->filter_intra_mode_info.use_filter_intra) |
| 851 | intra_dir = |
| 852 | fimode_to_intradir[mbmi->filter_intra_mode_info.filter_intra_mode]; |
| 853 | else |
| 854 | intra_dir = mbmi->mode; |
| 855 | aom_write_symbol( |
| 856 | w, av1_ext_tx_ind[tx_set_type][tx_type], |
| 857 | ec_ctx->intra_ext_tx_cdf[eset][square_tx_size][intra_dir], |
| 858 | av1_num_ext_tx_set[tx_set_type]); |
Lester Lu | 432012f | 2017-08-17 14:39:29 -0700 | [diff] [blame] | 859 | } |
Jingning Han | 2a4da94 | 2016-11-03 18:31:30 -0700 | [diff] [blame] | 860 | } |
| 861 | } |
| 862 | |
Jingning Han | f04254f | 2017-03-08 10:51:35 -0800 | [diff] [blame] | 863 | static void write_intra_mode(FRAME_CONTEXT *frame_ctx, BLOCK_SIZE bsize, |
| 864 | PREDICTION_MODE mode, aom_writer *w) { |
Hui Su | 814f41e | 2017-10-02 12:21:24 -0700 | [diff] [blame] | 865 | aom_write_symbol(w, mode, frame_ctx->y_mode_cdf[size_group_lookup[bsize]], |
Jingning Han | f04254f | 2017-03-08 10:51:35 -0800 | [diff] [blame] | 866 | INTRA_MODES); |
Jingning Han | f04254f | 2017-03-08 10:51:35 -0800 | [diff] [blame] | 867 | } |
| 868 | |
| 869 | static void write_intra_uv_mode(FRAME_CONTEXT *frame_ctx, |
Luc Trudeau | d6d9eee | 2017-07-12 12:36:50 -0400 | [diff] [blame] | 870 | UV_PREDICTION_MODE uv_mode, |
David Michael Barr | cb3a8ef | 2018-01-06 15:48:49 +0900 | [diff] [blame] | 871 | PREDICTION_MODE y_mode, |
Luc Trudeau | 3ec16a3 | 2018-03-01 20:58:09 -0500 | [diff] [blame] | 872 | CFL_ALLOWED_TYPE cfl_allowed, aom_writer *w) { |
David Michael Barr | cb3a8ef | 2018-01-06 15:48:49 +0900 | [diff] [blame] | 873 | aom_write_symbol(w, uv_mode, frame_ctx->uv_mode_cdf[cfl_allowed][y_mode], |
| 874 | UV_INTRA_MODES - !cfl_allowed); |
Jingning Han | f04254f | 2017-03-08 10:51:35 -0800 | [diff] [blame] | 875 | } |
| 876 | |
David Michael Barr | f6eaa15 | 2017-07-19 19:42:28 +0900 | [diff] [blame] | 877 | static void write_cfl_alphas(FRAME_CONTEXT *const ec_ctx, int idx, |
| 878 | int joint_sign, aom_writer *w) { |
| 879 | aom_write_symbol(w, joint_sign, ec_ctx->cfl_sign_cdf, CFL_JOINT_SIGNS); |
| 880 | // Magnitudes are only signaled for nonzero codes. |
| 881 | if (CFL_SIGN_U(joint_sign) != CFL_SIGN_ZERO) { |
| 882 | aom_cdf_prob *cdf_u = ec_ctx->cfl_alpha_cdf[CFL_CONTEXT_U(joint_sign)]; |
| 883 | aom_write_symbol(w, CFL_IDX_U(idx), cdf_u, CFL_ALPHABET_SIZE); |
| 884 | } |
| 885 | if (CFL_SIGN_V(joint_sign) != CFL_SIGN_ZERO) { |
| 886 | aom_cdf_prob *cdf_v = ec_ctx->cfl_alpha_cdf[CFL_CONTEXT_V(joint_sign)]; |
| 887 | aom_write_symbol(w, CFL_IDX_V(idx), cdf_v, CFL_ALPHABET_SIZE); |
| 888 | } |
Luc Trudeau | f533400 | 2017-04-25 12:21:26 -0400 | [diff] [blame] | 889 | } |
Luc Trudeau | f533400 | 2017-04-25 12:21:26 -0400 | [diff] [blame] | 890 | |
Steinar Midtskogen | 6c24b02 | 2017-09-15 09:46:39 +0200 | [diff] [blame] | 891 | static void write_cdef(AV1_COMMON *cm, aom_writer *w, int skip, int mi_col, |
| 892 | int mi_row) { |
Urvang Joshi | e60599a | 2018-03-06 12:57:02 -0800 | [diff] [blame] | 893 | if (cm->all_lossless || (cm->allow_intrabc && NO_FILTER_FOR_IBC)) { |
| 894 | // Initialize to indicate no CDEF for safety. |
| 895 | cm->cdef_bits = 0; |
| 896 | cm->cdef_strengths[0] = 0; |
| 897 | cm->nb_cdef_strengths = 1; |
| 898 | cm->cdef_uv_strengths[0] = 0; |
Hui Su | 7b8ce8d | 2018-02-23 23:03:01 -0800 | [diff] [blame] | 899 | return; |
| 900 | } |
Steinar Midtskogen | 6c24b02 | 2017-09-15 09:46:39 +0200 | [diff] [blame] | 901 | |
| 902 | const int m = ~((1 << (6 - MI_SIZE_LOG2)) - 1); |
| 903 | const MB_MODE_INFO *mbmi = |
| 904 | &cm->mi_grid_visible[(mi_row & m) * cm->mi_stride + (mi_col & m)]->mbmi; |
| 905 | // Initialise when at top left part of the superblock |
Imdad Sardharwalla | 4ec84ab | 2018-02-06 12:20:18 +0000 | [diff] [blame] | 906 | if (!(mi_row & (cm->seq_params.mib_size - 1)) && |
| 907 | !(mi_col & (cm->seq_params.mib_size - 1))) { // Top left? |
Steinar Midtskogen | 6c24b02 | 2017-09-15 09:46:39 +0200 | [diff] [blame] | 908 | cm->cdef_preset[0] = cm->cdef_preset[1] = cm->cdef_preset[2] = |
| 909 | cm->cdef_preset[3] = -1; |
Steinar Midtskogen | 6c24b02 | 2017-09-15 09:46:39 +0200 | [diff] [blame] | 910 | } |
| 911 | |
Debargha Mukherjee | 2ccf4b9 | 2018-02-27 17:30:46 -0800 | [diff] [blame] | 912 | // Emit CDEF param at first non-skip coding block |
Steinar Midtskogen | 6c24b02 | 2017-09-15 09:46:39 +0200 | [diff] [blame] | 913 | const int mask = 1 << (6 - MI_SIZE_LOG2); |
Imdad Sardharwalla | 4ec84ab | 2018-02-06 12:20:18 +0000 | [diff] [blame] | 914 | const int index = cm->seq_params.sb_size == BLOCK_128X128 |
Steinar Midtskogen | 6c24b02 | 2017-09-15 09:46:39 +0200 | [diff] [blame] | 915 | ? !!(mi_col & mask) + 2 * !!(mi_row & mask) |
| 916 | : 0; |
| 917 | if (cm->cdef_preset[index] == -1 && !skip) { |
| 918 | aom_write_literal(w, mbmi->cdef_strength, cm->cdef_bits); |
| 919 | cm->cdef_preset[index] = mbmi->cdef_strength; |
| 920 | } |
Steinar Midtskogen | 6c24b02 | 2017-09-15 09:46:39 +0200 | [diff] [blame] | 921 | } |
| 922 | |
Rostislav Pehlivanov | 938710c | 2017-11-28 02:26:21 +0000 | [diff] [blame] | 923 | static void write_inter_segment_id(AV1_COMP *cpi, aom_writer *w, |
| 924 | const struct segmentation *const seg, |
| 925 | struct segmentation_probs *const segp, |
| 926 | int mi_row, int mi_col, int skip, |
| 927 | int preskip) { |
| 928 | MACROBLOCKD *const xd = &cpi->td.mb.e_mbd; |
| 929 | const MODE_INFO *mi = xd->mi[0]; |
| 930 | const MB_MODE_INFO *const mbmi = &mi->mbmi; |
| 931 | #if CONFIG_SPATIAL_SEGMENTATION |
| 932 | AV1_COMMON *const cm = &cpi->common; |
| 933 | #else |
| 934 | (void)mi_row; |
| 935 | (void)mi_col; |
| 936 | (void)skip; |
| 937 | (void)preskip; |
| 938 | #endif |
| 939 | |
| 940 | if (seg->update_map) { |
| 941 | #if CONFIG_SPATIAL_SEGMENTATION |
| 942 | if (preskip) { |
Rostislav Pehlivanov | dd1a80c | 2018-03-05 21:26:45 +0000 | [diff] [blame] | 943 | if (!seg->preskip_segid) return; |
Rostislav Pehlivanov | 938710c | 2017-11-28 02:26:21 +0000 | [diff] [blame] | 944 | } else { |
Rostislav Pehlivanov | dd1a80c | 2018-03-05 21:26:45 +0000 | [diff] [blame] | 945 | if (seg->preskip_segid) return; |
Rostislav Pehlivanov | 938710c | 2017-11-28 02:26:21 +0000 | [diff] [blame] | 946 | if (skip) { |
Rostislav Pehlivanov | 2d4322b | 2018-01-11 17:19:58 +0000 | [diff] [blame] | 947 | write_segment_id(cpi, mbmi, w, seg, segp, mi_row, mi_col, 1); |
Hui Su | 52b1ba2 | 2017-12-27 14:25:25 -0800 | [diff] [blame] | 948 | if (seg->temporal_update) ((MB_MODE_INFO *)mbmi)->seg_id_predicted = 0; |
Rostislav Pehlivanov | 938710c | 2017-11-28 02:26:21 +0000 | [diff] [blame] | 949 | return; |
| 950 | } |
| 951 | } |
| 952 | #endif |
| 953 | if (seg->temporal_update) { |
| 954 | const int pred_flag = mbmi->seg_id_predicted; |
| 955 | aom_cdf_prob *pred_cdf = av1_get_pred_cdf_seg_id(segp, xd); |
| 956 | aom_write_symbol(w, pred_flag, pred_cdf, 2); |
| 957 | if (!pred_flag) { |
| 958 | #if CONFIG_SPATIAL_SEGMENTATION |
| 959 | write_segment_id(cpi, mbmi, w, seg, segp, mi_row, mi_col, 0); |
| 960 | #else |
| 961 | write_segment_id(w, seg, segp, mbmi->segment_id); |
| 962 | #endif |
| 963 | } |
| 964 | #if CONFIG_SPATIAL_SEGMENTATION |
| 965 | if (pred_flag) { |
| 966 | set_spatial_segment_id(cm, cm->current_frame_seg_map, mbmi->sb_type, |
| 967 | mi_row, mi_col, mbmi->segment_id); |
| 968 | } |
| 969 | #endif |
| 970 | } else { |
| 971 | #if CONFIG_SPATIAL_SEGMENTATION |
| 972 | write_segment_id(cpi, mbmi, w, seg, segp, mi_row, mi_col, 0); |
| 973 | #else |
| 974 | write_segment_id(w, seg, segp, mbmi->segment_id); |
| 975 | #endif |
| 976 | } |
| 977 | } |
| 978 | } |
| 979 | |
Angie Chiang | c31ea68 | 2017-04-13 16:20:54 -0700 | [diff] [blame] | 980 | static void pack_inter_mode_mvs(AV1_COMP *cpi, const int mi_row, |
Sebastien Alaiwan | 0cf54d4 | 2017-10-16 16:10:04 +0200 | [diff] [blame] | 981 | const int mi_col, aom_writer *w) { |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 982 | AV1_COMMON *const cm = &cpi->common; |
Arild Fuldseth | 0744116 | 2016-08-15 15:07:52 +0200 | [diff] [blame] | 983 | MACROBLOCK *const x = &cpi->td.mb; |
| 984 | MACROBLOCKD *const xd = &x->e_mbd; |
Thomas Davies | 2452329 | 2017-01-11 16:56:47 +0000 | [diff] [blame] | 985 | FRAME_CONTEXT *ec_ctx = xd->tile_ctx; |
Angie Chiang | c31ea68 | 2017-04-13 16:20:54 -0700 | [diff] [blame] | 986 | const MODE_INFO *mi = xd->mi[0]; |
Thomas Davies | 2452329 | 2017-01-11 16:56:47 +0000 | [diff] [blame] | 987 | |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 988 | const struct segmentation *const seg = &cm->seg; |
Thomas Davies | 9f5cedd | 2017-07-10 09:20:32 +0100 | [diff] [blame] | 989 | struct segmentation_probs *const segp = &ec_ctx->seg; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 990 | const MB_MODE_INFO *const mbmi = &mi->mbmi; |
| 991 | const MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext; |
| 992 | const PREDICTION_MODE mode = mbmi->mode; |
| 993 | const int segment_id = mbmi->segment_id; |
| 994 | const BLOCK_SIZE bsize = mbmi->sb_type; |
| 995 | const int allow_hp = cm->allow_high_precision_mv; |
| 996 | const int is_inter = is_inter_block(mbmi); |
| 997 | const int is_compound = has_second_ref(mbmi); |
| 998 | int skip, ref; |
David Barker | 45390c1 | 2017-02-20 14:44:40 +0000 | [diff] [blame] | 999 | (void)mi_row; |
| 1000 | (void)mi_col; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1001 | |
Rostislav Pehlivanov | 938710c | 2017-11-28 02:26:21 +0000 | [diff] [blame] | 1002 | write_inter_segment_id(cpi, w, seg, segp, mi_row, mi_col, 0, 1); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1003 | |
Zoe Liu | f40a957 | 2017-10-13 12:37:19 -0700 | [diff] [blame] | 1004 | write_skip_mode(cm, xd, segment_id, mi, w); |
| 1005 | |
Hui Su | e497413 | 2018-03-09 12:06:52 -0800 | [diff] [blame] | 1006 | assert(IMPLIES(mbmi->skip_mode, mbmi->skip)); |
| 1007 | skip = mbmi->skip_mode ? 1 : write_skip(cm, xd, segment_id, mi, w); |
Zoe Liu | f40a957 | 2017-10-13 12:37:19 -0700 | [diff] [blame] | 1008 | |
Rostislav Pehlivanov | 938710c | 2017-11-28 02:26:21 +0000 | [diff] [blame] | 1009 | #if CONFIG_SPATIAL_SEGMENTATION |
| 1010 | write_inter_segment_id(cpi, w, seg, segp, mi_row, mi_col, skip, 0); |
| 1011 | #endif |
Zoe Liu | f40a957 | 2017-10-13 12:37:19 -0700 | [diff] [blame] | 1012 | |
Steinar Midtskogen | 6c24b02 | 2017-09-15 09:46:39 +0200 | [diff] [blame] | 1013 | write_cdef(cm, w, skip, mi_col, mi_row); |
| 1014 | |
Arild Fuldseth | 0744116 | 2016-08-15 15:07:52 +0200 | [diff] [blame] | 1015 | if (cm->delta_q_present_flag) { |
Imdad Sardharwalla | 4ec84ab | 2018-02-06 12:20:18 +0000 | [diff] [blame] | 1016 | int super_block_upper_left = |
| 1017 | ((mi_row & (cm->seq_params.mib_size - 1)) == 0) && |
| 1018 | ((mi_col & (cm->seq_params.mib_size - 1)) == 0); |
| 1019 | if ((bsize != cm->seq_params.sb_size || skip == 0) && |
| 1020 | super_block_upper_left) { |
Arild Fuldseth (arilfuld) | 54de7d6 | 2017-03-20 13:07:11 +0100 | [diff] [blame] | 1021 | assert(mbmi->current_q_index > 0); |
Thomas Davies | f693610 | 2016-09-05 16:51:31 +0100 | [diff] [blame] | 1022 | int reduced_delta_qindex = |
| 1023 | (mbmi->current_q_index - xd->prev_qindex) / cm->delta_q_res; |
Thomas Davies | d6ee8a8 | 2017-03-02 14:42:50 +0000 | [diff] [blame] | 1024 | write_delta_qindex(cm, xd, reduced_delta_qindex, w); |
Arild Fuldseth | 0744116 | 2016-08-15 15:07:52 +0200 | [diff] [blame] | 1025 | xd->prev_qindex = mbmi->current_q_index; |
Fangwen Fu | 231fe42 | 2017-04-24 17:52:29 -0700 | [diff] [blame] | 1026 | #if CONFIG_EXT_DELTA_Q |
Cheng Chen | a97394f | 2017-09-27 15:05:14 -0700 | [diff] [blame] | 1027 | if (cm->delta_lf_present_flag) { |
Cheng Chen | 880166a | 2017-10-02 17:48:48 -0700 | [diff] [blame] | 1028 | if (cm->delta_lf_multi) { |
Imdad Sardharwalla | f74b4ab | 2018-02-20 17:22:42 +0000 | [diff] [blame] | 1029 | const int frame_lf_count = |
| 1030 | av1_num_planes(cm) > 1 ? FRAME_LF_COUNT : FRAME_LF_COUNT - 2; |
| 1031 | for (int lf_id = 0; lf_id < frame_lf_count; ++lf_id) { |
Cheng Chen | 880166a | 2017-10-02 17:48:48 -0700 | [diff] [blame] | 1032 | int reduced_delta_lflevel = |
| 1033 | (mbmi->curr_delta_lf[lf_id] - xd->prev_delta_lf[lf_id]) / |
| 1034 | cm->delta_lf_res; |
| 1035 | write_delta_lflevel(cm, xd, lf_id, reduced_delta_lflevel, w); |
| 1036 | xd->prev_delta_lf[lf_id] = mbmi->curr_delta_lf[lf_id]; |
| 1037 | } |
| 1038 | } else { |
Cheng Chen | a97394f | 2017-09-27 15:05:14 -0700 | [diff] [blame] | 1039 | int reduced_delta_lflevel = |
Cheng Chen | 880166a | 2017-10-02 17:48:48 -0700 | [diff] [blame] | 1040 | (mbmi->current_delta_lf_from_base - xd->prev_delta_lf_from_base) / |
Cheng Chen | a97394f | 2017-09-27 15:05:14 -0700 | [diff] [blame] | 1041 | cm->delta_lf_res; |
Cheng Chen | 880166a | 2017-10-02 17:48:48 -0700 | [diff] [blame] | 1042 | write_delta_lflevel(cm, xd, -1, reduced_delta_lflevel, w); |
| 1043 | xd->prev_delta_lf_from_base = mbmi->current_delta_lf_from_base; |
Cheng Chen | a97394f | 2017-09-27 15:05:14 -0700 | [diff] [blame] | 1044 | } |
| 1045 | } |
Fangwen Fu | 231fe42 | 2017-04-24 17:52:29 -0700 | [diff] [blame] | 1046 | #endif // CONFIG_EXT_DELTA_Q |
Arild Fuldseth | 0744116 | 2016-08-15 15:07:52 +0200 | [diff] [blame] | 1047 | } |
| 1048 | } |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1049 | |
Zoe Liu | 93c3502 | 2018-02-27 17:15:13 -0800 | [diff] [blame] | 1050 | if (!mbmi->skip_mode) write_is_inter(cm, xd, mbmi->segment_id, w, is_inter); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1051 | |
Zoe Liu | 5664419 | 2017-12-19 13:16:18 -0800 | [diff] [blame] | 1052 | if (mbmi->skip_mode) return; |
Zoe Liu | f40a957 | 2017-10-13 12:37:19 -0700 | [diff] [blame] | 1053 | |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1054 | if (!is_inter) { |
Debargha Mukherjee | edced25 | 2017-10-20 00:02:00 -0700 | [diff] [blame] | 1055 | write_intra_mode(ec_ctx, bsize, mode, w); |
Luc Trudeau | 866da79 | 2018-02-12 11:13:34 -0500 | [diff] [blame] | 1056 | const int use_angle_delta = av1_use_angle_delta(bsize); |
| 1057 | |
Hui Su | 7fb9397 | 2018-02-20 21:18:03 -0800 | [diff] [blame] | 1058 | if (use_angle_delta && av1_is_directional_mode(mode)) { |
Luc Trudeau | 866da79 | 2018-02-12 11:13:34 -0500 | [diff] [blame] | 1059 | write_angle_delta(w, mbmi->angle_delta[PLANE_TYPE_Y], |
| 1060 | ec_ctx->angle_delta_cdf[mode - V_PRED]); |
| 1061 | } |
| 1062 | |
David Barker | c2a680e | 2018-02-07 15:53:53 +0000 | [diff] [blame] | 1063 | if (!cm->seq_params.monochrome && |
| 1064 | is_chroma_reference(mi_row, mi_col, bsize, xd->plane[1].subsampling_x, |
Debargha Mukherjee | ce340c3 | 2018-02-26 09:18:33 -0800 | [diff] [blame] | 1065 | xd->plane[1].subsampling_y)) { |
Luc Trudeau | 866da79 | 2018-02-12 11:13:34 -0500 | [diff] [blame] | 1066 | const UV_PREDICTION_MODE uv_mode = mbmi->uv_mode; |
Luc Trudeau | 866da79 | 2018-02-12 11:13:34 -0500 | [diff] [blame] | 1067 | write_intra_uv_mode(ec_ctx, uv_mode, mode, is_cfl_allowed(mbmi), w); |
| 1068 | if (uv_mode == UV_CFL_PRED) |
David Michael Barr | 2319866 | 2017-06-19 23:19:48 +0900 | [diff] [blame] | 1069 | write_cfl_alphas(ec_ctx, mbmi->cfl_alpha_idx, mbmi->cfl_alpha_signs, w); |
Hui Su | 7fb9397 | 2018-02-20 21:18:03 -0800 | [diff] [blame] | 1070 | if (use_angle_delta && av1_is_directional_mode(get_uv_mode(uv_mode))) { |
Luc Trudeau | 866da79 | 2018-02-12 11:13:34 -0500 | [diff] [blame] | 1071 | write_angle_delta(w, mbmi->angle_delta[PLANE_TYPE_UV], |
| 1072 | ec_ctx->angle_delta_cdf[uv_mode - V_PRED]); |
| 1073 | } |
Luc Trudeau | b09b55d | 2017-04-26 10:06:35 -0400 | [diff] [blame] | 1074 | } |
Luc Trudeau | b09b55d | 2017-04-26 10:06:35 -0400 | [diff] [blame] | 1075 | |
Hui Su | e87fb23 | 2017-10-05 15:00:15 -0700 | [diff] [blame] | 1076 | if (av1_allow_palette(cm->allow_screen_content_tools, bsize)) |
Hui Su | 8b618f6 | 2017-12-20 12:03:35 -0800 | [diff] [blame] | 1077 | write_palette_mode_info(cm, xd, mi, mi_row, mi_col, w); |
Yue Chen | 45dfb79 | 2018-03-01 13:02:40 -0800 | [diff] [blame] | 1078 | |
Yue Chen | a938362 | 2018-03-08 14:37:09 -0800 | [diff] [blame] | 1079 | write_filter_intra_mode_info(cm, xd, mbmi, w); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1080 | } else { |
Yaowu Xu | b0d0d00 | 2016-11-22 09:26:43 -0800 | [diff] [blame] | 1081 | int16_t mode_ctx; |
Zoe Liu | fa8bad1 | 2018-01-23 14:32:31 -0800 | [diff] [blame] | 1082 | |
| 1083 | av1_collect_neighbors_ref_counts(xd); |
| 1084 | |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1085 | write_ref_frames(cm, xd, w); |
| 1086 | |
Jingning Han | 7ae50fd | 2018-02-05 16:33:40 -0800 | [diff] [blame] | 1087 | mode_ctx = |
| 1088 | av1_mode_context_analyzer(mbmi_ext->mode_context, mbmi->ref_frame); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1089 | |
| 1090 | // If segment skip is not enabled code the mode. |
| 1091 | if (!segfeature_active(seg, segment_id, SEG_LVL_SKIP)) { |
Debargha Mukherjee | edced25 | 2017-10-20 00:02:00 -0700 | [diff] [blame] | 1092 | if (is_inter_compound_mode(mode)) |
| 1093 | write_inter_compound_mode(cm, xd, w, mode, mode_ctx); |
Debargha Mukherjee | edced25 | 2017-10-20 00:02:00 -0700 | [diff] [blame] | 1094 | else if (is_inter_singleref_mode(mode)) |
| 1095 | write_inter_mode(w, mode, ec_ctx, mode_ctx); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1096 | |
Sebastien Alaiwan | 34d5566 | 2017-11-15 09:36:03 +0100 | [diff] [blame] | 1097 | if (mode == NEWMV || mode == NEW_NEWMV || have_nearmv_in_inter_mode(mode)) |
Debargha Mukherjee | edced25 | 2017-10-20 00:02:00 -0700 | [diff] [blame] | 1098 | write_drl_idx(ec_ctx, mbmi, mbmi_ext, w); |
| 1099 | else |
| 1100 | assert(mbmi->ref_mv_idx == 0); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1101 | } |
| 1102 | |
Debargha Mukherjee | edced25 | 2017-10-20 00:02:00 -0700 | [diff] [blame] | 1103 | if (mode == NEWMV || mode == NEW_NEWMV) { |
| 1104 | int_mv ref_mv; |
| 1105 | for (ref = 0; ref < 1 + is_compound; ++ref) { |
Jingning Han | f050fc1 | 2018-03-09 14:53:33 -0800 | [diff] [blame] | 1106 | nmv_context *nmvc = &ec_ctx->nmvc; |
Debargha Mukherjee | edced25 | 2017-10-20 00:02:00 -0700 | [diff] [blame] | 1107 | ref_mv = mbmi_ext->ref_mvs[mbmi->ref_frame[ref]][0]; |
| 1108 | av1_encode_mv(cpi, w, &mbmi->mv[ref].as_mv, &ref_mv.as_mv, nmvc, |
| 1109 | allow_hp); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1110 | } |
Debargha Mukherjee | edced25 | 2017-10-20 00:02:00 -0700 | [diff] [blame] | 1111 | } else if (mode == NEAREST_NEWMV || mode == NEAR_NEWMV) { |
Jingning Han | f050fc1 | 2018-03-09 14:53:33 -0800 | [diff] [blame] | 1112 | nmv_context *nmvc = &ec_ctx->nmvc; |
Debargha Mukherjee | edced25 | 2017-10-20 00:02:00 -0700 | [diff] [blame] | 1113 | av1_encode_mv(cpi, w, &mbmi->mv[1].as_mv, |
| 1114 | &mbmi_ext->ref_mvs[mbmi->ref_frame[1]][0].as_mv, nmvc, |
| 1115 | allow_hp); |
| 1116 | } else if (mode == NEW_NEARESTMV || mode == NEW_NEARMV) { |
Jingning Han | f050fc1 | 2018-03-09 14:53:33 -0800 | [diff] [blame] | 1117 | nmv_context *nmvc = &ec_ctx->nmvc; |
Debargha Mukherjee | edced25 | 2017-10-20 00:02:00 -0700 | [diff] [blame] | 1118 | av1_encode_mv(cpi, w, &mbmi->mv[0].as_mv, |
| 1119 | &mbmi_ext->ref_mvs[mbmi->ref_frame[0]][0].as_mv, nmvc, |
| 1120 | allow_hp); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1121 | } |
| 1122 | |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1123 | if (cpi->common.reference_mode != COMPOUND_REFERENCE && |
Debargha Mukherjee | 9e2c7a6 | 2017-05-23 21:18:42 -0700 | [diff] [blame] | 1124 | cpi->common.allow_interintra_compound && is_interintra_allowed(mbmi)) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1125 | const int interintra = mbmi->ref_frame[1] == INTRA_FRAME; |
| 1126 | const int bsize_group = size_group_lookup[bsize]; |
Thomas Davies | cff9171 | 2017-07-07 11:49:55 +0100 | [diff] [blame] | 1127 | aom_write_symbol(w, interintra, ec_ctx->interintra_cdf[bsize_group], 2); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1128 | if (interintra) { |
Thomas Davies | 299ff04 | 2017-06-27 13:41:59 +0100 | [diff] [blame] | 1129 | aom_write_symbol(w, mbmi->interintra_mode, |
| 1130 | ec_ctx->interintra_mode_cdf[bsize_group], |
| 1131 | INTERINTRA_MODES); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1132 | if (is_interintra_wedge_used(bsize)) { |
Thomas Davies | cff9171 | 2017-07-07 11:49:55 +0100 | [diff] [blame] | 1133 | aom_write_symbol(w, mbmi->use_wedge_interintra, |
| 1134 | ec_ctx->wedge_interintra_cdf[bsize], 2); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1135 | if (mbmi->use_wedge_interintra) { |
Yue Chen | 73335fa | 2017-12-20 23:33:41 -0800 | [diff] [blame] | 1136 | #if II_WEDGE_IDX_ENTROPY_CODING |
| 1137 | aom_write_symbol(w, mbmi->interintra_wedge_index, |
| 1138 | ec_ctx->wedge_idx_cdf[bsize], 16); |
| 1139 | #else |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 1140 | aom_write_literal(w, mbmi->interintra_wedge_index, |
| 1141 | get_wedge_bits_lookup(bsize)); |
Yue Chen | 73335fa | 2017-12-20 23:33:41 -0800 | [diff] [blame] | 1142 | #endif |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1143 | assert(mbmi->interintra_wedge_sign == 0); |
| 1144 | } |
| 1145 | } |
| 1146 | } |
| 1147 | } |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1148 | |
Sebastien Alaiwan | 0cf54d4 | 2017-10-16 16:10:04 +0200 | [diff] [blame] | 1149 | if (mbmi->ref_frame[1] != INTRA_FRAME) write_motion_mode(cm, xd, mi, w); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1150 | |
Cheng Chen | 33a13d9 | 2017-11-28 16:49:59 -0800 | [diff] [blame] | 1151 | // First write idx to indicate current compound inter prediction mode group |
| 1152 | // Group A (0): jnt_comp, compound_average |
| 1153 | // Group B (1): interintra, compound_segment, wedge |
| 1154 | if (has_second_ref(mbmi)) { |
Zoe Liu | 5f11e91 | 2017-12-05 23:23:56 -0800 | [diff] [blame] | 1155 | const int masked_compound_used = |
| 1156 | is_any_masked_compound_used(bsize) && cm->allow_masked_compound; |
Cheng Chen | 5a88172 | 2017-11-30 17:05:10 -0800 | [diff] [blame] | 1157 | |
Zoe Liu | 5f11e91 | 2017-12-05 23:23:56 -0800 | [diff] [blame] | 1158 | if (masked_compound_used) { |
Cheng Chen | 5a88172 | 2017-11-30 17:05:10 -0800 | [diff] [blame] | 1159 | const int ctx_comp_group_idx = get_comp_group_idx_context(xd); |
| 1160 | aom_write_symbol(w, mbmi->comp_group_idx, |
| 1161 | ec_ctx->comp_group_idx_cdf[ctx_comp_group_idx], 2); |
Zoe Liu | 5f11e91 | 2017-12-05 23:23:56 -0800 | [diff] [blame] | 1162 | } else { |
| 1163 | assert(mbmi->comp_group_idx == 0); |
Cheng Chen | 5a88172 | 2017-11-30 17:05:10 -0800 | [diff] [blame] | 1164 | } |
Cheng Chen | 33a13d9 | 2017-11-28 16:49:59 -0800 | [diff] [blame] | 1165 | |
| 1166 | if (mbmi->comp_group_idx == 0) { |
| 1167 | if (mbmi->compound_idx) |
| 1168 | assert(mbmi->interinter_compound_type == COMPOUND_AVERAGE); |
| 1169 | |
Imdad Sardharwalla | 4d8f777 | 2018-03-15 12:14:48 +0000 | [diff] [blame] | 1170 | if (cm->seq_params.enable_jnt_comp) { |
David Barker | e21f4d9 | 2018-02-26 16:37:24 +0000 | [diff] [blame] | 1171 | const int comp_index_ctx = get_comp_index_context(cm, xd); |
| 1172 | aom_write_symbol(w, mbmi->compound_idx, |
| 1173 | ec_ctx->compound_index_cdf[comp_index_ctx], 2); |
| 1174 | } else { |
| 1175 | assert(mbmi->compound_idx == 1); |
| 1176 | } |
Cheng Chen | 33a13d9 | 2017-11-28 16:49:59 -0800 | [diff] [blame] | 1177 | } else { |
Zoe Liu | 5f11e91 | 2017-12-05 23:23:56 -0800 | [diff] [blame] | 1178 | assert(cpi->common.reference_mode != SINGLE_REFERENCE && |
| 1179 | is_inter_compound_mode(mbmi->mode) && |
| 1180 | mbmi->motion_mode == SIMPLE_TRANSLATION); |
| 1181 | assert(masked_compound_used); |
| 1182 | // compound_segment, wedge |
Cheng Chen | 33a13d9 | 2017-11-28 16:49:59 -0800 | [diff] [blame] | 1183 | assert(mbmi->interinter_compound_type == COMPOUND_WEDGE || |
| 1184 | mbmi->interinter_compound_type == COMPOUND_SEG); |
Cheng Chen | 33a13d9 | 2017-11-28 16:49:59 -0800 | [diff] [blame] | 1185 | |
Zoe Liu | 5f11e91 | 2017-12-05 23:23:56 -0800 | [diff] [blame] | 1186 | if (is_interinter_compound_used(COMPOUND_WEDGE, bsize)) |
| 1187 | aom_write_symbol(w, mbmi->interinter_compound_type - 1, |
| 1188 | ec_ctx->compound_type_cdf[bsize], |
| 1189 | COMPOUND_TYPES - 1); |
| 1190 | |
| 1191 | if (mbmi->interinter_compound_type == COMPOUND_WEDGE) { |
| 1192 | assert(is_interinter_compound_used(COMPOUND_WEDGE, bsize)); |
Yue Chen | 73335fa | 2017-12-20 23:33:41 -0800 | [diff] [blame] | 1193 | #if WEDGE_IDX_ENTROPY_CODING |
| 1194 | aom_write_symbol(w, mbmi->wedge_index, ec_ctx->wedge_idx_cdf[bsize], |
| 1195 | 16); |
| 1196 | #else |
Zoe Liu | 5f11e91 | 2017-12-05 23:23:56 -0800 | [diff] [blame] | 1197 | aom_write_literal(w, mbmi->wedge_index, get_wedge_bits_lookup(bsize)); |
Yue Chen | 73335fa | 2017-12-20 23:33:41 -0800 | [diff] [blame] | 1198 | #endif |
Zoe Liu | 5f11e91 | 2017-12-05 23:23:56 -0800 | [diff] [blame] | 1199 | aom_write_bit(w, mbmi->wedge_sign); |
| 1200 | } else { |
| 1201 | assert(mbmi->interinter_compound_type == COMPOUND_SEG); |
| 1202 | aom_write_literal(w, mbmi->mask_type, MAX_SEG_MASK_BITS); |
Cheng Chen | 33a13d9 | 2017-11-28 16:49:59 -0800 | [diff] [blame] | 1203 | } |
| 1204 | } |
| 1205 | } |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1206 | |
Debargha Mukherjee | 0df711f | 2017-05-02 16:00:20 -0700 | [diff] [blame] | 1207 | write_mb_interp_filter(cpi, xd, w); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1208 | } |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1209 | } |
| 1210 | |
Hui Su | c2232cf | 2017-10-11 17:32:56 -0700 | [diff] [blame] | 1211 | static void write_intrabc_info(AV1_COMMON *cm, MACROBLOCKD *xd, |
| 1212 | const MB_MODE_INFO_EXT *mbmi_ext, |
Jingning Han | 088217b | 2018-02-23 21:55:21 -0800 | [diff] [blame] | 1213 | aom_writer *w) { |
| 1214 | (void)cm; |
Hui Su | c2232cf | 2017-10-11 17:32:56 -0700 | [diff] [blame] | 1215 | const MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi; |
| 1216 | int use_intrabc = is_intrabc_block(mbmi); |
| 1217 | FRAME_CONTEXT *ec_ctx = xd->tile_ctx; |
| 1218 | aom_write_symbol(w, use_intrabc, ec_ctx->intrabc_cdf, 2); |
| 1219 | if (use_intrabc) { |
| 1220 | assert(mbmi->mode == DC_PRED); |
| 1221 | assert(mbmi->uv_mode == UV_DC_PRED); |
Hui Su | 1fbe32a | 2018-02-26 21:44:54 -0800 | [diff] [blame] | 1222 | assert(mbmi->motion_mode == SIMPLE_TRANSLATION); |
Hui Su | c2232cf | 2017-10-11 17:32:56 -0700 | [diff] [blame] | 1223 | int_mv dv_ref = mbmi_ext->ref_mvs[INTRA_FRAME][0]; |
| 1224 | av1_encode_dv(w, &mbmi->mv[0].as_mv, &dv_ref.as_mv, &ec_ctx->ndvc); |
Hui Su | c2232cf | 2017-10-11 17:32:56 -0700 | [diff] [blame] | 1225 | } |
| 1226 | } |
Hui Su | c2232cf | 2017-10-11 17:32:56 -0700 | [diff] [blame] | 1227 | |
Rostislav Pehlivanov | 938710c | 2017-11-28 02:26:21 +0000 | [diff] [blame] | 1228 | static void write_mb_modes_kf(AV1_COMP *cpi, MACROBLOCKD *xd, |
Alex Converse | 44c2bad | 2017-05-11 09:36:10 -0700 | [diff] [blame] | 1229 | const MB_MODE_INFO_EXT *mbmi_ext, |
Jingning Han | 36fe320 | 2017-02-20 22:31:49 -0800 | [diff] [blame] | 1230 | const int mi_row, const int mi_col, |
Angie Chiang | c31ea68 | 2017-04-13 16:20:54 -0700 | [diff] [blame] | 1231 | aom_writer *w) { |
Rostislav Pehlivanov | 938710c | 2017-11-28 02:26:21 +0000 | [diff] [blame] | 1232 | AV1_COMMON *const cm = &cpi->common; |
Thomas Davies | 9f5cedd | 2017-07-10 09:20:32 +0100 | [diff] [blame] | 1233 | FRAME_CONTEXT *ec_ctx = xd->tile_ctx; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1234 | const struct segmentation *const seg = &cm->seg; |
Thomas Davies | 9f5cedd | 2017-07-10 09:20:32 +0100 | [diff] [blame] | 1235 | struct segmentation_probs *const segp = &ec_ctx->seg; |
Angie Chiang | c31ea68 | 2017-04-13 16:20:54 -0700 | [diff] [blame] | 1236 | const MODE_INFO *const mi = xd->mi[0]; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1237 | const MODE_INFO *const above_mi = xd->above_mi; |
| 1238 | const MODE_INFO *const left_mi = xd->left_mi; |
| 1239 | const MB_MODE_INFO *const mbmi = &mi->mbmi; |
| 1240 | const BLOCK_SIZE bsize = mbmi->sb_type; |
Luc Trudeau | 866da79 | 2018-02-12 11:13:34 -0500 | [diff] [blame] | 1241 | const PREDICTION_MODE mode = mbmi->mode; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1242 | |
Rostislav Pehlivanov | 938710c | 2017-11-28 02:26:21 +0000 | [diff] [blame] | 1243 | #if CONFIG_SPATIAL_SEGMENTATION |
Rostislav Pehlivanov | dd1a80c | 2018-03-05 21:26:45 +0000 | [diff] [blame] | 1244 | if (seg->preskip_segid && seg->update_map) |
Rostislav Pehlivanov | 938710c | 2017-11-28 02:26:21 +0000 | [diff] [blame] | 1245 | write_segment_id(cpi, mbmi, w, seg, segp, mi_row, mi_col, 0); |
| 1246 | #else |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1247 | if (seg->update_map) write_segment_id(w, seg, segp, mbmi->segment_id); |
Rostislav Pehlivanov | 938710c | 2017-11-28 02:26:21 +0000 | [diff] [blame] | 1248 | #endif |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1249 | |
Alex Converse | 619576b | 2017-05-10 15:14:18 -0700 | [diff] [blame] | 1250 | const int skip = write_skip(cm, xd, mbmi->segment_id, mi, w); |
Steinar Midtskogen | 6c24b02 | 2017-09-15 09:46:39 +0200 | [diff] [blame] | 1251 | |
Rostislav Pehlivanov | 938710c | 2017-11-28 02:26:21 +0000 | [diff] [blame] | 1252 | #if CONFIG_SPATIAL_SEGMENTATION |
Rostislav Pehlivanov | dd1a80c | 2018-03-05 21:26:45 +0000 | [diff] [blame] | 1253 | if (!seg->preskip_segid && seg->update_map) |
Rostislav Pehlivanov | 938710c | 2017-11-28 02:26:21 +0000 | [diff] [blame] | 1254 | write_segment_id(cpi, mbmi, w, seg, segp, mi_row, mi_col, skip); |
Rostislav Pehlivanov | f624dd5 | 2017-10-24 16:46:09 +0100 | [diff] [blame] | 1255 | #endif |
Steinar Midtskogen | 6c24b02 | 2017-09-15 09:46:39 +0200 | [diff] [blame] | 1256 | |
| 1257 | write_cdef(cm, w, skip, mi_col, mi_row); |
| 1258 | |
Arild Fuldseth | 0744116 | 2016-08-15 15:07:52 +0200 | [diff] [blame] | 1259 | if (cm->delta_q_present_flag) { |
Imdad Sardharwalla | 4ec84ab | 2018-02-06 12:20:18 +0000 | [diff] [blame] | 1260 | int super_block_upper_left = |
| 1261 | ((mi_row & (cm->seq_params.mib_size - 1)) == 0) && |
| 1262 | ((mi_col & (cm->seq_params.mib_size - 1)) == 0); |
| 1263 | if ((bsize != cm->seq_params.sb_size || skip == 0) && |
| 1264 | super_block_upper_left) { |
Arild Fuldseth (arilfuld) | 54de7d6 | 2017-03-20 13:07:11 +0100 | [diff] [blame] | 1265 | assert(mbmi->current_q_index > 0); |
Thomas Davies | f693610 | 2016-09-05 16:51:31 +0100 | [diff] [blame] | 1266 | int reduced_delta_qindex = |
| 1267 | (mbmi->current_q_index - xd->prev_qindex) / cm->delta_q_res; |
Thomas Davies | d6ee8a8 | 2017-03-02 14:42:50 +0000 | [diff] [blame] | 1268 | write_delta_qindex(cm, xd, reduced_delta_qindex, w); |
Arild Fuldseth | 0744116 | 2016-08-15 15:07:52 +0200 | [diff] [blame] | 1269 | xd->prev_qindex = mbmi->current_q_index; |
Fangwen Fu | 231fe42 | 2017-04-24 17:52:29 -0700 | [diff] [blame] | 1270 | #if CONFIG_EXT_DELTA_Q |
Cheng Chen | a97394f | 2017-09-27 15:05:14 -0700 | [diff] [blame] | 1271 | if (cm->delta_lf_present_flag) { |
Cheng Chen | 880166a | 2017-10-02 17:48:48 -0700 | [diff] [blame] | 1272 | if (cm->delta_lf_multi) { |
Imdad Sardharwalla | f74b4ab | 2018-02-20 17:22:42 +0000 | [diff] [blame] | 1273 | const int frame_lf_count = |
| 1274 | av1_num_planes(cm) > 1 ? FRAME_LF_COUNT : FRAME_LF_COUNT - 2; |
| 1275 | for (int lf_id = 0; lf_id < frame_lf_count; ++lf_id) { |
Cheng Chen | 880166a | 2017-10-02 17:48:48 -0700 | [diff] [blame] | 1276 | int reduced_delta_lflevel = |
| 1277 | (mbmi->curr_delta_lf[lf_id] - xd->prev_delta_lf[lf_id]) / |
| 1278 | cm->delta_lf_res; |
| 1279 | write_delta_lflevel(cm, xd, lf_id, reduced_delta_lflevel, w); |
| 1280 | xd->prev_delta_lf[lf_id] = mbmi->curr_delta_lf[lf_id]; |
| 1281 | } |
| 1282 | } else { |
Cheng Chen | a97394f | 2017-09-27 15:05:14 -0700 | [diff] [blame] | 1283 | int reduced_delta_lflevel = |
Cheng Chen | 880166a | 2017-10-02 17:48:48 -0700 | [diff] [blame] | 1284 | (mbmi->current_delta_lf_from_base - xd->prev_delta_lf_from_base) / |
Cheng Chen | a97394f | 2017-09-27 15:05:14 -0700 | [diff] [blame] | 1285 | cm->delta_lf_res; |
Cheng Chen | 880166a | 2017-10-02 17:48:48 -0700 | [diff] [blame] | 1286 | write_delta_lflevel(cm, xd, -1, reduced_delta_lflevel, w); |
| 1287 | xd->prev_delta_lf_from_base = mbmi->current_delta_lf_from_base; |
Cheng Chen | a97394f | 2017-09-27 15:05:14 -0700 | [diff] [blame] | 1288 | } |
| 1289 | } |
Fangwen Fu | 231fe42 | 2017-04-24 17:52:29 -0700 | [diff] [blame] | 1290 | #endif // CONFIG_EXT_DELTA_Q |
Arild Fuldseth | 0744116 | 2016-08-15 15:07:52 +0200 | [diff] [blame] | 1291 | } |
| 1292 | } |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1293 | |
Hui Su | eb2fd5c | 2017-12-15 14:38:01 -0800 | [diff] [blame] | 1294 | if (av1_allow_intrabc(cm)) { |
Jingning Han | 088217b | 2018-02-23 21:55:21 -0800 | [diff] [blame] | 1295 | write_intrabc_info(cm, xd, mbmi_ext, w); |
Hui Su | c2232cf | 2017-10-11 17:32:56 -0700 | [diff] [blame] | 1296 | if (is_intrabc_block(mbmi)) return; |
Alex Converse | 2874430 | 2017-04-13 14:46:22 -0700 | [diff] [blame] | 1297 | } |
Hui Su | c2232cf | 2017-10-11 17:32:56 -0700 | [diff] [blame] | 1298 | |
Luc Trudeau | 866da79 | 2018-02-12 11:13:34 -0500 | [diff] [blame] | 1299 | write_intra_mode_kf(ec_ctx, mi, above_mi, left_mi, mode, w); |
| 1300 | |
| 1301 | const int use_angle_delta = av1_use_angle_delta(bsize); |
Hui Su | 7fb9397 | 2018-02-20 21:18:03 -0800 | [diff] [blame] | 1302 | if (use_angle_delta && av1_is_directional_mode(mode)) { |
Luc Trudeau | 866da79 | 2018-02-12 11:13:34 -0500 | [diff] [blame] | 1303 | write_angle_delta(w, mbmi->angle_delta[PLANE_TYPE_Y], |
| 1304 | ec_ctx->angle_delta_cdf[mode - V_PRED]); |
| 1305 | } |
Jingning Han | 0b7cbe6 | 2017-03-08 10:22:47 -0800 | [diff] [blame] | 1306 | |
David Barker | c2a680e | 2018-02-07 15:53:53 +0000 | [diff] [blame] | 1307 | if (!cm->seq_params.monochrome && |
| 1308 | is_chroma_reference(mi_row, mi_col, bsize, xd->plane[1].subsampling_x, |
Debargha Mukherjee | ce340c3 | 2018-02-26 09:18:33 -0800 | [diff] [blame] | 1309 | xd->plane[1].subsampling_y)) { |
Luc Trudeau | 866da79 | 2018-02-12 11:13:34 -0500 | [diff] [blame] | 1310 | const UV_PREDICTION_MODE uv_mode = mbmi->uv_mode; |
Luc Trudeau | 866da79 | 2018-02-12 11:13:34 -0500 | [diff] [blame] | 1311 | write_intra_uv_mode(ec_ctx, uv_mode, mode, is_cfl_allowed(mbmi), w); |
| 1312 | if (uv_mode == UV_CFL_PRED) |
David Michael Barr | 2319866 | 2017-06-19 23:19:48 +0900 | [diff] [blame] | 1313 | write_cfl_alphas(ec_ctx, mbmi->cfl_alpha_idx, mbmi->cfl_alpha_signs, w); |
Hui Su | 7fb9397 | 2018-02-20 21:18:03 -0800 | [diff] [blame] | 1314 | if (use_angle_delta && av1_is_directional_mode(get_uv_mode(uv_mode))) { |
Luc Trudeau | 866da79 | 2018-02-12 11:13:34 -0500 | [diff] [blame] | 1315 | write_angle_delta(w, mbmi->angle_delta[PLANE_TYPE_UV], |
| 1316 | ec_ctx->angle_delta_cdf[uv_mode - V_PRED]); |
| 1317 | } |
Luc Trudeau | 2c31790 | 2017-04-28 11:06:50 -0400 | [diff] [blame] | 1318 | } |
Debargha Mukherjee | 6ea917e | 2017-10-19 09:31:29 -0700 | [diff] [blame] | 1319 | |
Hui Su | e87fb23 | 2017-10-05 15:00:15 -0700 | [diff] [blame] | 1320 | if (av1_allow_palette(cm->allow_screen_content_tools, bsize)) |
Hui Su | 8b618f6 | 2017-12-20 12:03:35 -0800 | [diff] [blame] | 1321 | write_palette_mode_info(cm, xd, mi, mi_row, mi_col, w); |
Yue Chen | 45dfb79 | 2018-03-01 13:02:40 -0800 | [diff] [blame] | 1322 | |
Yue Chen | a938362 | 2018-03-08 14:37:09 -0800 | [diff] [blame] | 1323 | write_filter_intra_mode_info(cm, xd, mbmi, w); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1324 | } |
| 1325 | |
Angie Chiang | d402282 | 2016-11-02 18:30:25 -0700 | [diff] [blame] | 1326 | #if CONFIG_RD_DEBUG |
| 1327 | static void dump_mode_info(MODE_INFO *mi) { |
| 1328 | printf("\nmi->mbmi.mi_row == %d\n", mi->mbmi.mi_row); |
| 1329 | printf("&& mi->mbmi.mi_col == %d\n", mi->mbmi.mi_col); |
| 1330 | printf("&& mi->mbmi.sb_type == %d\n", mi->mbmi.sb_type); |
| 1331 | printf("&& mi->mbmi.tx_size == %d\n", mi->mbmi.tx_size); |
Jingning Han | 2fac8a4 | 2017-12-14 16:26:00 -0800 | [diff] [blame] | 1332 | printf("&& mi->mbmi.mode == %d\n", mi->mbmi.mode); |
Angie Chiang | d402282 | 2016-11-02 18:30:25 -0700 | [diff] [blame] | 1333 | } |
Angie Chiang | d02001d | 2016-11-06 15:31:49 -0800 | [diff] [blame] | 1334 | static int rd_token_stats_mismatch(RD_STATS *rd_stats, TOKEN_STATS *token_stats, |
| 1335 | int plane) { |
| 1336 | if (rd_stats->txb_coeff_cost[plane] != token_stats->cost) { |
| 1337 | int r, c; |
| 1338 | printf("\nplane %d rd_stats->txb_coeff_cost %d token_stats->cost %d\n", |
| 1339 | plane, rd_stats->txb_coeff_cost[plane], token_stats->cost); |
Angie Chiang | d02001d | 2016-11-06 15:31:49 -0800 | [diff] [blame] | 1340 | printf("rd txb_coeff_cost_map\n"); |
| 1341 | for (r = 0; r < TXB_COEFF_COST_MAP_SIZE; ++r) { |
| 1342 | for (c = 0; c < TXB_COEFF_COST_MAP_SIZE; ++c) { |
| 1343 | printf("%d ", rd_stats->txb_coeff_cost_map[plane][r][c]); |
| 1344 | } |
| 1345 | printf("\n"); |
| 1346 | } |
| 1347 | |
| 1348 | printf("pack txb_coeff_cost_map\n"); |
| 1349 | for (r = 0; r < TXB_COEFF_COST_MAP_SIZE; ++r) { |
| 1350 | for (c = 0; c < TXB_COEFF_COST_MAP_SIZE; ++c) { |
| 1351 | printf("%d ", token_stats->txb_coeff_cost_map[r][c]); |
| 1352 | } |
| 1353 | printf("\n"); |
| 1354 | } |
Angie Chiang | d02001d | 2016-11-06 15:31:49 -0800 | [diff] [blame] | 1355 | return 1; |
| 1356 | } |
| 1357 | return 0; |
| 1358 | } |
Angie Chiang | d402282 | 2016-11-02 18:30:25 -0700 | [diff] [blame] | 1359 | #endif |
| 1360 | |
Di Chen | 5658662 | 2017-06-09 13:49:44 -0700 | [diff] [blame] | 1361 | #if ENC_MISMATCH_DEBUG |
| 1362 | static void enc_dump_logs(AV1_COMP *cpi, int mi_row, int mi_col) { |
| 1363 | AV1_COMMON *const cm = &cpi->common; |
| 1364 | MACROBLOCKD *const xd = &cpi->td.mb.e_mbd; |
| 1365 | MODE_INFO *m; |
| 1366 | xd->mi = cm->mi_grid_visible + (mi_row * cm->mi_stride + mi_col); |
| 1367 | m = xd->mi[0]; |
| 1368 | if (is_inter_block(&m->mbmi)) { |
Zoe Liu | f40a957 | 2017-10-13 12:37:19 -0700 | [diff] [blame] | 1369 | #define FRAME_TO_CHECK 11 |
Zoe Liu | 17af274 | 2017-10-06 10:36:42 -0700 | [diff] [blame] | 1370 | if (cm->current_video_frame == FRAME_TO_CHECK && cm->show_frame == 1) { |
Di Chen | 5658662 | 2017-06-09 13:49:44 -0700 | [diff] [blame] | 1371 | const MB_MODE_INFO *const mbmi = &m->mbmi; |
| 1372 | const BLOCK_SIZE bsize = mbmi->sb_type; |
| 1373 | |
| 1374 | int_mv mv[2]; |
| 1375 | int is_comp_ref = has_second_ref(&m->mbmi); |
| 1376 | int ref; |
| 1377 | |
| 1378 | for (ref = 0; ref < 1 + is_comp_ref; ++ref) |
| 1379 | mv[ref].as_mv = m->mbmi.mv[ref].as_mv; |
| 1380 | |
| 1381 | if (!is_comp_ref) { |
Sebastien Alaiwan | 34d5566 | 2017-11-15 09:36:03 +0100 | [diff] [blame] | 1382 | mv[1].as_int = 0; |
Di Chen | 5658662 | 2017-06-09 13:49:44 -0700 | [diff] [blame] | 1383 | } |
Di Chen | 5658662 | 2017-06-09 13:49:44 -0700 | [diff] [blame] | 1384 | |
Di Chen | 5658662 | 2017-06-09 13:49:44 -0700 | [diff] [blame] | 1385 | MACROBLOCK *const x = &cpi->td.mb; |
Di Chen | 5658662 | 2017-06-09 13:49:44 -0700 | [diff] [blame] | 1386 | const MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext; |
Zoe Liu | f40a957 | 2017-10-13 12:37:19 -0700 | [diff] [blame] | 1387 | const int16_t mode_ctx = |
| 1388 | is_comp_ref ? mbmi_ext->compound_mode_context[mbmi->ref_frame[0]] |
| 1389 | : av1_mode_context_analyzer(mbmi_ext->mode_context, |
Luc Trudeau | 15a18e3 | 2017-12-13 14:15:25 -0500 | [diff] [blame] | 1390 | mbmi->ref_frame); |
Zoe Liu | f40a957 | 2017-10-13 12:37:19 -0700 | [diff] [blame] | 1391 | |
Di Chen | 5658662 | 2017-06-09 13:49:44 -0700 | [diff] [blame] | 1392 | const int16_t newmv_ctx = mode_ctx & NEWMV_CTX_MASK; |
| 1393 | int16_t zeromv_ctx = -1; |
| 1394 | int16_t refmv_ctx = -1; |
Zoe Liu | f40a957 | 2017-10-13 12:37:19 -0700 | [diff] [blame] | 1395 | |
Di Chen | 5658662 | 2017-06-09 13:49:44 -0700 | [diff] [blame] | 1396 | if (mbmi->mode != NEWMV) { |
Sarah Parker | 2b9ec2e | 2017-10-30 17:34:08 -0700 | [diff] [blame] | 1397 | zeromv_ctx = (mode_ctx >> GLOBALMV_OFFSET) & GLOBALMV_CTX_MASK; |
Jingning Han | 59b1263 | 2018-02-12 10:44:52 -0800 | [diff] [blame] | 1398 | if (mbmi->mode != GLOBALMV) |
Di Chen | 5658662 | 2017-06-09 13:49:44 -0700 | [diff] [blame] | 1399 | refmv_ctx = (mode_ctx >> REFMV_OFFSET) & REFMV_CTX_MASK; |
Di Chen | 5658662 | 2017-06-09 13:49:44 -0700 | [diff] [blame] | 1400 | } |
| 1401 | |
Zoe Liu | f40a957 | 2017-10-13 12:37:19 -0700 | [diff] [blame] | 1402 | printf( |
| 1403 | "=== ENCODER ===: " |
| 1404 | "Frame=%d, (mi_row,mi_col)=(%d,%d), skip_mode=%d, mode=%d, bsize=%d, " |
| 1405 | "show_frame=%d, mv[0]=(%d,%d), mv[1]=(%d,%d), ref[0]=%d, " |
| 1406 | "ref[1]=%d, motion_mode=%d, mode_ctx=%d, " |
| 1407 | "newmv_ctx=%d, zeromv_ctx=%d, refmv_ctx=%d, tx_size=%d\n", |
| 1408 | cm->current_video_frame, mi_row, mi_col, mbmi->skip_mode, mbmi->mode, |
| 1409 | bsize, cm->show_frame, mv[0].as_mv.row, mv[0].as_mv.col, |
| 1410 | mv[1].as_mv.row, mv[1].as_mv.col, mbmi->ref_frame[0], |
| 1411 | mbmi->ref_frame[1], mbmi->motion_mode, mode_ctx, newmv_ctx, |
| 1412 | zeromv_ctx, refmv_ctx, mbmi->tx_size); |
Di Chen | 5658662 | 2017-06-09 13:49:44 -0700 | [diff] [blame] | 1413 | } |
| 1414 | } |
| 1415 | } |
| 1416 | #endif // ENC_MISMATCH_DEBUG |
| 1417 | |
Yue Chen | 64550b6 | 2017-01-12 12:18:22 -0800 | [diff] [blame] | 1418 | static void write_mbmi_b(AV1_COMP *cpi, const TileInfo *const tile, |
Sebastien Alaiwan | 0cf54d4 | 2017-10-16 16:10:04 +0200 | [diff] [blame] | 1419 | aom_writer *w, int mi_row, int mi_col) { |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 1420 | AV1_COMMON *const cm = &cpi->common; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1421 | MACROBLOCKD *const xd = &cpi->td.mb.e_mbd; |
| 1422 | MODE_INFO *m; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1423 | int bh, bw; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1424 | xd->mi = cm->mi_grid_visible + (mi_row * cm->mi_stride + mi_col); |
| 1425 | m = xd->mi[0]; |
| 1426 | |
Imdad Sardharwalla | 4ec84ab | 2018-02-06 12:20:18 +0000 | [diff] [blame] | 1427 | assert(m->mbmi.sb_type <= cm->seq_params.sb_size || |
Rupert Swarbrick | 7267857 | 2017-08-02 12:05:26 +0100 | [diff] [blame] | 1428 | (m->mbmi.sb_type >= BLOCK_SIZES && m->mbmi.sb_type < BLOCK_SIZES_ALL)); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1429 | |
Jingning Han | c709e1f | 2016-12-06 14:48:09 -0800 | [diff] [blame] | 1430 | bh = mi_size_high[m->mbmi.sb_type]; |
| 1431 | bw = mi_size_wide[m->mbmi.sb_type]; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1432 | |
| 1433 | cpi->td.mb.mbmi_ext = cpi->mbmi_ext_base + (mi_row * cm->mi_cols + mi_col); |
| 1434 | |
Yaowu Xu | 4a94765 | 2018-03-17 12:39:40 -0700 | [diff] [blame] | 1435 | set_mi_row_col(xd, tile, mi_row, bh, mi_col, bw, cm->mi_rows, cm->mi_cols); |
Yushin Cho | 77bba8d | 2016-11-04 16:36:56 -0700 | [diff] [blame] | 1436 | |
Jingning Han | 0238457 | 2018-02-21 11:28:59 -0800 | [diff] [blame] | 1437 | xd->above_txfm_context = |
| 1438 | cm->above_txfm_context + (mi_col << TX_UNIT_WIDE_LOG2); |
| 1439 | xd->left_txfm_context = xd->left_txfm_context_buffer + |
| 1440 | ((mi_row & MAX_MIB_MASK) << TX_UNIT_HIGH_LOG2); |
| 1441 | |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1442 | if (frame_is_intra_only(cm)) { |
Hui Su | 293f281 | 2018-02-26 14:41:18 -0800 | [diff] [blame] | 1443 | write_mb_modes_kf(cpi, xd, cpi->td.mb.mbmi_ext, mi_row, mi_col, w); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1444 | } else { |
Angie Chiang | 38edf68 | 2017-02-21 15:13:09 -0800 | [diff] [blame] | 1445 | // has_subpel_mv_component needs the ref frame buffers set up to look |
| 1446 | // up if they are scaled. has_subpel_mv_component is in turn needed by |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1447 | // write_switchable_interp_filter, which is called by pack_inter_mode_mvs. |
| 1448 | set_ref_ptrs(cm, xd, m->mbmi.ref_frame[0], m->mbmi.ref_frame[1]); |
Zoe Liu | 85b6646 | 2017-04-20 14:28:19 -0700 | [diff] [blame] | 1449 | |
Di Chen | 5658662 | 2017-06-09 13:49:44 -0700 | [diff] [blame] | 1450 | #if ENC_MISMATCH_DEBUG |
Di Chen | 5658662 | 2017-06-09 13:49:44 -0700 | [diff] [blame] | 1451 | enc_dump_logs(cpi, mi_row, mi_col); |
| 1452 | #endif // ENC_MISMATCH_DEBUG |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1453 | |
Sebastien Alaiwan | 0cf54d4 | 2017-10-16 16:10:04 +0200 | [diff] [blame] | 1454 | pack_inter_mode_mvs(cpi, mi_row, mi_col, w); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1455 | } |
Yue Chen | 64550b6 | 2017-01-12 12:18:22 -0800 | [diff] [blame] | 1456 | } |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1457 | |
Jingning Han | e5e8f4d | 2017-11-20 20:11:04 -0800 | [diff] [blame] | 1458 | static void write_inter_txb_coeff(AV1_COMMON *const cm, MACROBLOCK *const x, |
| 1459 | MB_MODE_INFO *const mbmi, aom_writer *w, |
| 1460 | const TOKENEXTRA **tok, |
| 1461 | const TOKENEXTRA *const tok_end, |
| 1462 | TOKEN_STATS *token_stats, const int row, |
| 1463 | const int col, int *block, const int plane) { |
| 1464 | MACROBLOCKD *const xd = &x->e_mbd; |
| 1465 | const struct macroblockd_plane *const pd = &xd->plane[plane]; |
Debargha Mukherjee | 1961988 | 2017-11-22 13:13:14 -0800 | [diff] [blame] | 1466 | const BLOCK_SIZE bsize = mbmi->sb_type; |
| 1467 | const BLOCK_SIZE bsizec = |
| 1468 | scale_chroma_bsize(bsize, pd->subsampling_x, pd->subsampling_y); |
Jingning Han | e5e8f4d | 2017-11-20 20:11:04 -0800 | [diff] [blame] | 1469 | |
Debargha Mukherjee | 5d149e1 | 2017-12-14 12:49:51 -0800 | [diff] [blame] | 1470 | const BLOCK_SIZE plane_bsize = get_plane_block_size(bsizec, pd); |
Jingning Han | e5e8f4d | 2017-11-20 20:11:04 -0800 | [diff] [blame] | 1471 | |
Debargha Mukherjee | 1961988 | 2017-11-22 13:13:14 -0800 | [diff] [blame] | 1472 | TX_SIZE max_tx_size = get_vartx_max_txsize( |
Debargha Mukherjee | 891a877 | 2017-11-22 10:09:37 -0800 | [diff] [blame] | 1473 | xd, plane_bsize, pd->subsampling_x || pd->subsampling_y); |
Jingning Han | e5e8f4d | 2017-11-20 20:11:04 -0800 | [diff] [blame] | 1474 | const int step = |
| 1475 | tx_size_wide_unit[max_tx_size] * tx_size_high_unit[max_tx_size]; |
| 1476 | const int bkw = tx_size_wide_unit[max_tx_size]; |
| 1477 | const int bkh = tx_size_high_unit[max_tx_size]; |
| 1478 | |
| 1479 | const BLOCK_SIZE max_unit_bsize = get_plane_block_size(BLOCK_64X64, pd); |
| 1480 | int mu_blocks_wide = block_size_wide[max_unit_bsize] >> tx_size_wide_log2[0]; |
| 1481 | int mu_blocks_high = block_size_high[max_unit_bsize] >> tx_size_high_log2[0]; |
| 1482 | |
| 1483 | int blk_row, blk_col; |
| 1484 | |
| 1485 | const int num_4x4_w = block_size_wide[plane_bsize] >> tx_size_wide_log2[0]; |
| 1486 | const int num_4x4_h = block_size_high[plane_bsize] >> tx_size_wide_log2[0]; |
| 1487 | |
Jingning Han | cdbc47f | 2018-01-12 16:21:07 -0800 | [diff] [blame] | 1488 | const int unit_height = |
| 1489 | AOMMIN(mu_blocks_high + (row >> pd->subsampling_y), num_4x4_h); |
| 1490 | const int unit_width = |
| 1491 | AOMMIN(mu_blocks_wide + (col >> pd->subsampling_x), num_4x4_w); |
| 1492 | for (blk_row = row >> pd->subsampling_y; blk_row < unit_height; |
| 1493 | blk_row += bkh) { |
| 1494 | for (blk_col = col >> pd->subsampling_x; blk_col < unit_width; |
| 1495 | blk_col += bkw) { |
Sebastien Alaiwan | cad5ebc | 2018-02-20 16:18:20 +0100 | [diff] [blame] | 1496 | pack_txb_tokens(w, cm, x, tok, tok_end, xd, mbmi, plane, plane_bsize, |
| 1497 | cm->bit_depth, *block, blk_row, blk_col, max_tx_size, |
| 1498 | token_stats); |
Jingning Han | e5e8f4d | 2017-11-20 20:11:04 -0800 | [diff] [blame] | 1499 | *block += step; |
| 1500 | } |
| 1501 | } |
| 1502 | } |
| 1503 | |
Yue Chen | 64550b6 | 2017-01-12 12:18:22 -0800 | [diff] [blame] | 1504 | static void write_tokens_b(AV1_COMP *cpi, const TileInfo *const tile, |
| 1505 | aom_writer *w, const TOKENEXTRA **tok, |
| 1506 | const TOKENEXTRA *const tok_end, int mi_row, |
| 1507 | int mi_col) { |
| 1508 | AV1_COMMON *const cm = &cpi->common; |
Imdad Sardharwalla | af8e264 | 2018-01-19 11:46:34 +0000 | [diff] [blame] | 1509 | const int num_planes = av1_num_planes(cm); |
Yue Chen | 64550b6 | 2017-01-12 12:18:22 -0800 | [diff] [blame] | 1510 | MACROBLOCKD *const xd = &cpi->td.mb.e_mbd; |
Wei-Ting Lin | 1d46d90 | 2017-06-26 15:57:18 -0700 | [diff] [blame] | 1511 | const int mi_offset = mi_row * cm->mi_stride + mi_col; |
| 1512 | MODE_INFO *const m = *(cm->mi_grid_visible + mi_offset); |
Luc Trudeau | 3e32f1a | 2017-03-08 10:37:49 -0500 | [diff] [blame] | 1513 | MB_MODE_INFO *const mbmi = &m->mbmi; |
Yue Chen | 64550b6 | 2017-01-12 12:18:22 -0800 | [diff] [blame] | 1514 | int plane; |
| 1515 | int bh, bw; |
Yushin Cho | 258a024 | 2017-03-06 13:53:01 -0800 | [diff] [blame] | 1516 | MACROBLOCK *const x = &cpi->td.mb; |
Yue Chen | 64550b6 | 2017-01-12 12:18:22 -0800 | [diff] [blame] | 1517 | (void)tok; |
| 1518 | (void)tok_end; |
Wei-Ting Lin | 1d46d90 | 2017-06-26 15:57:18 -0700 | [diff] [blame] | 1519 | xd->mi = cm->mi_grid_visible + mi_offset; |
Yue Chen | 64550b6 | 2017-01-12 12:18:22 -0800 | [diff] [blame] | 1520 | |
Imdad Sardharwalla | 4ec84ab | 2018-02-06 12:20:18 +0000 | [diff] [blame] | 1521 | assert(mbmi->sb_type <= cm->seq_params.sb_size || |
Rupert Swarbrick | 7267857 | 2017-08-02 12:05:26 +0100 | [diff] [blame] | 1522 | (mbmi->sb_type >= BLOCK_SIZES && mbmi->sb_type < BLOCK_SIZES_ALL)); |
Yue Chen | 64550b6 | 2017-01-12 12:18:22 -0800 | [diff] [blame] | 1523 | |
Luc Trudeau | 3e32f1a | 2017-03-08 10:37:49 -0500 | [diff] [blame] | 1524 | bh = mi_size_high[mbmi->sb_type]; |
| 1525 | bw = mi_size_wide[mbmi->sb_type]; |
Yue Chen | 64550b6 | 2017-01-12 12:18:22 -0800 | [diff] [blame] | 1526 | cpi->td.mb.mbmi_ext = cpi->mbmi_ext_base + (mi_row * cm->mi_cols + mi_col); |
| 1527 | |
Yaowu Xu | 4a94765 | 2018-03-17 12:39:40 -0700 | [diff] [blame] | 1528 | set_mi_row_col(xd, tile, mi_row, bh, mi_col, bw, cm->mi_rows, cm->mi_cols); |
Yue Chen | 64550b6 | 2017-01-12 12:18:22 -0800 | [diff] [blame] | 1529 | |
Luc Trudeau | 3e32f1a | 2017-03-08 10:37:49 -0500 | [diff] [blame] | 1530 | if (!mbmi->skip) { |
Jingning Han | ad54a98 | 2018-01-12 14:40:29 -0800 | [diff] [blame] | 1531 | if (!is_inter_block(mbmi)) |
| 1532 | av1_write_coeffs_mb(cm, x, mi_row, mi_col, w, mbmi->sb_type); |
| 1533 | |
Jingning Han | cdbc47f | 2018-01-12 16:21:07 -0800 | [diff] [blame] | 1534 | if (is_inter_block(mbmi)) { |
| 1535 | int block[MAX_MB_PLANE] = { 0 }; |
| 1536 | const struct macroblockd_plane *const y_pd = &xd->plane[0]; |
| 1537 | const BLOCK_SIZE plane_bsize = get_plane_block_size(mbmi->sb_type, y_pd); |
Jingning Han | 42a0fb3 | 2016-10-31 10:43:31 -0700 | [diff] [blame] | 1538 | const int num_4x4_w = |
| 1539 | block_size_wide[plane_bsize] >> tx_size_wide_log2[0]; |
| 1540 | const int num_4x4_h = |
| 1541 | block_size_high[plane_bsize] >> tx_size_wide_log2[0]; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1542 | int row, col; |
Angie Chiang | d402282 | 2016-11-02 18:30:25 -0700 | [diff] [blame] | 1543 | TOKEN_STATS token_stats; |
Angie Chiang | d02001d | 2016-11-06 15:31:49 -0800 | [diff] [blame] | 1544 | init_token_stats(&token_stats); |
Angie Chiang | d402282 | 2016-11-02 18:30:25 -0700 | [diff] [blame] | 1545 | |
Jingning Han | cdbc47f | 2018-01-12 16:21:07 -0800 | [diff] [blame] | 1546 | const BLOCK_SIZE max_unit_bsize = get_plane_block_size(BLOCK_64X64, y_pd); |
Jingning Han | c2b797f | 2017-07-19 09:37:11 -0700 | [diff] [blame] | 1547 | int mu_blocks_wide = |
| 1548 | block_size_wide[max_unit_bsize] >> tx_size_wide_log2[0]; |
| 1549 | int mu_blocks_high = |
| 1550 | block_size_high[max_unit_bsize] >> tx_size_high_log2[0]; |
| 1551 | |
| 1552 | mu_blocks_wide = AOMMIN(num_4x4_w, mu_blocks_wide); |
| 1553 | mu_blocks_high = AOMMIN(num_4x4_h, mu_blocks_high); |
| 1554 | |
Jingning Han | cdbc47f | 2018-01-12 16:21:07 -0800 | [diff] [blame] | 1555 | for (row = 0; row < num_4x4_h; row += mu_blocks_high) { |
| 1556 | for (col = 0; col < num_4x4_w; col += mu_blocks_wide) { |
| 1557 | for (plane = 0; plane < num_planes && is_inter_block(mbmi); ++plane) { |
| 1558 | const struct macroblockd_plane *const pd = &xd->plane[plane]; |
| 1559 | if (!is_chroma_reference(mi_row, mi_col, mbmi->sb_type, |
| 1560 | pd->subsampling_x, pd->subsampling_y)) { |
Jingning Han | cdbc47f | 2018-01-12 16:21:07 -0800 | [diff] [blame] | 1561 | continue; |
| 1562 | } |
Jingning Han | e5e8f4d | 2017-11-20 20:11:04 -0800 | [diff] [blame] | 1563 | write_inter_txb_coeff(cm, x, mbmi, w, tok, tok_end, &token_stats, |
Jingning Han | cdbc47f | 2018-01-12 16:21:07 -0800 | [diff] [blame] | 1564 | row, col, &block[plane], plane); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1565 | } |
| 1566 | } |
Angie Chiang | d02001d | 2016-11-06 15:31:49 -0800 | [diff] [blame] | 1567 | #if CONFIG_RD_DEBUG |
Angie Chiang | 3963d63 | 2016-11-10 18:41:40 -0800 | [diff] [blame] | 1568 | if (mbmi->sb_type >= BLOCK_8X8 && |
Luc Trudeau | 3e32f1a | 2017-03-08 10:37:49 -0500 | [diff] [blame] | 1569 | rd_token_stats_mismatch(&mbmi->rd_stats, &token_stats, plane)) { |
Angie Chiang | d02001d | 2016-11-06 15:31:49 -0800 | [diff] [blame] | 1570 | dump_mode_info(m); |
| 1571 | assert(0); |
| 1572 | } |
Jingning Han | fe45b21 | 2016-11-22 10:30:23 -0800 | [diff] [blame] | 1573 | #endif // CONFIG_RD_DEBUG |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1574 | } |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1575 | } |
| 1576 | } |
| 1577 | } |
| 1578 | |
Yue Chen | 64550b6 | 2017-01-12 12:18:22 -0800 | [diff] [blame] | 1579 | static void write_modes_b(AV1_COMP *cpi, const TileInfo *const tile, |
| 1580 | aom_writer *w, const TOKENEXTRA **tok, |
Sebastien Alaiwan | 0cf54d4 | 2017-10-16 16:10:04 +0200 | [diff] [blame] | 1581 | const TOKENEXTRA *const tok_end, int mi_row, |
| 1582 | int mi_col) { |
| 1583 | write_mbmi_b(cpi, tile, w, mi_row, mi_col); |
Jingning Han | f5a4d3b | 2017-08-27 23:01:19 -0700 | [diff] [blame] | 1584 | |
Jingning Han | 088217b | 2018-02-23 21:55:21 -0800 | [diff] [blame] | 1585 | AV1_COMMON *cm = &cpi->common; |
| 1586 | MACROBLOCKD *xd = &cpi->td.mb.e_mbd; |
| 1587 | MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi; |
| 1588 | for (int plane = 0; plane < AOMMIN(2, av1_num_planes(cm)); ++plane) { |
| 1589 | const uint8_t palette_size_plane = |
| 1590 | mbmi->palette_mode_info.palette_size[plane]; |
Jingning Han | 088217b | 2018-02-23 21:55:21 -0800 | [diff] [blame] | 1591 | assert(!mbmi->skip_mode || !palette_size_plane); |
Jingning Han | 088217b | 2018-02-23 21:55:21 -0800 | [diff] [blame] | 1592 | if (palette_size_plane > 0) { |
| 1593 | assert(mbmi->use_intrabc == 0); |
| 1594 | assert(av1_allow_palette(cm->allow_screen_content_tools, mbmi->sb_type)); |
| 1595 | int rows, cols; |
| 1596 | av1_get_block_dimensions(mbmi->sb_type, plane, xd, NULL, NULL, &rows, |
| 1597 | &cols); |
| 1598 | assert(*tok < tok_end); |
| 1599 | pack_map_tokens(w, tok, palette_size_plane, rows * cols); |
| 1600 | } |
| 1601 | } |
| 1602 | |
| 1603 | BLOCK_SIZE bsize = mbmi->sb_type; |
| 1604 | int is_inter_tx = is_inter_block(mbmi) || is_intrabc_block(mbmi); |
| 1605 | int skip = mbmi->skip; |
| 1606 | int segment_id = mbmi->segment_id; |
| 1607 | if (cm->tx_mode == TX_MODE_SELECT && block_signals_txsize(bsize) && |
| 1608 | !(is_inter_tx && skip) && !xd->lossless[segment_id]) { |
| 1609 | if (is_inter_tx) { // This implies skip flag is 0. |
| 1610 | const TX_SIZE max_tx_size = get_vartx_max_txsize(xd, bsize, 0); |
| 1611 | const int txbh = tx_size_high_unit[max_tx_size]; |
| 1612 | const int txbw = tx_size_wide_unit[max_tx_size]; |
| 1613 | const int width = block_size_wide[bsize] >> tx_size_wide_log2[0]; |
| 1614 | const int height = block_size_high[bsize] >> tx_size_wide_log2[0]; |
| 1615 | int idx, idy; |
| 1616 | for (idy = 0; idy < height; idy += txbh) |
| 1617 | for (idx = 0; idx < width; idx += txbw) |
| 1618 | write_tx_size_vartx(cm, xd, mbmi, max_tx_size, 0, idy, idx, w); |
| 1619 | } else { |
| 1620 | write_selected_tx_size(cm, xd, w); |
Jingning Han | b6211eb | 2018-02-27 10:46:42 -0800 | [diff] [blame] | 1621 | set_txfm_ctxs(mbmi->tx_size, xd->n8_w, xd->n8_h, 0, xd); |
Jingning Han | 088217b | 2018-02-23 21:55:21 -0800 | [diff] [blame] | 1622 | } |
| 1623 | } else { |
Jingning Han | b6211eb | 2018-02-27 10:46:42 -0800 | [diff] [blame] | 1624 | set_txfm_ctxs(mbmi->tx_size, xd->n8_w, xd->n8_h, |
| 1625 | skip && is_inter_block(mbmi), xd); |
Jingning Han | 088217b | 2018-02-23 21:55:21 -0800 | [diff] [blame] | 1626 | } |
| 1627 | |
Sebastien Alaiwan | 0cf54d4 | 2017-10-16 16:10:04 +0200 | [diff] [blame] | 1628 | write_tokens_b(cpi, tile, w, tok, tok_end, mi_row, mi_col); |
Yue Chen | 64550b6 | 2017-01-12 12:18:22 -0800 | [diff] [blame] | 1629 | } |
| 1630 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 1631 | static void write_partition(const AV1_COMMON *const cm, |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1632 | const MACROBLOCKD *const xd, int hbs, int mi_row, |
| 1633 | int mi_col, PARTITION_TYPE p, BLOCK_SIZE bsize, |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 1634 | aom_writer *w) { |
Alex Converse | 55c6bde | 2017-01-12 15:55:31 -0800 | [diff] [blame] | 1635 | const int is_partition_point = bsize >= BLOCK_8X8; |
Thomas Davies | c2ec0e4 | 2017-01-11 16:27:27 +0000 | [diff] [blame] | 1636 | |
Jingning Han | bf9c6b7 | 2016-12-14 14:50:45 -0800 | [diff] [blame] | 1637 | if (!is_partition_point) return; |
| 1638 | |
Rupert Swarbrick | eb12393 | 2017-11-22 15:20:47 +0000 | [diff] [blame] | 1639 | const int has_rows = (mi_row + hbs) < cm->mi_rows; |
| 1640 | const int has_cols = (mi_col + hbs) < cm->mi_cols; |
| 1641 | const int ctx = partition_plane_context(xd, mi_row, mi_col, bsize); |
| 1642 | FRAME_CONTEXT *ec_ctx = xd->tile_ctx; |
| 1643 | |
| 1644 | if (!has_rows && !has_cols) { |
| 1645 | assert(p == PARTITION_SPLIT); |
| 1646 | return; |
| 1647 | } |
| 1648 | |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1649 | if (has_rows && has_cols) { |
Rupert Swarbrick | eb12393 | 2017-11-22 15:20:47 +0000 | [diff] [blame] | 1650 | aom_write_symbol(w, p, ec_ctx->partition_cdf[ctx], |
| 1651 | partition_cdf_length(bsize)); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1652 | } else if (!has_rows && has_cols) { |
| 1653 | assert(p == PARTITION_SPLIT || p == PARTITION_HORZ); |
Stanislav Vitvitskyy | 8711cf5 | 2017-08-18 15:17:57 -0700 | [diff] [blame] | 1654 | assert(bsize > BLOCK_8X8); |
| 1655 | aom_cdf_prob cdf[2]; |
Rupert Swarbrick | eb12393 | 2017-11-22 15:20:47 +0000 | [diff] [blame] | 1656 | partition_gather_vert_alike(cdf, ec_ctx->partition_cdf[ctx], bsize); |
Stanislav Vitvitskyy | 8711cf5 | 2017-08-18 15:17:57 -0700 | [diff] [blame] | 1657 | aom_write_cdf(w, p == PARTITION_SPLIT, cdf, 2); |
Rupert Swarbrick | eb12393 | 2017-11-22 15:20:47 +0000 | [diff] [blame] | 1658 | } else { |
| 1659 | assert(has_rows && !has_cols); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1660 | assert(p == PARTITION_SPLIT || p == PARTITION_VERT); |
Stanislav Vitvitskyy | 8711cf5 | 2017-08-18 15:17:57 -0700 | [diff] [blame] | 1661 | assert(bsize > BLOCK_8X8); |
| 1662 | aom_cdf_prob cdf[2]; |
Rupert Swarbrick | eb12393 | 2017-11-22 15:20:47 +0000 | [diff] [blame] | 1663 | partition_gather_horz_alike(cdf, ec_ctx->partition_cdf[ctx], bsize); |
Stanislav Vitvitskyy | 8711cf5 | 2017-08-18 15:17:57 -0700 | [diff] [blame] | 1664 | aom_write_cdf(w, p == PARTITION_SPLIT, cdf, 2); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1665 | } |
| 1666 | } |
| 1667 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 1668 | static void write_modes_sb(AV1_COMP *const cpi, const TileInfo *const tile, |
| 1669 | aom_writer *const w, const TOKENEXTRA **tok, |
Sebastien Alaiwan | 0cf54d4 | 2017-10-16 16:10:04 +0200 | [diff] [blame] | 1670 | const TOKENEXTRA *const tok_end, int mi_row, |
| 1671 | int mi_col, BLOCK_SIZE bsize) { |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 1672 | const AV1_COMMON *const cm = &cpi->common; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1673 | MACROBLOCKD *const xd = &cpi->td.mb.e_mbd; |
Jingning Han | c709e1f | 2016-12-06 14:48:09 -0800 | [diff] [blame] | 1674 | const int hbs = mi_size_wide[bsize] / 2; |
Rupert Swarbrick | 93c39e9 | 2017-07-12 11:11:02 +0100 | [diff] [blame] | 1675 | const int quarter_step = mi_size_wide[bsize] / 4; |
| 1676 | int i; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1677 | const PARTITION_TYPE partition = get_partition(cm, mi_row, mi_col, bsize); |
| 1678 | const BLOCK_SIZE subsize = get_subsize(bsize, partition); |
Jingning Han | 5226184 | 2016-12-14 12:17:49 -0800 | [diff] [blame] | 1679 | |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1680 | if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return; |
| 1681 | |
Debargha Mukherjee | a78c8f5 | 2018-01-31 11:14:38 -0800 | [diff] [blame] | 1682 | const int num_planes = av1_num_planes(cm); |
Imdad Sardharwalla | af8e264 | 2018-01-19 11:46:34 +0000 | [diff] [blame] | 1683 | for (int plane = 0; plane < num_planes; ++plane) { |
Imdad Sardharwalla | 7d2e5c9 | 2018-01-05 18:41:00 +0000 | [diff] [blame] | 1684 | int rcol0, rcol1, rrow0, rrow1, tile_tl_idx; |
| 1685 | if (av1_loop_restoration_corners_in_sb(cm, plane, mi_row, mi_col, bsize, |
| 1686 | &rcol0, &rcol1, &rrow0, &rrow1, |
| 1687 | &tile_tl_idx)) { |
| 1688 | const int rstride = cm->rst_info[plane].horz_units_per_tile; |
| 1689 | for (int rrow = rrow0; rrow < rrow1; ++rrow) { |
| 1690 | for (int rcol = rcol0; rcol < rcol1; ++rcol) { |
Urvang Joshi | 813186b | 2018-03-08 15:38:46 -0800 | [diff] [blame] | 1691 | const int runit_idx = tile_tl_idx + rcol + rrow * rstride; |
Imdad Sardharwalla | 7d2e5c9 | 2018-01-05 18:41:00 +0000 | [diff] [blame] | 1692 | const RestorationUnitInfo *rui = |
Urvang Joshi | 813186b | 2018-03-08 15:38:46 -0800 | [diff] [blame] | 1693 | &cm->rst_info[plane].unit_info[runit_idx]; |
Yue Chen | 4439151 | 2018-03-13 15:37:26 -0700 | [diff] [blame] | 1694 | loop_restoration_write_sb_coeffs(cm, xd, rui, w, plane, |
| 1695 | cpi->td.counts); |
Imdad Sardharwalla | 7d2e5c9 | 2018-01-05 18:41:00 +0000 | [diff] [blame] | 1696 | } |
| 1697 | } |
| 1698 | } |
| 1699 | } |
Imdad Sardharwalla | 7d2e5c9 | 2018-01-05 18:41:00 +0000 | [diff] [blame] | 1700 | |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1701 | write_partition(cm, xd, hbs, mi_row, mi_col, partition, bsize, w); |
Debargha Mukherjee | edced25 | 2017-10-20 00:02:00 -0700 | [diff] [blame] | 1702 | switch (partition) { |
| 1703 | case PARTITION_NONE: |
| 1704 | write_modes_b(cpi, tile, w, tok, tok_end, mi_row, mi_col); |
| 1705 | break; |
| 1706 | case PARTITION_HORZ: |
| 1707 | write_modes_b(cpi, tile, w, tok, tok_end, mi_row, mi_col); |
| 1708 | if (mi_row + hbs < cm->mi_rows) |
| 1709 | write_modes_b(cpi, tile, w, tok, tok_end, mi_row + hbs, mi_col); |
| 1710 | break; |
| 1711 | case PARTITION_VERT: |
| 1712 | write_modes_b(cpi, tile, w, tok, tok_end, mi_row, mi_col); |
| 1713 | if (mi_col + hbs < cm->mi_cols) |
| 1714 | write_modes_b(cpi, tile, w, tok, tok_end, mi_row, mi_col + hbs); |
| 1715 | break; |
| 1716 | case PARTITION_SPLIT: |
| 1717 | write_modes_sb(cpi, tile, w, tok, tok_end, mi_row, mi_col, subsize); |
| 1718 | write_modes_sb(cpi, tile, w, tok, tok_end, mi_row, mi_col + hbs, subsize); |
| 1719 | write_modes_sb(cpi, tile, w, tok, tok_end, mi_row + hbs, mi_col, subsize); |
| 1720 | write_modes_sb(cpi, tile, w, tok, tok_end, mi_row + hbs, mi_col + hbs, |
| 1721 | subsize); |
| 1722 | break; |
Debargha Mukherjee | edced25 | 2017-10-20 00:02:00 -0700 | [diff] [blame] | 1723 | case PARTITION_HORZ_A: |
| 1724 | write_modes_b(cpi, tile, w, tok, tok_end, mi_row, mi_col); |
| 1725 | write_modes_b(cpi, tile, w, tok, tok_end, mi_row, mi_col + hbs); |
| 1726 | write_modes_b(cpi, tile, w, tok, tok_end, mi_row + hbs, mi_col); |
| 1727 | break; |
| 1728 | case PARTITION_HORZ_B: |
| 1729 | write_modes_b(cpi, tile, w, tok, tok_end, mi_row, mi_col); |
| 1730 | write_modes_b(cpi, tile, w, tok, tok_end, mi_row + hbs, mi_col); |
| 1731 | write_modes_b(cpi, tile, w, tok, tok_end, mi_row + hbs, mi_col + hbs); |
| 1732 | break; |
| 1733 | case PARTITION_VERT_A: |
| 1734 | write_modes_b(cpi, tile, w, tok, tok_end, mi_row, mi_col); |
| 1735 | write_modes_b(cpi, tile, w, tok, tok_end, mi_row + hbs, mi_col); |
| 1736 | write_modes_b(cpi, tile, w, tok, tok_end, mi_row, mi_col + hbs); |
| 1737 | break; |
| 1738 | case PARTITION_VERT_B: |
| 1739 | write_modes_b(cpi, tile, w, tok, tok_end, mi_row, mi_col); |
| 1740 | write_modes_b(cpi, tile, w, tok, tok_end, mi_row, mi_col + hbs); |
| 1741 | write_modes_b(cpi, tile, w, tok, tok_end, mi_row + hbs, mi_col + hbs); |
| 1742 | break; |
Debargha Mukherjee | edced25 | 2017-10-20 00:02:00 -0700 | [diff] [blame] | 1743 | case PARTITION_HORZ_4: |
| 1744 | for (i = 0; i < 4; ++i) { |
| 1745 | int this_mi_row = mi_row + i * quarter_step; |
| 1746 | if (i > 0 && this_mi_row >= cm->mi_rows) break; |
Rupert Swarbrick | 93c39e9 | 2017-07-12 11:11:02 +0100 | [diff] [blame] | 1747 | |
Debargha Mukherjee | edced25 | 2017-10-20 00:02:00 -0700 | [diff] [blame] | 1748 | write_modes_b(cpi, tile, w, tok, tok_end, this_mi_row, mi_col); |
| 1749 | } |
| 1750 | break; |
| 1751 | case PARTITION_VERT_4: |
| 1752 | for (i = 0; i < 4; ++i) { |
| 1753 | int this_mi_col = mi_col + i * quarter_step; |
| 1754 | if (i > 0 && this_mi_col >= cm->mi_cols) break; |
Rupert Swarbrick | 93c39e9 | 2017-07-12 11:11:02 +0100 | [diff] [blame] | 1755 | |
Debargha Mukherjee | edced25 | 2017-10-20 00:02:00 -0700 | [diff] [blame] | 1756 | write_modes_b(cpi, tile, w, tok, tok_end, mi_row, this_mi_col); |
| 1757 | } |
| 1758 | break; |
Debargha Mukherjee | edced25 | 2017-10-20 00:02:00 -0700 | [diff] [blame] | 1759 | default: assert(0); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1760 | } |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1761 | |
Debargha Mukherjee | 1687085 | 2018-02-28 10:00:17 -0800 | [diff] [blame] | 1762 | // update partition context |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1763 | update_ext_partition_context(xd, mi_row, mi_col, subsize, bsize, partition); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1764 | } |
| 1765 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 1766 | static void write_modes(AV1_COMP *const cpi, const TileInfo *const tile, |
| 1767 | aom_writer *const w, const TOKENEXTRA **tok, |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1768 | const TOKENEXTRA *const tok_end) { |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 1769 | AV1_COMMON *const cm = &cpi->common; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1770 | MACROBLOCKD *const xd = &cpi->td.mb.e_mbd; |
| 1771 | const int mi_row_start = tile->mi_row_start; |
| 1772 | const int mi_row_end = tile->mi_row_end; |
| 1773 | const int mi_col_start = tile->mi_col_start; |
| 1774 | const int mi_col_end = tile->mi_col_end; |
| 1775 | int mi_row, mi_col; |
Fangwen Fu | 7b9f2b3 | 2017-01-17 14:01:52 -0800 | [diff] [blame] | 1776 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 1777 | av1_zero_above_context(cm, mi_col_start, mi_col_end); |
Arild Fuldseth | 0744116 | 2016-08-15 15:07:52 +0200 | [diff] [blame] | 1778 | if (cpi->common.delta_q_present_flag) { |
| 1779 | xd->prev_qindex = cpi->common.base_qindex; |
Fangwen Fu | 231fe42 | 2017-04-24 17:52:29 -0700 | [diff] [blame] | 1780 | #if CONFIG_EXT_DELTA_Q |
| 1781 | if (cpi->common.delta_lf_present_flag) { |
Imdad Sardharwalla | f74b4ab | 2018-02-20 17:22:42 +0000 | [diff] [blame] | 1782 | const int frame_lf_count = |
| 1783 | av1_num_planes(cm) > 1 ? FRAME_LF_COUNT : FRAME_LF_COUNT - 2; |
| 1784 | for (int lf_id = 0; lf_id < frame_lf_count; ++lf_id) |
Cheng Chen | a97394f | 2017-09-27 15:05:14 -0700 | [diff] [blame] | 1785 | xd->prev_delta_lf[lf_id] = 0; |
Fangwen Fu | 231fe42 | 2017-04-24 17:52:29 -0700 | [diff] [blame] | 1786 | xd->prev_delta_lf_from_base = 0; |
| 1787 | } |
| 1788 | #endif // CONFIG_EXT_DELTA_Q |
Arild Fuldseth | 0744116 | 2016-08-15 15:07:52 +0200 | [diff] [blame] | 1789 | } |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1790 | |
Imdad Sardharwalla | 4ec84ab | 2018-02-06 12:20:18 +0000 | [diff] [blame] | 1791 | for (mi_row = mi_row_start; mi_row < mi_row_end; |
| 1792 | mi_row += cm->seq_params.mib_size) { |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 1793 | av1_zero_left_context(xd); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1794 | |
Imdad Sardharwalla | 4ec84ab | 2018-02-06 12:20:18 +0000 | [diff] [blame] | 1795 | for (mi_col = mi_col_start; mi_col < mi_col_end; |
| 1796 | mi_col += cm->seq_params.mib_size) { |
| 1797 | write_modes_sb(cpi, tile, w, tok, tok_end, mi_row, mi_col, |
| 1798 | cm->seq_params.sb_size); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1799 | } |
| 1800 | } |
| 1801 | } |
| 1802 | |
Debargha Mukherjee | 5cd2ab9 | 2016-09-08 15:15:17 -0700 | [diff] [blame] | 1803 | static void encode_restoration_mode(AV1_COMMON *cm, |
| 1804 | struct aom_write_bit_buffer *wb) { |
Urvang Joshi | 5ec7b81 | 2018-02-28 14:37:06 -0800 | [diff] [blame] | 1805 | assert(!cm->all_lossless); |
Hui Su | 27df834 | 2017-11-07 15:16:05 -0800 | [diff] [blame] | 1806 | if (cm->allow_intrabc && NO_FILTER_FOR_IBC) return; |
Hui Su | 293f281 | 2018-02-26 14:41:18 -0800 | [diff] [blame] | 1807 | const int num_planes = av1_num_planes(cm); |
Rupert Swarbrick | dcb3cff | 2017-11-09 15:58:33 +0000 | [diff] [blame] | 1808 | int all_none = 1, chroma_none = 1; |
Imdad Sardharwalla | af8e264 | 2018-01-19 11:46:34 +0000 | [diff] [blame] | 1809 | for (int p = 0; p < num_planes; ++p) { |
Rupert Swarbrick | 4596deb | 2017-11-07 18:06:38 +0000 | [diff] [blame] | 1810 | RestorationInfo *rsi = &cm->rst_info[p]; |
Rupert Swarbrick | dcb3cff | 2017-11-09 15:58:33 +0000 | [diff] [blame] | 1811 | if (rsi->frame_restoration_type != RESTORE_NONE) { |
| 1812 | all_none = 0; |
| 1813 | chroma_none &= p == 0; |
| 1814 | } |
Debargha Mukherjee | a43a2d9 | 2017-01-03 15:14:57 -0800 | [diff] [blame] | 1815 | switch (rsi->frame_restoration_type) { |
Debargha Mukherjee | a3d4fe5 | 2017-05-19 16:22:54 -0700 | [diff] [blame] | 1816 | case RESTORE_NONE: |
| 1817 | aom_wb_write_bit(wb, 0); |
| 1818 | aom_wb_write_bit(wb, 0); |
| 1819 | break; |
Debargha Mukherjee | d23ceea | 2017-05-18 20:33:52 -0700 | [diff] [blame] | 1820 | case RESTORE_WIENER: |
| 1821 | aom_wb_write_bit(wb, 1); |
| 1822 | aom_wb_write_bit(wb, 0); |
| 1823 | break; |
| 1824 | case RESTORE_SGRPROJ: |
| 1825 | aom_wb_write_bit(wb, 1); |
| 1826 | aom_wb_write_bit(wb, 1); |
| 1827 | break; |
Debargha Mukherjee | a3d4fe5 | 2017-05-19 16:22:54 -0700 | [diff] [blame] | 1828 | case RESTORE_SWITCHABLE: |
| 1829 | aom_wb_write_bit(wb, 0); |
| 1830 | aom_wb_write_bit(wb, 1); |
| 1831 | break; |
Debargha Mukherjee | a43a2d9 | 2017-01-03 15:14:57 -0800 | [diff] [blame] | 1832 | default: assert(0); |
| 1833 | } |
| 1834 | } |
Rupert Swarbrick | dcb3cff | 2017-11-09 15:58:33 +0000 | [diff] [blame] | 1835 | if (!all_none) { |
Imdad Sardharwalla | b1dce0a | 2018-02-12 16:43:59 +0000 | [diff] [blame] | 1836 | assert(cm->seq_params.sb_size == BLOCK_64X64 || |
| 1837 | cm->seq_params.sb_size == BLOCK_128X128); |
| 1838 | const int sb_size = cm->seq_params.sb_size == BLOCK_128X128 ? 128 : 64; |
| 1839 | |
Rupert Swarbrick | 4596deb | 2017-11-07 18:06:38 +0000 | [diff] [blame] | 1840 | RestorationInfo *rsi = &cm->rst_info[0]; |
Imdad Sardharwalla | b1dce0a | 2018-02-12 16:43:59 +0000 | [diff] [blame] | 1841 | |
| 1842 | assert(rsi->restoration_unit_size >= sb_size); |
Urvang Joshi | 813186b | 2018-03-08 15:38:46 -0800 | [diff] [blame] | 1843 | assert(RESTORATION_UNITSIZE_MAX == 256); |
Imdad Sardharwalla | b1dce0a | 2018-02-12 16:43:59 +0000 | [diff] [blame] | 1844 | |
| 1845 | if (sb_size == 64) { |
| 1846 | aom_wb_write_bit(wb, rsi->restoration_unit_size > 64); |
| 1847 | } |
| 1848 | if (rsi->restoration_unit_size > 64) { |
| 1849 | aom_wb_write_bit(wb, rsi->restoration_unit_size > 128); |
Debargha Mukherjee | 1008c1e | 2017-03-06 19:18:43 -0800 | [diff] [blame] | 1850 | } |
| 1851 | } |
Rupert Swarbrick | dcb3cff | 2017-11-09 15:58:33 +0000 | [diff] [blame] | 1852 | |
Imdad Sardharwalla | af8e264 | 2018-01-19 11:46:34 +0000 | [diff] [blame] | 1853 | if (num_planes > 1) { |
Rupert Swarbrick | dcb3cff | 2017-11-09 15:58:33 +0000 | [diff] [blame] | 1854 | int s = AOMMIN(cm->subsampling_x, cm->subsampling_y); |
| 1855 | if (s && !chroma_none) { |
Johann | b0ef6ff | 2018-02-08 14:32:21 -0800 | [diff] [blame] | 1856 | aom_wb_write_bit(wb, cm->rst_info[1].restoration_unit_size != |
| 1857 | cm->rst_info[0].restoration_unit_size); |
Rupert Swarbrick | dcb3cff | 2017-11-09 15:58:33 +0000 | [diff] [blame] | 1858 | assert(cm->rst_info[1].restoration_unit_size == |
| 1859 | cm->rst_info[0].restoration_unit_size || |
| 1860 | cm->rst_info[1].restoration_unit_size == |
| 1861 | (cm->rst_info[0].restoration_unit_size >> s)); |
| 1862 | assert(cm->rst_info[2].restoration_unit_size == |
| 1863 | cm->rst_info[1].restoration_unit_size); |
| 1864 | } else if (!s) { |
| 1865 | assert(cm->rst_info[1].restoration_unit_size == |
| 1866 | cm->rst_info[0].restoration_unit_size); |
| 1867 | assert(cm->rst_info[2].restoration_unit_size == |
| 1868 | cm->rst_info[1].restoration_unit_size); |
| 1869 | } |
Debargha Mukherjee | 84f567c | 2017-06-21 10:53:59 -0700 | [diff] [blame] | 1870 | } |
Debargha Mukherjee | 5cd2ab9 | 2016-09-08 15:15:17 -0700 | [diff] [blame] | 1871 | } |
| 1872 | |
Rupert Swarbrick | dd6f09a | 2017-10-19 16:10:23 +0100 | [diff] [blame] | 1873 | static void write_wiener_filter(int wiener_win, const WienerInfo *wiener_info, |
Debargha Mukherjee | cfc12f3 | 2017-04-18 07:03:32 -0700 | [diff] [blame] | 1874 | WienerInfo *ref_wiener_info, aom_writer *wb) { |
Debargha Mukherjee | 1cb757c | 2017-08-21 02:46:31 -0700 | [diff] [blame] | 1875 | if (wiener_win == WIENER_WIN) |
| 1876 | aom_write_primitive_refsubexpfin( |
| 1877 | wb, WIENER_FILT_TAP0_MAXV - WIENER_FILT_TAP0_MINV + 1, |
| 1878 | WIENER_FILT_TAP0_SUBEXP_K, |
| 1879 | ref_wiener_info->vfilter[0] - WIENER_FILT_TAP0_MINV, |
| 1880 | wiener_info->vfilter[0] - WIENER_FILT_TAP0_MINV); |
| 1881 | else |
| 1882 | assert(wiener_info->vfilter[0] == 0 && |
| 1883 | wiener_info->vfilter[WIENER_WIN - 1] == 0); |
Debargha Mukherjee | cfc12f3 | 2017-04-18 07:03:32 -0700 | [diff] [blame] | 1884 | aom_write_primitive_refsubexpfin( |
| 1885 | wb, WIENER_FILT_TAP1_MAXV - WIENER_FILT_TAP1_MINV + 1, |
| 1886 | WIENER_FILT_TAP1_SUBEXP_K, |
| 1887 | ref_wiener_info->vfilter[1] - WIENER_FILT_TAP1_MINV, |
| 1888 | wiener_info->vfilter[1] - WIENER_FILT_TAP1_MINV); |
| 1889 | aom_write_primitive_refsubexpfin( |
| 1890 | wb, WIENER_FILT_TAP2_MAXV - WIENER_FILT_TAP2_MINV + 1, |
| 1891 | WIENER_FILT_TAP2_SUBEXP_K, |
| 1892 | ref_wiener_info->vfilter[2] - WIENER_FILT_TAP2_MINV, |
| 1893 | wiener_info->vfilter[2] - WIENER_FILT_TAP2_MINV); |
Debargha Mukherjee | 1cb757c | 2017-08-21 02:46:31 -0700 | [diff] [blame] | 1894 | if (wiener_win == WIENER_WIN) |
| 1895 | aom_write_primitive_refsubexpfin( |
| 1896 | wb, WIENER_FILT_TAP0_MAXV - WIENER_FILT_TAP0_MINV + 1, |
| 1897 | WIENER_FILT_TAP0_SUBEXP_K, |
| 1898 | ref_wiener_info->hfilter[0] - WIENER_FILT_TAP0_MINV, |
| 1899 | wiener_info->hfilter[0] - WIENER_FILT_TAP0_MINV); |
| 1900 | else |
| 1901 | assert(wiener_info->hfilter[0] == 0 && |
| 1902 | wiener_info->hfilter[WIENER_WIN - 1] == 0); |
Debargha Mukherjee | cfc12f3 | 2017-04-18 07:03:32 -0700 | [diff] [blame] | 1903 | aom_write_primitive_refsubexpfin( |
| 1904 | wb, WIENER_FILT_TAP1_MAXV - WIENER_FILT_TAP1_MINV + 1, |
| 1905 | WIENER_FILT_TAP1_SUBEXP_K, |
| 1906 | ref_wiener_info->hfilter[1] - WIENER_FILT_TAP1_MINV, |
| 1907 | wiener_info->hfilter[1] - WIENER_FILT_TAP1_MINV); |
| 1908 | aom_write_primitive_refsubexpfin( |
| 1909 | wb, WIENER_FILT_TAP2_MAXV - WIENER_FILT_TAP2_MINV + 1, |
| 1910 | WIENER_FILT_TAP2_SUBEXP_K, |
| 1911 | ref_wiener_info->hfilter[2] - WIENER_FILT_TAP2_MINV, |
| 1912 | wiener_info->hfilter[2] - WIENER_FILT_TAP2_MINV); |
| 1913 | memcpy(ref_wiener_info, wiener_info, sizeof(*wiener_info)); |
Debargha Mukherjee | 8f209a8 | 2016-10-12 10:47:01 -0700 | [diff] [blame] | 1914 | } |
| 1915 | |
Imdad Sardharwalla | fdeb116 | 2018-02-21 17:38:20 +0000 | [diff] [blame] | 1916 | #if CONFIG_SKIP_SGR |
| 1917 | static void write_sgrproj_filter(const SgrprojInfo *sgrproj_info, |
| 1918 | SgrprojInfo *ref_sgrproj_info, |
| 1919 | aom_writer *wb) { |
| 1920 | aom_write_literal(wb, sgrproj_info->ep, SGRPROJ_PARAMS_BITS); |
| 1921 | const sgr_params_type *params = &sgr_params[sgrproj_info->ep]; |
| 1922 | |
Imdad Sardharwalla | 7d3bd8d | 2018-02-22 15:47:33 +0000 | [diff] [blame] | 1923 | if (params->r0 == 0) { |
Imdad Sardharwalla | fdeb116 | 2018-02-21 17:38:20 +0000 | [diff] [blame] | 1924 | assert(sgrproj_info->xqd[0] == 0); |
| 1925 | aom_write_primitive_refsubexpfin( |
| 1926 | wb, SGRPROJ_PRJ_MAX1 - SGRPROJ_PRJ_MIN1 + 1, SGRPROJ_PRJ_SUBEXP_K, |
| 1927 | ref_sgrproj_info->xqd[1] - SGRPROJ_PRJ_MIN1, |
| 1928 | sgrproj_info->xqd[1] - SGRPROJ_PRJ_MIN1); |
Imdad Sardharwalla | 7d3bd8d | 2018-02-22 15:47:33 +0000 | [diff] [blame] | 1929 | } else if (params->r1 == 0) { |
Imdad Sardharwalla | fdeb116 | 2018-02-21 17:38:20 +0000 | [diff] [blame] | 1930 | aom_write_primitive_refsubexpfin( |
| 1931 | wb, SGRPROJ_PRJ_MAX0 - SGRPROJ_PRJ_MIN0 + 1, SGRPROJ_PRJ_SUBEXP_K, |
| 1932 | ref_sgrproj_info->xqd[0] - SGRPROJ_PRJ_MIN0, |
| 1933 | sgrproj_info->xqd[0] - SGRPROJ_PRJ_MIN0); |
Imdad Sardharwalla | fdeb116 | 2018-02-21 17:38:20 +0000 | [diff] [blame] | 1934 | } else { |
| 1935 | aom_write_primitive_refsubexpfin( |
| 1936 | wb, SGRPROJ_PRJ_MAX0 - SGRPROJ_PRJ_MIN0 + 1, SGRPROJ_PRJ_SUBEXP_K, |
| 1937 | ref_sgrproj_info->xqd[0] - SGRPROJ_PRJ_MIN0, |
| 1938 | sgrproj_info->xqd[0] - SGRPROJ_PRJ_MIN0); |
| 1939 | aom_write_primitive_refsubexpfin( |
| 1940 | wb, SGRPROJ_PRJ_MAX1 - SGRPROJ_PRJ_MIN1 + 1, SGRPROJ_PRJ_SUBEXP_K, |
| 1941 | ref_sgrproj_info->xqd[1] - SGRPROJ_PRJ_MIN1, |
| 1942 | sgrproj_info->xqd[1] - SGRPROJ_PRJ_MIN1); |
| 1943 | } |
| 1944 | |
| 1945 | memcpy(ref_sgrproj_info, sgrproj_info, sizeof(*sgrproj_info)); |
| 1946 | } |
| 1947 | #else // CONFIG_SKIP_SGR |
Rupert Swarbrick | dd6f09a | 2017-10-19 16:10:23 +0100 | [diff] [blame] | 1948 | static void write_sgrproj_filter(const SgrprojInfo *sgrproj_info, |
Debargha Mukherjee | cfc12f3 | 2017-04-18 07:03:32 -0700 | [diff] [blame] | 1949 | SgrprojInfo *ref_sgrproj_info, |
| 1950 | aom_writer *wb) { |
Debargha Mukherjee | 8f209a8 | 2016-10-12 10:47:01 -0700 | [diff] [blame] | 1951 | aom_write_literal(wb, sgrproj_info->ep, SGRPROJ_PARAMS_BITS); |
Debargha Mukherjee | cfc12f3 | 2017-04-18 07:03:32 -0700 | [diff] [blame] | 1952 | aom_write_primitive_refsubexpfin(wb, SGRPROJ_PRJ_MAX0 - SGRPROJ_PRJ_MIN0 + 1, |
| 1953 | SGRPROJ_PRJ_SUBEXP_K, |
| 1954 | ref_sgrproj_info->xqd[0] - SGRPROJ_PRJ_MIN0, |
| 1955 | sgrproj_info->xqd[0] - SGRPROJ_PRJ_MIN0); |
| 1956 | aom_write_primitive_refsubexpfin(wb, SGRPROJ_PRJ_MAX1 - SGRPROJ_PRJ_MIN1 + 1, |
| 1957 | SGRPROJ_PRJ_SUBEXP_K, |
| 1958 | ref_sgrproj_info->xqd[1] - SGRPROJ_PRJ_MIN1, |
| 1959 | sgrproj_info->xqd[1] - SGRPROJ_PRJ_MIN1); |
| 1960 | memcpy(ref_sgrproj_info, sgrproj_info, sizeof(*sgrproj_info)); |
Debargha Mukherjee | 8f209a8 | 2016-10-12 10:47:01 -0700 | [diff] [blame] | 1961 | } |
Imdad Sardharwalla | fdeb116 | 2018-02-21 17:38:20 +0000 | [diff] [blame] | 1962 | #endif // CONFIG_SKIP_SGR |
Debargha Mukherjee | 8f209a8 | 2016-10-12 10:47:01 -0700 | [diff] [blame] | 1963 | |
Rupert Swarbrick | 6c54521 | 2017-09-01 17:17:25 +0100 | [diff] [blame] | 1964 | static void loop_restoration_write_sb_coeffs(const AV1_COMMON *const cm, |
| 1965 | MACROBLOCKD *xd, |
Rupert Swarbrick | dd6f09a | 2017-10-19 16:10:23 +0100 | [diff] [blame] | 1966 | const RestorationUnitInfo *rui, |
Yue Chen | 4439151 | 2018-03-13 15:37:26 -0700 | [diff] [blame] | 1967 | aom_writer *const w, int plane, |
| 1968 | FRAME_COUNTS *counts) { |
Rupert Swarbrick | 6c54521 | 2017-09-01 17:17:25 +0100 | [diff] [blame] | 1969 | const RestorationInfo *rsi = cm->rst_info + plane; |
Rupert Swarbrick | dd6f09a | 2017-10-19 16:10:23 +0100 | [diff] [blame] | 1970 | RestorationType frame_rtype = rsi->frame_restoration_type; |
| 1971 | if (frame_rtype == RESTORE_NONE) return; |
Rupert Swarbrick | 09b5b16 | 2017-08-31 16:32:29 +0100 | [diff] [blame] | 1972 | |
Urvang Joshi | 5ec7b81 | 2018-02-28 14:37:06 -0800 | [diff] [blame] | 1973 | assert(!cm->all_lossless); |
| 1974 | |
Rupert Swarbrick | 6c54521 | 2017-09-01 17:17:25 +0100 | [diff] [blame] | 1975 | const int wiener_win = (plane > 0) ? WIENER_WIN_CHROMA : WIENER_WIN; |
| 1976 | WienerInfo *wiener_info = xd->wiener_info + plane; |
| 1977 | SgrprojInfo *sgrproj_info = xd->sgrproj_info + plane; |
Rupert Swarbrick | dd6f09a | 2017-10-19 16:10:23 +0100 | [diff] [blame] | 1978 | RestorationType unit_rtype = rui->restoration_type; |
Rupert Swarbrick | 09b5b16 | 2017-08-31 16:32:29 +0100 | [diff] [blame] | 1979 | |
Rupert Swarbrick | dd6f09a | 2017-10-19 16:10:23 +0100 | [diff] [blame] | 1980 | if (frame_rtype == RESTORE_SWITCHABLE) { |
| 1981 | aom_write_symbol(w, unit_rtype, xd->tile_ctx->switchable_restore_cdf, |
Debargha Mukherjee | bc732ef | 2017-10-12 12:40:25 -0700 | [diff] [blame] | 1982 | RESTORE_SWITCHABLE_TYPES); |
Yue Chen | 4439151 | 2018-03-13 15:37:26 -0700 | [diff] [blame] | 1983 | ++counts->switchable_restore[unit_rtype]; |
Rupert Swarbrick | dd6f09a | 2017-10-19 16:10:23 +0100 | [diff] [blame] | 1984 | switch (unit_rtype) { |
| 1985 | case RESTORE_WIENER: |
| 1986 | write_wiener_filter(wiener_win, &rui->wiener_info, wiener_info, w); |
| 1987 | break; |
| 1988 | case RESTORE_SGRPROJ: |
| 1989 | write_sgrproj_filter(&rui->sgrproj_info, sgrproj_info, w); |
| 1990 | break; |
| 1991 | default: assert(unit_rtype == RESTORE_NONE); break; |
Rupert Swarbrick | 6c54521 | 2017-09-01 17:17:25 +0100 | [diff] [blame] | 1992 | } |
Rupert Swarbrick | dd6f09a | 2017-10-19 16:10:23 +0100 | [diff] [blame] | 1993 | } else if (frame_rtype == RESTORE_WIENER) { |
Rupert Swarbrick | dd6f09a | 2017-10-19 16:10:23 +0100 | [diff] [blame] | 1994 | aom_write_symbol(w, unit_rtype != RESTORE_NONE, |
Debargha Mukherjee | bc732ef | 2017-10-12 12:40:25 -0700 | [diff] [blame] | 1995 | xd->tile_ctx->wiener_restore_cdf, 2); |
Yue Chen | 4439151 | 2018-03-13 15:37:26 -0700 | [diff] [blame] | 1996 | ++counts->wiener_restore[unit_rtype != RESTORE_NONE]; |
Rupert Swarbrick | dd6f09a | 2017-10-19 16:10:23 +0100 | [diff] [blame] | 1997 | if (unit_rtype != RESTORE_NONE) { |
| 1998 | write_wiener_filter(wiener_win, &rui->wiener_info, wiener_info, w); |
Rupert Swarbrick | 6c54521 | 2017-09-01 17:17:25 +0100 | [diff] [blame] | 1999 | } |
Rupert Swarbrick | dd6f09a | 2017-10-19 16:10:23 +0100 | [diff] [blame] | 2000 | } else if (frame_rtype == RESTORE_SGRPROJ) { |
Rupert Swarbrick | dd6f09a | 2017-10-19 16:10:23 +0100 | [diff] [blame] | 2001 | aom_write_symbol(w, unit_rtype != RESTORE_NONE, |
Debargha Mukherjee | bc732ef | 2017-10-12 12:40:25 -0700 | [diff] [blame] | 2002 | xd->tile_ctx->sgrproj_restore_cdf, 2); |
Yue Chen | 4439151 | 2018-03-13 15:37:26 -0700 | [diff] [blame] | 2003 | ++counts->sgrproj_restore[unit_rtype != RESTORE_NONE]; |
Rupert Swarbrick | dd6f09a | 2017-10-19 16:10:23 +0100 | [diff] [blame] | 2004 | if (unit_rtype != RESTORE_NONE) { |
| 2005 | write_sgrproj_filter(&rui->sgrproj_info, sgrproj_info, w); |
Rupert Swarbrick | 09b5b16 | 2017-08-31 16:32:29 +0100 | [diff] [blame] | 2006 | } |
| 2007 | } |
| 2008 | } |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2009 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2010 | static void encode_loopfilter(AV1_COMMON *cm, struct aom_write_bit_buffer *wb) { |
Urvang Joshi | 65c9efd | 2018-03-01 12:02:12 -0800 | [diff] [blame] | 2011 | assert(!cm->all_lossless); |
Hui Su | 27df834 | 2017-11-07 15:16:05 -0800 | [diff] [blame] | 2012 | if (cm->allow_intrabc && NO_FILTER_FOR_IBC) return; |
Hui Su | 293f281 | 2018-02-26 14:41:18 -0800 | [diff] [blame] | 2013 | const int num_planes = av1_num_planes(cm); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2014 | int i; |
| 2015 | struct loopfilter *lf = &cm->lf; |
| 2016 | |
Debargha Mukherjee | 2382b14 | 2018-02-26 14:31:32 -0800 | [diff] [blame] | 2017 | // Encode the loop filter level and type |
Cheng Chen | 76224b0 | 2017-12-15 12:21:01 -0800 | [diff] [blame] | 2018 | aom_wb_write_literal(wb, lf->filter_level[0], 6); |
| 2019 | aom_wb_write_literal(wb, lf->filter_level[1], 6); |
Imdad Sardharwalla | af8e264 | 2018-01-19 11:46:34 +0000 | [diff] [blame] | 2020 | if (num_planes > 1) { |
Cheng Chen | 76224b0 | 2017-12-15 12:21:01 -0800 | [diff] [blame] | 2021 | if (lf->filter_level[0] || lf->filter_level[1]) { |
| 2022 | aom_wb_write_literal(wb, lf->filter_level_u, 6); |
| 2023 | aom_wb_write_literal(wb, lf->filter_level_v, 6); |
Cheng Chen | 765e34e | 2017-12-11 11:43:35 -0800 | [diff] [blame] | 2024 | } |
Cheng Chen | e94df5c | 2017-07-19 17:25:33 -0700 | [diff] [blame] | 2025 | } |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2026 | aom_wb_write_literal(wb, lf->sharpness_level, 3); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2027 | |
| 2028 | // Write out loop filter deltas applied at the MB level based on mode or |
| 2029 | // ref frame (if they are enabled). |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2030 | aom_wb_write_bit(wb, lf->mode_ref_delta_enabled); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2031 | |
| 2032 | if (lf->mode_ref_delta_enabled) { |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2033 | aom_wb_write_bit(wb, lf->mode_ref_delta_update); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2034 | if (lf->mode_ref_delta_update) { |
| 2035 | for (i = 0; i < TOTAL_REFS_PER_FRAME; i++) { |
| 2036 | const int delta = lf->ref_deltas[i]; |
David Barker | d776f28 | 2018-03-19 11:37:36 +0000 | [diff] [blame^] | 2037 | const int changed = delta != lf->last_ref_deltas[i]; |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2038 | aom_wb_write_bit(wb, changed); |
David Barker | d776f28 | 2018-03-19 11:37:36 +0000 | [diff] [blame^] | 2039 | if (changed) { |
| 2040 | lf->last_ref_deltas[i] = delta; |
| 2041 | aom_wb_write_inv_signed_literal(wb, delta, 6); |
| 2042 | } |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2043 | } |
| 2044 | |
| 2045 | for (i = 0; i < MAX_MODE_LF_DELTAS; i++) { |
| 2046 | const int delta = lf->mode_deltas[i]; |
David Barker | d776f28 | 2018-03-19 11:37:36 +0000 | [diff] [blame^] | 2047 | const int changed = delta != lf->last_mode_deltas[i]; |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2048 | aom_wb_write_bit(wb, changed); |
David Barker | d776f28 | 2018-03-19 11:37:36 +0000 | [diff] [blame^] | 2049 | if (changed) { |
| 2050 | lf->last_mode_deltas[i] = delta; |
| 2051 | aom_wb_write_inv_signed_literal(wb, delta, 6); |
| 2052 | } |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2053 | } |
| 2054 | } |
| 2055 | } |
| 2056 | } |
| 2057 | |
Steinar Midtskogen | a9d41e8 | 2017-03-17 12:48:15 +0100 | [diff] [blame] | 2058 | static void encode_cdef(const AV1_COMMON *cm, struct aom_write_bit_buffer *wb) { |
Hui Su | 27df834 | 2017-11-07 15:16:05 -0800 | [diff] [blame] | 2059 | if (cm->allow_intrabc && NO_FILTER_FOR_IBC) return; |
Hui Su | 293f281 | 2018-02-26 14:41:18 -0800 | [diff] [blame] | 2060 | const int num_planes = av1_num_planes(cm); |
Jean-Marc Valin | 5f5c132 | 2017-03-21 16:20:21 -0400 | [diff] [blame] | 2061 | int i; |
Steinar Midtskogen | 5978212 | 2017-07-20 08:49:43 +0200 | [diff] [blame] | 2062 | aom_wb_write_literal(wb, cm->cdef_pri_damping - 3, 2); |
| 2063 | assert(cm->cdef_pri_damping == cm->cdef_sec_damping); |
Jean-Marc Valin | 5f5c132 | 2017-03-21 16:20:21 -0400 | [diff] [blame] | 2064 | aom_wb_write_literal(wb, cm->cdef_bits, 2); |
| 2065 | for (i = 0; i < cm->nb_cdef_strengths; i++) { |
| 2066 | aom_wb_write_literal(wb, cm->cdef_strengths[i], CDEF_STRENGTH_BITS); |
Imdad Sardharwalla | af8e264 | 2018-01-19 11:46:34 +0000 | [diff] [blame] | 2067 | if (num_planes > 1) |
Steinar Midtskogen | 1c1161f | 2017-09-08 15:03:51 +0200 | [diff] [blame] | 2068 | aom_wb_write_literal(wb, cm->cdef_uv_strengths[i], CDEF_STRENGTH_BITS); |
Jean-Marc Valin | 5f5c132 | 2017-03-21 16:20:21 -0400 | [diff] [blame] | 2069 | } |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2070 | } |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2071 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2072 | static void write_delta_q(struct aom_write_bit_buffer *wb, int delta_q) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2073 | if (delta_q != 0) { |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2074 | aom_wb_write_bit(wb, 1); |
| 2075 | aom_wb_write_inv_signed_literal(wb, delta_q, 6); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2076 | } else { |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2077 | aom_wb_write_bit(wb, 0); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2078 | } |
| 2079 | } |
| 2080 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2081 | static void encode_quantization(const AV1_COMMON *const cm, |
| 2082 | struct aom_write_bit_buffer *wb) { |
Imdad Sardharwalla | af8e264 | 2018-01-19 11:46:34 +0000 | [diff] [blame] | 2083 | const int num_planes = av1_num_planes(cm); |
| 2084 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2085 | aom_wb_write_literal(wb, cm->base_qindex, QINDEX_BITS); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2086 | write_delta_q(wb, cm->y_dc_delta_q); |
Imdad Sardharwalla | af8e264 | 2018-01-19 11:46:34 +0000 | [diff] [blame] | 2087 | if (num_planes > 1) { |
Debargha Mukherjee | 18f4fb2 | 2017-12-14 14:26:27 -0800 | [diff] [blame] | 2088 | int diff_uv_delta = (cm->u_dc_delta_q != cm->v_dc_delta_q) || |
| 2089 | (cm->u_ac_delta_q != cm->v_ac_delta_q); |
Debargha Mukherjee | 18f4fb2 | 2017-12-14 14:26:27 -0800 | [diff] [blame] | 2090 | if (cm->separate_uv_delta_q) aom_wb_write_bit(wb, diff_uv_delta); |
Debargha Mukherjee | 18f4fb2 | 2017-12-14 14:26:27 -0800 | [diff] [blame] | 2091 | write_delta_q(wb, cm->u_dc_delta_q); |
| 2092 | write_delta_q(wb, cm->u_ac_delta_q); |
| 2093 | if (diff_uv_delta) { |
| 2094 | write_delta_q(wb, cm->v_dc_delta_q); |
| 2095 | write_delta_q(wb, cm->v_ac_delta_q); |
| 2096 | } |
Yaowu Xu | 6fc47e5 | 2017-12-04 15:07:48 -0800 | [diff] [blame] | 2097 | } |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2098 | aom_wb_write_bit(wb, cm->using_qmatrix); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2099 | if (cm->using_qmatrix) { |
Yaowu Xu | f7a1242 | 2018-01-31 15:29:20 -0800 | [diff] [blame] | 2100 | #if CONFIG_AOM_QM_EXT |
| 2101 | aom_wb_write_literal(wb, cm->qm_y, QM_LEVEL_BITS); |
| 2102 | aom_wb_write_literal(wb, cm->qm_u, QM_LEVEL_BITS); |
Yaowu Xu | f7a1242 | 2018-01-31 15:29:20 -0800 | [diff] [blame] | 2103 | if (!cm->separate_uv_delta_q) |
| 2104 | assert(cm->qm_u == cm->qm_v); |
| 2105 | else |
Yaowu Xu | f7a1242 | 2018-01-31 15:29:20 -0800 | [diff] [blame] | 2106 | aom_wb_write_literal(wb, cm->qm_v, QM_LEVEL_BITS); |
| 2107 | #else |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2108 | aom_wb_write_literal(wb, cm->min_qmlevel, QM_LEVEL_BITS); |
| 2109 | aom_wb_write_literal(wb, cm->max_qmlevel, QM_LEVEL_BITS); |
Yaowu Xu | f7a1242 | 2018-01-31 15:29:20 -0800 | [diff] [blame] | 2110 | #endif |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2111 | } |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2112 | } |
| 2113 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2114 | static void encode_segmentation(AV1_COMMON *cm, MACROBLOCKD *xd, |
| 2115 | struct aom_write_bit_buffer *wb) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2116 | int i, j; |
Rostislav Pehlivanov | dd1a80c | 2018-03-05 21:26:45 +0000 | [diff] [blame] | 2117 | struct segmentation *seg = &cm->seg; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2118 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2119 | aom_wb_write_bit(wb, seg->enabled); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2120 | if (!seg->enabled) return; |
| 2121 | |
David Barker | 190b77a | 2018-03-16 14:29:46 +0000 | [diff] [blame] | 2122 | // Write update flags |
| 2123 | if (frame_is_intra_only(cm) || cm->error_resilient_mode) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2124 | assert(seg->update_map == 1); |
David Barker | 190b77a | 2018-03-16 14:29:46 +0000 | [diff] [blame] | 2125 | seg->temporal_update = 0; |
| 2126 | assert(seg->update_data == 1); |
| 2127 | } else { |
| 2128 | aom_wb_write_bit(wb, seg->update_map); |
| 2129 | if (seg->update_map) { |
| 2130 | // Select the coding strategy (temporal or spatial) |
| 2131 | av1_choose_segmap_coding_method(cm, xd); |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2132 | aom_wb_write_bit(wb, seg->temporal_update); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2133 | } |
David Barker | 190b77a | 2018-03-16 14:29:46 +0000 | [diff] [blame] | 2134 | aom_wb_write_bit(wb, seg->update_data); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2135 | } |
| 2136 | |
Rostislav Pehlivanov | 3a96462 | 2018-03-14 18:00:32 +0000 | [diff] [blame] | 2137 | #if !CONFIG_SEGMENT_PRED_LAST && CONFIG_SPATIAL_SEGMENTATION |
Rostislav Pehlivanov | dd1a80c | 2018-03-05 21:26:45 +0000 | [diff] [blame] | 2138 | seg->preskip_segid = 0; |
Rostislav Pehlivanov | 938710c | 2017-11-28 02:26:21 +0000 | [diff] [blame] | 2139 | #endif |
| 2140 | |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2141 | // Segmentation data |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2142 | if (seg->update_data) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2143 | for (i = 0; i < MAX_SEGMENTS; i++) { |
| 2144 | for (j = 0; j < SEG_LVL_MAX; j++) { |
| 2145 | const int active = segfeature_active(seg, i, j); |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2146 | aom_wb_write_bit(wb, active); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2147 | if (active) { |
Rostislav Pehlivanov | 3a96462 | 2018-03-14 18:00:32 +0000 | [diff] [blame] | 2148 | #if !CONFIG_SEGMENT_PRED_LAST && CONFIG_SPATIAL_SEGMENTATION |
Rostislav Pehlivanov | dd1a80c | 2018-03-05 21:26:45 +0000 | [diff] [blame] | 2149 | seg->preskip_segid |= j >= SEG_LVL_REF_FRAME; |
| 2150 | seg->last_active_segid = i; |
Rostislav Pehlivanov | 938710c | 2017-11-28 02:26:21 +0000 | [diff] [blame] | 2151 | #endif |
Sebastien Alaiwan | ca14b47 | 2017-12-11 11:46:00 +0100 | [diff] [blame] | 2152 | const int data_max = av1_seg_feature_data_max(j); |
| 2153 | const int data_min = -data_max; |
| 2154 | const int ubits = get_unsigned_bits(data_max); |
| 2155 | const int data = clamp(get_segdata(seg, i, j), data_min, data_max); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2156 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2157 | if (av1_is_segfeature_signed(j)) { |
Sebastien Alaiwan | ca14b47 | 2017-12-11 11:46:00 +0100 | [diff] [blame] | 2158 | aom_wb_write_inv_signed_literal(wb, data, ubits); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2159 | } else { |
Sebastien Alaiwan | ca14b47 | 2017-12-11 11:46:00 +0100 | [diff] [blame] | 2160 | aom_wb_write_literal(wb, data, ubits); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2161 | } |
| 2162 | } |
| 2163 | } |
| 2164 | } |
| 2165 | } |
| 2166 | } |
| 2167 | |
Thomas Daede | f636d5c | 2017-06-29 13:48:27 -0700 | [diff] [blame] | 2168 | static void write_tx_mode(AV1_COMMON *cm, TX_MODE *mode, |
Yue Chen | eeacc4c | 2017-01-17 17:29:17 -0800 | [diff] [blame] | 2169 | struct aom_write_bit_buffer *wb) { |
Thomas Daede | f636d5c | 2017-06-29 13:48:27 -0700 | [diff] [blame] | 2170 | if (cm->all_lossless) { |
Yue Chen | eeacc4c | 2017-01-17 17:29:17 -0800 | [diff] [blame] | 2171 | *mode = ONLY_4X4; |
| 2172 | return; |
| 2173 | } |
Debargha Mukherjee | 923b73d | 2017-10-31 18:11:34 -0700 | [diff] [blame] | 2174 | aom_wb_write_bit(wb, *mode == TX_MODE_SELECT); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2175 | } |
| 2176 | |
Angie Chiang | 5678ad9 | 2016-11-21 09:38:40 -0800 | [diff] [blame] | 2177 | static void write_frame_interp_filter(InterpFilter filter, |
| 2178 | struct aom_write_bit_buffer *wb) { |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2179 | aom_wb_write_bit(wb, filter == SWITCHABLE); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2180 | if (filter != SWITCHABLE) |
Angie Chiang | 6305abe | 2016-10-24 12:24:44 -0700 | [diff] [blame] | 2181 | aom_wb_write_literal(wb, filter, LOG_SWITCHABLE_FILTERS); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2182 | } |
| 2183 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2184 | static void fix_interp_filter(AV1_COMMON *cm, FRAME_COUNTS *counts) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2185 | if (cm->interp_filter == SWITCHABLE) { |
| 2186 | // Check to see if only one of the filters is actually used |
| 2187 | int count[SWITCHABLE_FILTERS]; |
| 2188 | int i, j, c = 0; |
| 2189 | for (i = 0; i < SWITCHABLE_FILTERS; ++i) { |
| 2190 | count[i] = 0; |
| 2191 | for (j = 0; j < SWITCHABLE_FILTER_CONTEXTS; ++j) |
| 2192 | count[i] += counts->switchable_interp[j][i]; |
| 2193 | c += (count[i] > 0); |
| 2194 | } |
| 2195 | if (c == 1) { |
| 2196 | // Only one filter is used. So set the filter at frame level |
| 2197 | for (i = 0; i < SWITCHABLE_FILTERS; ++i) { |
| 2198 | if (count[i]) { |
Sarah Parker | 4c10a3c | 2017-04-10 19:37:59 -0700 | [diff] [blame] | 2199 | if (i == EIGHTTAP_REGULAR || WARP_WM_NEIGHBORS_WITH_OBMC) |
Debargha Mukherjee | 604d846 | 2017-04-06 15:27:00 -0700 | [diff] [blame] | 2200 | cm->interp_filter = i; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2201 | break; |
| 2202 | } |
| 2203 | } |
| 2204 | } |
| 2205 | } |
| 2206 | } |
| 2207 | |
Dominic Symes | db5d66f | 2017-08-18 18:11:34 +0200 | [diff] [blame] | 2208 | #if CONFIG_MAX_TILE |
| 2209 | |
| 2210 | // Same function as write_uniform but writing to uncompresses header wb |
| 2211 | static void wb_write_uniform(struct aom_write_bit_buffer *wb, int n, int v) { |
| 2212 | const int l = get_unsigned_bits(n); |
| 2213 | const int m = (1 << l) - n; |
| 2214 | if (l == 0) return; |
| 2215 | if (v < m) { |
| 2216 | aom_wb_write_literal(wb, v, l - 1); |
| 2217 | } else { |
| 2218 | aom_wb_write_literal(wb, m + ((v - m) >> 1), l - 1); |
| 2219 | aom_wb_write_literal(wb, (v - m) & 1, 1); |
| 2220 | } |
| 2221 | } |
| 2222 | |
| 2223 | static void write_tile_info_max_tile(const AV1_COMMON *const cm, |
| 2224 | struct aom_write_bit_buffer *wb) { |
Imdad Sardharwalla | 4ec84ab | 2018-02-06 12:20:18 +0000 | [diff] [blame] | 2225 | int width_mi = ALIGN_POWER_OF_TWO(cm->mi_cols, cm->seq_params.mib_size_log2); |
| 2226 | int height_mi = ALIGN_POWER_OF_TWO(cm->mi_rows, cm->seq_params.mib_size_log2); |
| 2227 | int width_sb = width_mi >> cm->seq_params.mib_size_log2; |
| 2228 | int height_sb = height_mi >> cm->seq_params.mib_size_log2; |
Dominic Symes | db5d66f | 2017-08-18 18:11:34 +0200 | [diff] [blame] | 2229 | int size_sb, i; |
| 2230 | |
| 2231 | aom_wb_write_bit(wb, cm->uniform_tile_spacing_flag); |
| 2232 | |
| 2233 | if (cm->uniform_tile_spacing_flag) { |
| 2234 | // Uniform spaced tiles with power-of-two number of rows and columns |
| 2235 | // tile columns |
| 2236 | int ones = cm->log2_tile_cols - cm->min_log2_tile_cols; |
| 2237 | while (ones--) { |
| 2238 | aom_wb_write_bit(wb, 1); |
| 2239 | } |
| 2240 | if (cm->log2_tile_cols < cm->max_log2_tile_cols) { |
| 2241 | aom_wb_write_bit(wb, 0); |
| 2242 | } |
| 2243 | |
| 2244 | // rows |
| 2245 | ones = cm->log2_tile_rows - cm->min_log2_tile_rows; |
| 2246 | while (ones--) { |
| 2247 | aom_wb_write_bit(wb, 1); |
| 2248 | } |
| 2249 | if (cm->log2_tile_rows < cm->max_log2_tile_rows) { |
| 2250 | aom_wb_write_bit(wb, 0); |
| 2251 | } |
| 2252 | } else { |
| 2253 | // Explicit tiles with configurable tile widths and heights |
| 2254 | // columns |
| 2255 | for (i = 0; i < cm->tile_cols; i++) { |
| 2256 | size_sb = cm->tile_col_start_sb[i + 1] - cm->tile_col_start_sb[i]; |
David Barker | 6cd5a82 | 2018-03-05 16:19:28 +0000 | [diff] [blame] | 2257 | wb_write_uniform(wb, AOMMIN(width_sb, cm->max_tile_width_sb), |
| 2258 | size_sb - 1); |
Dominic Symes | db5d66f | 2017-08-18 18:11:34 +0200 | [diff] [blame] | 2259 | width_sb -= size_sb; |
| 2260 | } |
| 2261 | assert(width_sb == 0); |
| 2262 | |
| 2263 | // rows |
| 2264 | for (i = 0; i < cm->tile_rows; i++) { |
| 2265 | size_sb = cm->tile_row_start_sb[i + 1] - cm->tile_row_start_sb[i]; |
| 2266 | wb_write_uniform(wb, AOMMIN(height_sb, cm->max_tile_height_sb), |
| 2267 | size_sb - 1); |
| 2268 | height_sb -= size_sb; |
| 2269 | } |
| 2270 | assert(height_sb == 0); |
| 2271 | } |
| 2272 | } |
| 2273 | #endif |
| 2274 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2275 | static void write_tile_info(const AV1_COMMON *const cm, |
James Zern | 8b007ff | 2018-02-26 22:49:13 -0800 | [diff] [blame] | 2276 | struct aom_write_bit_buffer *saved_wb, |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2277 | struct aom_write_bit_buffer *wb) { |
Yunqing Wang | eeb08a9 | 2017-07-07 21:25:18 -0700 | [diff] [blame] | 2278 | if (cm->large_scale_tile) { |
| 2279 | const int tile_width = |
Imdad Sardharwalla | 4ec84ab | 2018-02-06 12:20:18 +0000 | [diff] [blame] | 2280 | ALIGN_POWER_OF_TWO(cm->tile_width, cm->seq_params.mib_size_log2) >> |
| 2281 | cm->seq_params.mib_size_log2; |
Yunqing Wang | eeb08a9 | 2017-07-07 21:25:18 -0700 | [diff] [blame] | 2282 | const int tile_height = |
Imdad Sardharwalla | 4ec84ab | 2018-02-06 12:20:18 +0000 | [diff] [blame] | 2283 | ALIGN_POWER_OF_TWO(cm->tile_height, cm->seq_params.mib_size_log2) >> |
| 2284 | cm->seq_params.mib_size_log2; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2285 | |
Yunqing Wang | eeb08a9 | 2017-07-07 21:25:18 -0700 | [diff] [blame] | 2286 | assert(tile_width > 0); |
| 2287 | assert(tile_height > 0); |
Yunqing Wang | d8cd55f | 2017-02-27 12:16:00 -0800 | [diff] [blame] | 2288 | |
Debargha Mukherjee | 2ccf4b9 | 2018-02-27 17:30:46 -0800 | [diff] [blame] | 2289 | // Write the tile sizes |
Imdad Sardharwalla | 4ec84ab | 2018-02-06 12:20:18 +0000 | [diff] [blame] | 2290 | if (cm->seq_params.sb_size == BLOCK_128X128) { |
Yunqing Wang | eeb08a9 | 2017-07-07 21:25:18 -0700 | [diff] [blame] | 2291 | assert(tile_width <= 32); |
| 2292 | assert(tile_height <= 32); |
| 2293 | aom_wb_write_literal(wb, tile_width - 1, 5); |
| 2294 | aom_wb_write_literal(wb, tile_height - 1, 5); |
| 2295 | } else { |
Yunqing Wang | eeb08a9 | 2017-07-07 21:25:18 -0700 | [diff] [blame] | 2296 | assert(tile_width <= 64); |
| 2297 | assert(tile_height <= 64); |
| 2298 | aom_wb_write_literal(wb, tile_width - 1, 6); |
| 2299 | aom_wb_write_literal(wb, tile_height - 1, 6); |
Yunqing Wang | eeb08a9 | 2017-07-07 21:25:18 -0700 | [diff] [blame] | 2300 | } |
Yunqing Wang | eeb08a9 | 2017-07-07 21:25:18 -0700 | [diff] [blame] | 2301 | } else { |
Dominic Symes | db5d66f | 2017-08-18 18:11:34 +0200 | [diff] [blame] | 2302 | #if CONFIG_MAX_TILE |
| 2303 | write_tile_info_max_tile(cm, wb); |
| 2304 | #else |
Yaowu Xu | dd6ef6c | 2018-03-02 16:43:52 -0800 | [diff] [blame] | 2305 | int min_log2_tile_cols, max_log2_tile_cols, ones; |
| 2306 | av1_get_tile_n_bits(cm->mi_cols, &min_log2_tile_cols, &max_log2_tile_cols); |
Yunqing Wang | eeb08a9 | 2017-07-07 21:25:18 -0700 | [diff] [blame] | 2307 | |
Yaowu Xu | dd6ef6c | 2018-03-02 16:43:52 -0800 | [diff] [blame] | 2308 | // columns |
| 2309 | ones = cm->log2_tile_cols - min_log2_tile_cols; |
| 2310 | while (ones--) aom_wb_write_bit(wb, 1); |
Yunqing Wang | eeb08a9 | 2017-07-07 21:25:18 -0700 | [diff] [blame] | 2311 | |
Yaowu Xu | dd6ef6c | 2018-03-02 16:43:52 -0800 | [diff] [blame] | 2312 | if (cm->log2_tile_cols < max_log2_tile_cols) aom_wb_write_bit(wb, 0); |
Dominic Symes | db5d66f | 2017-08-18 18:11:34 +0200 | [diff] [blame] | 2313 | |
Yaowu Xu | dd6ef6c | 2018-03-02 16:43:52 -0800 | [diff] [blame] | 2314 | // rows |
| 2315 | aom_wb_write_bit(wb, cm->log2_tile_rows != 0); |
| 2316 | if (cm->log2_tile_rows != 0) aom_wb_write_bit(wb, cm->log2_tile_rows != 1); |
Dominic Symes | db5d66f | 2017-08-18 18:11:34 +0200 | [diff] [blame] | 2317 | #endif |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2318 | } |
Fangwen Fu | 7b9f2b3 | 2017-01-17 14:01:52 -0800 | [diff] [blame] | 2319 | |
Ryan Lei | 9b02b0e | 2017-01-30 15:52:20 -0800 | [diff] [blame] | 2320 | #if CONFIG_LOOPFILTERING_ACROSS_TILES |
Lei | 7bb501d | 2017-12-13 15:10:34 -0800 | [diff] [blame] | 2321 | #if CONFIG_LOOPFILTERING_ACROSS_TILES_EXT |
| 2322 | if (cm->tile_cols > 1) { |
| 2323 | aom_wb_write_bit(wb, cm->loop_filter_across_tiles_v_enabled); |
| 2324 | } |
| 2325 | if (cm->tile_rows > 1) { |
| 2326 | aom_wb_write_bit(wb, cm->loop_filter_across_tiles_h_enabled); |
| 2327 | } |
| 2328 | #else |
Yunqing Wang | 42015d1 | 2017-10-17 15:43:49 -0700 | [diff] [blame] | 2329 | if (cm->tile_cols * cm->tile_rows > 1) |
| 2330 | aom_wb_write_bit(wb, cm->loop_filter_across_tiles_enabled); |
Lei | 7bb501d | 2017-12-13 15:10:34 -0800 | [diff] [blame] | 2331 | #endif // CONFIG_LOOPFILTERING_ACROSS_TILES_EXT |
Ryan Lei | 9b02b0e | 2017-01-30 15:52:20 -0800 | [diff] [blame] | 2332 | #endif // CONFIG_LOOPFILTERING_ACROSS_TILES |
Cyril Concolato | 3b5afc1 | 2017-12-15 12:54:15 -0800 | [diff] [blame] | 2333 | |
James Zern | 8b007ff | 2018-02-26 22:49:13 -0800 | [diff] [blame] | 2334 | *saved_wb = *wb; |
| 2335 | if (cm->large_scale_tile) { |
| 2336 | if (cm->tile_rows * cm->tile_cols > 1) { |
| 2337 | // Note that the last item in the uncompressed header is the data |
| 2338 | // describing tile configuration. |
| 2339 | // Number of bytes in tile column size - 1 |
| 2340 | aom_wb_write_literal(wb, 0, 2); |
| 2341 | // Number of bytes in tile size - 1 |
| 2342 | aom_wb_write_literal(wb, 0, 2); |
| 2343 | } |
| 2344 | return; |
| 2345 | } |
James Zern | 9e9f7ad | 2018-03-02 17:38:53 -0800 | [diff] [blame] | 2346 | if (cm->tile_rows * cm->tile_cols > 1) { |
| 2347 | // Number of bytes in tile size - 1 |
| 2348 | aom_wb_write_literal(wb, 3, 2); |
| 2349 | } |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2350 | } |
| 2351 | |
Zoe Liu | 8dd1c98 | 2017-09-11 10:14:35 -0700 | [diff] [blame] | 2352 | #if USE_GF16_MULTI_LAYER |
| 2353 | static int get_refresh_mask_gf16(AV1_COMP *cpi) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2354 | int refresh_mask = 0; |
| 2355 | |
Zoe Liu | 8dd1c98 | 2017-09-11 10:14:35 -0700 | [diff] [blame] | 2356 | if (cpi->refresh_last_frame || cpi->refresh_golden_frame || |
| 2357 | cpi->refresh_bwd_ref_frame || cpi->refresh_alt2_ref_frame || |
| 2358 | cpi->refresh_alt_ref_frame) { |
| 2359 | assert(cpi->refresh_fb_idx >= 0 && cpi->refresh_fb_idx < REF_FRAMES); |
| 2360 | refresh_mask |= (1 << cpi->refresh_fb_idx); |
| 2361 | } |
| 2362 | |
| 2363 | return refresh_mask; |
| 2364 | } |
| 2365 | #endif // USE_GF16_MULTI_LAYER |
Zoe Liu | 8dd1c98 | 2017-09-11 10:14:35 -0700 | [diff] [blame] | 2366 | |
| 2367 | static int get_refresh_mask(AV1_COMP *cpi) { |
Yi Luo | 2e6a9ab | 2017-09-15 08:13:59 -0700 | [diff] [blame] | 2368 | int refresh_mask = 0; |
Zoe Liu | 8dd1c98 | 2017-09-11 10:14:35 -0700 | [diff] [blame] | 2369 | #if USE_GF16_MULTI_LAYER |
| 2370 | if (cpi->rc.baseline_gf_interval == 16) return get_refresh_mask_gf16(cpi); |
| 2371 | #endif // USE_GF16_MULTI_LAYER |
| 2372 | |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2373 | // NOTE(zoeliu): When LAST_FRAME is to get refreshed, the decoder will be |
| 2374 | // notified to get LAST3_FRAME refreshed and then the virtual indexes for all |
| 2375 | // the 3 LAST reference frames will be updated accordingly, i.e.: |
| 2376 | // (1) The original virtual index for LAST3_FRAME will become the new virtual |
| 2377 | // index for LAST_FRAME; and |
| 2378 | // (2) The original virtual indexes for LAST_FRAME and LAST2_FRAME will be |
| 2379 | // shifted and become the new virtual indexes for LAST2_FRAME and |
| 2380 | // LAST3_FRAME. |
| 2381 | refresh_mask |= |
| 2382 | (cpi->refresh_last_frame << cpi->lst_fb_idxes[LAST_REF_FRAMES - 1]); |
Zoe Liu | e9b15e2 | 2017-07-19 15:53:01 -0700 | [diff] [blame] | 2383 | |
Zoe Liu | e9b15e2 | 2017-07-19 15:53:01 -0700 | [diff] [blame] | 2384 | refresh_mask |= (cpi->refresh_bwd_ref_frame << cpi->bwd_fb_idx); |
| 2385 | refresh_mask |= (cpi->refresh_alt2_ref_frame << cpi->alt2_fb_idx); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2386 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2387 | if (av1_preserve_existing_gf(cpi)) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2388 | // We have decided to preserve the previously existing golden frame as our |
| 2389 | // new ARF frame. However, in the short term we leave it in the GF slot and, |
| 2390 | // if we're updating the GF with the current decoded frame, we save it |
| 2391 | // instead to the ARF slot. |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2392 | // Later, in the function av1_encoder.c:av1_update_reference_frames() we |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2393 | // will swap gld_fb_idx and alt_fb_idx to achieve our objective. We do it |
| 2394 | // there so that it can be done outside of the recode loop. |
| 2395 | // Note: This is highly specific to the use of ARF as a forward reference, |
| 2396 | // and this needs to be generalized as other uses are implemented |
| 2397 | // (like RTC/temporal scalability). |
| 2398 | return refresh_mask | (cpi->refresh_golden_frame << cpi->alt_fb_idx); |
| 2399 | } else { |
Zoe Liu | e9b15e2 | 2017-07-19 15:53:01 -0700 | [diff] [blame] | 2400 | const int arf_idx = cpi->alt_fb_idx; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2401 | return refresh_mask | (cpi->refresh_golden_frame << cpi->gld_fb_idx) | |
| 2402 | (cpi->refresh_alt_ref_frame << arf_idx); |
| 2403 | } |
| 2404 | } |
| 2405 | |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2406 | static INLINE int find_identical_tile( |
| 2407 | const int tile_row, const int tile_col, |
| 2408 | TileBufferEnc (*const tile_buffers)[1024]) { |
| 2409 | const MV32 candidate_offset[1] = { { 1, 0 } }; |
| 2410 | const uint8_t *const cur_tile_data = |
| 2411 | tile_buffers[tile_row][tile_col].data + 4; |
Jingning Han | 99ffce6 | 2017-04-25 15:48:41 -0700 | [diff] [blame] | 2412 | const size_t cur_tile_size = tile_buffers[tile_row][tile_col].size; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2413 | |
| 2414 | int i; |
| 2415 | |
| 2416 | if (tile_row == 0) return 0; |
| 2417 | |
| 2418 | // (TODO: yunqingwang) For now, only above tile is checked and used. |
| 2419 | // More candidates such as left tile can be added later. |
| 2420 | for (i = 0; i < 1; i++) { |
| 2421 | int row_offset = candidate_offset[0].row; |
| 2422 | int col_offset = candidate_offset[0].col; |
| 2423 | int row = tile_row - row_offset; |
| 2424 | int col = tile_col - col_offset; |
| 2425 | uint8_t tile_hdr; |
| 2426 | const uint8_t *tile_data; |
| 2427 | TileBufferEnc *candidate; |
| 2428 | |
| 2429 | if (row < 0 || col < 0) continue; |
| 2430 | |
| 2431 | tile_hdr = *(tile_buffers[row][col].data); |
| 2432 | |
| 2433 | // Read out tcm bit |
| 2434 | if ((tile_hdr >> 7) == 1) { |
| 2435 | // The candidate is a copy tile itself |
| 2436 | row_offset += tile_hdr & 0x7f; |
| 2437 | row = tile_row - row_offset; |
| 2438 | } |
| 2439 | |
| 2440 | candidate = &tile_buffers[row][col]; |
| 2441 | |
| 2442 | if (row_offset >= 128 || candidate->size != cur_tile_size) continue; |
| 2443 | |
| 2444 | tile_data = candidate->data + 4; |
| 2445 | |
| 2446 | if (memcmp(tile_data, cur_tile_data, cur_tile_size) != 0) continue; |
| 2447 | |
| 2448 | // Identical tile found |
| 2449 | assert(row_offset > 0); |
| 2450 | return row_offset; |
| 2451 | } |
| 2452 | |
| 2453 | // No identical tile found |
| 2454 | return 0; |
| 2455 | } |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2456 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2457 | static void write_render_size(const AV1_COMMON *cm, |
| 2458 | struct aom_write_bit_buffer *wb) { |
Fergus Simpson | d2bcbb5 | 2017-05-22 23:15:05 -0700 | [diff] [blame] | 2459 | const int scaling_active = !av1_resize_unscaled(cm); |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2460 | aom_wb_write_bit(wb, scaling_active); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2461 | if (scaling_active) { |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2462 | aom_wb_write_literal(wb, cm->render_width - 1, 16); |
| 2463 | aom_wb_write_literal(wb, cm->render_height - 1, 16); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2464 | } |
| 2465 | } |
| 2466 | |
Fergus Simpson | e750841 | 2017-03-14 18:14:09 -0700 | [diff] [blame] | 2467 | static void write_superres_scale(const AV1_COMMON *const cm, |
| 2468 | struct aom_write_bit_buffer *wb) { |
Fergus Simpson | e750841 | 2017-03-14 18:14:09 -0700 | [diff] [blame] | 2469 | // First bit is whether to to scale or not |
Urvang Joshi | de71d14 | 2017-10-05 12:12:15 -0700 | [diff] [blame] | 2470 | if (cm->superres_scale_denominator == SCALE_NUMERATOR) { |
Fergus Simpson | e750841 | 2017-03-14 18:14:09 -0700 | [diff] [blame] | 2471 | aom_wb_write_bit(wb, 0); // no scaling |
| 2472 | } else { |
| 2473 | aom_wb_write_bit(wb, 1); // scaling, write scale factor |
Urvang Joshi | 8301018 | 2017-10-27 12:36:02 -0700 | [diff] [blame] | 2474 | assert(cm->superres_scale_denominator >= SUPERRES_SCALE_DENOMINATOR_MIN); |
| 2475 | assert(cm->superres_scale_denominator < |
| 2476 | SUPERRES_SCALE_DENOMINATOR_MIN + (1 << SUPERRES_SCALE_BITS)); |
Fergus Simpson | e750841 | 2017-03-14 18:14:09 -0700 | [diff] [blame] | 2477 | aom_wb_write_literal( |
Urvang Joshi | de71d14 | 2017-10-05 12:12:15 -0700 | [diff] [blame] | 2478 | wb, cm->superres_scale_denominator - SUPERRES_SCALE_DENOMINATOR_MIN, |
Fergus Simpson | e750841 | 2017-03-14 18:14:09 -0700 | [diff] [blame] | 2479 | SUPERRES_SCALE_BITS); |
| 2480 | } |
| 2481 | } |
Fergus Simpson | e750841 | 2017-03-14 18:14:09 -0700 | [diff] [blame] | 2482 | |
Arild Fuldseth (arilfuld) | 7193f02 | 2017-10-30 12:24:57 +0100 | [diff] [blame] | 2483 | static void write_frame_size(const AV1_COMMON *cm, int frame_size_override, |
Tom Finegan | 8ab2bba | 2018-02-28 07:36:28 -0800 | [diff] [blame] | 2484 | struct aom_write_bit_buffer *wb) { |
David Barker | 2217131 | 2017-11-20 11:26:04 +0000 | [diff] [blame] | 2485 | const int coded_width = cm->superres_upscaled_width - 1; |
| 2486 | const int coded_height = cm->superres_upscaled_height - 1; |
David Barker | 2217131 | 2017-11-20 11:26:04 +0000 | [diff] [blame] | 2487 | |
Arild Fuldseth (arilfuld) | 7193f02 | 2017-10-30 12:24:57 +0100 | [diff] [blame] | 2488 | if (frame_size_override) { |
| 2489 | const SequenceHeader *seq_params = &cm->seq_params; |
| 2490 | int num_bits_width = seq_params->num_bits_width; |
| 2491 | int num_bits_height = seq_params->num_bits_height; |
David Barker | 2217131 | 2017-11-20 11:26:04 +0000 | [diff] [blame] | 2492 | aom_wb_write_literal(wb, coded_width, num_bits_width); |
| 2493 | aom_wb_write_literal(wb, coded_height, num_bits_height); |
Arild Fuldseth (arilfuld) | 7193f02 | 2017-10-30 12:24:57 +0100 | [diff] [blame] | 2494 | } |
David Barker | 2217131 | 2017-11-20 11:26:04 +0000 | [diff] [blame] | 2495 | |
David Barker | 2217131 | 2017-11-20 11:26:04 +0000 | [diff] [blame] | 2496 | write_superres_scale(cm, wb); |
Fergus Simpson | d2bcbb5 | 2017-05-22 23:15:05 -0700 | [diff] [blame] | 2497 | write_render_size(cm, wb); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2498 | } |
| 2499 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2500 | static void write_frame_size_with_refs(AV1_COMP *cpi, |
| 2501 | struct aom_write_bit_buffer *wb) { |
| 2502 | AV1_COMMON *const cm = &cpi->common; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2503 | int found = 0; |
| 2504 | |
| 2505 | MV_REFERENCE_FRAME ref_frame; |
| 2506 | for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) { |
| 2507 | YV12_BUFFER_CONFIG *cfg = get_ref_frame_buffer(cpi, ref_frame); |
| 2508 | |
| 2509 | if (cfg != NULL) { |
Fergus Simpson | d2bcbb5 | 2017-05-22 23:15:05 -0700 | [diff] [blame] | 2510 | found = cm->superres_upscaled_width == cfg->y_crop_width && |
| 2511 | cm->superres_upscaled_height == cfg->y_crop_height; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2512 | found &= cm->render_width == cfg->render_width && |
| 2513 | cm->render_height == cfg->render_height; |
| 2514 | } |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2515 | aom_wb_write_bit(wb, found); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2516 | if (found) { |
Fergus Simpson | d2bcbb5 | 2017-05-22 23:15:05 -0700 | [diff] [blame] | 2517 | write_superres_scale(cm, wb); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2518 | break; |
| 2519 | } |
| 2520 | } |
| 2521 | |
Arild Fuldseth (arilfuld) | 7193f02 | 2017-10-30 12:24:57 +0100 | [diff] [blame] | 2522 | if (!found) { |
Tom Finegan | 8ab2bba | 2018-02-28 07:36:28 -0800 | [diff] [blame] | 2523 | int frame_size_override = 1; // Always equal to 1 in this function |
Arild Fuldseth (arilfuld) | 7193f02 | 2017-10-30 12:24:57 +0100 | [diff] [blame] | 2524 | write_frame_size(cm, frame_size_override, wb); |
| 2525 | } |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2526 | } |
| 2527 | |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2528 | static void write_profile(BITSTREAM_PROFILE profile, |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2529 | struct aom_write_bit_buffer *wb) { |
Debargha Mukherjee | f9a50ea | 2018-01-09 22:28:20 -0800 | [diff] [blame] | 2530 | assert(profile >= PROFILE_0 && profile < MAX_PROFILES); |
| 2531 | aom_wb_write_literal(wb, profile, 2); |
| 2532 | } |
| 2533 | |
| 2534 | static void write_bitdepth(AV1_COMMON *const cm, |
| 2535 | struct aom_write_bit_buffer *wb) { |
| 2536 | // Profile 0/1: [0] for 8 bit, [1] 10-bit |
| 2537 | // Profile 2: [0] for 8 bit, [10] 10-bit, [11] - 12-bit |
| 2538 | aom_wb_write_bit(wb, cm->bit_depth == AOM_BITS_8 ? 0 : 1); |
| 2539 | if (cm->profile == PROFILE_2 && cm->bit_depth != AOM_BITS_8) { |
| 2540 | aom_wb_write_bit(wb, cm->bit_depth == AOM_BITS_10 ? 0 : 1); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2541 | } |
| 2542 | } |
| 2543 | |
| 2544 | static void write_bitdepth_colorspace_sampling( |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2545 | AV1_COMMON *const cm, struct aom_write_bit_buffer *wb) { |
Debargha Mukherjee | f9a50ea | 2018-01-09 22:28:20 -0800 | [diff] [blame] | 2546 | write_bitdepth(cm, wb); |
Debargha Mukherjee | f340fec | 2018-01-10 18:12:22 -0800 | [diff] [blame] | 2547 | const int is_monochrome = cm->seq_params.monochrome; |
Debargha Mukherjee | f9a50ea | 2018-01-09 22:28:20 -0800 | [diff] [blame] | 2548 | // monochrome bit |
| 2549 | if (cm->profile != PROFILE_1) |
| 2550 | aom_wb_write_bit(wb, is_monochrome); |
| 2551 | else |
| 2552 | assert(!is_monochrome); |
Andrey Norkin | 9e69463 | 2017-12-21 18:50:57 -0800 | [diff] [blame] | 2553 | if (cm->color_primaries == AOM_CICP_CP_UNSPECIFIED && |
| 2554 | cm->transfer_characteristics == AOM_CICP_TC_UNSPECIFIED && |
| 2555 | cm->matrix_coefficients == AOM_CICP_MC_UNSPECIFIED) { |
| 2556 | aom_wb_write_bit(wb, 0); // No color description present |
| 2557 | } else { |
| 2558 | aom_wb_write_bit(wb, 1); // Color description present |
| 2559 | aom_wb_write_literal(wb, cm->color_primaries, 8); |
| 2560 | aom_wb_write_literal(wb, cm->transfer_characteristics, 8); |
| 2561 | aom_wb_write_literal(wb, cm->matrix_coefficients, 8); |
| 2562 | } |
Debargha Mukherjee | e526769 | 2018-01-16 09:41:15 -0800 | [diff] [blame] | 2563 | if (is_monochrome) return; |
Andrey Norkin | 9e69463 | 2017-12-21 18:50:57 -0800 | [diff] [blame] | 2564 | if (cm->color_primaries == AOM_CICP_CP_BT_709 && |
| 2565 | cm->transfer_characteristics == AOM_CICP_TC_SRGB && |
| 2566 | cm->matrix_coefficients == |
| 2567 | AOM_CICP_MC_IDENTITY) { // it would be better to remove this |
| 2568 | // dependency too |
Debargha Mukherjee | f9a50ea | 2018-01-09 22:28:20 -0800 | [diff] [blame] | 2569 | assert(cm->subsampling_x == 0 && cm->subsampling_y == 0); |
| 2570 | assert(cm->profile == PROFILE_1 || |
| 2571 | (cm->profile == PROFILE_2 && cm->bit_depth == AOM_BITS_12)); |
Imdad Sardharwalla | 317002f | 2017-12-05 16:24:56 +0000 | [diff] [blame] | 2572 | } else { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2573 | // 0: [16, 235] (i.e. xvYCC), 1: [0, 255] |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2574 | aom_wb_write_bit(wb, cm->color_range); |
Debargha Mukherjee | f9a50ea | 2018-01-09 22:28:20 -0800 | [diff] [blame] | 2575 | if (cm->profile == PROFILE_0) { |
| 2576 | // 420 only |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2577 | assert(cm->subsampling_x == 1 && cm->subsampling_y == 1); |
Debargha Mukherjee | f9a50ea | 2018-01-09 22:28:20 -0800 | [diff] [blame] | 2578 | } else if (cm->profile == PROFILE_1) { |
| 2579 | // 444 only |
| 2580 | assert(cm->subsampling_x == 0 && cm->subsampling_y == 0); |
| 2581 | } else if (cm->profile == PROFILE_2) { |
| 2582 | if (cm->bit_depth == AOM_BITS_12) { |
| 2583 | // 420, 444 or 422 |
| 2584 | aom_wb_write_bit(wb, cm->subsampling_x); |
David Barker | 0c3545b | 2018-01-16 17:32:23 +0000 | [diff] [blame] | 2585 | if (cm->subsampling_x == 0) { |
| 2586 | assert(cm->subsampling_y == 0 && |
| 2587 | "4:4:0 subsampling not allowed in AV1"); |
| 2588 | } else { |
| 2589 | aom_wb_write_bit(wb, cm->subsampling_y); |
| 2590 | } |
Debargha Mukherjee | f9a50ea | 2018-01-09 22:28:20 -0800 | [diff] [blame] | 2591 | } else { |
| 2592 | // 422 only |
| 2593 | assert(cm->subsampling_x == 1 && cm->subsampling_y == 0); |
| 2594 | } |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2595 | } |
anorkin | 76fb126 | 2017-03-22 15:12:12 -0700 | [diff] [blame] | 2596 | if (cm->subsampling_x == 1 && cm->subsampling_y == 1) { |
| 2597 | aom_wb_write_literal(wb, cm->chroma_sample_position, 2); |
| 2598 | } |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2599 | } |
Yaowu Xu | 6fc47e5 | 2017-12-04 15:07:48 -0800 | [diff] [blame] | 2600 | aom_wb_write_bit(wb, cm->separate_uv_delta_q); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2601 | } |
| 2602 | |
Andrey Norkin | 28e9ce2 | 2018-01-08 10:11:21 -0800 | [diff] [blame] | 2603 | static void write_timing_info_header(AV1_COMMON *const cm, |
| 2604 | struct aom_write_bit_buffer *wb) { |
| 2605 | aom_wb_write_bit(wb, cm->timing_info_present); // timing info present flag |
| 2606 | |
| 2607 | if (cm->timing_info_present) { |
| 2608 | aom_wb_write_unsigned_literal(wb, cm->num_units_in_tick, |
| 2609 | 32); // Number of units in tick |
| 2610 | aom_wb_write_unsigned_literal(wb, cm->time_scale, 32); // Time scale |
| 2611 | aom_wb_write_bit(wb, |
| 2612 | cm->equal_picture_interval); // Equal picture interval bit |
| 2613 | if (cm->equal_picture_interval) { |
| 2614 | aom_wb_write_uvlc(wb, |
| 2615 | cm->num_ticks_per_picture - 1); // ticks per picture |
| 2616 | } |
| 2617 | } |
| 2618 | } |
Andrey Norkin | 28e9ce2 | 2018-01-08 10:11:21 -0800 | [diff] [blame] | 2619 | |
Andrey Norkin | 6f1c2f7 | 2018-01-15 20:08:52 -0800 | [diff] [blame] | 2620 | #if CONFIG_FILM_GRAIN |
Dominic Symes | d492901 | 2018-01-31 17:32:01 +0100 | [diff] [blame] | 2621 | static void write_film_grain_params(AV1_COMP *cpi, |
Andrey Norkin | 6f1c2f7 | 2018-01-15 20:08:52 -0800 | [diff] [blame] | 2622 | struct aom_write_bit_buffer *wb) { |
Dominic Symes | d492901 | 2018-01-31 17:32:01 +0100 | [diff] [blame] | 2623 | AV1_COMMON *const cm = &cpi->common; |
Andrey Norkin | 6f1c2f7 | 2018-01-15 20:08:52 -0800 | [diff] [blame] | 2624 | aom_film_grain_t *pars = &cm->film_grain_params; |
| 2625 | |
Dominic Symes | d492901 | 2018-01-31 17:32:01 +0100 | [diff] [blame] | 2626 | cm->cur_frame->film_grain_params = *pars; |
| 2627 | |
Andrey Norkin | 6f1c2f7 | 2018-01-15 20:08:52 -0800 | [diff] [blame] | 2628 | aom_wb_write_bit(wb, pars->apply_grain); |
| 2629 | if (!pars->apply_grain) return; |
| 2630 | |
| 2631 | aom_wb_write_literal(wb, pars->random_seed, 16); |
| 2632 | |
| 2633 | pars->random_seed += 3245; // For film grain test vectors purposes |
| 2634 | if (!pars->random_seed) // Random seed should not be zero |
| 2635 | pars->random_seed += 1735; |
Andrey Norkin | 879488f | 2018-02-28 15:30:26 -0800 | [diff] [blame] | 2636 | if (cm->frame_type == INTER_FRAME) |
| 2637 | aom_wb_write_bit(wb, pars->update_parameters); |
| 2638 | else |
| 2639 | pars->update_parameters = 1; |
Dominic Symes | d492901 | 2018-01-31 17:32:01 +0100 | [diff] [blame] | 2640 | #if CONFIG_FILM_GRAIN_SHOWEX |
| 2641 | if (!pars->update_parameters) { |
| 2642 | RefCntBuffer *const frame_bufs = cm->buffer_pool->frame_bufs; |
| 2643 | int ref_frame, ref_idx, buf_idx; |
| 2644 | for (ref_frame = LAST_FRAME; ref_frame < TOTAL_REFS_PER_FRAME; |
| 2645 | ref_frame++) { |
| 2646 | ref_idx = get_ref_frame_map_idx(cpi, ref_frame); |
Dominic Symes | 4d37568 | 2018-02-28 17:26:04 +0100 | [diff] [blame] | 2647 | assert(ref_idx != INVALID_IDX); |
Dominic Symes | d492901 | 2018-01-31 17:32:01 +0100 | [diff] [blame] | 2648 | buf_idx = cm->ref_frame_map[ref_idx]; |
| 2649 | if (frame_bufs[buf_idx].film_grain_params_present && |
| 2650 | memcmp(pars, &frame_bufs[buf_idx].film_grain_params, sizeof(*pars))) { |
| 2651 | break; |
| 2652 | } |
| 2653 | } |
| 2654 | assert(ref_frame < TOTAL_REFS_PER_FRAME); |
| 2655 | aom_wb_write_literal(wb, ref_idx, 3); |
| 2656 | return; |
| 2657 | } |
| 2658 | #else |
Andrey Norkin | 6f1c2f7 | 2018-01-15 20:08:52 -0800 | [diff] [blame] | 2659 | if (!pars->update_parameters) return; |
Dominic Symes | d492901 | 2018-01-31 17:32:01 +0100 | [diff] [blame] | 2660 | #endif |
Andrey Norkin | 6f1c2f7 | 2018-01-15 20:08:52 -0800 | [diff] [blame] | 2661 | |
| 2662 | // Scaling functions parameters |
| 2663 | |
| 2664 | aom_wb_write_literal(wb, pars->num_y_points, 4); // max 14 |
| 2665 | for (int i = 0; i < pars->num_y_points; i++) { |
| 2666 | aom_wb_write_literal(wb, pars->scaling_points_y[i][0], 8); |
| 2667 | aom_wb_write_literal(wb, pars->scaling_points_y[i][1], 8); |
| 2668 | } |
| 2669 | |
Andrey Norkin | 20be545 | 2018-02-20 17:46:13 -0800 | [diff] [blame] | 2670 | if (!cm->seq_params.monochrome) |
| 2671 | aom_wb_write_bit(wb, pars->chroma_scaling_from_luma); |
Andrey Norkin | 6f1c2f7 | 2018-01-15 20:08:52 -0800 | [diff] [blame] | 2672 | |
Andrey Norkin | 20be545 | 2018-02-20 17:46:13 -0800 | [diff] [blame] | 2673 | if (cm->seq_params.monochrome || pars->chroma_scaling_from_luma) { |
| 2674 | pars->num_cb_points = 0; |
| 2675 | pars->num_cr_points = 0; |
Andrey Norkin | 0c294fa | 2018-02-16 18:32:12 -0800 | [diff] [blame] | 2676 | } else { |
Andrey Norkin | 6f1c2f7 | 2018-01-15 20:08:52 -0800 | [diff] [blame] | 2677 | aom_wb_write_literal(wb, pars->num_cb_points, 4); // max 10 |
| 2678 | for (int i = 0; i < pars->num_cb_points; i++) { |
| 2679 | aom_wb_write_literal(wb, pars->scaling_points_cb[i][0], 8); |
| 2680 | aom_wb_write_literal(wb, pars->scaling_points_cb[i][1], 8); |
| 2681 | } |
| 2682 | |
| 2683 | aom_wb_write_literal(wb, pars->num_cr_points, 4); // max 10 |
| 2684 | for (int i = 0; i < pars->num_cr_points; i++) { |
| 2685 | aom_wb_write_literal(wb, pars->scaling_points_cr[i][0], 8); |
| 2686 | aom_wb_write_literal(wb, pars->scaling_points_cr[i][1], 8); |
| 2687 | } |
| 2688 | } |
| 2689 | |
| 2690 | aom_wb_write_literal(wb, pars->scaling_shift - 8, 2); // 8 + value |
| 2691 | |
| 2692 | // AR coefficients |
| 2693 | // Only sent if the corresponsing scaling function has |
| 2694 | // more than 0 points |
| 2695 | |
| 2696 | aom_wb_write_literal(wb, pars->ar_coeff_lag, 2); |
| 2697 | |
| 2698 | int num_pos_luma = 2 * pars->ar_coeff_lag * (pars->ar_coeff_lag + 1); |
Andrey Norkin | 20be545 | 2018-02-20 17:46:13 -0800 | [diff] [blame] | 2699 | int num_pos_chroma = num_pos_luma; |
| 2700 | if (pars->num_y_points > 0) ++num_pos_chroma; |
Andrey Norkin | 6f1c2f7 | 2018-01-15 20:08:52 -0800 | [diff] [blame] | 2701 | |
| 2702 | if (pars->num_y_points) |
| 2703 | for (int i = 0; i < num_pos_luma; i++) |
| 2704 | aom_wb_write_literal(wb, pars->ar_coeffs_y[i] + 128, 8); |
| 2705 | |
| 2706 | if (pars->num_cb_points || pars->chroma_scaling_from_luma) |
| 2707 | for (int i = 0; i < num_pos_chroma; i++) |
| 2708 | aom_wb_write_literal(wb, pars->ar_coeffs_cb[i] + 128, 8); |
| 2709 | |
| 2710 | if (pars->num_cr_points || pars->chroma_scaling_from_luma) |
| 2711 | for (int i = 0; i < num_pos_chroma; i++) |
| 2712 | aom_wb_write_literal(wb, pars->ar_coeffs_cr[i] + 128, 8); |
| 2713 | |
| 2714 | aom_wb_write_literal(wb, pars->ar_coeff_shift - 6, 2); // 8 + value |
| 2715 | |
Andrey Norkin | a840cde | 2018-02-16 15:39:50 -0800 | [diff] [blame] | 2716 | aom_wb_write_literal(wb, pars->grain_scale_shift, 2); |
| 2717 | |
Andrey Norkin | 6f1c2f7 | 2018-01-15 20:08:52 -0800 | [diff] [blame] | 2718 | if (pars->num_cb_points) { |
| 2719 | aom_wb_write_literal(wb, pars->cb_mult, 8); |
| 2720 | aom_wb_write_literal(wb, pars->cb_luma_mult, 8); |
| 2721 | aom_wb_write_literal(wb, pars->cb_offset, 9); |
| 2722 | } |
| 2723 | |
| 2724 | if (pars->num_cr_points) { |
| 2725 | aom_wb_write_literal(wb, pars->cr_mult, 8); |
| 2726 | aom_wb_write_literal(wb, pars->cr_luma_mult, 8); |
| 2727 | aom_wb_write_literal(wb, pars->cr_offset, 9); |
| 2728 | } |
| 2729 | |
| 2730 | aom_wb_write_bit(wb, pars->overlap_flag); |
| 2731 | |
| 2732 | aom_wb_write_bit(wb, pars->clip_to_restricted_range); |
| 2733 | } |
| 2734 | #endif // CONFIG_FILM_GRAIN |
| 2735 | |
Imdad Sardharwalla | 4ec84ab | 2018-02-06 12:20:18 +0000 | [diff] [blame] | 2736 | static void write_sb_size(SequenceHeader *seq_params, |
| 2737 | struct aom_write_bit_buffer *wb) { |
| 2738 | (void)seq_params; |
| 2739 | (void)wb; |
| 2740 | assert(seq_params->mib_size == mi_size_wide[seq_params->sb_size]); |
| 2741 | assert(seq_params->mib_size == 1 << seq_params->mib_size_log2); |
Imdad Sardharwalla | 4ec84ab | 2018-02-06 12:20:18 +0000 | [diff] [blame] | 2742 | assert(seq_params->sb_size == BLOCK_128X128 || |
| 2743 | seq_params->sb_size == BLOCK_64X64); |
| 2744 | aom_wb_write_bit(wb, seq_params->sb_size == BLOCK_128X128 ? 1 : 0); |
Imdad Sardharwalla | 4ec84ab | 2018-02-06 12:20:18 +0000 | [diff] [blame] | 2745 | } |
| 2746 | |
Arild Fuldseth (arilfuld) | b638074 | 2017-11-03 09:42:05 +0100 | [diff] [blame] | 2747 | void write_sequence_header(AV1_COMP *cpi, struct aom_write_bit_buffer *wb) { |
| 2748 | AV1_COMMON *const cm = &cpi->common; |
David Barker | 5e70a11 | 2017-10-03 14:28:17 +0100 | [diff] [blame] | 2749 | SequenceHeader *seq_params = &cm->seq_params; |
Arild Fuldseth (arilfuld) | 7193f02 | 2017-10-30 12:24:57 +0100 | [diff] [blame] | 2750 | |
Arild Fuldseth (arilfuld) | 7193f02 | 2017-10-30 12:24:57 +0100 | [diff] [blame] | 2751 | int num_bits_width = 16; |
| 2752 | int num_bits_height = 16; |
Imdad Sardharwalla | 102c865 | 2018-02-23 16:35:13 +0000 | [diff] [blame] | 2753 | int max_frame_width = cpi->oxcf.forced_max_frame_width |
| 2754 | ? cpi->oxcf.forced_max_frame_width |
| 2755 | : cpi->oxcf.width; |
| 2756 | int max_frame_height = cpi->oxcf.forced_max_frame_height |
| 2757 | ? cpi->oxcf.forced_max_frame_height |
| 2758 | : cpi->oxcf.height; |
Arild Fuldseth (arilfuld) | 7193f02 | 2017-10-30 12:24:57 +0100 | [diff] [blame] | 2759 | |
| 2760 | seq_params->num_bits_width = num_bits_width; |
| 2761 | seq_params->num_bits_height = num_bits_height; |
| 2762 | seq_params->max_frame_width = max_frame_width; |
| 2763 | seq_params->max_frame_height = max_frame_height; |
| 2764 | |
| 2765 | aom_wb_write_literal(wb, num_bits_width - 1, 4); |
| 2766 | aom_wb_write_literal(wb, num_bits_height - 1, 4); |
| 2767 | aom_wb_write_literal(wb, max_frame_width - 1, num_bits_width); |
| 2768 | aom_wb_write_literal(wb, max_frame_height - 1, num_bits_height); |
Arild Fuldseth (arilfuld) | 7193f02 | 2017-10-30 12:24:57 +0100 | [diff] [blame] | 2769 | |
Arild Fuldseth (arilfuld) | 5114b7b | 2016-11-09 13:32:54 +0100 | [diff] [blame] | 2770 | /* Placeholder for actually writing to the bitstream */ |
Yunqing Wang | c2502b5 | 2017-07-19 17:44:18 -0700 | [diff] [blame] | 2771 | seq_params->frame_id_numbers_present_flag = |
Yaowu Xu | dd6ef6c | 2018-03-02 16:43:52 -0800 | [diff] [blame] | 2772 | cm->large_scale_tile ? 0 : cm->error_resilient_mode; |
Sebastien Alaiwan | d418f68 | 2017-10-19 15:06:52 +0200 | [diff] [blame] | 2773 | seq_params->frame_id_length = FRAME_ID_LENGTH; |
| 2774 | seq_params->delta_frame_id_length = DELTA_FRAME_ID_LENGTH; |
David Barker | 5e70a11 | 2017-10-03 14:28:17 +0100 | [diff] [blame] | 2775 | |
| 2776 | aom_wb_write_bit(wb, seq_params->frame_id_numbers_present_flag); |
| 2777 | if (seq_params->frame_id_numbers_present_flag) { |
Frederic Barbier | 4d5d90e | 2017-10-13 09:22:33 +0200 | [diff] [blame] | 2778 | // We must always have delta_frame_id_length < frame_id_length, |
| 2779 | // in order for a frame to be referenced with a unique delta. |
| 2780 | // Avoid wasting bits by using a coding that enforces this restriction. |
Frederic Barbier | e83fcfe | 2017-10-13 10:37:50 +0200 | [diff] [blame] | 2781 | aom_wb_write_literal(wb, seq_params->delta_frame_id_length - 2, 4); |
Frederic Barbier | 4d5d90e | 2017-10-13 09:22:33 +0200 | [diff] [blame] | 2782 | aom_wb_write_literal( |
| 2783 | wb, seq_params->frame_id_length - seq_params->delta_frame_id_length - 1, |
| 2784 | 3); |
David Barker | 5e70a11 | 2017-10-03 14:28:17 +0100 | [diff] [blame] | 2785 | } |
Imdad Sardharwalla | 4ec84ab | 2018-02-06 12:20:18 +0000 | [diff] [blame] | 2786 | |
| 2787 | write_sb_size(seq_params, wb); |
Imdad Sardharwalla | bf2cc01 | 2018-02-09 17:32:10 +0000 | [diff] [blame] | 2788 | |
Jingning Han | 127c823 | 2018-02-22 16:54:13 -0800 | [diff] [blame] | 2789 | aom_wb_write_bit(wb, seq_params->enable_dual_filter); |
| 2790 | |
Cheng Chen | fecd9a7 | 2018-03-08 15:23:51 -0800 | [diff] [blame] | 2791 | aom_wb_write_bit(wb, seq_params->enable_order_hint); |
| 2792 | |
| 2793 | if (seq_params->enable_order_hint) |
| 2794 | aom_wb_write_bit(wb, seq_params->enable_jnt_comp); |
Cheng Chen | e0c918a | 2018-02-22 19:38:31 -0800 | [diff] [blame] | 2795 | |
Imdad Sardharwalla | bf2cc01 | 2018-02-09 17:32:10 +0000 | [diff] [blame] | 2796 | if (seq_params->force_screen_content_tools == 2) { |
| 2797 | aom_wb_write_bit(wb, 1); |
| 2798 | } else { |
| 2799 | aom_wb_write_bit(wb, 0); |
| 2800 | aom_wb_write_bit(wb, seq_params->force_screen_content_tools); |
| 2801 | } |
| 2802 | |
| 2803 | #if CONFIG_AMVR |
| 2804 | if (seq_params->force_screen_content_tools > 0) { |
| 2805 | if (seq_params->force_integer_mv == 2) { |
| 2806 | aom_wb_write_bit(wb, 1); |
| 2807 | } else { |
| 2808 | aom_wb_write_bit(wb, 0); |
| 2809 | aom_wb_write_bit(wb, seq_params->force_integer_mv); |
| 2810 | } |
| 2811 | } else { |
| 2812 | assert(seq_params->force_integer_mv == 2); |
| 2813 | } |
| 2814 | #endif |
Imdad Sardharwalla | e68aa8a | 2018-03-07 18:52:54 +0000 | [diff] [blame] | 2815 | |
| 2816 | #if CONFIG_EXPLICIT_ORDER_HINT |
Zoe Liu | 17bdcdf | 2018-03-09 15:06:58 -0800 | [diff] [blame] | 2817 | if (seq_params->enable_order_hint) |
| 2818 | aom_wb_write_literal(wb, seq_params->order_hint_bits_minus1, 3); |
Imdad Sardharwalla | e68aa8a | 2018-03-07 18:52:54 +0000 | [diff] [blame] | 2819 | #endif |
Arild Fuldseth (arilfuld) | 5114b7b | 2016-11-09 13:32:54 +0100 | [diff] [blame] | 2820 | } |
Arild Fuldseth (arilfuld) | 5114b7b | 2016-11-09 13:32:54 +0100 | [diff] [blame] | 2821 | |
Debargha Mukherjee | 9e2c7a6 | 2017-05-23 21:18:42 -0700 | [diff] [blame] | 2822 | static void write_compound_tools(const AV1_COMMON *cm, |
| 2823 | struct aom_write_bit_buffer *wb) { |
Debargha Mukherjee | 9e2c7a6 | 2017-05-23 21:18:42 -0700 | [diff] [blame] | 2824 | if (!frame_is_intra_only(cm) && cm->reference_mode != COMPOUND_REFERENCE) { |
| 2825 | aom_wb_write_bit(wb, cm->allow_interintra_compound); |
| 2826 | } else { |
| 2827 | assert(cm->allow_interintra_compound == 0); |
| 2828 | } |
Debargha Mukherjee | 9e2c7a6 | 2017-05-23 21:18:42 -0700 | [diff] [blame] | 2829 | if (!frame_is_intra_only(cm) && cm->reference_mode != SINGLE_REFERENCE) { |
| 2830 | aom_wb_write_bit(wb, cm->allow_masked_compound); |
| 2831 | } else { |
| 2832 | assert(cm->allow_masked_compound == 0); |
| 2833 | } |
Debargha Mukherjee | 9e2c7a6 | 2017-05-23 21:18:42 -0700 | [diff] [blame] | 2834 | } |
Debargha Mukherjee | 9e2c7a6 | 2017-05-23 21:18:42 -0700 | [diff] [blame] | 2835 | |
David Barker | d7c8bd5 | 2017-09-25 14:47:29 +0100 | [diff] [blame] | 2836 | static void write_global_motion_params(const WarpedMotionParams *params, |
| 2837 | const WarpedMotionParams *ref_params, |
Sarah Parker | 3e579a6 | 2017-08-23 16:53:20 -0700 | [diff] [blame] | 2838 | struct aom_write_bit_buffer *wb, |
| 2839 | int allow_hp) { |
Sebastien Alaiwan | e4984ff | 2017-10-31 15:27:44 +0100 | [diff] [blame] | 2840 | const TransformationType type = params->wmtype; |
Sarah Parker | 3e579a6 | 2017-08-23 16:53:20 -0700 | [diff] [blame] | 2841 | |
| 2842 | aom_wb_write_bit(wb, type != IDENTITY); |
| 2843 | if (type != IDENTITY) { |
| 2844 | #if GLOBAL_TRANS_TYPES > 4 |
| 2845 | aom_wb_write_literal(wb, type - 1, GLOBAL_TYPE_BITS); |
| 2846 | #else |
| 2847 | aom_wb_write_bit(wb, type == ROTZOOM); |
| 2848 | if (type != ROTZOOM) aom_wb_write_bit(wb, type == TRANSLATION); |
| 2849 | #endif // GLOBAL_TRANS_TYPES > 4 |
| 2850 | } |
| 2851 | |
Sebastien Alaiwan | e4984ff | 2017-10-31 15:27:44 +0100 | [diff] [blame] | 2852 | if (type >= ROTZOOM) { |
| 2853 | aom_wb_write_signed_primitive_refsubexpfin( |
| 2854 | wb, GM_ALPHA_MAX + 1, SUBEXPFIN_K, |
| 2855 | (ref_params->wmmat[2] >> GM_ALPHA_PREC_DIFF) - |
| 2856 | (1 << GM_ALPHA_PREC_BITS), |
| 2857 | (params->wmmat[2] >> GM_ALPHA_PREC_DIFF) - (1 << GM_ALPHA_PREC_BITS)); |
| 2858 | aom_wb_write_signed_primitive_refsubexpfin( |
| 2859 | wb, GM_ALPHA_MAX + 1, SUBEXPFIN_K, |
| 2860 | (ref_params->wmmat[3] >> GM_ALPHA_PREC_DIFF), |
| 2861 | (params->wmmat[3] >> GM_ALPHA_PREC_DIFF)); |
| 2862 | } |
| 2863 | |
| 2864 | if (type >= AFFINE) { |
| 2865 | aom_wb_write_signed_primitive_refsubexpfin( |
| 2866 | wb, GM_ALPHA_MAX + 1, SUBEXPFIN_K, |
| 2867 | (ref_params->wmmat[4] >> GM_ALPHA_PREC_DIFF), |
| 2868 | (params->wmmat[4] >> GM_ALPHA_PREC_DIFF)); |
| 2869 | aom_wb_write_signed_primitive_refsubexpfin( |
| 2870 | wb, GM_ALPHA_MAX + 1, SUBEXPFIN_K, |
| 2871 | (ref_params->wmmat[5] >> GM_ALPHA_PREC_DIFF) - |
| 2872 | (1 << GM_ALPHA_PREC_BITS), |
| 2873 | (params->wmmat[5] >> GM_ALPHA_PREC_DIFF) - (1 << GM_ALPHA_PREC_BITS)); |
| 2874 | } |
| 2875 | |
| 2876 | if (type >= TRANSLATION) { |
| 2877 | const int trans_bits = (type == TRANSLATION) |
| 2878 | ? GM_ABS_TRANS_ONLY_BITS - !allow_hp |
| 2879 | : GM_ABS_TRANS_BITS; |
| 2880 | const int trans_prec_diff = (type == TRANSLATION) |
| 2881 | ? GM_TRANS_ONLY_PREC_DIFF + !allow_hp |
| 2882 | : GM_TRANS_PREC_DIFF; |
| 2883 | aom_wb_write_signed_primitive_refsubexpfin( |
| 2884 | wb, (1 << trans_bits) + 1, SUBEXPFIN_K, |
| 2885 | (ref_params->wmmat[0] >> trans_prec_diff), |
| 2886 | (params->wmmat[0] >> trans_prec_diff)); |
| 2887 | aom_wb_write_signed_primitive_refsubexpfin( |
| 2888 | wb, (1 << trans_bits) + 1, SUBEXPFIN_K, |
| 2889 | (ref_params->wmmat[1] >> trans_prec_diff), |
| 2890 | (params->wmmat[1] >> trans_prec_diff)); |
Sarah Parker | 3e579a6 | 2017-08-23 16:53:20 -0700 | [diff] [blame] | 2891 | } |
| 2892 | } |
| 2893 | |
| 2894 | static void write_global_motion(AV1_COMP *cpi, |
| 2895 | struct aom_write_bit_buffer *wb) { |
| 2896 | AV1_COMMON *const cm = &cpi->common; |
| 2897 | int frame; |
| 2898 | for (frame = LAST_FRAME; frame <= ALTREF_FRAME; ++frame) { |
David Barker | d7c8bd5 | 2017-09-25 14:47:29 +0100 | [diff] [blame] | 2899 | const WarpedMotionParams *ref_params = |
Yue Chen | d90d343 | 2018-03-16 11:28:42 -0700 | [diff] [blame] | 2900 | (cm->error_resilient_mode || cm->prev_frame == NULL) |
| 2901 | ? &default_warp_params |
| 2902 | : &cm->prev_frame->global_motion[frame]; |
David Barker | d7c8bd5 | 2017-09-25 14:47:29 +0100 | [diff] [blame] | 2903 | write_global_motion_params(&cm->global_motion[frame], ref_params, wb, |
Sarah Parker | 3e579a6 | 2017-08-23 16:53:20 -0700 | [diff] [blame] | 2904 | cm->allow_high_precision_mv); |
| 2905 | // TODO(sarahparker, debargha): The logic in the commented out code below |
| 2906 | // does not work currently and causes mismatches when resize is on. |
| 2907 | // Fix it before turning the optimization back on. |
| 2908 | /* |
| 2909 | YV12_BUFFER_CONFIG *ref_buf = get_ref_frame_buffer(cpi, frame); |
| 2910 | if (cpi->source->y_crop_width == ref_buf->y_crop_width && |
| 2911 | cpi->source->y_crop_height == ref_buf->y_crop_height) { |
| 2912 | write_global_motion_params(&cm->global_motion[frame], |
| 2913 | &cm->prev_frame->global_motion[frame], wb, |
| 2914 | cm->allow_high_precision_mv); |
| 2915 | } else { |
| 2916 | assert(cm->global_motion[frame].wmtype == IDENTITY && |
| 2917 | "Invalid warp type for frames of different resolutions"); |
| 2918 | } |
| 2919 | */ |
| 2920 | /* |
| 2921 | printf("Frame %d/%d: Enc Ref %d: %d %d %d %d\n", |
| 2922 | cm->current_video_frame, cm->show_frame, frame, |
| 2923 | cm->global_motion[frame].wmmat[0], |
| 2924 | cm->global_motion[frame].wmmat[1], cm->global_motion[frame].wmmat[2], |
| 2925 | cm->global_motion[frame].wmmat[3]); |
| 2926 | */ |
| 2927 | } |
| 2928 | } |
Sarah Parker | 3e579a6 | 2017-08-23 16:53:20 -0700 | [diff] [blame] | 2929 | |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 2930 | // New function based on HLS R18 |
| 2931 | static void write_uncompressed_header_obu(AV1_COMP *cpi, |
Jingning Han | da11e69 | 2017-12-19 08:45:08 -0800 | [diff] [blame] | 2932 | struct aom_write_bit_buffer *saved_wb, |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 2933 | struct aom_write_bit_buffer *wb) { |
| 2934 | AV1_COMMON *const cm = &cpi->common; |
| 2935 | MACROBLOCKD *const xd = &cpi->td.mb.e_mbd; |
| 2936 | |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 2937 | // NOTE: By default all coded frames to be used as a reference |
| 2938 | cm->is_reference_frame = 1; |
| 2939 | |
| 2940 | if (cm->show_existing_frame) { |
| 2941 | RefCntBuffer *const frame_bufs = cm->buffer_pool->frame_bufs; |
| 2942 | const int frame_to_show = cm->ref_frame_map[cpi->existing_fb_idx_to_show]; |
| 2943 | |
| 2944 | if (frame_to_show < 0 || frame_bufs[frame_to_show].ref_count < 1) { |
| 2945 | aom_internal_error(&cm->error, AOM_CODEC_UNSUP_BITSTREAM, |
| 2946 | "Buffer %d does not contain a reconstructed frame", |
| 2947 | frame_to_show); |
| 2948 | } |
| 2949 | ref_cnt_fb(frame_bufs, &cm->new_fb_idx, frame_to_show); |
| 2950 | |
| 2951 | aom_wb_write_bit(wb, 1); // show_existing_frame |
| 2952 | aom_wb_write_literal(wb, cpi->existing_fb_idx_to_show, 3); |
| 2953 | |
David Barker | 5e70a11 | 2017-10-03 14:28:17 +0100 | [diff] [blame] | 2954 | if (cm->seq_params.frame_id_numbers_present_flag) { |
Frederic Barbier | e83fcfe | 2017-10-13 10:37:50 +0200 | [diff] [blame] | 2955 | int frame_id_len = cm->seq_params.frame_id_length; |
David Barker | 5e70a11 | 2017-10-03 14:28:17 +0100 | [diff] [blame] | 2956 | int display_frame_id = cm->ref_frame_id[cpi->existing_fb_idx_to_show]; |
| 2957 | aom_wb_write_literal(wb, display_frame_id, frame_id_len); |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 2958 | } |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 2959 | |
Dominic Symes | d492901 | 2018-01-31 17:32:01 +0100 | [diff] [blame] | 2960 | #if CONFIG_FILM_GRAIN && !CONFIG_FILM_GRAIN_SHOWEX |
Andrey Norkin | 6f1c2f7 | 2018-01-15 20:08:52 -0800 | [diff] [blame] | 2961 | if (cm->film_grain_params_present && cm->show_frame) { |
| 2962 | int flip_back_update_parameters_flag = 0; |
| 2963 | if (cm->frame_type == KEY_FRAME && |
| 2964 | cm->film_grain_params.update_parameters == 0) { |
| 2965 | cm->film_grain_params.update_parameters = 1; |
| 2966 | flip_back_update_parameters_flag = 1; |
| 2967 | } |
Dominic Symes | d492901 | 2018-01-31 17:32:01 +0100 | [diff] [blame] | 2968 | write_film_grain_params(cpi, wb); |
Andrey Norkin | 6f1c2f7 | 2018-01-15 20:08:52 -0800 | [diff] [blame] | 2969 | |
| 2970 | if (flip_back_update_parameters_flag) |
| 2971 | cm->film_grain_params.update_parameters = 0; |
| 2972 | } |
| 2973 | #endif |
| 2974 | |
Zoe Liu | b499120 | 2017-12-21 15:31:06 -0800 | [diff] [blame] | 2975 | #if CONFIG_FWD_KF |
Zoe Liu | 2723a9d | 2018-02-22 20:17:00 -0800 | [diff] [blame] | 2976 | if (cm->reset_decoder_state && |
| 2977 | frame_bufs[frame_to_show].frame_type != KEY_FRAME) { |
Zoe Liu | b499120 | 2017-12-21 15:31:06 -0800 | [diff] [blame] | 2978 | aom_internal_error( |
| 2979 | &cm->error, AOM_CODEC_UNSUP_BITSTREAM, |
Zoe Liu | 2723a9d | 2018-02-22 20:17:00 -0800 | [diff] [blame] | 2980 | "show_existing_frame to reset state on KEY_FRAME only"); |
Zoe Liu | b499120 | 2017-12-21 15:31:06 -0800 | [diff] [blame] | 2981 | } |
Zoe Liu | b499120 | 2017-12-21 15:31:06 -0800 | [diff] [blame] | 2982 | #endif // CONFIG_FWD_KF |
| 2983 | |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 2984 | return; |
| 2985 | } else { |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 2986 | aom_wb_write_bit(wb, 0); // show_existing_frame |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 2987 | } |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 2988 | |
| 2989 | cm->frame_type = cm->intra_only ? INTRA_ONLY_FRAME : cm->frame_type; |
| 2990 | aom_wb_write_literal(wb, cm->frame_type, 2); |
| 2991 | |
| 2992 | if (cm->intra_only) cm->frame_type = INTRA_ONLY_FRAME; |
| 2993 | |
| 2994 | aom_wb_write_bit(wb, cm->show_frame); |
| 2995 | aom_wb_write_bit(wb, cm->error_resilient_mode); |
| 2996 | |
Yue Chen | 00dcf5a | 2018-03-09 14:31:47 -0800 | [diff] [blame] | 2997 | aom_wb_write_bit(wb, cm->enable_intra_edge_filter); |
Yue Chen | a938362 | 2018-03-08 14:37:09 -0800 | [diff] [blame] | 2998 | aom_wb_write_bit(wb, cm->allow_filter_intra); |
Joe Young | db5eb4c | 2018-02-16 17:30:40 -0800 | [diff] [blame] | 2999 | |
Hui Su | 483a845 | 2018-02-26 12:28:48 -0800 | [diff] [blame] | 3000 | #if CONFIG_CDF_UPDATE_MODE |
| 3001 | aom_wb_write_bit(wb, cm->disable_cdf_update); |
| 3002 | #endif // CONFIG_CDF_UPDATE_MODE |
| 3003 | |
Imdad Sardharwalla | bf2cc01 | 2018-02-09 17:32:10 +0000 | [diff] [blame] | 3004 | if (cm->seq_params.force_screen_content_tools == 2) { |
| 3005 | aom_wb_write_bit(wb, cm->allow_screen_content_tools); |
| 3006 | } else { |
| 3007 | assert(cm->allow_screen_content_tools == |
| 3008 | cm->seq_params.force_screen_content_tools); |
| 3009 | } |
| 3010 | |
| 3011 | #if CONFIG_AMVR |
| 3012 | if (cm->allow_screen_content_tools) { |
| 3013 | if (cm->seq_params.force_integer_mv == 2) { |
| 3014 | aom_wb_write_bit(wb, cm->cur_frame_force_integer_mv); |
| 3015 | } else { |
| 3016 | assert(cm->cur_frame_force_integer_mv == cm->seq_params.force_integer_mv); |
| 3017 | } |
| 3018 | } else { |
| 3019 | assert(cm->cur_frame_force_integer_mv == 0); |
| 3020 | } |
| 3021 | #endif // CONFIG_AMVR |
| 3022 | |
David Barker | 5e70a11 | 2017-10-03 14:28:17 +0100 | [diff] [blame] | 3023 | cm->invalid_delta_frame_id_minus1 = 0; |
| 3024 | if (cm->seq_params.frame_id_numbers_present_flag) { |
Frederic Barbier | e83fcfe | 2017-10-13 10:37:50 +0200 | [diff] [blame] | 3025 | int frame_id_len = cm->seq_params.frame_id_length; |
David Barker | 5e70a11 | 2017-10-03 14:28:17 +0100 | [diff] [blame] | 3026 | aom_wb_write_literal(wb, cm->current_frame_id, frame_id_len); |
Debargha Mukherjee | 778023d | 2017-09-26 17:50:27 -0700 | [diff] [blame] | 3027 | } |
Arild Fuldseth (arilfuld) | 7193f02 | 2017-10-30 12:24:57 +0100 | [diff] [blame] | 3028 | |
Arild Fuldseth (arilfuld) | b638074 | 2017-11-03 09:42:05 +0100 | [diff] [blame] | 3029 | if (cm->width > cm->seq_params.max_frame_width || |
| 3030 | cm->height > cm->seq_params.max_frame_height) { |
| 3031 | aom_internal_error(&cm->error, AOM_CODEC_UNSUP_BITSTREAM, |
| 3032 | "Frame dimensions are larger than the maximum values"); |
| 3033 | } |
Arild Fuldseth (arilfuld) | 7193f02 | 2017-10-30 12:24:57 +0100 | [diff] [blame] | 3034 | int frame_size_override_flag = |
| 3035 | (cm->width != cm->seq_params.max_frame_width || |
| 3036 | cm->height != cm->seq_params.max_frame_height); |
| 3037 | aom_wb_write_bit(wb, frame_size_override_flag); |
Arild Fuldseth (arilfuld) | 7193f02 | 2017-10-30 12:24:57 +0100 | [diff] [blame] | 3038 | |
Zoe Liu | d4a67a8 | 2018-02-21 12:35:33 -0800 | [diff] [blame] | 3039 | #if CONFIG_FRAME_REFS_SIGNALING |
| 3040 | cm->frame_refs_short_signaling = 0; |
| 3041 | #endif // CONFIG_FRAME_REFS_SIGNALING |
| 3042 | |
Imdad Sardharwalla | e68aa8a | 2018-03-07 18:52:54 +0000 | [diff] [blame] | 3043 | #if CONFIG_EXPLICIT_ORDER_HINT |
Zoe Liu | 17bdcdf | 2018-03-09 15:06:58 -0800 | [diff] [blame] | 3044 | aom_wb_write_literal(wb, cm->frame_offset, |
| 3045 | cm->seq_params.order_hint_bits_minus1 + 1); |
Imdad Sardharwalla | e68aa8a | 2018-03-07 18:52:54 +0000 | [diff] [blame] | 3046 | #else |
Zoe Liu | 45a8fed | 2018-03-02 16:51:02 -0800 | [diff] [blame] | 3047 | if (cm->show_frame == 0) { |
| 3048 | int arf_offset = AOMMIN( |
| 3049 | (MAX_GF_INTERVAL - 1), |
| 3050 | cpi->twopass.gf_group.arf_src_offset[cpi->twopass.gf_group.index]); |
| 3051 | int brf_offset = |
| 3052 | cpi->twopass.gf_group.brf_src_offset[cpi->twopass.gf_group.index]; |
| 3053 | |
| 3054 | arf_offset = AOMMIN((MAX_GF_INTERVAL - 1), arf_offset + brf_offset); |
| 3055 | aom_wb_write_literal(wb, arf_offset, FRAME_OFFSET_BITS); |
| 3056 | } |
Imdad Sardharwalla | e68aa8a | 2018-03-07 18:52:54 +0000 | [diff] [blame] | 3057 | #endif |
Zoe Liu | 45a8fed | 2018-03-02 16:51:02 -0800 | [diff] [blame] | 3058 | |
Yue Chen | d90d343 | 2018-03-16 11:28:42 -0700 | [diff] [blame] | 3059 | if (!cm->error_resilient_mode && !frame_is_intra_only(cm)) { |
| 3060 | aom_wb_write_literal(wb, cm->primary_ref_frame, PRIMARY_REF_BITS); |
| 3061 | } |
| 3062 | |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3063 | if (cm->frame_type == KEY_FRAME) { |
Arild Fuldseth (arilfuld) | 7193f02 | 2017-10-30 12:24:57 +0100 | [diff] [blame] | 3064 | write_frame_size(cm, frame_size_override_flag, wb); |
David Barker | 218556e | 2018-02-14 14:23:12 +0000 | [diff] [blame] | 3065 | assert(av1_superres_unscaled(cm) || |
| 3066 | !(cm->allow_intrabc && NO_FILTER_FOR_IBC)); |
| 3067 | if (cm->allow_screen_content_tools && |
| 3068 | (av1_superres_unscaled(cm) || !NO_FILTER_FOR_IBC)) |
David Barker | 218556e | 2018-02-14 14:23:12 +0000 | [diff] [blame] | 3069 | aom_wb_write_bit(wb, cm->allow_intrabc); |
Thomas Daede | 51020e1 | 2017-12-14 20:12:44 -0800 | [diff] [blame] | 3070 | // all eight fbs are refreshed, pick one that will live long enough |
| 3071 | cm->fb_of_context_type[REGULAR_FRAME] = 0; |
Imdad Sardharwalla | 21cc90b | 2018-03-12 16:39:38 +0000 | [diff] [blame] | 3072 | } else { |
| 3073 | #if CONFIG_EXPLICIT_ORDER_HINT |
| 3074 | // Write all ref frame order hints if error_resilient_mode == 1 |
| 3075 | if (cm->error_resilient_mode && cm->seq_params.enable_order_hint) { |
| 3076 | RefCntBuffer *const frame_bufs = cm->buffer_pool->frame_bufs; |
| 3077 | for (int ref_idx = 0; ref_idx < REF_FRAMES; ref_idx++) { |
| 3078 | // Get buffer index |
| 3079 | const int buf_idx = cm->ref_frame_map[ref_idx]; |
| 3080 | assert(buf_idx >= 0 && buf_idx < FRAME_BUFFERS); |
| 3081 | |
| 3082 | // Write order hint to bit stream |
| 3083 | aom_wb_write_literal(wb, frame_bufs[buf_idx].cur_frame_offset, |
| 3084 | cm->seq_params.order_hint_bits_minus1 + 1); |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3085 | } |
| 3086 | } |
Imdad Sardharwalla | 21cc90b | 2018-03-12 16:39:38 +0000 | [diff] [blame] | 3087 | #endif // CONFIG_EXPLICIT_ORDER_HINT |
Zoe Liu | 48acf88 | 2018-02-21 12:16:50 -0800 | [diff] [blame] | 3088 | |
Imdad Sardharwalla | 21cc90b | 2018-03-12 16:39:38 +0000 | [diff] [blame] | 3089 | if (cm->frame_type == INTRA_ONLY_FRAME) { |
Zoe Liu | 48acf88 | 2018-02-21 12:16:50 -0800 | [diff] [blame] | 3090 | cpi->refresh_frame_mask = get_refresh_mask(cpi); |
Imdad Sardharwalla | 21cc90b | 2018-03-12 16:39:38 +0000 | [diff] [blame] | 3091 | int updated_fb = -1; |
| 3092 | for (int i = 0; i < REF_FRAMES; i++) { |
| 3093 | // If more than one frame is refreshed, it doesn't matter which one |
| 3094 | // we pick, so pick the first. |
| 3095 | if (cpi->refresh_frame_mask & (1 << i)) { |
| 3096 | updated_fb = i; |
| 3097 | break; |
| 3098 | } |
Thomas Daede | 51020e1 | 2017-12-14 20:12:44 -0800 | [diff] [blame] | 3099 | } |
Imdad Sardharwalla | 21cc90b | 2018-03-12 16:39:38 +0000 | [diff] [blame] | 3100 | assert(updated_fb >= 0); |
Thomas Daede | 2b4984a | 2018-03-06 15:52:01 -0800 | [diff] [blame] | 3101 | cm->fb_of_context_type[cm->frame_context_idx] = updated_fb; |
Imdad Sardharwalla | 21cc90b | 2018-03-12 16:39:38 +0000 | [diff] [blame] | 3102 | if (cm->intra_only) { |
| 3103 | aom_wb_write_literal(wb, cpi->refresh_frame_mask, REF_FRAMES); |
| 3104 | write_frame_size(cm, frame_size_override_flag, wb); |
| 3105 | assert(av1_superres_unscaled(cm) || |
| 3106 | !(cm->allow_intrabc && NO_FILTER_FOR_IBC)); |
| 3107 | if (cm->allow_screen_content_tools && |
| 3108 | (av1_superres_unscaled(cm) || !NO_FILTER_FOR_IBC)) |
| 3109 | aom_wb_write_bit(wb, cm->allow_intrabc); |
| 3110 | } |
| 3111 | } else if (cm->frame_type == INTER_FRAME || cm->frame_type == S_FRAME) { |
| 3112 | MV_REFERENCE_FRAME ref_frame; |
| 3113 | |
Imdad Sardharwalla | 21cc90b | 2018-03-12 16:39:38 +0000 | [diff] [blame] | 3114 | if (cm->frame_type == INTER_FRAME) { |
| 3115 | cpi->refresh_frame_mask = get_refresh_mask(cpi); |
| 3116 | aom_wb_write_literal(wb, cpi->refresh_frame_mask, REF_FRAMES); |
| 3117 | } |
| 3118 | |
Imdad Sardharwalla | 21cc90b | 2018-03-12 16:39:38 +0000 | [diff] [blame] | 3119 | int updated_fb = -1; |
| 3120 | for (int i = 0; i < REF_FRAMES; i++) { |
| 3121 | // If more than one frame is refreshed, it doesn't matter which one |
| 3122 | // we pick, so pick the first. |
| 3123 | if (cpi->refresh_frame_mask & (1 << i)) { |
| 3124 | updated_fb = i; |
| 3125 | break; |
| 3126 | } |
| 3127 | } |
| 3128 | // large scale tile sometimes won't refresh any fbs |
| 3129 | if (updated_fb >= 0) { |
| 3130 | cm->fb_of_context_type[cm->frame_context_idx] = updated_fb; |
| 3131 | } |
Imdad Sardharwalla | 21cc90b | 2018-03-12 16:39:38 +0000 | [diff] [blame] | 3132 | |
| 3133 | if (!cpi->refresh_frame_mask) { |
| 3134 | // NOTE: "cpi->refresh_frame_mask == 0" indicates that the coded frame |
| 3135 | // will not be used as a reference |
| 3136 | cm->is_reference_frame = 0; |
| 3137 | } |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3138 | |
Zoe Liu | d4a67a8 | 2018-02-21 12:35:33 -0800 | [diff] [blame] | 3139 | #if CONFIG_FRAME_REFS_SIGNALING |
Zoe Liu | d4a67a8 | 2018-02-21 12:35:33 -0800 | [diff] [blame] | 3140 | assert(cm->frame_refs_short_signaling == 0); |
Imdad Sardharwalla | 21cc90b | 2018-03-12 16:39:38 +0000 | [diff] [blame] | 3141 | // NOTE: Error resilient mode turns off frame_refs_short_signaling |
| 3142 | // automatically. |
Debargha Mukherjee | 7f1dfa0 | 2018-03-14 22:25:43 -0700 | [diff] [blame] | 3143 | if (cm->seq_params.enable_order_hint) |
Imdad Sardharwalla | 21cc90b | 2018-03-12 16:39:38 +0000 | [diff] [blame] | 3144 | aom_wb_write_bit(wb, cm->frame_refs_short_signaling); |
| 3145 | else |
| 3146 | assert(cm->frame_refs_short_signaling == 0); |
Zoe Liu | d4a67a8 | 2018-02-21 12:35:33 -0800 | [diff] [blame] | 3147 | |
Imdad Sardharwalla | 21cc90b | 2018-03-12 16:39:38 +0000 | [diff] [blame] | 3148 | if (cm->frame_refs_short_signaling) { |
| 3149 | assert(get_ref_frame_map_idx(cpi, LAST_FRAME) != INVALID_IDX); |
| 3150 | aom_wb_write_literal(wb, get_ref_frame_map_idx(cpi, LAST_FRAME), |
Zoe Liu | d4a67a8 | 2018-02-21 12:35:33 -0800 | [diff] [blame] | 3151 | REF_FRAMES_LOG2); |
Imdad Sardharwalla | 21cc90b | 2018-03-12 16:39:38 +0000 | [diff] [blame] | 3152 | assert(get_ref_frame_map_idx(cpi, GOLDEN_FRAME) != INVALID_IDX); |
| 3153 | aom_wb_write_literal(wb, get_ref_frame_map_idx(cpi, GOLDEN_FRAME), |
| 3154 | REF_FRAMES_LOG2); |
| 3155 | } |
| 3156 | #endif // CONFIG_FRAME_REFS_SIGNALING |
| 3157 | |
| 3158 | for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) { |
| 3159 | assert(get_ref_frame_map_idx(cpi, ref_frame) != INVALID_IDX); |
| 3160 | #if CONFIG_FRAME_REFS_SIGNALING |
| 3161 | if (!cm->frame_refs_short_signaling) |
| 3162 | #endif // CONFIG_FRAME_REFS_SIGNALING |
| 3163 | aom_wb_write_literal(wb, get_ref_frame_map_idx(cpi, ref_frame), |
| 3164 | REF_FRAMES_LOG2); |
| 3165 | if (cm->frame_type == S_FRAME) { |
| 3166 | assert(cm->ref_frame_sign_bias[ref_frame] == 0); |
| 3167 | } |
| 3168 | |
| 3169 | if (cm->seq_params.frame_id_numbers_present_flag) { |
| 3170 | int i = get_ref_frame_map_idx(cpi, ref_frame); |
| 3171 | int frame_id_len = cm->seq_params.frame_id_length; |
| 3172 | int diff_len = cm->seq_params.delta_frame_id_length; |
| 3173 | int delta_frame_id_minus1 = |
| 3174 | ((cm->current_frame_id - cm->ref_frame_id[i] + |
| 3175 | (1 << frame_id_len)) % |
| 3176 | (1 << frame_id_len)) - |
| 3177 | 1; |
| 3178 | if (delta_frame_id_minus1 < 0 || |
| 3179 | delta_frame_id_minus1 >= (1 << diff_len)) |
| 3180 | cm->invalid_delta_frame_id_minus1 = 1; |
| 3181 | aom_wb_write_literal(wb, delta_frame_id_minus1, diff_len); |
| 3182 | } |
Zoe Liu | 48acf88 | 2018-02-21 12:16:50 -0800 | [diff] [blame] | 3183 | } |
Zoe Liu | ca0cd3f | 2018-02-26 15:07:50 -0800 | [diff] [blame] | 3184 | |
Imdad Sardharwalla | 21cc90b | 2018-03-12 16:39:38 +0000 | [diff] [blame] | 3185 | if (cm->error_resilient_mode == 0 && frame_size_override_flag) { |
| 3186 | write_frame_size_with_refs(cpi, wb); |
| 3187 | } else { |
| 3188 | write_frame_size(cm, frame_size_override_flag, wb); |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3189 | } |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3190 | |
| 3191 | #if CONFIG_AMVR |
Imdad Sardharwalla | 21cc90b | 2018-03-12 16:39:38 +0000 | [diff] [blame] | 3192 | if (cm->cur_frame_force_integer_mv) { |
| 3193 | cm->allow_high_precision_mv = 0; |
| 3194 | } else { |
| 3195 | aom_wb_write_bit(wb, cm->allow_high_precision_mv); |
| 3196 | } |
RogerZhou | 0bf3690 | 2017-12-19 13:51:10 -0800 | [diff] [blame] | 3197 | #else |
Imdad Sardharwalla | 21cc90b | 2018-03-12 16:39:38 +0000 | [diff] [blame] | 3198 | aom_wb_write_bit(wb, cm->allow_high_precision_mv); |
RogerZhou | 0bf3690 | 2017-12-19 13:51:10 -0800 | [diff] [blame] | 3199 | #endif |
Imdad Sardharwalla | 21cc90b | 2018-03-12 16:39:38 +0000 | [diff] [blame] | 3200 | fix_interp_filter(cm, cpi->td.counts); |
| 3201 | write_frame_interp_filter(cm->interp_filter, wb); |
| 3202 | aom_wb_write_bit(wb, cm->switchable_motion_mode); |
| 3203 | if (frame_might_use_prev_frame_mvs(cm) && |
| 3204 | cm->seq_params.enable_order_hint) { |
| 3205 | aom_wb_write_bit(wb, cm->use_ref_frame_mvs); |
| 3206 | } |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3207 | } |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3208 | } |
| 3209 | |
David Barker | 5e70a11 | 2017-10-03 14:28:17 +0100 | [diff] [blame] | 3210 | if (cm->seq_params.frame_id_numbers_present_flag) { |
Debargha Mukherjee | 778023d | 2017-09-26 17:50:27 -0700 | [diff] [blame] | 3211 | cm->refresh_mask = |
| 3212 | cm->frame_type == KEY_FRAME ? 0xFF : get_refresh_mask(cpi); |
| 3213 | } |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3214 | |
Debargha Mukherjee | 229fdc8 | 2018-03-10 07:45:33 -0800 | [diff] [blame] | 3215 | const int might_bwd_adapt = !(cm->large_scale_tile); |
Jingning Han | da11e69 | 2017-12-19 08:45:08 -0800 | [diff] [blame] | 3216 | if (might_bwd_adapt) { |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3217 | aom_wb_write_bit( |
James Zern | f34dfc8 | 2018-02-23 16:53:33 -0800 | [diff] [blame] | 3218 | wb, cm->refresh_frame_context == REFRESH_FRAME_CONTEXT_DISABLED); |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3219 | } |
Yue Chen | d90d343 | 2018-03-16 11:28:42 -0700 | [diff] [blame] | 3220 | |
Cyril Concolato | 3b5afc1 | 2017-12-15 12:54:15 -0800 | [diff] [blame] | 3221 | #if CONFIG_TILE_INFO_FIRST |
James Zern | 8b007ff | 2018-02-26 22:49:13 -0800 | [diff] [blame] | 3222 | write_tile_info(cm, saved_wb, wb); |
| 3223 | #endif // CONFIG_TILE_INFO_FIRST |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3224 | encode_quantization(cm, wb); |
| 3225 | encode_segmentation(cm, xd, wb); |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3226 | { |
Thomas Davies | 28444be | 2017-10-13 18:12:25 +0100 | [diff] [blame] | 3227 | int delta_q_allowed = 1; |
| 3228 | #if !CONFIG_EXT_DELTA_Q |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3229 | int i; |
| 3230 | struct segmentation *const seg = &cm->seg; |
| 3231 | int segment_quantizer_active = 0; |
| 3232 | for (i = 0; i < MAX_SEGMENTS; i++) { |
| 3233 | if (segfeature_active(seg, i, SEG_LVL_ALT_Q)) { |
| 3234 | segment_quantizer_active = 1; |
| 3235 | } |
| 3236 | } |
Thomas Davies | 28444be | 2017-10-13 18:12:25 +0100 | [diff] [blame] | 3237 | delta_q_allowed = !segment_quantizer_active; |
| 3238 | #endif |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3239 | |
| 3240 | if (cm->delta_q_present_flag) |
Thomas Davies | 28444be | 2017-10-13 18:12:25 +0100 | [diff] [blame] | 3241 | assert(delta_q_allowed == 1 && cm->base_qindex > 0); |
| 3242 | if (delta_q_allowed == 1 && cm->base_qindex > 0) { |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3243 | aom_wb_write_bit(wb, cm->delta_q_present_flag); |
| 3244 | if (cm->delta_q_present_flag) { |
| 3245 | aom_wb_write_literal(wb, OD_ILOG_NZ(cm->delta_q_res) - 1, 2); |
| 3246 | xd->prev_qindex = cm->base_qindex; |
| 3247 | #if CONFIG_EXT_DELTA_Q |
Hui Su | 22a51d9 | 2018-01-16 13:02:18 -0800 | [diff] [blame] | 3248 | if (cm->allow_intrabc && NO_FILTER_FOR_IBC) |
| 3249 | assert(cm->delta_lf_present_flag == 0); |
| 3250 | else |
Hui Su | 22a51d9 | 2018-01-16 13:02:18 -0800 | [diff] [blame] | 3251 | aom_wb_write_bit(wb, cm->delta_lf_present_flag); |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3252 | if (cm->delta_lf_present_flag) { |
| 3253 | aom_wb_write_literal(wb, OD_ILOG_NZ(cm->delta_lf_res) - 1, 2); |
Yaowu Xu | b02d0b1 | 2017-12-15 01:32:34 +0000 | [diff] [blame] | 3254 | xd->prev_delta_lf_from_base = 0; |
Yaowu Xu | b02d0b1 | 2017-12-15 01:32:34 +0000 | [diff] [blame] | 3255 | aom_wb_write_bit(wb, cm->delta_lf_multi); |
Imdad Sardharwalla | f74b4ab | 2018-02-20 17:22:42 +0000 | [diff] [blame] | 3256 | const int frame_lf_count = |
| 3257 | av1_num_planes(cm) > 1 ? FRAME_LF_COUNT : FRAME_LF_COUNT - 2; |
| 3258 | for (int lf_id = 0; lf_id < frame_lf_count; ++lf_id) |
Cheng Chen | a97394f | 2017-09-27 15:05:14 -0700 | [diff] [blame] | 3259 | xd->prev_delta_lf[lf_id] = 0; |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3260 | } |
| 3261 | #endif // CONFIG_EXT_DELTA_Q |
| 3262 | } |
| 3263 | } |
| 3264 | } |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3265 | if (!cm->all_lossless) { |
Urvang Joshi | 65c9efd | 2018-03-01 12:02:12 -0800 | [diff] [blame] | 3266 | encode_loopfilter(cm, wb); |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3267 | encode_cdef(cm, wb); |
Urvang Joshi | 5ec7b81 | 2018-02-28 14:37:06 -0800 | [diff] [blame] | 3268 | encode_restoration_mode(cm, wb); |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3269 | } |
Urvang Joshi | 5ec7b81 | 2018-02-28 14:37:06 -0800 | [diff] [blame] | 3270 | |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3271 | write_tx_mode(cm, &cm->tx_mode, wb); |
| 3272 | |
| 3273 | if (cpi->allow_comp_inter_inter) { |
| 3274 | const int use_hybrid_pred = cm->reference_mode == REFERENCE_MODE_SELECT; |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3275 | |
| 3276 | aom_wb_write_bit(wb, use_hybrid_pred); |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3277 | } |
Zoe Liu | 4b847e1 | 2017-12-07 12:44:45 -0800 | [diff] [blame] | 3278 | |
Zoe Liu | 4b847e1 | 2017-12-07 12:44:45 -0800 | [diff] [blame] | 3279 | if (cm->is_skip_mode_allowed) aom_wb_write_bit(wb, cm->skip_mode_flag); |
Zoe Liu | 4b847e1 | 2017-12-07 12:44:45 -0800 | [diff] [blame] | 3280 | |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3281 | write_compound_tools(cm, wb); |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3282 | |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3283 | aom_wb_write_bit(wb, cm->reduced_tx_set_used); |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3284 | |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3285 | if (!frame_is_intra_only(cm)) write_global_motion(cpi, wb); |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3286 | |
Dominic Symes | d492901 | 2018-01-31 17:32:01 +0100 | [diff] [blame] | 3287 | #if CONFIG_FILM_GRAIN_SHOWEX |
| 3288 | if (!cm->show_frame) { |
| 3289 | aom_wb_write_bit(wb, cm->showable_frame); |
| 3290 | } |
| 3291 | #endif |
Andrey Norkin | 6f1c2f7 | 2018-01-15 20:08:52 -0800 | [diff] [blame] | 3292 | #if CONFIG_FILM_GRAIN |
Dominic Symes | d492901 | 2018-01-31 17:32:01 +0100 | [diff] [blame] | 3293 | #if CONFIG_FILM_GRAIN_SHOWEX |
| 3294 | if (cm->film_grain_params_present && (cm->show_frame || cm->showable_frame)) { |
| 3295 | #else |
Andrey Norkin | 6f1c2f7 | 2018-01-15 20:08:52 -0800 | [diff] [blame] | 3296 | if (cm->film_grain_params_present && cm->show_frame) { |
Dominic Symes | d492901 | 2018-01-31 17:32:01 +0100 | [diff] [blame] | 3297 | #endif |
Andrey Norkin | 6f1c2f7 | 2018-01-15 20:08:52 -0800 | [diff] [blame] | 3298 | int flip_back_update_parameters_flag = 0; |
Andrey Norkin | 879488f | 2018-02-28 15:30:26 -0800 | [diff] [blame] | 3299 | if (cm->frame_type != INTER_FRAME && |
Andrey Norkin | 6f1c2f7 | 2018-01-15 20:08:52 -0800 | [diff] [blame] | 3300 | cm->film_grain_params.update_parameters == 0) { |
| 3301 | cm->film_grain_params.update_parameters = 1; |
| 3302 | flip_back_update_parameters_flag = 1; |
| 3303 | } |
Dominic Symes | d492901 | 2018-01-31 17:32:01 +0100 | [diff] [blame] | 3304 | write_film_grain_params(cpi, wb); |
Andrey Norkin | 6f1c2f7 | 2018-01-15 20:08:52 -0800 | [diff] [blame] | 3305 | |
| 3306 | if (flip_back_update_parameters_flag) |
| 3307 | cm->film_grain_params.update_parameters = 0; |
| 3308 | } |
| 3309 | #endif |
| 3310 | |
Cyril Concolato | 3b5afc1 | 2017-12-15 12:54:15 -0800 | [diff] [blame] | 3311 | #if !CONFIG_TILE_INFO_FIRST |
James Zern | 8b007ff | 2018-02-26 22:49:13 -0800 | [diff] [blame] | 3312 | write_tile_info(cm, saved_wb, wb); |
Jingning Han | da11e69 | 2017-12-19 08:45:08 -0800 | [diff] [blame] | 3313 | #endif // !CONFIG_TILE_INFO_FIRST |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3314 | } |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3315 | |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 3316 | static int choose_size_bytes(uint32_t size, int spare_msbs) { |
| 3317 | // Choose the number of bytes required to represent size, without |
| 3318 | // using the 'spare_msbs' number of most significant bits. |
| 3319 | |
| 3320 | // Make sure we will fit in 4 bytes to start with.. |
| 3321 | if (spare_msbs > 0 && size >> (32 - spare_msbs) != 0) return -1; |
| 3322 | |
| 3323 | // Normalise to 32 bits |
| 3324 | size <<= spare_msbs; |
| 3325 | |
| 3326 | if (size >> 24 != 0) |
| 3327 | return 4; |
| 3328 | else if (size >> 16 != 0) |
| 3329 | return 3; |
| 3330 | else if (size >> 8 != 0) |
| 3331 | return 2; |
| 3332 | else |
| 3333 | return 1; |
| 3334 | } |
| 3335 | |
| 3336 | static void mem_put_varsize(uint8_t *const dst, const int sz, const int val) { |
| 3337 | switch (sz) { |
| 3338 | case 1: dst[0] = (uint8_t)(val & 0xff); break; |
| 3339 | case 2: mem_put_le16(dst, val); break; |
| 3340 | case 3: mem_put_le24(dst, val); break; |
| 3341 | case 4: mem_put_le32(dst, val); break; |
James Zern | 06c372d | 2017-04-20 16:08:29 -0700 | [diff] [blame] | 3342 | default: assert(0 && "Invalid size"); break; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 3343 | } |
| 3344 | } |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3345 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 3346 | static int remux_tiles(const AV1_COMMON *const cm, uint8_t *dst, |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 3347 | const uint32_t data_size, const uint32_t max_tile_size, |
| 3348 | const uint32_t max_tile_col_size, |
| 3349 | int *const tile_size_bytes, |
| 3350 | int *const tile_col_size_bytes) { |
Yunqing Wang | eeb08a9 | 2017-07-07 21:25:18 -0700 | [diff] [blame] | 3351 | // Choose the tile size bytes (tsb) and tile column size bytes (tcsb) |
| 3352 | int tsb; |
| 3353 | int tcsb; |
| 3354 | |
Yunqing Wang | eeb08a9 | 2017-07-07 21:25:18 -0700 | [diff] [blame] | 3355 | if (cm->large_scale_tile) { |
| 3356 | // The top bit in the tile size field indicates tile copy mode, so we |
| 3357 | // have 1 less bit to code the tile size |
| 3358 | tsb = choose_size_bytes(max_tile_size, 1); |
| 3359 | tcsb = choose_size_bytes(max_tile_col_size, 0); |
| 3360 | } else { |
Yunqing Wang | eeb08a9 | 2017-07-07 21:25:18 -0700 | [diff] [blame] | 3361 | tsb = choose_size_bytes(max_tile_size, 0); |
| 3362 | tcsb = 4; // This is ignored |
| 3363 | (void)max_tile_col_size; |
Yunqing Wang | eeb08a9 | 2017-07-07 21:25:18 -0700 | [diff] [blame] | 3364 | } |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 3365 | |
| 3366 | assert(tsb > 0); |
| 3367 | assert(tcsb > 0); |
| 3368 | |
| 3369 | *tile_size_bytes = tsb; |
| 3370 | *tile_col_size_bytes = tcsb; |
James Zern | a60ff58 | 2018-02-24 14:02:12 -0800 | [diff] [blame] | 3371 | if (tsb == 4 && tcsb == 4) return data_size; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 3372 | |
James Zern | a60ff58 | 2018-02-24 14:02:12 -0800 | [diff] [blame] | 3373 | uint32_t wpos = 0; |
| 3374 | uint32_t rpos = 0; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 3375 | |
James Zern | a60ff58 | 2018-02-24 14:02:12 -0800 | [diff] [blame] | 3376 | if (cm->large_scale_tile) { |
| 3377 | int tile_row; |
| 3378 | int tile_col; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 3379 | |
James Zern | a60ff58 | 2018-02-24 14:02:12 -0800 | [diff] [blame] | 3380 | for (tile_col = 0; tile_col < cm->tile_cols; tile_col++) { |
| 3381 | // All but the last column has a column header |
| 3382 | if (tile_col < cm->tile_cols - 1) { |
| 3383 | uint32_t tile_col_size = mem_get_le32(dst + rpos); |
| 3384 | rpos += 4; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 3385 | |
James Zern | a60ff58 | 2018-02-24 14:02:12 -0800 | [diff] [blame] | 3386 | // Adjust the tile column size by the number of bytes removed |
| 3387 | // from the tile size fields. |
| 3388 | tile_col_size -= (4 - tsb) * cm->tile_rows; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 3389 | |
James Zern | a60ff58 | 2018-02-24 14:02:12 -0800 | [diff] [blame] | 3390 | mem_put_varsize(dst + wpos, tcsb, tile_col_size); |
| 3391 | wpos += tcsb; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 3392 | } |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 3393 | |
James Zern | a60ff58 | 2018-02-24 14:02:12 -0800 | [diff] [blame] | 3394 | for (tile_row = 0; tile_row < cm->tile_rows; tile_row++) { |
| 3395 | // All, including the last row has a header |
| 3396 | uint32_t tile_header = mem_get_le32(dst + rpos); |
| 3397 | rpos += 4; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 3398 | |
James Zern | a60ff58 | 2018-02-24 14:02:12 -0800 | [diff] [blame] | 3399 | // If this is a copy tile, we need to shift the MSB to the |
| 3400 | // top bit of the new width, and there is no data to copy. |
| 3401 | if (tile_header >> 31 != 0) { |
| 3402 | if (tsb < 4) tile_header >>= 32 - 8 * tsb; |
| 3403 | mem_put_varsize(dst + wpos, tsb, tile_header); |
Yunqing Wang | eeb08a9 | 2017-07-07 21:25:18 -0700 | [diff] [blame] | 3404 | wpos += tsb; |
James Zern | a60ff58 | 2018-02-24 14:02:12 -0800 | [diff] [blame] | 3405 | } else { |
| 3406 | mem_put_varsize(dst + wpos, tsb, tile_header); |
| 3407 | wpos += tsb; |
| 3408 | |
| 3409 | memmove(dst + wpos, dst + rpos, tile_header); |
| 3410 | rpos += tile_header; |
| 3411 | wpos += tile_header; |
Yunqing Wang | eeb08a9 | 2017-07-07 21:25:18 -0700 | [diff] [blame] | 3412 | } |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 3413 | } |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 3414 | } |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 3415 | |
| 3416 | assert(rpos > wpos); |
| 3417 | assert(rpos == data_size); |
| 3418 | |
| 3419 | return wpos; |
| 3420 | } |
James Zern | a60ff58 | 2018-02-24 14:02:12 -0800 | [diff] [blame] | 3421 | const int n_tiles = cm->tile_cols * cm->tile_rows; |
| 3422 | int n; |
| 3423 | |
| 3424 | for (n = 0; n < n_tiles; n++) { |
| 3425 | int tile_size; |
| 3426 | |
| 3427 | if (n == n_tiles - 1) { |
| 3428 | tile_size = data_size - rpos; |
| 3429 | } else { |
| 3430 | tile_size = mem_get_le32(dst + rpos); |
| 3431 | rpos += 4; |
| 3432 | mem_put_varsize(dst + wpos, tsb, tile_size); |
| 3433 | wpos += tsb; |
| 3434 | } |
| 3435 | |
| 3436 | memmove(dst + wpos, dst + rpos, tile_size); |
| 3437 | |
| 3438 | rpos += tile_size; |
| 3439 | wpos += tile_size; |
| 3440 | } |
| 3441 | |
| 3442 | assert(rpos > wpos); |
| 3443 | assert(rpos == data_size); |
| 3444 | |
| 3445 | return wpos; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 3446 | } |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3447 | |
Soo-Chul Han | 38427e8 | 2017-09-27 15:06:13 -0400 | [diff] [blame] | 3448 | uint32_t write_obu_header(OBU_TYPE obu_type, int obu_extension, |
| 3449 | uint8_t *const dst) { |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3450 | struct aom_write_bit_buffer wb = { dst, 0 }; |
| 3451 | uint32_t size = 0; |
| 3452 | |
Tom Finegan | f927381 | 2018-03-14 09:49:45 -0700 | [diff] [blame] | 3453 | aom_wb_write_literal(&wb, 0, 1); // forbidden bit. |
Soo-Chul Han | 38427e8 | 2017-09-27 15:06:13 -0400 | [diff] [blame] | 3454 | aom_wb_write_literal(&wb, (int)obu_type, 4); |
Vignesh Venkatasubramanian | 726f795 | 2018-03-08 15:03:35 -0800 | [diff] [blame] | 3455 | #if CONFIG_OBU_SIZE_AFTER_HEADER |
| 3456 | aom_wb_write_literal(&wb, obu_extension ? 1 : 0, 1); |
| 3457 | aom_wb_write_literal(&wb, 1, 1); // obu_has_payload_length_field |
| 3458 | aom_wb_write_literal(&wb, 0, 1); // reserved |
| 3459 | #else |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3460 | aom_wb_write_literal(&wb, 0, 2); |
| 3461 | aom_wb_write_literal(&wb, obu_extension ? 1 : 0, 1); |
Vignesh Venkatasubramanian | 726f795 | 2018-03-08 15:03:35 -0800 | [diff] [blame] | 3462 | #endif // CONFIG_OBU_SIZE_AFTER_HEADER |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3463 | if (obu_extension) { |
| 3464 | aom_wb_write_literal(&wb, obu_extension & 0xFF, 8); |
| 3465 | } |
| 3466 | |
| 3467 | size = aom_wb_bytes_written(&wb); |
| 3468 | return size; |
| 3469 | } |
| 3470 | |
Vignesh Venkatasubramanian | ea0257d | 2018-02-28 14:43:34 -0800 | [diff] [blame] | 3471 | size_t get_uleb_obu_size_in_bytes(uint32_t obu_header_size, |
| 3472 | uint32_t obu_payload_size) { |
| 3473 | #if CONFIG_OBU_SIZE_AFTER_HEADER |
| 3474 | const uint32_t obu_size = obu_payload_size; |
| 3475 | (void)obu_header_size; |
| 3476 | #else |
| 3477 | const uint32_t obu_size = obu_header_size + obu_payload_size; |
| 3478 | #endif // CONFIG_OBU_SIZE_AFTER_HEADER |
| 3479 | return aom_uleb_size_in_bytes(obu_size); |
| 3480 | } |
| 3481 | |
| 3482 | int write_uleb_obu_size(uint32_t obu_header_size, uint32_t obu_payload_size, |
| 3483 | uint8_t *dest) { |
| 3484 | #if CONFIG_OBU_SIZE_AFTER_HEADER |
| 3485 | const uint32_t obu_size = obu_payload_size; |
| 3486 | const uint32_t offset = obu_header_size; |
| 3487 | #else |
| 3488 | const uint32_t obu_size = obu_header_size + obu_payload_size; |
| 3489 | const uint32_t offset = 0; |
| 3490 | #endif // CONFIG_OBU_SIZE_AFTER_HEADER |
Tom Finegan | 41150ad | 2018-01-23 11:42:55 -0800 | [diff] [blame] | 3491 | size_t coded_obu_size = 0; |
| 3492 | |
Vignesh Venkatasubramanian | ea0257d | 2018-02-28 14:43:34 -0800 | [diff] [blame] | 3493 | if (aom_uleb_encode(obu_size, sizeof(obu_size), dest + offset, |
| 3494 | &coded_obu_size) != 0) { |
Tom Finegan | 41150ad | 2018-01-23 11:42:55 -0800 | [diff] [blame] | 3495 | return AOM_CODEC_ERROR; |
Vignesh Venkatasubramanian | ea0257d | 2018-02-28 14:43:34 -0800 | [diff] [blame] | 3496 | } |
Tom Finegan | 41150ad | 2018-01-23 11:42:55 -0800 | [diff] [blame] | 3497 | |
| 3498 | return AOM_CODEC_OK; |
| 3499 | } |
Vignesh Venkatasubramanian | ea0257d | 2018-02-28 14:43:34 -0800 | [diff] [blame] | 3500 | |
| 3501 | static size_t obu_memmove(uint32_t obu_header_size, uint32_t obu_payload_size, |
| 3502 | uint8_t *data) { |
| 3503 | const size_t length_field_size = |
| 3504 | get_uleb_obu_size_in_bytes(obu_header_size, obu_payload_size); |
| 3505 | uint32_t move_dst_offset = (uint32_t)length_field_size; |
| 3506 | #if CONFIG_OBU_SIZE_AFTER_HEADER |
| 3507 | // In this case, header shouldn't be moved. |
| 3508 | move_dst_offset += obu_header_size; |
| 3509 | const uint32_t move_src_offset = obu_header_size; |
| 3510 | const uint32_t move_size = obu_payload_size; |
| 3511 | #else |
| 3512 | const uint32_t move_src_offset = 0; |
| 3513 | const uint32_t move_size = obu_header_size + obu_payload_size; |
| 3514 | #endif // CONFIG_OBU_SIZE_AFTER_HEADER |
| 3515 | memmove(data + move_dst_offset, data + move_src_offset, move_size); |
| 3516 | return length_field_size; |
| 3517 | } |
Tom Finegan | 41150ad | 2018-01-23 11:42:55 -0800 | [diff] [blame] | 3518 | |
Cyril Concolato | 2dab275 | 2018-02-26 14:25:47 -0800 | [diff] [blame] | 3519 | #if CONFIG_TRAILING_BITS |
| 3520 | static void add_trailing_bits(struct aom_write_bit_buffer *wb) { |
| 3521 | if (aom_wb_is_byte_aligned(wb)) { |
| 3522 | aom_wb_write_literal(wb, 0x80, 8); |
| 3523 | } else { |
| 3524 | // assumes that the other bits are already 0s |
| 3525 | aom_wb_write_bit(wb, 1); |
| 3526 | } |
| 3527 | } |
| 3528 | #endif |
| 3529 | |
Soo-Chul Han | f858986 | 2018-01-24 03:13:14 +0000 | [diff] [blame] | 3530 | static uint32_t write_sequence_header_obu(AV1_COMP *cpi, uint8_t *const dst |
| 3531 | #if CONFIG_SCALABILITY |
| 3532 | , |
| 3533 | uint8_t enhancement_layers_cnt) { |
| 3534 | #else |
Johann | b0ef6ff | 2018-02-08 14:32:21 -0800 | [diff] [blame] | 3535 | ) { |
Soo-Chul Han | f858986 | 2018-01-24 03:13:14 +0000 | [diff] [blame] | 3536 | #endif |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3537 | AV1_COMMON *const cm = &cpi->common; |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3538 | struct aom_write_bit_buffer wb = { dst, 0 }; |
| 3539 | uint32_t size = 0; |
| 3540 | |
| 3541 | write_profile(cm->profile, &wb); |
| 3542 | |
| 3543 | aom_wb_write_literal(&wb, 0, 4); |
Soo-Chul Han | f858986 | 2018-01-24 03:13:14 +0000 | [diff] [blame] | 3544 | #if CONFIG_SCALABILITY |
| 3545 | aom_wb_write_literal(&wb, enhancement_layers_cnt, 2); |
| 3546 | int i; |
| 3547 | for (i = 1; i <= enhancement_layers_cnt; i++) { |
| 3548 | aom_wb_write_literal(&wb, 0, 4); |
| 3549 | } |
| 3550 | #endif |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3551 | |
Arild Fuldseth (arilfuld) | b638074 | 2017-11-03 09:42:05 +0100 | [diff] [blame] | 3552 | write_sequence_header(cpi, &wb); |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3553 | |
| 3554 | // color_config |
| 3555 | write_bitdepth_colorspace_sampling(cm, &wb); |
| 3556 | |
Andrey Norkin | 28e9ce2 | 2018-01-08 10:11:21 -0800 | [diff] [blame] | 3557 | // timing_info |
| 3558 | write_timing_info_header(cm, &wb); |
Andrey Norkin | 28e9ce2 | 2018-01-08 10:11:21 -0800 | [diff] [blame] | 3559 | |
Andrey Norkin | 6f1c2f7 | 2018-01-15 20:08:52 -0800 | [diff] [blame] | 3560 | #if CONFIG_FILM_GRAIN |
| 3561 | aom_wb_write_bit(&wb, cm->film_grain_params_present); |
| 3562 | #endif |
| 3563 | |
Cyril Concolato | 2dab275 | 2018-02-26 14:25:47 -0800 | [diff] [blame] | 3564 | #if CONFIG_TRAILING_BITS |
| 3565 | add_trailing_bits(&wb); |
| 3566 | #endif |
| 3567 | |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3568 | size = aom_wb_bytes_written(&wb); |
| 3569 | return size; |
| 3570 | } |
| 3571 | |
Jingning Han | da11e69 | 2017-12-19 08:45:08 -0800 | [diff] [blame] | 3572 | static uint32_t write_frame_header_obu(AV1_COMP *cpi, |
Jingning Han | da11e69 | 2017-12-19 08:45:08 -0800 | [diff] [blame] | 3573 | struct aom_write_bit_buffer *saved_wb, |
Jingning Han | da11e69 | 2017-12-19 08:45:08 -0800 | [diff] [blame] | 3574 | uint8_t *const dst) { |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3575 | AV1_COMMON *const cm = &cpi->common; |
| 3576 | struct aom_write_bit_buffer wb = { dst, 0 }; |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3577 | uint32_t total_size = 0; |
Yunqing Wang | e7142e1 | 2018-01-17 11:20:12 -0800 | [diff] [blame] | 3578 | uint32_t uncompressed_hdr_size; |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3579 | |
Yaowu Xu | dd6ef6c | 2018-03-02 16:43:52 -0800 | [diff] [blame] | 3580 | write_uncompressed_header_obu(cpi, saved_wb, &wb); |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3581 | |
| 3582 | if (cm->show_existing_frame) { |
| 3583 | total_size = aom_wb_bytes_written(&wb); |
| 3584 | return total_size; |
| 3585 | } |
| 3586 | |
Cyril Concolato | 2dab275 | 2018-02-26 14:25:47 -0800 | [diff] [blame] | 3587 | #if CONFIG_TRAILING_BITS |
| 3588 | add_trailing_bits(&wb); |
| 3589 | #endif |
| 3590 | |
Yunqing Wang | e7142e1 | 2018-01-17 11:20:12 -0800 | [diff] [blame] | 3591 | uncompressed_hdr_size = aom_wb_bytes_written(&wb); |
| 3592 | total_size = uncompressed_hdr_size; |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3593 | return total_size; |
| 3594 | } |
| 3595 | |
| 3596 | static uint32_t write_tile_group_header(uint8_t *const dst, int startTile, |
Vignesh Venkatasubramanian | 2a06b41 | 2018-03-01 15:18:06 -0800 | [diff] [blame] | 3597 | int endTile, int tiles_log2, |
| 3598 | int tile_start_and_end_present_flag) { |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3599 | struct aom_write_bit_buffer wb = { dst, 0 }; |
| 3600 | uint32_t size = 0; |
| 3601 | |
Vignesh Venkatasubramanian | 2a06b41 | 2018-03-01 15:18:06 -0800 | [diff] [blame] | 3602 | if (!tiles_log2) return size; |
| 3603 | |
| 3604 | aom_wb_write_bit(&wb, tile_start_and_end_present_flag); |
| 3605 | |
| 3606 | if (tile_start_and_end_present_flag) { |
| 3607 | aom_wb_write_literal(&wb, startTile, tiles_log2); |
| 3608 | aom_wb_write_literal(&wb, endTile, tiles_log2); |
| 3609 | } |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3610 | |
| 3611 | size = aom_wb_bytes_written(&wb); |
| 3612 | return size; |
| 3613 | } |
| 3614 | |
Tom Finegan | 07afef6 | 2018-03-07 12:07:53 -0800 | [diff] [blame] | 3615 | typedef struct { |
| 3616 | uint8_t *frame_header; |
Tom Finegan | f927381 | 2018-03-14 09:49:45 -0700 | [diff] [blame] | 3617 | size_t obu_header_byte_offset; |
Tom Finegan | 07afef6 | 2018-03-07 12:07:53 -0800 | [diff] [blame] | 3618 | size_t total_length; |
| 3619 | } FrameHeaderInfo; |
| 3620 | |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3621 | static uint32_t write_tiles_in_tg_obus(AV1_COMP *const cpi, uint8_t *const dst, |
| 3622 | unsigned int *max_tile_size, |
| 3623 | unsigned int *max_tile_col_size, |
Jingning Han | da11e69 | 2017-12-19 08:45:08 -0800 | [diff] [blame] | 3624 | struct aom_write_bit_buffer *saved_wb, |
Tom Finegan | 07afef6 | 2018-03-07 12:07:53 -0800 | [diff] [blame] | 3625 | uint8_t obu_extension_header, |
| 3626 | const FrameHeaderInfo *fh_info) { |
Thomas Davies | 4822e14 | 2017-10-10 11:30:36 +0100 | [diff] [blame] | 3627 | AV1_COMMON *const cm = &cpi->common; |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3628 | aom_writer mode_bc; |
| 3629 | int tile_row, tile_col; |
| 3630 | TOKENEXTRA *(*const tok_buffers)[MAX_TILE_COLS] = cpi->tile_tok; |
| 3631 | TileBufferEnc(*const tile_buffers)[MAX_TILE_COLS] = cpi->tile_buffers; |
| 3632 | uint32_t total_size = 0; |
| 3633 | const int tile_cols = cm->tile_cols; |
| 3634 | const int tile_rows = cm->tile_rows; |
| 3635 | unsigned int tile_size = 0; |
| 3636 | const int n_log2_tiles = cm->log2_tile_rows + cm->log2_tile_cols; |
| 3637 | // Fixed size tile groups for the moment |
| 3638 | const int num_tg_hdrs = cm->num_tg; |
| 3639 | const int tg_size = |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3640 | (cm->large_scale_tile) |
| 3641 | ? 1 |
Yaowu Xu | dd6ef6c | 2018-03-02 16:43:52 -0800 | [diff] [blame] | 3642 | : (tile_rows * tile_cols + num_tg_hdrs - 1) / num_tg_hdrs; |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3643 | int tile_count = 0; |
| 3644 | int curr_tg_data_size = 0; |
| 3645 | uint8_t *data = dst; |
| 3646 | int new_tg = 1; |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3647 | const int have_tiles = tile_cols * tile_rows > 1; |
Tom Finegan | 07afef6 | 2018-03-07 12:07:53 -0800 | [diff] [blame] | 3648 | int first_tg = 1; |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3649 | |
Thomas Davies | 4822e14 | 2017-10-10 11:30:36 +0100 | [diff] [blame] | 3650 | cm->largest_tile_id = 0; |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3651 | *max_tile_size = 0; |
| 3652 | *max_tile_col_size = 0; |
| 3653 | |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3654 | if (cm->large_scale_tile) { |
Vignesh Venkatasubramanian | b2ce34e | 2018-03-05 16:57:40 -0800 | [diff] [blame] | 3655 | #if CONFIG_OBU_FRAME |
| 3656 | // For large_scale_tile case, we always have only one tile group, so it can |
| 3657 | // be written as an OBU_FRAME. |
| 3658 | const OBU_TYPE obu_type = OBU_FRAME; |
| 3659 | #else |
| 3660 | const OBU_TYPE obu_type = OBU_TILE_GROUP; |
| 3661 | #endif // CONFIG_OBU_FRAME |
Tom Finegan | 9d9ec1f | 2018-03-14 17:55:18 -0700 | [diff] [blame] | 3662 | const uint32_t tg_hdr_size = write_obu_header(obu_type, 0, data); |
Jingning Han | da11e69 | 2017-12-19 08:45:08 -0800 | [diff] [blame] | 3663 | data += tg_hdr_size; |
| 3664 | |
Vignesh Venkatasubramanian | b2ce34e | 2018-03-05 16:57:40 -0800 | [diff] [blame] | 3665 | #if CONFIG_OBU_FRAME |
Vignesh Venkatasubramanian | 9d68118 | 2018-03-13 15:16:19 -0700 | [diff] [blame] | 3666 | const uint32_t frame_header_size = |
| 3667 | write_frame_header_obu(cpi, saved_wb, data); |
| 3668 | #else |
| 3669 | const uint32_t frame_header_size = 0; |
Vignesh Venkatasubramanian | b2ce34e | 2018-03-05 16:57:40 -0800 | [diff] [blame] | 3670 | #endif // CONFIG_OBU_FRAME |
Vignesh Venkatasubramanian | 9d68118 | 2018-03-13 15:16:19 -0700 | [diff] [blame] | 3671 | data += frame_header_size; |
| 3672 | total_size += frame_header_size; |
Vignesh Venkatasubramanian | b2ce34e | 2018-03-05 16:57:40 -0800 | [diff] [blame] | 3673 | |
Yunqing Wang | f279c6b | 2018-02-23 11:15:46 -0800 | [diff] [blame] | 3674 | int tile_size_bytes = 0; |
| 3675 | int tile_col_size_bytes = 0; |
Jingning Han | da11e69 | 2017-12-19 08:45:08 -0800 | [diff] [blame] | 3676 | |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3677 | for (tile_col = 0; tile_col < tile_cols; tile_col++) { |
| 3678 | TileInfo tile_info; |
| 3679 | const int is_last_col = (tile_col == tile_cols - 1); |
| 3680 | const uint32_t col_offset = total_size; |
| 3681 | |
| 3682 | av1_tile_set_col(&tile_info, cm, tile_col); |
| 3683 | |
| 3684 | // The last column does not have a column header |
| 3685 | if (!is_last_col) total_size += 4; |
| 3686 | |
| 3687 | for (tile_row = 0; tile_row < tile_rows; tile_row++) { |
| 3688 | TileBufferEnc *const buf = &tile_buffers[tile_row][tile_col]; |
| 3689 | const TOKENEXTRA *tok = tok_buffers[tile_row][tile_col]; |
| 3690 | const TOKENEXTRA *tok_end = tok + cpi->tok_count[tile_row][tile_col]; |
| 3691 | const int data_offset = have_tiles ? 4 : 0; |
| 3692 | const int tile_idx = tile_row * tile_cols + tile_col; |
| 3693 | TileDataEnc *this_tile = &cpi->tile_data[tile_idx]; |
| 3694 | av1_tile_set_row(&tile_info, cm, tile_row); |
| 3695 | |
Jingning Han | da11e69 | 2017-12-19 08:45:08 -0800 | [diff] [blame] | 3696 | buf->data = dst + total_size + tg_hdr_size; |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3697 | |
| 3698 | // Is CONFIG_EXT_TILE = 1, every tile in the row has a header, |
| 3699 | // even for the last one, unless no tiling is used at all. |
| 3700 | total_size += data_offset; |
| 3701 | // Initialise tile context from the frame context |
| 3702 | this_tile->tctx = *cm->fc; |
| 3703 | cpi->td.mb.e_mbd.tile_ctx = &this_tile->tctx; |
Yunqing Wang | 0e141b5 | 2017-11-02 15:08:58 -0700 | [diff] [blame] | 3704 | mode_bc.allow_update_cdf = !cm->large_scale_tile; |
Hui Su | 483a845 | 2018-02-26 12:28:48 -0800 | [diff] [blame] | 3705 | #if CONFIG_CDF_UPDATE_MODE |
| 3706 | mode_bc.allow_update_cdf = |
| 3707 | mode_bc.allow_update_cdf && !cm->disable_cdf_update; |
| 3708 | #endif // CONFIG_CDF_UPDATE_MODE |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3709 | aom_start_encode(&mode_bc, buf->data + data_offset); |
| 3710 | write_modes(cpi, &tile_info, &mode_bc, &tok, tok_end); |
| 3711 | assert(tok == tok_end); |
| 3712 | aom_stop_encode(&mode_bc); |
| 3713 | tile_size = mode_bc.pos; |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3714 | buf->size = tile_size; |
| 3715 | |
| 3716 | // Record the maximum tile size we see, so we can compact headers later. |
Thomas Davies | 4822e14 | 2017-10-10 11:30:36 +0100 | [diff] [blame] | 3717 | if (tile_size > *max_tile_size) { |
| 3718 | *max_tile_size = tile_size; |
Thomas Davies | 4822e14 | 2017-10-10 11:30:36 +0100 | [diff] [blame] | 3719 | cm->largest_tile_id = tile_cols * tile_row + tile_col; |
Thomas Davies | 4822e14 | 2017-10-10 11:30:36 +0100 | [diff] [blame] | 3720 | } |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3721 | |
| 3722 | if (have_tiles) { |
| 3723 | // tile header: size of this tile, or copy offset |
| 3724 | uint32_t tile_header = tile_size; |
| 3725 | const int tile_copy_mode = |
| 3726 | ((AOMMAX(cm->tile_width, cm->tile_height) << MI_SIZE_LOG2) <= 256) |
| 3727 | ? 1 |
| 3728 | : 0; |
| 3729 | |
| 3730 | // If tile_copy_mode = 1, check if this tile is a copy tile. |
| 3731 | // Very low chances to have copy tiles on the key frames, so don't |
| 3732 | // search on key frames to reduce unnecessary search. |
| 3733 | if (cm->frame_type != KEY_FRAME && tile_copy_mode) { |
James Zern | 1a79a7e | 2018-03-08 18:17:18 -0800 | [diff] [blame] | 3734 | const int identical_tile_offset = |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3735 | find_identical_tile(tile_row, tile_col, tile_buffers); |
| 3736 | |
James Zern | 1a79a7e | 2018-03-08 18:17:18 -0800 | [diff] [blame] | 3737 | if (identical_tile_offset > 0) { |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3738 | tile_size = 0; |
James Zern | 1a79a7e | 2018-03-08 18:17:18 -0800 | [diff] [blame] | 3739 | tile_header = identical_tile_offset | 0x80; |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3740 | tile_header <<= 24; |
| 3741 | } |
| 3742 | } |
| 3743 | |
| 3744 | mem_put_le32(buf->data, tile_header); |
| 3745 | } |
| 3746 | |
| 3747 | total_size += tile_size; |
| 3748 | } |
| 3749 | |
| 3750 | if (!is_last_col) { |
| 3751 | uint32_t col_size = total_size - col_offset - 4; |
Jingning Han | da11e69 | 2017-12-19 08:45:08 -0800 | [diff] [blame] | 3752 | mem_put_le32(dst + col_offset + tg_hdr_size, col_size); |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3753 | |
Yunqing Wang | f279c6b | 2018-02-23 11:15:46 -0800 | [diff] [blame] | 3754 | // Record the maximum tile column size we see. |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3755 | *max_tile_col_size = AOMMAX(*max_tile_col_size, col_size); |
| 3756 | } |
| 3757 | } |
Jingning Han | da11e69 | 2017-12-19 08:45:08 -0800 | [diff] [blame] | 3758 | |
| 3759 | if (have_tiles) { |
Vignesh Venkatasubramanian | 9d68118 | 2018-03-13 15:16:19 -0700 | [diff] [blame] | 3760 | total_size = remux_tiles(cm, data, total_size - frame_header_size, |
| 3761 | *max_tile_size, *max_tile_col_size, |
| 3762 | &tile_size_bytes, &tile_col_size_bytes); |
| 3763 | total_size += frame_header_size; |
Jingning Han | da11e69 | 2017-12-19 08:45:08 -0800 | [diff] [blame] | 3764 | } |
| 3765 | |
Yunqing Wang | f279c6b | 2018-02-23 11:15:46 -0800 | [diff] [blame] | 3766 | // In EXT_TILE case, only use 1 tile group. Follow the obu syntax, write |
| 3767 | // current tile group size before tile data(include tile column header). |
| 3768 | // Tile group size doesn't include the bytes storing tg size. |
Tom Finegan | 9d9ec1f | 2018-03-14 17:55:18 -0700 | [diff] [blame] | 3769 | total_size += tg_hdr_size; |
Vignesh Venkatasubramanian | ea0257d | 2018-02-28 14:43:34 -0800 | [diff] [blame] | 3770 | const uint32_t obu_payload_size = total_size - tg_hdr_size; |
| 3771 | const size_t length_field_size = |
| 3772 | obu_memmove(tg_hdr_size, obu_payload_size, dst); |
| 3773 | if (write_uleb_obu_size(tg_hdr_size, obu_payload_size, dst) != |
| 3774 | AOM_CODEC_OK) { |
| 3775 | assert(0); |
| 3776 | } |
Yaowu Xu | 68dc87e | 2018-02-28 14:41:50 -0800 | [diff] [blame] | 3777 | total_size += (uint32_t)length_field_size; |
Vignesh Venkatasubramanian | 9d68118 | 2018-03-13 15:16:19 -0700 | [diff] [blame] | 3778 | #if CONFIG_OBU_FRAME |
| 3779 | saved_wb->bit_buffer += length_field_size; |
| 3780 | #endif // CONFIG_OBU_FRAME |
Yunqing Wang | f279c6b | 2018-02-23 11:15:46 -0800 | [diff] [blame] | 3781 | |
Jingning Han | da11e69 | 2017-12-19 08:45:08 -0800 | [diff] [blame] | 3782 | // Now fill in the gaps in the uncompressed header. |
| 3783 | if (have_tiles) { |
| 3784 | assert(tile_col_size_bytes >= 1 && tile_col_size_bytes <= 4); |
James Zern | 56f7cff | 2018-02-28 20:30:26 -0800 | [diff] [blame] | 3785 | aom_wb_overwrite_literal(saved_wb, tile_col_size_bytes - 1, 2); |
Jingning Han | da11e69 | 2017-12-19 08:45:08 -0800 | [diff] [blame] | 3786 | |
| 3787 | assert(tile_size_bytes >= 1 && tile_size_bytes <= 4); |
James Zern | 56f7cff | 2018-02-28 20:30:26 -0800 | [diff] [blame] | 3788 | aom_wb_overwrite_literal(saved_wb, tile_size_bytes - 1, 2); |
Jingning Han | da11e69 | 2017-12-19 08:45:08 -0800 | [diff] [blame] | 3789 | } |
James Zern | a60ff58 | 2018-02-24 14:02:12 -0800 | [diff] [blame] | 3790 | return (uint32_t)total_size; |
| 3791 | } |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3792 | |
Vignesh Venkatasubramanian | 6198ebc | 2018-03-02 12:47:33 -0800 | [diff] [blame] | 3793 | uint32_t obu_header_size = 0; |
James Zern | a60ff58 | 2018-02-24 14:02:12 -0800 | [diff] [blame] | 3794 | for (tile_row = 0; tile_row < tile_rows; tile_row++) { |
| 3795 | TileInfo tile_info; |
| 3796 | const int is_last_row = (tile_row == tile_rows - 1); |
| 3797 | av1_tile_set_row(&tile_info, cm, tile_row); |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3798 | |
James Zern | a60ff58 | 2018-02-24 14:02:12 -0800 | [diff] [blame] | 3799 | for (tile_col = 0; tile_col < tile_cols; tile_col++) { |
| 3800 | const int tile_idx = tile_row * tile_cols + tile_col; |
| 3801 | TileBufferEnc *const buf = &tile_buffers[tile_row][tile_col]; |
| 3802 | TileDataEnc *this_tile = &cpi->tile_data[tile_idx]; |
| 3803 | const TOKENEXTRA *tok = tok_buffers[tile_row][tile_col]; |
| 3804 | const TOKENEXTRA *tok_end = tok + cpi->tok_count[tile_row][tile_col]; |
| 3805 | const int is_last_col = (tile_col == tile_cols - 1); |
| 3806 | const int is_last_tile = is_last_col && is_last_row; |
| 3807 | int is_last_tile_in_tg = 0; |
Cyril Concolato | 2dab275 | 2018-02-26 14:25:47 -0800 | [diff] [blame] | 3808 | #if CONFIG_TRAILING_BITS |
| 3809 | int nb_bits = 0; |
| 3810 | #endif |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3811 | |
James Zern | a60ff58 | 2018-02-24 14:02:12 -0800 | [diff] [blame] | 3812 | if (new_tg) { |
| 3813 | data = dst + total_size; |
Tom Finegan | 07afef6 | 2018-03-07 12:07:53 -0800 | [diff] [blame] | 3814 | |
James Zern | a60ff58 | 2018-02-24 14:02:12 -0800 | [diff] [blame] | 3815 | // A new tile group begins at this tile. Write the obu header and |
| 3816 | // tile group header |
Vignesh Venkatasubramanian | b2ce34e | 2018-03-05 16:57:40 -0800 | [diff] [blame] | 3817 | #if CONFIG_OBU_FRAME |
| 3818 | const OBU_TYPE obu_type = |
| 3819 | (num_tg_hdrs == 1) ? OBU_FRAME : OBU_TILE_GROUP; |
| 3820 | #else |
| 3821 | const OBU_TYPE obu_type = OBU_TILE_GROUP; |
| 3822 | #endif |
Tom Finegan | 9d9ec1f | 2018-03-14 17:55:18 -0700 | [diff] [blame] | 3823 | curr_tg_data_size = |
| 3824 | write_obu_header(obu_type, obu_extension_header, data); |
Vignesh Venkatasubramanian | ea0257d | 2018-02-28 14:43:34 -0800 | [diff] [blame] | 3825 | obu_header_size = curr_tg_data_size; |
Tom Finegan | 9d9ec1f | 2018-03-14 17:55:18 -0700 | [diff] [blame] | 3826 | |
Vignesh Venkatasubramanian | b2ce34e | 2018-03-05 16:57:40 -0800 | [diff] [blame] | 3827 | #if CONFIG_OBU_FRAME |
| 3828 | if (num_tg_hdrs == 1) { |
Tom Finegan | 9d9ec1f | 2018-03-14 17:55:18 -0700 | [diff] [blame] | 3829 | curr_tg_data_size += |
| 3830 | write_frame_header_obu(cpi, saved_wb, data + curr_tg_data_size); |
Vignesh Venkatasubramanian | b2ce34e | 2018-03-05 16:57:40 -0800 | [diff] [blame] | 3831 | } |
| 3832 | #endif |
Vignesh Venkatasubramanian | 2a06b41 | 2018-03-01 15:18:06 -0800 | [diff] [blame] | 3833 | curr_tg_data_size += write_tile_group_header( |
Tom Finegan | 9d9ec1f | 2018-03-14 17:55:18 -0700 | [diff] [blame] | 3834 | data + curr_tg_data_size, tile_idx, |
Vignesh Venkatasubramanian | 2a06b41 | 2018-03-01 15:18:06 -0800 | [diff] [blame] | 3835 | AOMMIN(tile_idx + tg_size - 1, tile_cols * tile_rows - 1), |
| 3836 | n_log2_tiles, cm->num_tg > 1); |
Tom Finegan | 9d9ec1f | 2018-03-14 17:55:18 -0700 | [diff] [blame] | 3837 | total_size += curr_tg_data_size; |
James Zern | a60ff58 | 2018-02-24 14:02:12 -0800 | [diff] [blame] | 3838 | new_tg = 0; |
| 3839 | tile_count = 0; |
| 3840 | } |
| 3841 | tile_count++; |
| 3842 | av1_tile_set_col(&tile_info, cm, tile_col); |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3843 | |
James Zern | a60ff58 | 2018-02-24 14:02:12 -0800 | [diff] [blame] | 3844 | if (tile_count == tg_size || tile_idx == (tile_cols * tile_rows - 1)) { |
| 3845 | is_last_tile_in_tg = 1; |
| 3846 | new_tg = 1; |
| 3847 | } else { |
| 3848 | is_last_tile_in_tg = 0; |
| 3849 | } |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3850 | |
James Zern | a60ff58 | 2018-02-24 14:02:12 -0800 | [diff] [blame] | 3851 | buf->data = dst + total_size; |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3852 | |
James Zern | a60ff58 | 2018-02-24 14:02:12 -0800 | [diff] [blame] | 3853 | // The last tile of the tile group does not have a header. |
| 3854 | if (!is_last_tile_in_tg) total_size += 4; |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3855 | |
James Zern | a60ff58 | 2018-02-24 14:02:12 -0800 | [diff] [blame] | 3856 | // Initialise tile context from the frame context |
| 3857 | this_tile->tctx = *cm->fc; |
| 3858 | cpi->td.mb.e_mbd.tile_ctx = &this_tile->tctx; |
| 3859 | mode_bc.allow_update_cdf = 1; |
Hui Su | 483a845 | 2018-02-26 12:28:48 -0800 | [diff] [blame] | 3860 | #if CONFIG_CDF_UPDATE_MODE |
| 3861 | mode_bc.allow_update_cdf = |
| 3862 | mode_bc.allow_update_cdf && !cm->disable_cdf_update; |
| 3863 | #endif // CONFIG_CDF_UPDATE_MODE |
James Zern | a60ff58 | 2018-02-24 14:02:12 -0800 | [diff] [blame] | 3864 | const int num_planes = av1_num_planes(cm); |
| 3865 | av1_reset_loop_restoration(&cpi->td.mb.e_mbd, num_planes); |
Soo-Chul Han | 13f0d9c | 2017-10-22 21:55:52 -0400 | [diff] [blame] | 3866 | |
James Zern | a60ff58 | 2018-02-24 14:02:12 -0800 | [diff] [blame] | 3867 | aom_start_encode(&mode_bc, dst + total_size); |
| 3868 | write_modes(cpi, &tile_info, &mode_bc, &tok, tok_end); |
Cyril Concolato | 2dab275 | 2018-02-26 14:25:47 -0800 | [diff] [blame] | 3869 | #if CONFIG_TRAILING_BITS |
| 3870 | nb_bits = aom_stop_encode(&mode_bc); |
| 3871 | #else |
James Zern | a60ff58 | 2018-02-24 14:02:12 -0800 | [diff] [blame] | 3872 | aom_stop_encode(&mode_bc); |
Cyril Concolato | 2dab275 | 2018-02-26 14:25:47 -0800 | [diff] [blame] | 3873 | #endif |
James Zern | a60ff58 | 2018-02-24 14:02:12 -0800 | [diff] [blame] | 3874 | tile_size = mode_bc.pos; |
| 3875 | assert(tile_size > 0); |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3876 | |
Cyril Concolato | 2dab275 | 2018-02-26 14:25:47 -0800 | [diff] [blame] | 3877 | #if CONFIG_TRAILING_BITS |
| 3878 | // similar to add_trailing_bits, but specific to end of last tile |
| 3879 | if (is_last_tile) { |
| 3880 | if (nb_bits % 8 == 0) { |
| 3881 | // the arithmetic encoder ended on a byte boundary |
| 3882 | // adding a 0b10000000 byte |
| 3883 | *(dst + total_size + tile_size) = 0x80; |
| 3884 | tile_size += 1; |
| 3885 | } else { |
| 3886 | // arithmetic encoder left several 0 bits |
| 3887 | // changing the first 0 bit to 1 |
| 3888 | int bit_offset = 7 - nb_bits % 8; |
| 3889 | *(dst + total_size + tile_size) |= 1 << bit_offset; |
| 3890 | } |
| 3891 | } |
| 3892 | #endif |
| 3893 | |
James Zern | a60ff58 | 2018-02-24 14:02:12 -0800 | [diff] [blame] | 3894 | curr_tg_data_size += (tile_size + (is_last_tile_in_tg ? 0 : 4)); |
| 3895 | buf->size = tile_size; |
| 3896 | if (tile_size > *max_tile_size) { |
| 3897 | cm->largest_tile_id = tile_cols * tile_row + tile_col; |
| 3898 | } |
| 3899 | if (!is_last_tile) { |
| 3900 | *max_tile_size = AOMMAX(*max_tile_size, tile_size); |
| 3901 | } |
Thomas Davies | 4822e14 | 2017-10-10 11:30:36 +0100 | [diff] [blame] | 3902 | |
James Zern | a60ff58 | 2018-02-24 14:02:12 -0800 | [diff] [blame] | 3903 | if (!is_last_tile_in_tg) { |
| 3904 | // size of this tile |
| 3905 | mem_put_le32(buf->data, tile_size); |
| 3906 | } else { |
Tom Finegan | 9d9ec1f | 2018-03-14 17:55:18 -0700 | [diff] [blame] | 3907 | // write current tile group size |
James Zern | 3c24b8f | 2018-03-12 17:42:30 -0700 | [diff] [blame] | 3908 | const uint32_t obu_payload_size = curr_tg_data_size - obu_header_size; |
James Zern | a60ff58 | 2018-02-24 14:02:12 -0800 | [diff] [blame] | 3909 | const size_t length_field_size = |
James Zern | 3c24b8f | 2018-03-12 17:42:30 -0700 | [diff] [blame] | 3910 | obu_memmove(obu_header_size, obu_payload_size, data); |
Vignesh Venkatasubramanian | ea0257d | 2018-02-28 14:43:34 -0800 | [diff] [blame] | 3911 | if (write_uleb_obu_size(obu_header_size, obu_payload_size, data) != |
| 3912 | AOM_CODEC_OK) { |
James Zern | a60ff58 | 2018-02-24 14:02:12 -0800 | [diff] [blame] | 3913 | assert(0); |
Vignesh Venkatasubramanian | ea0257d | 2018-02-28 14:43:34 -0800 | [diff] [blame] | 3914 | } |
Yaowu Xu | 68dc87e | 2018-02-28 14:41:50 -0800 | [diff] [blame] | 3915 | curr_tg_data_size += (int)length_field_size; |
| 3916 | total_size += (uint32_t)length_field_size; |
Tom Finegan | 07afef6 | 2018-03-07 12:07:53 -0800 | [diff] [blame] | 3917 | |
| 3918 | if (!first_tg && cm->error_resilient_mode) { |
| 3919 | // Make room for a duplicate Frame Header OBU. |
| 3920 | memmove(data + fh_info->total_length, data, curr_tg_data_size); |
| 3921 | |
| 3922 | // Insert a copy of the Frame Header OBU. |
| 3923 | memcpy(data, fh_info->frame_header, fh_info->total_length); |
Tom Finegan | f927381 | 2018-03-14 09:49:45 -0700 | [diff] [blame] | 3924 | |
| 3925 | #if CONFIG_OBU_REDUNDANT_FRAME_HEADER |
| 3926 | // Rewrite the OBU header to change the OBU type to Redundant Frame |
| 3927 | // Header. |
| 3928 | write_obu_header(OBU_REDUNDANT_FRAME_HEADER, obu_extension_header, |
| 3929 | &data[fh_info->obu_header_byte_offset]); |
| 3930 | #endif // CONFIG_OBU_REDUNDANT_FRAME_HEADER |
| 3931 | |
Tom Finegan | 07afef6 | 2018-03-07 12:07:53 -0800 | [diff] [blame] | 3932 | data += fh_info->total_length; |
| 3933 | |
| 3934 | curr_tg_data_size += fh_info->total_length; |
| 3935 | total_size += fh_info->total_length; |
| 3936 | } |
| 3937 | first_tg = 0; |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3938 | } |
James Zern | a60ff58 | 2018-02-24 14:02:12 -0800 | [diff] [blame] | 3939 | |
| 3940 | total_size += tile_size; |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3941 | } |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3942 | } |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3943 | return (uint32_t)total_size; |
| 3944 | } |
| 3945 | |
Tom Finegan | e4099e3 | 2018-01-23 12:01:51 -0800 | [diff] [blame] | 3946 | int av1_pack_bitstream(AV1_COMP *const cpi, uint8_t *dst, size_t *size) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 3947 | uint8_t *data = dst; |
Yunqing Wang | eeb08a9 | 2017-07-07 21:25:18 -0700 | [diff] [blame] | 3948 | uint32_t data_size; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 3949 | unsigned int max_tile_size; |
| 3950 | unsigned int max_tile_col_size; |
Soo-Chul Han | f858986 | 2018-01-24 03:13:14 +0000 | [diff] [blame] | 3951 | AV1_COMMON *const cm = &cpi->common; |
Vignesh Venkatasubramanian | ea0257d | 2018-02-28 14:43:34 -0800 | [diff] [blame] | 3952 | uint32_t obu_header_size = 0; |
| 3953 | uint32_t obu_payload_size = 0; |
Tom Finegan | f927381 | 2018-03-14 09:49:45 -0700 | [diff] [blame] | 3954 | FrameHeaderInfo fh_info = { NULL, 0, 0 }; |
Soo-Chul Han | f858986 | 2018-01-24 03:13:14 +0000 | [diff] [blame] | 3955 | #if CONFIG_SCALABILITY |
| 3956 | const uint8_t enhancement_layers_cnt = cm->enhancement_layers_cnt; |
| 3957 | const uint8_t obu_extension_header = |
| 3958 | cm->temporal_layer_id << 5 | cm->enhancement_layer_id << 3 | 0; |
| 3959 | #else |
| 3960 | uint8_t obu_extension_header = 0; |
| 3961 | #endif // CONFIG_SCALABILITY |
Soo-Chul Han | f858986 | 2018-01-24 03:13:14 +0000 | [diff] [blame] | 3962 | |
Angie Chiang | b11aedf | 2017-03-10 17:31:46 -0800 | [diff] [blame] | 3963 | #if CONFIG_BITSTREAM_DEBUG |
| 3964 | bitstream_queue_reset_write(); |
| 3965 | #endif |
| 3966 | |
Soo-Chul Han | 38427e8 | 2017-09-27 15:06:13 -0400 | [diff] [blame] | 3967 | // The TD is now written outside the frame encode loop |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3968 | |
| 3969 | // write sequence header obu if KEY_FRAME, preceded by 4-byte size |
| 3970 | if (cm->frame_type == KEY_FRAME) { |
Tom Finegan | 9d9ec1f | 2018-03-14 17:55:18 -0700 | [diff] [blame] | 3971 | obu_header_size = write_obu_header(OBU_SEQUENCE_HEADER, 0, data); |
Soo-Chul Han | f858986 | 2018-01-24 03:13:14 +0000 | [diff] [blame] | 3972 | |
Soo-Chul Han | f858986 | 2018-01-24 03:13:14 +0000 | [diff] [blame] | 3973 | #if CONFIG_SCALABILITY |
Tom Finegan | 9d9ec1f | 2018-03-14 17:55:18 -0700 | [diff] [blame] | 3974 | obu_payload_size = write_sequence_header_obu(cpi, data + obu_header_size, |
| 3975 | enhancement_layers_cnt); |
Soo-Chul Han | f858986 | 2018-01-24 03:13:14 +0000 | [diff] [blame] | 3976 | #else |
Tom Finegan | 9d9ec1f | 2018-03-14 17:55:18 -0700 | [diff] [blame] | 3977 | obu_payload_size = write_sequence_header_obu(cpi, data + obu_header_size); |
Soo-Chul Han | f858986 | 2018-01-24 03:13:14 +0000 | [diff] [blame] | 3978 | #endif // CONFIG_SCALABILITY |
Tom Finegan | 41150ad | 2018-01-23 11:42:55 -0800 | [diff] [blame] | 3979 | |
Vignesh Venkatasubramanian | ea0257d | 2018-02-28 14:43:34 -0800 | [diff] [blame] | 3980 | const size_t length_field_size = |
| 3981 | obu_memmove(obu_header_size, obu_payload_size, data); |
| 3982 | if (write_uleb_obu_size(obu_header_size, obu_payload_size, data) != |
Tom Finegan | 9d9ec1f | 2018-03-14 17:55:18 -0700 | [diff] [blame] | 3983 | AOM_CODEC_OK) { |
Tom Finegan | 41150ad | 2018-01-23 11:42:55 -0800 | [diff] [blame] | 3984 | return AOM_CODEC_ERROR; |
Tom Finegan | 9d9ec1f | 2018-03-14 17:55:18 -0700 | [diff] [blame] | 3985 | } |
Tom Finegan | 41150ad | 2018-01-23 11:42:55 -0800 | [diff] [blame] | 3986 | |
Vignesh Venkatasubramanian | ea0257d | 2018-02-28 14:43:34 -0800 | [diff] [blame] | 3987 | data += obu_header_size + obu_payload_size + length_field_size; |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 3988 | } |
| 3989 | |
Vignesh Venkatasubramanian | b2ce34e | 2018-03-05 16:57:40 -0800 | [diff] [blame] | 3990 | #if CONFIG_OBU_FRAME |
| 3991 | const int write_frame_header = (cm->num_tg > 1 || cm->show_existing_frame); |
| 3992 | #else |
| 3993 | const int write_frame_header = 1; |
| 3994 | #endif // CONFIG_OBU_FRAME |
Jingning Han | da11e69 | 2017-12-19 08:45:08 -0800 | [diff] [blame] | 3995 | |
Vignesh Venkatasubramanian | b2ce34e | 2018-03-05 16:57:40 -0800 | [diff] [blame] | 3996 | struct aom_write_bit_buffer saved_wb; |
| 3997 | if (write_frame_header) { |
| 3998 | // Write Frame Header OBU. |
| 3999 | fh_info.frame_header = data; |
Tom Finegan | 9d9ec1f | 2018-03-14 17:55:18 -0700 | [diff] [blame] | 4000 | obu_header_size = |
| 4001 | write_obu_header(OBU_FRAME_HEADER, obu_extension_header, data); |
| 4002 | obu_payload_size = |
| 4003 | write_frame_header_obu(cpi, &saved_wb, data + obu_header_size); |
Tom Finegan | 41150ad | 2018-01-23 11:42:55 -0800 | [diff] [blame] | 4004 | |
Vignesh Venkatasubramanian | b2ce34e | 2018-03-05 16:57:40 -0800 | [diff] [blame] | 4005 | const size_t length_field_size = |
| 4006 | obu_memmove(obu_header_size, obu_payload_size, data); |
| 4007 | if (write_uleb_obu_size(obu_header_size, obu_payload_size, data) != |
| 4008 | AOM_CODEC_OK) { |
| 4009 | return AOM_CODEC_ERROR; |
| 4010 | } |
Tom Finegan | 41150ad | 2018-01-23 11:42:55 -0800 | [diff] [blame] | 4011 | |
Tom Finegan | f927381 | 2018-03-14 09:49:45 -0700 | [diff] [blame] | 4012 | #if CONFIG_OBU_REDUNDANT_FRAME_HEADER |
| 4013 | #if CONFIG_OBU_SIZE_AFTER_HEADER |
| 4014 | fh_info.obu_header_byte_offset = 0; |
| 4015 | #else |
| 4016 | fh_info.obu_header_byte_offset = length_field_size; |
| 4017 | #endif // CONFIG_OBU_SIZE_AFTER_HEADER |
| 4018 | #endif // CONFIG_OBU_REDUNDANT_FRAME_HEADER |
| 4019 | |
Vignesh Venkatasubramanian | b2ce34e | 2018-03-05 16:57:40 -0800 | [diff] [blame] | 4020 | fh_info.total_length = |
| 4021 | obu_header_size + obu_payload_size + length_field_size; |
| 4022 | data += fh_info.total_length; |
Tom Finegan | 07afef6 | 2018-03-07 12:07:53 -0800 | [diff] [blame] | 4023 | |
Vignesh Venkatasubramanian | b2ce34e | 2018-03-05 16:57:40 -0800 | [diff] [blame] | 4024 | // Since length_field_size is determined adaptively after frame header |
| 4025 | // encoding, saved_wb must be adjusted accordingly. |
| 4026 | saved_wb.bit_buffer += length_field_size; |
| 4027 | } |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 4028 | |
Yunqing Wang | 8cb64b8 | 2018-02-27 15:05:12 -0800 | [diff] [blame] | 4029 | #define EXT_TILE_DEBUG 0 |
| 4030 | #if EXT_TILE_DEBUG |
| 4031 | { |
| 4032 | char fn[20] = "./fh"; |
| 4033 | fn[4] = cm->current_video_frame / 100 + '0'; |
| 4034 | fn[5] = (cm->current_video_frame % 100) / 10 + '0'; |
| 4035 | fn[6] = (cm->current_video_frame % 10) + '0'; |
| 4036 | fn[7] = '\0'; |
| 4037 | av1_print_uncompressed_frame_header(data - obu_size, obu_size, fn); |
| 4038 | } |
| 4039 | #endif // EXT_TILE_DEBUG |
| 4040 | #undef EXT_TILE_DEBUG |
| 4041 | |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 4042 | if (cm->show_existing_frame) { |
| 4043 | data_size = 0; |
| 4044 | } else { |
| 4045 | // Each tile group obu will be preceded by 4-byte size of the tile group |
| 4046 | // obu |
Tom Finegan | f2d40f6 | 2018-02-01 11:52:49 -0800 | [diff] [blame] | 4047 | data_size = |
| 4048 | write_tiles_in_tg_obus(cpi, data, &max_tile_size, &max_tile_col_size, |
Tom Finegan | 07afef6 | 2018-03-07 12:07:53 -0800 | [diff] [blame] | 4049 | &saved_wb, obu_extension_header, &fh_info); |
Soo-Chul Han | 65c00ae | 2017-09-07 13:12:35 -0400 | [diff] [blame] | 4050 | } |
Yaowu Xu | d29ea97 | 2018-02-22 09:50:58 -0800 | [diff] [blame] | 4051 | data += data_size; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 4052 | *size = data - dst; |
Tom Finegan | e4099e3 | 2018-01-23 12:01:51 -0800 | [diff] [blame] | 4053 | return AOM_CODEC_OK; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 4054 | } |