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