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 #ifndef AV1_COMMON_ONYXC_INT_H_
13 #define AV1_COMMON_ONYXC_INT_H_
14
15 #include "./aom_config.h"
16 #include "./av1_rtcd.h"
17 #include "aom/internal/aom_codec_internal.h"
18 #include "aom_util/aom_thread.h"
19 #if CONFIG_ANS
20 #include "aom_dsp/ans.h"
21 #endif
22 #include "av1/common/alloccommon.h"
23 #include "av1/common/av1_loopfilter.h"
24 #include "av1/common/entropy.h"
25 #include "av1/common/entropymode.h"
26 #include "av1/common/entropymv.h"
27 #include "av1/common/frame_buffers.h"
28 #include "av1/common/mv.h"
29 #include "av1/common/quant_common.h"
30 #if CONFIG_LOOP_RESTORATION
31 #include "av1/common/restoration.h"
32 #endif // CONFIG_LOOP_RESTORATION
33 #include "av1/common/tile_common.h"
34 #include "av1/common/odintrin.h"
35 #if CONFIG_PVQ
36 #include "av1/common/pvq.h"
37 #endif
38 #if CONFIG_CFL
39 #include "av1/common/cfl.h"
40 #endif
41 #if CONFIG_HASH_ME
42 // TODO(youzhou@microsoft.com): Encoder only. Move it out of common
43 #include "av1/encoder/hash_motion.h"
44 #endif
45 #ifdef __cplusplus
46 extern "C" {
47 #endif
48
49 #define CDEF_MAX_STRENGTHS 16
50
51 #define REF_FRAMES_LOG2 3
52 #define REF_FRAMES (1 << REF_FRAMES_LOG2)
53
54 // 4 scratch frames for the new frames to support a maximum of 4 cores decoding
55 // in parallel, 3 for scaled references on the encoder.
56 // TODO(hkuang): Add ondemand frame buffers instead of hardcoding the number
57 // of framebuffers.
58 // TODO(jkoleszar): These 3 extra references could probably come from the
59 // normal reference pool.
60 #define FRAME_BUFFERS (REF_FRAMES + 7)
61
62 #if CONFIG_REFERENCE_BUFFER
63 /* Constant values while waiting for the sequence header */
64 #define FRAME_ID_NUMBERS_PRESENT_FLAG 1
65 #define FRAME_ID_LENGTH_MINUS7 8 // Allows frame id up to 2^15-1
66 #define DELTA_FRAME_ID_LENGTH_MINUS2 12 // Allows frame id deltas up to 2^14-1
67 #endif // CONFIG_REFERENCE_BUFFER
68
69 #if CONFIG_NO_FRAME_CONTEXT_SIGNALING
70 #define FRAME_CONTEXTS (FRAME_BUFFERS + 1)
71 // Extra frame context which is always kept at default values
72 #define FRAME_CONTEXT_DEFAULTS (FRAME_CONTEXTS - 1)
73 #else
74
75 #if CONFIG_EXT_REFS
76 #define FRAME_CONTEXTS_LOG2 3
77 #else
78 #define FRAME_CONTEXTS_LOG2 2
79 #endif
80
81 #define FRAME_CONTEXTS (1 << FRAME_CONTEXTS_LOG2)
82 #endif // CONFIG_NO_FRAME_CONTEXT_SIGNALING
83
84 #define NUM_PING_PONG_BUFFERS 2
85
86 typedef enum {
87 SINGLE_REFERENCE = 0,
88 COMPOUND_REFERENCE = 1,
89 REFERENCE_MODE_SELECT = 2,
90 REFERENCE_MODES = 3,
91 } REFERENCE_MODE;
92
93 #if !CONFIG_NO_FRAME_CONTEXT_SIGNALING
94 typedef enum {
95 RESET_FRAME_CONTEXT_NONE = 0,
96 RESET_FRAME_CONTEXT_CURRENT = 1,
97 RESET_FRAME_CONTEXT_ALL = 2,
98 } RESET_FRAME_CONTEXT_MODE;
99 #endif
100
101 typedef enum {
102 /**
103 * Update frame context to values resulting from forward probability
104 * updates signaled in the frame header
105 */
106 REFRESH_FRAME_CONTEXT_FORWARD,
107 /**
108 * Update frame context to values resulting from backward probability
109 * updates based on entropy/counts in the decoded frame
110 */
111 REFRESH_FRAME_CONTEXT_BACKWARD,
112 } REFRESH_FRAME_CONTEXT_MODE;
113
114 #if CONFIG_MFMV
115 #define MFMV_STACK_SIZE INTER_REFS_PER_FRAME
116
117 typedef struct {
118 int_mv mfmv[INTER_REFS_PER_FRAME][MFMV_STACK_SIZE];
119 } TPL_MV_REF;
120 #endif
121
122 typedef struct {
123 int_mv mv[2];
124 int_mv pred_mv[2];
125 MV_REFERENCE_FRAME ref_frame[2];
126 } MV_REF;
127
128 typedef struct {
129 int ref_count;
130
131 #if CONFIG_FRAME_MARKER
132 int cur_frame_offset;
133 int lst_frame_offset;
134 int alt_frame_offset;
135 int gld_frame_offset;
136 #if CONFIG_EXT_REFS
137 int lst2_frame_offset;
138 int lst3_frame_offset;
139 int bwd_frame_offset;
140 int alt2_frame_offset;
141 #endif
142 #endif // CONFIG_FRAME_MARKER
143
144 #if CONFIG_MFMV
145 TPL_MV_REF *tpl_mvs;
146 #endif
147 MV_REF *mvs;
148 int mi_rows;
149 int mi_cols;
150 // Width and height give the size of the buffer (before any upscaling, unlike
151 // the sizes that can be derived from the buf structure)
152 int width;
153 int height;
154 #if CONFIG_GLOBAL_MOTION
155 WarpedMotionParams global_motion[TOTAL_REFS_PER_FRAME];
156 #endif // CONFIG_GLOBAL_MOTION
157 aom_codec_frame_buffer_t raw_frame_buffer;
158 YV12_BUFFER_CONFIG buf;
159 #if CONFIG_HASH_ME
160 hash_table hash_table;
161 #endif
162 #if CONFIG_TEMPMV_SIGNALING
163 uint8_t intra_only;
164 #endif
165 // The Following variables will only be used in frame parallel decode.
166
167 // frame_worker_owner indicates which FrameWorker owns this buffer. NULL means
168 // that no FrameWorker owns, or is decoding, this buffer.
169 AVxWorker *frame_worker_owner;
170
171 // row and col indicate which position frame has been decoded to in real
172 // pixel unit. They are reset to -1 when decoding begins and set to INT_MAX
173 // when the frame is fully decoded.
174 int row;
175 int col;
176 } RefCntBuffer;
177
178 typedef struct BufferPool {
179 // Protect BufferPool from being accessed by several FrameWorkers at
180 // the same time during frame parallel decode.
181 // TODO(hkuang): Try to use atomic variable instead of locking the whole pool.
182 #if CONFIG_MULTITHREAD
183 pthread_mutex_t pool_mutex;
184 #endif
185
186 // Private data associated with the frame buffer callbacks.
187 void *cb_priv;
188
189 aom_get_frame_buffer_cb_fn_t get_fb_cb;
190 aom_release_frame_buffer_cb_fn_t release_fb_cb;
191
192 RefCntBuffer frame_bufs[FRAME_BUFFERS];
193
194 // Frame buffers allocated internally by the codec.
195 InternalFrameBufferList int_frame_buffers;
196 } BufferPool;
197
198 #if CONFIG_LV_MAP
199 typedef struct {
200 int base_ctx_table[2 /*row*/][2 /*col*/][2 /*sig_map*/]
201 [BASE_CONTEXT_POSITION_NUM + 1];
202 } LV_MAP_CTX_TABLE;
203 typedef int BASE_CTX_TABLE[2 /*col*/][2 /*sig_map*/]
204 [BASE_CONTEXT_POSITION_NUM + 1];
205 #endif
206
207 #if CONFIG_REFERENCE_BUFFER
208 /* Initial version of sequence header structure */
209 typedef struct SequenceHeader {
210 int frame_id_numbers_present_flag;
211 int frame_id_length_minus7;
212 int delta_frame_id_length_minus2;
213 } SequenceHeader;
214 #endif // CONFIG_REFERENCE_BUFFER
215
216 typedef struct AV1Common {
217 struct aom_internal_error_info error;
218 aom_color_space_t color_space;
219 aom_transfer_function_t transfer_function;
220 aom_chroma_sample_position_t chroma_sample_position;
221 int color_range;
222 int width;
223 int height;
224 int render_width;
225 int render_height;
226 int last_width;
227 int last_height;
228
229 // TODO(jkoleszar): this implies chroma ss right now, but could vary per
230 // plane. Revisit as part of the future change to YV12_BUFFER_CONFIG to
231 // support additional planes.
232 int subsampling_x;
233 int subsampling_y;
234
235 #if CONFIG_HIGHBITDEPTH
236 // Marks if we need to use 16bit frame buffers (1: yes, 0: no).
237 int use_highbitdepth;
238 #endif
239 YV12_BUFFER_CONFIG *frame_to_show;
240 RefCntBuffer *prev_frame;
241
242 // TODO(hkuang): Combine this with cur_buf in macroblockd.
243 RefCntBuffer *cur_frame;
244
245 int ref_frame_map[REF_FRAMES]; /* maps fb_idx to reference slot */
246
247 // Prepare ref_frame_map for the next frame.
248 // Only used in frame parallel decode.
249 int next_ref_frame_map[REF_FRAMES];
250
251 // TODO(jkoleszar): could expand active_ref_idx to 4, with 0 as intra, and
252 // roll new_fb_idx into it.
253
254 // Each Inter frame can reference INTER_REFS_PER_FRAME buffers
255 RefBuffer frame_refs[INTER_REFS_PER_FRAME];
256
257 int new_fb_idx;
258
259 FRAME_TYPE last_frame_type; /* last frame's frame type for motion search.*/
260 FRAME_TYPE frame_type;
261
262 int show_frame;
263 int last_show_frame;
264 int show_existing_frame;
265 #if CONFIG_EXT_REFS
266 // Flag for a frame used as a reference - not written to the bitstream
267 int is_reference_frame;
268 #endif // CONFIG_EXT_REFS
269
270 // Flag signaling that the frame is encoded using only INTRA modes.
271 uint8_t intra_only;
272 uint8_t last_intra_only;
273
274 int allow_high_precision_mv;
275 #if CONFIG_AMVR
276 int seq_mv_precision_level; // 0 the default in AOM, 1 only integer, 2
277 // adaptive
278 int cur_frame_mv_precision_level; // 0 the default in AOM, 1 only integer
279 #endif
280
281 int allow_screen_content_tools;
282 #if CONFIG_INTERINTRA
283 int allow_interintra_compound;
284 #endif // CONFIG_INTERINTRA
285 #if CONFIG_WEDGE || CONFIG_COMPOUND_SEGMENT
286 int allow_masked_compound;
287 #endif // CONFIG_WEDGE || CONFIG_COMPOUND_SEGMENT
288
289 #if !CONFIG_NO_FRAME_CONTEXT_SIGNALING
290 // Flag signaling which frame contexts should be reset to default values.
291 RESET_FRAME_CONTEXT_MODE reset_frame_context;
292 #endif
293
294 // MBs, mb_rows/cols is in 16-pixel units; mi_rows/cols is in
295 // MODE_INFO (8-pixel) units.
296 int MBs;
297 int mb_rows, mi_rows;
298 int mb_cols, mi_cols;
299 int mi_stride;
300
301 /* profile settings */
302 TX_MODE tx_mode;
303
304 int base_qindex;
305 int y_dc_delta_q;
306 int uv_dc_delta_q;
307 int uv_ac_delta_q;
308 int16_t y_dequant[MAX_SEGMENTS][2];
309 int16_t uv_dequant[MAX_SEGMENTS][2];
310
311 #if CONFIG_AOM_QM
312 // Global quant matrix tables
313 const qm_val_t *giqmatrix[NUM_QM_LEVELS][2][2][TX_SIZES_ALL];
314 const qm_val_t *gqmatrix[NUM_QM_LEVELS][2][2][TX_SIZES_ALL];
315
316 // Local quant matrix tables for each frame
317 const qm_val_t *y_iqmatrix[MAX_SEGMENTS][2][TX_SIZES_ALL];
318 const qm_val_t *uv_iqmatrix[MAX_SEGMENTS][2][TX_SIZES_ALL];
319 // Encoder
320 const qm_val_t *y_qmatrix[MAX_SEGMENTS][2][TX_SIZES_ALL];
321 const qm_val_t *uv_qmatrix[MAX_SEGMENTS][2][TX_SIZES_ALL];
322
323 int using_qmatrix;
324 int min_qmlevel;
325 int max_qmlevel;
326 #endif
327 #if CONFIG_NEW_QUANT
328 dequant_val_type_nuq y_dequant_nuq[MAX_SEGMENTS][QUANT_PROFILES][COEF_BANDS];
329 dequant_val_type_nuq uv_dequant_nuq[MAX_SEGMENTS][QUANT_PROFILES][COEF_BANDS];
330 #endif
331
332 /* We allocate a MODE_INFO struct for each macroblock, together with
333 an extra row on top and column on the left to simplify prediction. */
334 int mi_alloc_size;
335 MODE_INFO *mip; /* Base of allocated array */
336 MODE_INFO *mi; /* Corresponds to upper left visible macroblock */
337
338 // TODO(agrange): Move prev_mi into encoder structure.
339 // prev_mip and prev_mi will only be allocated in encoder.
340 MODE_INFO *prev_mip; /* MODE_INFO array 'mip' from last decoded frame */
341 MODE_INFO *prev_mi; /* 'mi' from last frame (points into prev_mip) */
342
343 // Separate mi functions between encoder and decoder.
344 int (*alloc_mi)(struct AV1Common *cm, int mi_size);
345 void (*free_mi)(struct AV1Common *cm);
346 void (*setup_mi)(struct AV1Common *cm);
347
348 // Grid of pointers to 8x8 MODE_INFO structs. Any 8x8 not in the visible
349 // area will be NULL.
350 MODE_INFO **mi_grid_base;
351 MODE_INFO **mi_grid_visible;
352 MODE_INFO **prev_mi_grid_base;
353 MODE_INFO **prev_mi_grid_visible;
354
355 // Whether to use previous frame's motion vectors for prediction.
356 int use_prev_frame_mvs;
357
358 // Persistent mb segment id map used in prediction.
359 int seg_map_idx;
360 int prev_seg_map_idx;
361
362 uint8_t *seg_map_array[NUM_PING_PONG_BUFFERS];
363 uint8_t *last_frame_seg_map;
364 uint8_t *current_frame_seg_map;
365 int seg_map_alloc_size;
366
367 InterpFilter interp_filter;
368
369 loop_filter_info_n lf_info;
370 #if CONFIG_FRAME_SUPERRES
371 // The denominator of the superres scale; the numerator is fixed.
372 uint8_t superres_scale_denominator;
373 int superres_upscaled_width;
374 int superres_upscaled_height;
375 #endif // CONFIG_FRAME_SUPERRES
376 #if CONFIG_LOOP_RESTORATION
377 RestorationInfo rst_info[MAX_MB_PLANE];
378 RestorationInternal rst_internal;
379 #endif // CONFIG_LOOP_RESTORATION
380
381 // Flag signaling how frame contexts should be updated at the end of
382 // a frame decode
383 REFRESH_FRAME_CONTEXT_MODE refresh_frame_context;
384
385 int ref_frame_sign_bias[TOTAL_REFS_PER_FRAME]; /* Two state 0, 1 */
386
387 struct loopfilter lf;
388 struct segmentation seg;
389 int all_lossless;
390 int frame_parallel_decode; // frame-based threading.
391
392 #if CONFIG_EXT_TX
393 int reduced_tx_set_used;
394 #endif // CONFIG_EXT_TX
395
396 // Context probabilities for reference frame prediction
397 #if CONFIG_EXT_REFS
398 MV_REFERENCE_FRAME comp_fwd_ref[FWD_REFS];
399 MV_REFERENCE_FRAME comp_bwd_ref[BWD_REFS];
400 #else
401 MV_REFERENCE_FRAME comp_fixed_ref;
402 MV_REFERENCE_FRAME comp_var_ref[COMP_REFS];
403 #endif // CONFIG_EXT_REFS
404 REFERENCE_MODE reference_mode;
405
406 FRAME_CONTEXT *fc; /* this frame entropy */
407 FRAME_CONTEXT *frame_contexts; // FRAME_CONTEXTS
408 FRAME_CONTEXT *pre_fc; // Context referenced in this frame
409 #if !CONFIG_NO_FRAME_CONTEXT_SIGNALING
410 unsigned int frame_context_idx; /* Context to use/update */
411 #endif
412 FRAME_COUNTS counts;
413
414 #if CONFIG_FRAME_MARKER
415 unsigned int frame_offset;
416 #endif
417
418 unsigned int current_video_frame;
419 BITSTREAM_PROFILE profile;
420
421 // AOM_BITS_8 in profile 0 or 1, AOM_BITS_10 or AOM_BITS_12 in profile 2 or 3.
422 aom_bit_depth_t bit_depth;
423 aom_bit_depth_t dequant_bit_depth; // bit_depth of current dequantizer
424
425 int error_resilient_mode;
426
427 int tile_cols, tile_rows;
428 int last_tile_cols, last_tile_rows;
429
430 #if CONFIG_MAX_TILE
431 int min_log2_tile_cols;
432 int max_log2_tile_cols;
433 int max_log2_tile_rows;
434 int min_log2_tile_rows;
435 int min_log2_tiles;
436 int max_tile_width_sb;
437 int max_tile_height_sb;
438 int uniform_tile_spacing_flag;
439 int log2_tile_cols; // only valid for uniform tiles
440 int log2_tile_rows; // only valid for uniform tiles
441 int tile_col_start_sb[MAX_TILE_COLS + 1]; // valid for 0 <= i <= tile_cols
442 int tile_row_start_sb[MAX_TILE_ROWS + 1]; // valid for 0 <= i <= tile_rows
443 #if CONFIG_DEPENDENT_HORZTILES
444 int tile_row_independent[MAX_TILE_ROWS]; // valid for 0 <= i < tile_rows
445 #endif
446 #else
447 int log2_tile_cols, log2_tile_rows; // Used in non-large_scale_tile_coding.
448 int tile_width, tile_height; // In MI units
449 #endif // CONFIG_MAX_TILE
450
451 #if CONFIG_EXT_TILE
452 unsigned int large_scale_tile;
453 unsigned int single_tile_decoding;
454 #endif // CONFIG_EXT_TILE
455
456 #if CONFIG_DEPENDENT_HORZTILES
457 int dependent_horz_tiles;
458 int tile_group_start_row[MAX_TILE_ROWS][MAX_TILE_COLS];
459 int tile_group_start_col[MAX_TILE_ROWS][MAX_TILE_COLS];
460 #endif
461 #if CONFIG_LOOPFILTERING_ACROSS_TILES
462 int loop_filter_across_tiles_enabled;
463 #endif // CONFIG_LOOPFILTERING_ACROSS_TILES
464
465 int byte_alignment;
466 int skip_loop_filter;
467
468 // Private data associated with the frame buffer callbacks.
469 void *cb_priv;
470 aom_get_frame_buffer_cb_fn_t get_fb_cb;
471 aom_release_frame_buffer_cb_fn_t release_fb_cb;
472
473 // Handles memory for the codec.
474 InternalFrameBufferList int_frame_buffers;
475
476 // External BufferPool passed from outside.
477 BufferPool *buffer_pool;
478
479 PARTITION_CONTEXT *above_seg_context;
480 ENTROPY_CONTEXT *above_context[MAX_MB_PLANE];
481 #if CONFIG_VAR_TX
482 TXFM_CONTEXT *above_txfm_context;
483 TXFM_CONTEXT *top_txfm_context[MAX_MB_PLANE];
484 TXFM_CONTEXT left_txfm_context[MAX_MB_PLANE][2 * MAX_MIB_SIZE];
485 #endif
486 int above_context_alloc_cols;
487
488 // scratch memory for intraonly/keyframe forward updates from default tables
489 // - this is intentionally not placed in FRAME_CONTEXT since it's reset upon
490 // each keyframe and not used afterwards
491 aom_prob kf_y_prob[INTRA_MODES][INTRA_MODES][INTRA_MODES - 1];
492 #if CONFIG_GLOBAL_MOTION
493 WarpedMotionParams global_motion[TOTAL_REFS_PER_FRAME];
494 #endif
495
496 BLOCK_SIZE sb_size; // Size of the superblock used for this frame
497 int mib_size; // Size of the superblock in units of MI blocks
498 int mib_size_log2; // Log 2 of above.
499 #if CONFIG_CDEF
500 int cdef_pri_damping;
501 int cdef_sec_damping;
502 int nb_cdef_strengths;
503 int cdef_strengths[CDEF_MAX_STRENGTHS];
504 int cdef_uv_strengths[CDEF_MAX_STRENGTHS];
505 int cdef_bits;
506 #endif
507
508 int delta_q_present_flag;
509 // Resolution of delta quant
510 int delta_q_res;
511 #if CONFIG_EXT_DELTA_Q
512 int delta_lf_present_flag;
513 // Resolution of delta lf level
514 int delta_lf_res;
515 #if CONFIG_LOOPFILTER_LEVEL
516 // This is a flag for number of deltas of loop filter level
517 // 0: use 1 delta, for y_vertical, y_horizontal, u, and v
518 // 1: use separate deltas for each filter level
519 int delta_lf_multi;
520 #endif // CONFIG_LOOPFILTER_LEVEL
521 #endif
522 int num_tg;
523 #if CONFIG_REFERENCE_BUFFER
524 SequenceHeader seq_params;
525 int current_frame_id;
526 int ref_frame_id[REF_FRAMES];
527 int valid_for_referencing[REF_FRAMES];
528 int refresh_mask;
529 int invalid_delta_frame_id_minus1;
530 #endif // CONFIG_REFERENCE_BUFFER
531 #if CONFIG_ANS && ANS_MAX_SYMBOLS
532 int ans_window_size_log2;
533 #endif
534 #if CONFIG_NCOBMC_ADAPT_WEIGHT
535 NCOBMC_KERNELS ncobmc_kernels[ADAPT_OVERLAP_BLOCKS][ALL_NCOBMC_MODES];
536 uint8_t *ncobmcaw_buf[4];
537 #endif
538 #if CONFIG_LV_MAP
539 LV_MAP_CTX_TABLE coeff_ctx_table;
540 #endif
541 #if CONFIG_LPF_SB
542 int final_lpf_encode;
543 #endif
544 #if CONFIG_ADAPT_SCAN
545 int use_adapt_scan;
546 #endif
547 } AV1_COMMON;
548
549 // TODO(hkuang): Don't need to lock the whole pool after implementing atomic
550 // frame reference count.
lock_buffer_pool(BufferPool * const pool)551 static void lock_buffer_pool(BufferPool *const pool) {
552 #if CONFIG_MULTITHREAD
553 pthread_mutex_lock(&pool->pool_mutex);
554 #else
555 (void)pool;
556 #endif
557 }
558
unlock_buffer_pool(BufferPool * const pool)559 static void unlock_buffer_pool(BufferPool *const pool) {
560 #if CONFIG_MULTITHREAD
561 pthread_mutex_unlock(&pool->pool_mutex);
562 #else
563 (void)pool;
564 #endif
565 }
566
get_ref_frame(AV1_COMMON * cm,int index)567 static INLINE YV12_BUFFER_CONFIG *get_ref_frame(AV1_COMMON *cm, int index) {
568 if (index < 0 || index >= REF_FRAMES) return NULL;
569 if (cm->ref_frame_map[index] < 0) return NULL;
570 assert(cm->ref_frame_map[index] < FRAME_BUFFERS);
571 return &cm->buffer_pool->frame_bufs[cm->ref_frame_map[index]].buf;
572 }
573
get_frame_new_buffer(const AV1_COMMON * const cm)574 static INLINE YV12_BUFFER_CONFIG *get_frame_new_buffer(
575 const AV1_COMMON *const cm) {
576 return &cm->buffer_pool->frame_bufs[cm->new_fb_idx].buf;
577 }
578
get_free_fb(AV1_COMMON * cm)579 static INLINE int get_free_fb(AV1_COMMON *cm) {
580 RefCntBuffer *const frame_bufs = cm->buffer_pool->frame_bufs;
581 int i;
582
583 lock_buffer_pool(cm->buffer_pool);
584 for (i = 0; i < FRAME_BUFFERS; ++i)
585 if (frame_bufs[i].ref_count == 0) break;
586
587 if (i != FRAME_BUFFERS) {
588 frame_bufs[i].ref_count = 1;
589 } else {
590 // Reset i to be INVALID_IDX to indicate no free buffer found.
591 i = INVALID_IDX;
592 }
593
594 unlock_buffer_pool(cm->buffer_pool);
595 return i;
596 }
597
ref_cnt_fb(RefCntBuffer * bufs,int * idx,int new_idx)598 static INLINE void ref_cnt_fb(RefCntBuffer *bufs, int *idx, int new_idx) {
599 const int ref_index = *idx;
600
601 if (ref_index >= 0 && bufs[ref_index].ref_count > 0)
602 bufs[ref_index].ref_count--;
603
604 *idx = new_idx;
605
606 bufs[new_idx].ref_count++;
607 }
608
609 #if CONFIG_TEMPMV_SIGNALING
610 // Returns 1 if this frame might use mvs from some previous frame. This
611 // function doesn't consider whether prev_frame is actually suitable (see
612 // frame_can_use_prev_frame_mvs for that)
frame_might_use_prev_frame_mvs(const AV1_COMMON * cm)613 static INLINE int frame_might_use_prev_frame_mvs(const AV1_COMMON *cm) {
614 return !cm->error_resilient_mode && !cm->intra_only;
615 }
616
617 // Returns 1 if this frame really can use MVs from some previous frame.
frame_can_use_prev_frame_mvs(const AV1_COMMON * cm)618 static INLINE int frame_can_use_prev_frame_mvs(const AV1_COMMON *cm) {
619 return (frame_might_use_prev_frame_mvs(cm) && cm->last_show_frame &&
620 cm->prev_frame && !cm->prev_frame->intra_only &&
621 cm->width == cm->prev_frame->width &&
622 cm->height == cm->prev_frame->height);
623 }
624 #endif
625
ensure_mv_buffer(RefCntBuffer * buf,AV1_COMMON * cm)626 static INLINE void ensure_mv_buffer(RefCntBuffer *buf, AV1_COMMON *cm) {
627 if (buf->mvs == NULL || buf->mi_rows < cm->mi_rows ||
628 buf->mi_cols < cm->mi_cols) {
629 aom_free(buf->mvs);
630 buf->mi_rows = cm->mi_rows;
631 buf->mi_cols = cm->mi_cols;
632 #if CONFIG_TMV
633 CHECK_MEM_ERROR(cm, buf->mvs,
634 (MV_REF *)aom_calloc(
635 ((cm->mi_rows + 1) >> 1) * ((cm->mi_cols + 1) >> 1),
636 sizeof(*buf->mvs)));
637 #else
638 CHECK_MEM_ERROR(
639 cm, buf->mvs,
640 (MV_REF *)aom_calloc(cm->mi_rows * cm->mi_cols, sizeof(*buf->mvs)));
641 #endif // CONFIG_TMV
642
643 #if CONFIG_MFMV
644 aom_free(buf->tpl_mvs);
645 CHECK_MEM_ERROR(
646 cm, buf->tpl_mvs,
647 (TPL_MV_REF *)aom_calloc((cm->mi_rows + MAX_MIB_SIZE) * cm->mi_stride,
648 sizeof(*buf->tpl_mvs)));
649 #endif
650 }
651 }
652
653 #if CONFIG_VAR_REFS
654 #define LAST_IS_VALID(cm) ((cm)->frame_refs[LAST_FRAME - 1].is_valid)
655 #define LAST2_IS_VALID(cm) ((cm)->frame_refs[LAST2_FRAME - 1].is_valid)
656 #define LAST3_IS_VALID(cm) ((cm)->frame_refs[LAST3_FRAME - 1].is_valid)
657 #define GOLDEN_IS_VALID(cm) ((cm)->frame_refs[GOLDEN_FRAME - 1].is_valid)
658 #define BWDREF_IS_VALID(cm) ((cm)->frame_refs[BWDREF_FRAME - 1].is_valid)
659 #define ALTREF2_IS_VALID(cm) ((cm)->frame_refs[ALTREF2_FRAME - 1].is_valid)
660 #define ALTREF_IS_VALID(cm) ((cm)->frame_refs[ALTREF_FRAME - 1].is_valid)
661
662 #define L_OR_L2(cm) (LAST_IS_VALID(cm) || LAST2_IS_VALID(cm))
663 #define L_AND_L2(cm) (LAST_IS_VALID(cm) && LAST2_IS_VALID(cm))
664 #define L_AND_L3(cm) (LAST_IS_VALID(cm) && LAST3_IS_VALID(cm))
665 #define L_AND_G(cm) (LAST_IS_VALID(cm) && GOLDEN_IS_VALID(cm))
666
667 #define L3_OR_G(cm) (LAST3_IS_VALID(cm) || GOLDEN_IS_VALID(cm))
668 #define L3_AND_G(cm) (LAST3_IS_VALID(cm) && GOLDEN_IS_VALID(cm))
669
670 #define BWD_OR_ALT2(cm) (BWDREF_IS_VALID(cm) || ALTREF2_IS_VALID(cm))
671 #define BWD_AND_ALT2(cm) (BWDREF_IS_VALID(cm) && ALTREF2_IS_VALID(cm))
672 #define BWD_OR_ALT(cm) (BWDREF_IS_VALID(cm) || ALTREF_IS_VALID(cm))
673 #define BWD_AND_ALT(cm) (BWDREF_IS_VALID(cm) && ALTREF_IS_VALID(cm))
674 #endif // CONFIG_VAR_REFS
675
mi_cols_aligned_to_sb(const AV1_COMMON * cm)676 static INLINE int mi_cols_aligned_to_sb(const AV1_COMMON *cm) {
677 return ALIGN_POWER_OF_TWO(cm->mi_cols, cm->mib_size_log2);
678 }
679
mi_rows_aligned_to_sb(const AV1_COMMON * cm)680 static INLINE int mi_rows_aligned_to_sb(const AV1_COMMON *cm) {
681 return ALIGN_POWER_OF_TWO(cm->mi_rows, cm->mib_size_log2);
682 }
683
frame_is_intra_only(const AV1_COMMON * const cm)684 static INLINE int frame_is_intra_only(const AV1_COMMON *const cm) {
685 return cm->frame_type == KEY_FRAME || cm->intra_only;
686 }
687
688 #if CONFIG_CFL
689 #if CONFIG_CHROMA_SUB8X8 && CONFIG_DEBUG
cfl_clear_sub8x8_val(CFL_CTX * cfl)690 static INLINE void cfl_clear_sub8x8_val(CFL_CTX *cfl) {
691 memset(cfl->sub8x8_val, 0, sizeof(cfl->sub8x8_val));
692 }
693 #endif // CONFIG_CHROMA_SUB8X8 && CONFIG_DEBUG
694 void cfl_init(CFL_CTX *cfl, AV1_COMMON *cm);
695 #endif // CONFIG_CFL
696
av1_init_macroblockd(AV1_COMMON * cm,MACROBLOCKD * xd,tran_low_t * pvq_ref_coeff,CFL_CTX * cfl,tran_low_t * dqcoeff)697 static INLINE void av1_init_macroblockd(AV1_COMMON *cm, MACROBLOCKD *xd,
698 #if CONFIG_PVQ
699 tran_low_t *pvq_ref_coeff,
700 #endif
701 #if CONFIG_CFL
702 CFL_CTX *cfl,
703 #endif
704 tran_low_t *dqcoeff) {
705 for (int i = 0; i < MAX_MB_PLANE; ++i) {
706 xd->plane[i].dqcoeff = dqcoeff;
707 #if CONFIG_PVQ
708 xd->plane[i].pvq_ref_coeff = pvq_ref_coeff;
709 #endif
710 xd->above_context[i] = cm->above_context[i];
711 if (xd->plane[i].plane_type == PLANE_TYPE_Y) {
712 memcpy(xd->plane[i].seg_dequant, cm->y_dequant, sizeof(cm->y_dequant));
713 #if CONFIG_AOM_QM
714 memcpy(xd->plane[i].seg_iqmatrix, cm->y_iqmatrix, sizeof(cm->y_iqmatrix));
715 #endif
716
717 #if CONFIG_NEW_QUANT
718 memcpy(xd->plane[i].seg_dequant_nuq, cm->y_dequant_nuq,
719 sizeof(cm->y_dequant_nuq));
720 #endif
721 } else {
722 memcpy(xd->plane[i].seg_dequant, cm->uv_dequant, sizeof(cm->uv_dequant));
723 #if CONFIG_AOM_QM
724 memcpy(xd->plane[i].seg_iqmatrix, cm->uv_iqmatrix,
725 sizeof(cm->uv_iqmatrix));
726 #endif
727 #if CONFIG_NEW_QUANT
728 memcpy(xd->plane[i].seg_dequant_nuq, cm->uv_dequant_nuq,
729 sizeof(cm->uv_dequant_nuq));
730 #endif
731 }
732 }
733 xd->fc = cm->fc;
734 xd->above_seg_context = cm->above_seg_context;
735 #if CONFIG_VAR_TX
736 xd->above_txfm_context = cm->above_txfm_context;
737 #endif
738 #if CONFIG_CFL
739 cfl_init(cfl, cm);
740 xd->cfl = cfl;
741 #endif
742 xd->mi_stride = cm->mi_stride;
743 xd->error_info = &cm->error;
744 }
745
set_skip_context(MACROBLOCKD * xd,int mi_row,int mi_col)746 static INLINE void set_skip_context(MACROBLOCKD *xd, int mi_row, int mi_col) {
747 int i;
748 int row_offset = mi_row;
749 int col_offset = mi_col;
750 for (i = 0; i < MAX_MB_PLANE; ++i) {
751 struct macroblockd_plane *const pd = &xd->plane[i];
752 #if CONFIG_CHROMA_SUB8X8
753 // Offset the buffer pointer
754 const BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
755 if (pd->subsampling_y && (mi_row & 0x01) && (mi_size_high[bsize] == 1))
756 row_offset = mi_row - 1;
757 if (pd->subsampling_x && (mi_col & 0x01) && (mi_size_wide[bsize] == 1))
758 col_offset = mi_col - 1;
759 #endif
760 int above_idx = col_offset << (MI_SIZE_LOG2 - tx_size_wide_log2[0]);
761 int left_idx = (row_offset & MAX_MIB_MASK)
762 << (MI_SIZE_LOG2 - tx_size_high_log2[0]);
763 pd->above_context = &xd->above_context[i][above_idx >> pd->subsampling_x];
764 pd->left_context = &xd->left_context[i][left_idx >> pd->subsampling_y];
765 }
766 }
767
calc_mi_size(int len)768 static INLINE int calc_mi_size(int len) {
769 // len is in mi units.
770 return len + MAX_MIB_SIZE;
771 }
772
set_plane_n4(MACROBLOCKD * const xd,int bw,int bh)773 static INLINE void set_plane_n4(MACROBLOCKD *const xd, int bw, int bh) {
774 int i;
775 for (i = 0; i < MAX_MB_PLANE; i++) {
776 xd->plane[i].n4_w = (bw << 1) >> xd->plane[i].subsampling_x;
777 xd->plane[i].n4_h = (bh << 1) >> xd->plane[i].subsampling_y;
778
779 xd->plane[i].width = (bw * MI_SIZE) >> xd->plane[i].subsampling_x;
780 xd->plane[i].height = (bh * MI_SIZE) >> xd->plane[i].subsampling_y;
781
782 #if !CONFIG_CHROMA_2X2
783 xd->plane[i].width = AOMMAX(xd->plane[i].width, 4);
784 xd->plane[i].height = AOMMAX(xd->plane[i].height, 4);
785 #endif
786 }
787 }
788
set_mi_row_col(MACROBLOCKD * xd,const TileInfo * const tile,int mi_row,int bh,int mi_col,int bw,int dependent_horz_tile_flag,int mi_rows,int mi_cols)789 static INLINE void set_mi_row_col(MACROBLOCKD *xd, const TileInfo *const tile,
790 int mi_row, int bh, int mi_col, int bw,
791 #if CONFIG_DEPENDENT_HORZTILES
792 int dependent_horz_tile_flag,
793 #endif // CONFIG_DEPENDENT_HORZTILES
794 int mi_rows, int mi_cols) {
795 xd->mb_to_top_edge = -((mi_row * MI_SIZE) * 8);
796 xd->mb_to_bottom_edge = ((mi_rows - bh - mi_row) * MI_SIZE) * 8;
797 xd->mb_to_left_edge = -((mi_col * MI_SIZE) * 8);
798 xd->mb_to_right_edge = ((mi_cols - bw - mi_col) * MI_SIZE) * 8;
799
800 #if CONFIG_DEPENDENT_HORZTILES
801 if (dependent_horz_tile_flag) {
802 xd->up_available = (mi_row > tile->mi_row_start) || !tile->tg_horz_boundary;
803 } else {
804 #endif // CONFIG_DEPENDENT_HORZTILES
805 // Are edges available for intra prediction?
806 xd->up_available = (mi_row > tile->mi_row_start);
807 #if CONFIG_DEPENDENT_HORZTILES
808 }
809 #endif // CONFIG_DEPENDENT_HORZTILES
810
811 xd->left_available = (mi_col > tile->mi_col_start);
812 #if CONFIG_CHROMA_SUB8X8
813 xd->chroma_up_available = xd->up_available;
814 xd->chroma_left_available = xd->left_available;
815 if (xd->plane[1].subsampling_x && bw < mi_size_wide[BLOCK_8X8])
816 xd->chroma_left_available = (mi_col - 1) > tile->mi_col_start;
817 if (xd->plane[1].subsampling_y && bh < mi_size_high[BLOCK_8X8])
818 xd->chroma_up_available = (mi_row - 1) > tile->mi_row_start;
819 #endif
820 if (xd->up_available) {
821 xd->above_mi = xd->mi[-xd->mi_stride];
822 // above_mi may be NULL in encoder's first pass.
823 xd->above_mbmi = xd->above_mi ? &xd->above_mi->mbmi : NULL;
824 } else {
825 xd->above_mi = NULL;
826 xd->above_mbmi = NULL;
827 }
828
829 if (xd->left_available) {
830 xd->left_mi = xd->mi[-1];
831 // left_mi may be NULL in encoder's first pass.
832 xd->left_mbmi = xd->left_mi ? &xd->left_mi->mbmi : NULL;
833 } else {
834 xd->left_mi = NULL;
835 xd->left_mbmi = NULL;
836 }
837
838 xd->n8_h = bh;
839 xd->n8_w = bw;
840 xd->is_sec_rect = 0;
841 if (xd->n8_w < xd->n8_h)
842 if (mi_col & (xd->n8_h - 1)) xd->is_sec_rect = 1;
843
844 if (xd->n8_w > xd->n8_h)
845 if (mi_row & (xd->n8_w - 1)) xd->is_sec_rect = 1;
846 }
847
get_y_mode_probs(const AV1_COMMON * cm,const MODE_INFO * mi,const MODE_INFO * above_mi,const MODE_INFO * left_mi,int block)848 static INLINE const aom_prob *get_y_mode_probs(const AV1_COMMON *cm,
849 const MODE_INFO *mi,
850 const MODE_INFO *above_mi,
851 const MODE_INFO *left_mi,
852 int block) {
853 const PREDICTION_MODE above = av1_above_block_mode(mi, above_mi, block);
854 const PREDICTION_MODE left = av1_left_block_mode(mi, left_mi, block);
855 return cm->kf_y_prob[above][left];
856 }
857
get_y_mode_cdf(FRAME_CONTEXT * tile_ctx,const MODE_INFO * mi,const MODE_INFO * above_mi,const MODE_INFO * left_mi,int block)858 static INLINE aom_cdf_prob *get_y_mode_cdf(FRAME_CONTEXT *tile_ctx,
859 const MODE_INFO *mi,
860 const MODE_INFO *above_mi,
861 const MODE_INFO *left_mi,
862 int block) {
863 const PREDICTION_MODE above = av1_above_block_mode(mi, above_mi, block);
864 const PREDICTION_MODE left = av1_left_block_mode(mi, left_mi, block);
865
866 #if CONFIG_KF_CTX
867 int above_ctx = intra_mode_context[above];
868 int left_ctx = intra_mode_context[left];
869 return tile_ctx->kf_y_cdf[above_ctx][left_ctx];
870 #else
871 return tile_ctx->kf_y_cdf[above][left];
872 #endif
873 }
874
update_partition_context(MACROBLOCKD * xd,int mi_row,int mi_col,BLOCK_SIZE subsize,BLOCK_SIZE bsize)875 static INLINE void update_partition_context(MACROBLOCKD *xd, int mi_row,
876 int mi_col, BLOCK_SIZE subsize,
877 BLOCK_SIZE bsize) {
878 PARTITION_CONTEXT *const above_ctx = xd->above_seg_context + mi_col;
879 PARTITION_CONTEXT *const left_ctx =
880 xd->left_seg_context + (mi_row & MAX_MIB_MASK);
881
882 #if CONFIG_EXT_PARTITION_TYPES
883 const int bw = mi_size_wide[bsize];
884 const int bh = mi_size_high[bsize];
885 memset(above_ctx, partition_context_lookup[subsize].above, bw);
886 memset(left_ctx, partition_context_lookup[subsize].left, bh);
887 #else
888 // num_4x4_blocks_wide_lookup[bsize] / 2
889 const int bs = mi_size_wide[bsize];
890
891 // update the partition context at the end notes. set partition bits
892 // of block sizes larger than the current one to be one, and partition
893 // bits of smaller block sizes to be zero.
894 memset(above_ctx, partition_context_lookup[subsize].above, bs);
895 memset(left_ctx, partition_context_lookup[subsize].left, bs);
896 #endif // CONFIG_EXT_PARTITION_TYPES
897 }
898
899 #if CONFIG_CB4X4
is_chroma_reference(int mi_row,int mi_col,BLOCK_SIZE bsize,int subsampling_x,int subsampling_y)900 static INLINE int is_chroma_reference(int mi_row, int mi_col, BLOCK_SIZE bsize,
901 int subsampling_x, int subsampling_y) {
902 #if CONFIG_CHROMA_2X2
903 return 1;
904 #endif
905
906 #if CONFIG_CHROMA_SUB8X8
907 const int bw = mi_size_wide[bsize];
908 const int bh = mi_size_high[bsize];
909
910 int ref_pos = ((mi_row & 0x01) || !(bh & 0x01) || !subsampling_y) &&
911 ((mi_col & 0x01) || !(bw & 0x01) || !subsampling_x);
912
913 return ref_pos;
914 #else
915 int ref_pos = !(((mi_row & 0x01) && subsampling_y) ||
916 ((mi_col & 0x01) && subsampling_x));
917
918 if (bsize >= BLOCK_8X8) ref_pos = 1;
919
920 return ref_pos;
921 #endif
922 }
923
924 #if CONFIG_SUPERTX
need_handle_chroma_sub8x8(BLOCK_SIZE bsize,int subsampling_x,int subsampling_y)925 static INLINE int need_handle_chroma_sub8x8(BLOCK_SIZE bsize, int subsampling_x,
926 int subsampling_y) {
927 const int bw = mi_size_wide[bsize];
928 const int bh = mi_size_high[bsize];
929
930 if (bsize >= BLOCK_8X8 ||
931 ((!(bh & 0x01) || !subsampling_y) && (!(bw & 0x01) || !subsampling_x)))
932 return 0;
933 else
934 return 1;
935 }
936 #endif
937
scale_chroma_bsize(BLOCK_SIZE bsize,int subsampling_x,int subsampling_y)938 static INLINE BLOCK_SIZE scale_chroma_bsize(BLOCK_SIZE bsize, int subsampling_x,
939 int subsampling_y) {
940 BLOCK_SIZE bs = bsize;
941
942 if (bs < BLOCK_8X8) {
943 if (subsampling_x == 1 && subsampling_y == 1)
944 bs = BLOCK_8X8;
945 else if (subsampling_x == 1)
946 bs = BLOCK_8X4;
947 else if (subsampling_y == 1)
948 bs = BLOCK_4X8;
949 }
950
951 return bs;
952 }
953 #endif
954
cdf_element_prob(const aom_cdf_prob * cdf,size_t element)955 static INLINE aom_cdf_prob cdf_element_prob(const aom_cdf_prob *cdf,
956 size_t element) {
957 assert(cdf != NULL);
958 #if !CONFIG_ANS
959 return (element > 0 ? cdf[element - 1] : CDF_PROB_TOP) - cdf[element];
960 #else
961 return cdf[element] - (element > 0 ? cdf[element - 1] : 0);
962 #endif
963 }
964
partition_gather_horz_alike(aom_cdf_prob * out,const aom_cdf_prob * const in)965 static INLINE void partition_gather_horz_alike(aom_cdf_prob *out,
966 const aom_cdf_prob *const in) {
967 out[0] = CDF_PROB_TOP;
968 out[0] -= cdf_element_prob(in, PARTITION_HORZ);
969 out[0] -= cdf_element_prob(in, PARTITION_SPLIT);
970 #if CONFIG_EXT_PARTITION_TYPES
971 out[0] -= cdf_element_prob(in, PARTITION_HORZ_A);
972 out[0] -= cdf_element_prob(in, PARTITION_HORZ_B);
973 out[0] -= cdf_element_prob(in, PARTITION_VERT_A);
974 #endif
975 out[0] = AOM_ICDF(out[0]);
976 out[1] = AOM_ICDF(CDF_PROB_TOP);
977 }
978
partition_gather_vert_alike(aom_cdf_prob * out,const aom_cdf_prob * const in)979 static INLINE void partition_gather_vert_alike(aom_cdf_prob *out,
980 const aom_cdf_prob *const in) {
981 out[0] = CDF_PROB_TOP;
982 out[0] -= cdf_element_prob(in, PARTITION_VERT);
983 out[0] -= cdf_element_prob(in, PARTITION_SPLIT);
984 #if CONFIG_EXT_PARTITION_TYPES
985 out[0] -= cdf_element_prob(in, PARTITION_HORZ_A);
986 out[0] -= cdf_element_prob(in, PARTITION_VERT_A);
987 out[0] -= cdf_element_prob(in, PARTITION_VERT_B);
988 #endif
989 out[0] = AOM_ICDF(out[0]);
990 out[1] = AOM_ICDF(CDF_PROB_TOP);
991 }
992
993 #if CONFIG_EXT_PARTITION_TYPES
update_ext_partition_context(MACROBLOCKD * xd,int mi_row,int mi_col,BLOCK_SIZE subsize,BLOCK_SIZE bsize,PARTITION_TYPE partition)994 static INLINE void update_ext_partition_context(MACROBLOCKD *xd, int mi_row,
995 int mi_col, BLOCK_SIZE subsize,
996 BLOCK_SIZE bsize,
997 PARTITION_TYPE partition) {
998 if (bsize >= BLOCK_8X8) {
999 #if !CONFIG_EXT_PARTITION_TYPES_AB
1000 const int hbs = mi_size_wide[bsize] / 2;
1001 BLOCK_SIZE bsize2 = get_subsize(bsize, PARTITION_SPLIT);
1002 #endif
1003 switch (partition) {
1004 case PARTITION_SPLIT:
1005 if (bsize != BLOCK_8X8) break;
1006 case PARTITION_NONE:
1007 case PARTITION_HORZ:
1008 case PARTITION_VERT:
1009 case PARTITION_HORZ_4:
1010 case PARTITION_VERT_4:
1011 update_partition_context(xd, mi_row, mi_col, subsize, bsize);
1012 break;
1013 #if CONFIG_EXT_PARTITION_TYPES_AB
1014 case PARTITION_HORZ_A:
1015 update_partition_context(xd, mi_row, mi_col,
1016 get_subsize(bsize, PARTITION_HORZ_4), subsize);
1017 update_partition_context(xd, mi_row + mi_size_high[bsize] / 2, mi_col,
1018 subsize, subsize);
1019 break;
1020 case PARTITION_HORZ_B:
1021 update_partition_context(xd, mi_row, mi_col, subsize, subsize);
1022 update_partition_context(xd, mi_row + mi_size_high[bsize] / 2, mi_col,
1023 get_subsize(bsize, PARTITION_HORZ_4), subsize);
1024 break;
1025 case PARTITION_VERT_A:
1026 update_partition_context(xd, mi_row, mi_col,
1027 get_subsize(bsize, PARTITION_VERT_4), subsize);
1028 update_partition_context(xd, mi_row, mi_col + mi_size_wide[bsize] / 2,
1029 subsize, subsize);
1030 break;
1031 case PARTITION_VERT_B:
1032 update_partition_context(xd, mi_row, mi_col, subsize, subsize);
1033 update_partition_context(xd, mi_row, mi_col + mi_size_wide[bsize] / 2,
1034 get_subsize(bsize, PARTITION_VERT_4), subsize);
1035 break;
1036 #else
1037 case PARTITION_HORZ_A:
1038 update_partition_context(xd, mi_row, mi_col, bsize2, subsize);
1039 update_partition_context(xd, mi_row + hbs, mi_col, subsize, subsize);
1040 break;
1041 case PARTITION_HORZ_B:
1042 update_partition_context(xd, mi_row, mi_col, subsize, subsize);
1043 update_partition_context(xd, mi_row + hbs, mi_col, bsize2, subsize);
1044 break;
1045 case PARTITION_VERT_A:
1046 update_partition_context(xd, mi_row, mi_col, bsize2, subsize);
1047 update_partition_context(xd, mi_row, mi_col + hbs, subsize, subsize);
1048 break;
1049 case PARTITION_VERT_B:
1050 update_partition_context(xd, mi_row, mi_col, subsize, subsize);
1051 update_partition_context(xd, mi_row, mi_col + hbs, bsize2, subsize);
1052 break;
1053 #endif
1054 default: assert(0 && "Invalid partition type");
1055 }
1056 }
1057 }
1058 #endif // CONFIG_EXT_PARTITION_TYPES
1059
partition_plane_context(const MACROBLOCKD * xd,int mi_row,int mi_col,int has_rows,int has_cols,BLOCK_SIZE bsize)1060 static INLINE int partition_plane_context(const MACROBLOCKD *xd, int mi_row,
1061 int mi_col,
1062 #if CONFIG_UNPOISON_PARTITION_CTX
1063 int has_rows, int has_cols,
1064 #endif
1065 BLOCK_SIZE bsize) {
1066 const PARTITION_CONTEXT *above_ctx = xd->above_seg_context + mi_col;
1067 const PARTITION_CONTEXT *left_ctx =
1068 xd->left_seg_context + (mi_row & MAX_MIB_MASK);
1069 // Minimum partition point is 8x8. Offset the bsl accordingly.
1070 const int bsl = mi_width_log2_lookup[bsize] - mi_width_log2_lookup[BLOCK_8X8];
1071 int above = (*above_ctx >> bsl) & 1, left = (*left_ctx >> bsl) & 1;
1072
1073 assert(b_width_log2_lookup[bsize] == b_height_log2_lookup[bsize]);
1074 assert(bsl >= 0);
1075
1076 #if CONFIG_UNPOISON_PARTITION_CTX
1077 if (has_rows && has_cols)
1078 return (left * 2 + above) + bsl * PARTITION_PLOFFSET;
1079 else if (has_rows && !has_cols)
1080 return PARTITION_CONTEXTS_PRIMARY + bsl;
1081 else if (!has_rows && has_cols)
1082 return PARTITION_CONTEXTS_PRIMARY + PARTITION_BLOCK_SIZES + bsl;
1083 else
1084 return INVALID_PARTITION_CTX; // Bogus context, forced SPLIT
1085 #else
1086 return (left * 2 + above) + bsl * PARTITION_PLOFFSET;
1087 #endif
1088 }
1089
max_block_wide(const MACROBLOCKD * xd,BLOCK_SIZE bsize,int plane)1090 static INLINE int max_block_wide(const MACROBLOCKD *xd, BLOCK_SIZE bsize,
1091 int plane) {
1092 int max_blocks_wide = block_size_wide[bsize];
1093 const struct macroblockd_plane *const pd = &xd->plane[plane];
1094
1095 if (xd->mb_to_right_edge < 0)
1096 max_blocks_wide += xd->mb_to_right_edge >> (3 + pd->subsampling_x);
1097
1098 // Scale the width in the transform block unit.
1099 return max_blocks_wide >> tx_size_wide_log2[0];
1100 }
1101
max_block_high(const MACROBLOCKD * xd,BLOCK_SIZE bsize,int plane)1102 static INLINE int max_block_high(const MACROBLOCKD *xd, BLOCK_SIZE bsize,
1103 int plane) {
1104 int max_blocks_high = block_size_high[bsize];
1105 const struct macroblockd_plane *const pd = &xd->plane[plane];
1106
1107 if (xd->mb_to_bottom_edge < 0)
1108 max_blocks_high += xd->mb_to_bottom_edge >> (3 + pd->subsampling_y);
1109
1110 // Scale the width in the transform block unit.
1111 return max_blocks_high >> tx_size_wide_log2[0];
1112 }
1113
1114 #if CONFIG_CFL
max_intra_block_width(const MACROBLOCKD * xd,BLOCK_SIZE plane_bsize,int plane,TX_SIZE tx_size)1115 static INLINE int max_intra_block_width(const MACROBLOCKD *xd,
1116 BLOCK_SIZE plane_bsize, int plane,
1117 TX_SIZE tx_size) {
1118 const int max_blocks_wide = max_block_wide(xd, plane_bsize, plane)
1119 << tx_size_wide_log2[0];
1120 return ALIGN_POWER_OF_TWO(max_blocks_wide, tx_size_wide_log2[tx_size]);
1121 }
1122
max_intra_block_height(const MACROBLOCKD * xd,BLOCK_SIZE plane_bsize,int plane,TX_SIZE tx_size)1123 static INLINE int max_intra_block_height(const MACROBLOCKD *xd,
1124 BLOCK_SIZE plane_bsize, int plane,
1125 TX_SIZE tx_size) {
1126 const int max_blocks_high = max_block_high(xd, plane_bsize, plane)
1127 << tx_size_high_log2[0];
1128 return ALIGN_POWER_OF_TWO(max_blocks_high, tx_size_high_log2[tx_size]);
1129 }
1130 #endif // CONFIG_CFL
1131
av1_zero_above_context(AV1_COMMON * const cm,int mi_col_start,int mi_col_end)1132 static INLINE void av1_zero_above_context(AV1_COMMON *const cm,
1133 int mi_col_start, int mi_col_end) {
1134 const int width = mi_col_end - mi_col_start;
1135 const int aligned_width = ALIGN_POWER_OF_TWO(width, cm->mib_size_log2);
1136
1137 const int offset_y = mi_col_start << (MI_SIZE_LOG2 - tx_size_wide_log2[0]);
1138 const int width_y = aligned_width << (MI_SIZE_LOG2 - tx_size_wide_log2[0]);
1139 const int offset_uv = offset_y >> cm->subsampling_x;
1140 const int width_uv = width_y >> cm->subsampling_x;
1141
1142 av1_zero_array(cm->above_context[0] + offset_y, width_y);
1143 av1_zero_array(cm->above_context[1] + offset_uv, width_uv);
1144 av1_zero_array(cm->above_context[2] + offset_uv, width_uv);
1145
1146 av1_zero_array(cm->above_seg_context + mi_col_start, aligned_width);
1147
1148 #if CONFIG_VAR_TX
1149 av1_zero_array(cm->above_txfm_context + (mi_col_start << TX_UNIT_WIDE_LOG2),
1150 aligned_width << TX_UNIT_WIDE_LOG2);
1151 #endif // CONFIG_VAR_TX
1152 }
1153
av1_zero_left_context(MACROBLOCKD * const xd)1154 static INLINE void av1_zero_left_context(MACROBLOCKD *const xd) {
1155 av1_zero(xd->left_context);
1156 av1_zero(xd->left_seg_context);
1157 #if CONFIG_VAR_TX
1158 av1_zero(xd->left_txfm_context_buffer);
1159 #endif
1160 }
1161
1162 // Disable array-bounds checks as the TX_SIZE enum contains values larger than
1163 // TX_SIZES_ALL (TX_INVALID) which make extending the array as a workaround
1164 // infeasible. The assert is enough for static analysis and this or other tools
1165 // asan, valgrind would catch oob access at runtime.
1166 #if defined(__GNUC__) && __GNUC__ >= 4
1167 #pragma GCC diagnostic ignored "-Warray-bounds"
1168 #endif
get_min_tx_size(TX_SIZE tx_size)1169 static INLINE TX_SIZE get_min_tx_size(TX_SIZE tx_size) {
1170 assert(tx_size < TX_SIZES_ALL);
1171 return txsize_sqr_map[tx_size];
1172 }
1173 #if defined(__GNUC__) && __GNUC__ >= 4
1174 #pragma GCC diagnostic warning "-Warray-bounds"
1175 #endif
1176
1177 #if CONFIG_VAR_TX
set_txfm_ctx(TXFM_CONTEXT * txfm_ctx,uint8_t txs,int len)1178 static INLINE void set_txfm_ctx(TXFM_CONTEXT *txfm_ctx, uint8_t txs, int len) {
1179 int i;
1180 for (i = 0; i < len; ++i) txfm_ctx[i] = txs;
1181 }
1182
set_txfm_ctxs(TX_SIZE tx_size,int n8_w,int n8_h,int skip,const MACROBLOCKD * xd)1183 static INLINE void set_txfm_ctxs(TX_SIZE tx_size, int n8_w, int n8_h, int skip,
1184 const MACROBLOCKD *xd) {
1185 uint8_t bw = tx_size_wide[tx_size];
1186 uint8_t bh = tx_size_high[tx_size];
1187
1188 if (skip) {
1189 bw = n8_w * MI_SIZE;
1190 bh = n8_h * MI_SIZE;
1191 }
1192
1193 set_txfm_ctx(xd->above_txfm_context, bw, n8_w << TX_UNIT_WIDE_LOG2);
1194 set_txfm_ctx(xd->left_txfm_context, bh, n8_h << TX_UNIT_HIGH_LOG2);
1195 }
1196
txfm_partition_update(TXFM_CONTEXT * above_ctx,TXFM_CONTEXT * left_ctx,TX_SIZE tx_size,TX_SIZE txb_size)1197 static INLINE void txfm_partition_update(TXFM_CONTEXT *above_ctx,
1198 TXFM_CONTEXT *left_ctx,
1199 TX_SIZE tx_size, TX_SIZE txb_size) {
1200 BLOCK_SIZE bsize = txsize_to_bsize[txb_size];
1201 int bh = mi_size_high[bsize] << TX_UNIT_HIGH_LOG2;
1202 int bw = mi_size_wide[bsize] << TX_UNIT_WIDE_LOG2;
1203 uint8_t txw = tx_size_wide[tx_size];
1204 uint8_t txh = tx_size_high[tx_size];
1205 int i;
1206 for (i = 0; i < bh; ++i) left_ctx[i] = txh;
1207 for (i = 0; i < bw; ++i) above_ctx[i] = txw;
1208 }
1209
get_sqr_tx_size(int tx_dim)1210 static INLINE TX_SIZE get_sqr_tx_size(int tx_dim) {
1211 switch (tx_dim) {
1212 #if CONFIG_EXT_PARTITION
1213 case 128:
1214 #endif // CONFIG_EXT_PARTITION
1215 case 64:
1216 #if CONFIG_TX64X64
1217 return TX_64X64;
1218 #else
1219 return TX_32X32;
1220 #endif // CONFIG_TX64X64
1221 break;
1222 case 32: return TX_32X32; break;
1223 case 16: return TX_16X16; break;
1224 case 8: return TX_8X8; break;
1225 default: return TX_4X4;
1226 }
1227 }
1228
txfm_partition_context(TXFM_CONTEXT * above_ctx,TXFM_CONTEXT * left_ctx,BLOCK_SIZE bsize,TX_SIZE tx_size)1229 static INLINE int txfm_partition_context(TXFM_CONTEXT *above_ctx,
1230 TXFM_CONTEXT *left_ctx,
1231 BLOCK_SIZE bsize, TX_SIZE tx_size) {
1232 const uint8_t txw = tx_size_wide[tx_size];
1233 const uint8_t txh = tx_size_high[tx_size];
1234 const int above = *above_ctx < txw;
1235 const int left = *left_ctx < txh;
1236 int category = TXFM_PARTITION_CONTEXTS - 1;
1237
1238 // dummy return, not used by others.
1239 if (tx_size <= TX_4X4) return 0;
1240
1241 TX_SIZE max_tx_size =
1242 get_sqr_tx_size(AOMMAX(block_size_wide[bsize], block_size_high[bsize]));
1243
1244 if (max_tx_size >= TX_8X8) {
1245 category = (tx_size != max_tx_size && max_tx_size > TX_8X8) +
1246 (TX_SIZES - 1 - max_tx_size) * 2;
1247 }
1248 if (category == TXFM_PARTITION_CONTEXTS - 1) return category;
1249 return category * 3 + above + left;
1250 }
1251 #endif
1252
1253 // Compute the next partition in the direction of the sb_type stored in the mi
1254 // array, starting with bsize.
get_partition(const AV1_COMMON * const cm,int mi_row,int mi_col,BLOCK_SIZE bsize)1255 static INLINE PARTITION_TYPE get_partition(const AV1_COMMON *const cm,
1256 int mi_row, int mi_col,
1257 BLOCK_SIZE bsize) {
1258 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return PARTITION_INVALID;
1259
1260 const int offset = mi_row * cm->mi_stride + mi_col;
1261 MODE_INFO **mi = cm->mi_grid_visible + offset;
1262 const BLOCK_SIZE subsize = mi[0]->mbmi.sb_type;
1263
1264 if (subsize == bsize) return PARTITION_NONE;
1265
1266 const int bhigh = mi_size_high[bsize];
1267 const int bwide = mi_size_wide[bsize];
1268 const int sshigh = mi_size_high[subsize];
1269 const int sswide = mi_size_wide[subsize];
1270
1271 #if CONFIG_EXT_PARTITION_TYPES
1272 if (bsize > BLOCK_8X8 && mi_row + bwide / 2 < cm->mi_rows &&
1273 mi_col + bhigh / 2 < cm->mi_cols) {
1274 // In this case, the block might be using an extended partition
1275 // type.
1276 const MB_MODE_INFO *const mbmi_right = &mi[bwide / 2]->mbmi;
1277 const MB_MODE_INFO *const mbmi_below = &mi[bhigh / 2 * cm->mi_stride]->mbmi;
1278
1279 if (sswide == bwide) {
1280 #if CONFIG_EXT_PARTITION_TYPES_AB
1281 // Smaller height but same width. Is PARTITION_HORZ, PARTITION_HORZ_4,
1282 // PARTITION_HORZ_A or PARTITION_HORZ_B.
1283 if (sshigh * 2 == bhigh)
1284 return (mbmi_below->sb_type == subsize) ? PARTITION_HORZ
1285 : PARTITION_HORZ_B;
1286 assert(sshigh * 4 == bhigh);
1287 return (mbmi_below->sb_type == subsize) ? PARTITION_HORZ_4
1288 : PARTITION_HORZ_A;
1289 #else
1290 // Smaller height but same width. Is PARTITION_HORZ_4, PARTITION_HORZ or
1291 // PARTITION_HORZ_B. To distinguish the latter two, check if the lower
1292 // half was split.
1293 if (sshigh * 4 == bhigh) return PARTITION_HORZ_4;
1294 assert(sshigh * 2 == bhigh);
1295
1296 if (mbmi_below->sb_type == subsize)
1297 return PARTITION_HORZ;
1298 else
1299 return PARTITION_HORZ_B;
1300 #endif
1301 } else if (sshigh == bhigh) {
1302 #if CONFIG_EXT_PARTITION_TYPES_AB
1303 // Smaller width but same height. Is PARTITION_VERT, PARTITION_VERT_4,
1304 // PARTITION_VERT_A or PARTITION_VERT_B.
1305 if (sswide * 2 == bwide)
1306 return (mbmi_right->sb_type == subsize) ? PARTITION_VERT
1307 : PARTITION_VERT_B;
1308 assert(sswide * 4 == bwide);
1309 return (mbmi_right->sb_type == subsize) ? PARTITION_VERT_4
1310 : PARTITION_VERT_A;
1311 #else
1312 // Smaller width but same height. Is PARTITION_VERT_4, PARTITION_VERT or
1313 // PARTITION_VERT_B. To distinguish the latter two, check if the right
1314 // half was split.
1315 if (sswide * 4 == bwide) return PARTITION_VERT_4;
1316 assert(sswide * 2 == bhigh);
1317
1318 if (mbmi_right->sb_type == subsize)
1319 return PARTITION_VERT;
1320 else
1321 return PARTITION_VERT_B;
1322 #endif
1323 } else {
1324 #if !CONFIG_EXT_PARTITION_TYPES_AB
1325 // Smaller width and smaller height. Might be PARTITION_SPLIT or could be
1326 // PARTITION_HORZ_A or PARTITION_VERT_A. If subsize isn't halved in both
1327 // dimensions, we immediately know this is a split (which will recurse to
1328 // get to subsize). Otherwise look down and to the right. With
1329 // PARTITION_VERT_A, the right block will have height bhigh; with
1330 // PARTITION_HORZ_A, the lower block with have width bwide. Otherwise
1331 // it's PARTITION_SPLIT.
1332 if (sswide * 2 != bwide || sshigh * 2 != bhigh) return PARTITION_SPLIT;
1333
1334 if (mi_size_wide[mbmi_below->sb_type] == bwide) return PARTITION_HORZ_A;
1335 if (mi_size_high[mbmi_right->sb_type] == bhigh) return PARTITION_VERT_A;
1336 #endif
1337
1338 return PARTITION_SPLIT;
1339 }
1340 }
1341 #endif
1342 const int vert_split = sswide < bwide;
1343 const int horz_split = sshigh < bhigh;
1344 const int split_idx = (vert_split << 1) | horz_split;
1345 assert(split_idx != 0);
1346
1347 static const PARTITION_TYPE base_partitions[4] = {
1348 PARTITION_INVALID, PARTITION_HORZ, PARTITION_VERT, PARTITION_SPLIT
1349 };
1350
1351 return base_partitions[split_idx];
1352 }
1353
set_use_reference_buffer(AV1_COMMON * const cm,int use)1354 static INLINE void set_use_reference_buffer(AV1_COMMON *const cm, int use) {
1355 #if CONFIG_REFERENCE_BUFFER
1356 cm->seq_params.frame_id_numbers_present_flag = use;
1357 #else
1358 (void)cm;
1359 (void)use;
1360 #endif
1361 }
1362
set_sb_size(AV1_COMMON * const cm,BLOCK_SIZE sb_size)1363 static INLINE void set_sb_size(AV1_COMMON *const cm, BLOCK_SIZE sb_size) {
1364 cm->sb_size = sb_size;
1365 cm->mib_size = mi_size_wide[cm->sb_size];
1366 #if CONFIG_CB4X4
1367 cm->mib_size_log2 = b_width_log2_lookup[cm->sb_size];
1368 #else
1369 cm->mib_size_log2 = mi_width_log2_lookup[cm->sb_size];
1370 #endif
1371 }
1372
all_lossless(const AV1_COMMON * cm,const MACROBLOCKD * xd)1373 static INLINE int all_lossless(const AV1_COMMON *cm, const MACROBLOCKD *xd) {
1374 int i;
1375 int all_lossless = 1;
1376 if (cm->seg.enabled) {
1377 for (i = 0; i < MAX_SEGMENTS; ++i) {
1378 if (!xd->lossless[i]) {
1379 all_lossless = 0;
1380 break;
1381 }
1382 }
1383 } else {
1384 all_lossless = xd->lossless[0];
1385 }
1386 return all_lossless;
1387 }
1388
use_compressed_header(const AV1_COMMON * cm)1389 static INLINE int use_compressed_header(const AV1_COMMON *cm) {
1390 (void)cm;
1391 #if CONFIG_RESTRICT_COMPRESSED_HDR && CONFIG_NEW_MULTISYMBOL
1392 return 0;
1393 #elif CONFIG_RESTRICT_COMPRESSED_HDR
1394 return cm->refresh_frame_context == REFRESH_FRAME_CONTEXT_FORWARD;
1395 #else
1396 return 1;
1397 #endif // CONFIG_RESTRICT_COMPRESSED_HDR && CONFIG_NEW_MULTISYMBOL
1398 }
1399
1400 #ifdef __cplusplus
1401 } // extern "C"
1402 #endif
1403
1404 #endif // AV1_COMMON_ONYXC_INT_H_
1405