xref: /aosp_15_r20/external/libaom/av1/encoder/tokenize.h (revision 77c1e3ccc04c968bd2bc212e87364f250e820521)
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 AOM_AV1_ENCODER_TOKENIZE_H_
13 #define AOM_AV1_ENCODER_TOKENIZE_H_
14 
15 #include "av1/common/entropy.h"
16 #include "av1/encoder/block.h"
17 #include "aom_dsp/bitwriter.h"
18 
19 #ifdef __cplusplus
20 extern "C" {
21 #endif
22 
23 // The token and color_ctx members of the TokenExtra structure are used
24 // to store the indices of color and color context of each pixel in
25 // case of palette mode.
26 // 1) token can take values in the range of [0, 7] as maximum number of possible
27 // colors is 8 (PALETTE_COLORS). Hence token requires 3 bits (unsigned).
28 // 2) The reserved field (1-bit) is positioned such that color_ctx occupies the
29 // most significant bits and token occupies the least significant bits of the
30 // byte. Thus accesses to token and color_ctx are optimal. If TokenExtra is
31 // defined as:
32 //   typedef struct {
33 //     int8_t color_ctx : 4;
34 //     uint8_t token : 3;
35 //   } TokenExtra;
36 // then read of color_ctx requires an extra left shift to facilitate sign
37 // extension and write of token requires an extra masking.
38 // 3) color_ctx can take 5 (PALETTE_COLOR_INDEX_CONTEXTS) valid values, i.e.,
39 // from 0 to 4. As per the current implementation it can take values in the
40 // range of [-1, 4]. Here -1 corresponds to invalid color index context and is
41 // used for default initialization. Hence color_ctx requires 4 bits (signed).
42 typedef struct {
43   uint8_t token : 3;
44   uint8_t reserved : 1;
45   int8_t color_ctx : 4;
46 } TokenExtra;
47 
48 typedef struct {
49   TokenExtra *start;
50   unsigned int count;
51 } TokenList;
52 
53 typedef struct {
54   // Number of tile tokens for which memory is allocated.
55   unsigned int tokens_allocated;
56   // tile_tok[i][j] is a pointer to the buffer storing palette tokens of the ith
57   // tile row, jth tile column.
58   TokenExtra *tile_tok[MAX_TILE_ROWS][MAX_TILE_COLS];
59   // tplist[i][j][k] holds the start pointer of tile_tok[i][j] and the count of
60   // palette tokens for the kth superblock row of the ith tile row, jth tile
61   // column.
62   TokenList *tplist[MAX_TILE_ROWS][MAX_TILE_COLS];
63 } TokenInfo;
64 
65 struct AV1_COMP;
66 struct ThreadData;
67 struct FRAME_COUNTS;
68 
69 enum {
70   OUTPUT_ENABLED = 0,
71   DRY_RUN_NORMAL,
72   DRY_RUN_COSTCOEFFS,
73 } UENUM1BYTE(RUN_TYPE);
74 
75 struct tokenize_b_args {
76   const struct AV1_COMP *cpi;
77   struct ThreadData *td;
78   int this_rate;
79   uint8_t allow_update_cdf;
80   RUN_TYPE dry_run;
81 };
82 
83 // Note in all the tokenize functions rate if non NULL is incremented
84 // with the coefficient token cost only if dry_run = DRY_RUN_COSTCOEFS,
85 // otherwise rate is not incremented.
86 void av1_tokenize_sb_vartx(const struct AV1_COMP *cpi, struct ThreadData *td,
87                            RUN_TYPE dry_run, BLOCK_SIZE bsize, int *rate,
88                            uint8_t allow_update_cdf);
89 
90 int av1_cost_color_map(const MACROBLOCK *const x, int plane, BLOCK_SIZE bsize,
91                        TX_SIZE tx_size, COLOR_MAP_TYPE type);
92 
93 void av1_tokenize_color_map(const MACROBLOCK *const x, int plane,
94                             TokenExtra **t, BLOCK_SIZE bsize, TX_SIZE tx_size,
95                             COLOR_MAP_TYPE type, int allow_update_cdf,
96                             struct FRAME_COUNTS *counts);
97 
av1_get_tx_eob(const struct segmentation * seg,int segment_id,TX_SIZE tx_size)98 static inline int av1_get_tx_eob(const struct segmentation *seg, int segment_id,
99                                  TX_SIZE tx_size) {
100   const int eob_max = av1_get_max_eob(tx_size);
101   return segfeature_active(seg, segment_id, SEG_LVL_SKIP) ? 0 : eob_max;
102 }
103 
104 // Token buffer is only used for palette tokens.
get_token_alloc(int mb_rows,int mb_cols,int sb_size_log2,const int num_planes)105 static inline unsigned int get_token_alloc(int mb_rows, int mb_cols,
106                                            int sb_size_log2,
107                                            const int num_planes) {
108   // Calculate the maximum number of max superblocks in the image.
109   const int shift = sb_size_log2 - 4;
110   const int sb_size = 1 << sb_size_log2;
111   const int sb_size_square = sb_size * sb_size;
112   const int sb_rows = CEIL_POWER_OF_TWO(mb_rows, shift);
113   const int sb_cols = CEIL_POWER_OF_TWO(mb_cols, shift);
114 
115   // One palette token for each pixel. There can be palettes on two planes.
116   const int sb_palette_toks = AOMMIN(2, num_planes) * sb_size_square;
117 
118   return sb_rows * sb_cols * sb_palette_toks;
119 }
120 
121 // Allocate memory for token related info.
alloc_token_info(AV1_COMMON * cm,TokenInfo * token_info,unsigned int tokens_required)122 static inline void alloc_token_info(AV1_COMMON *cm, TokenInfo *token_info,
123                                     unsigned int tokens_required) {
124   int sb_rows =
125       CEIL_POWER_OF_TWO(cm->mi_params.mi_rows, cm->seq_params->mib_size_log2);
126   token_info->tokens_allocated = tokens_required;
127 
128   CHECK_MEM_ERROR(cm, token_info->tile_tok[0][0],
129                   (TokenExtra *)aom_calloc(
130                       tokens_required, sizeof(*token_info->tile_tok[0][0])));
131 
132   CHECK_MEM_ERROR(
133       cm, token_info->tplist[0][0],
134       (TokenList *)aom_calloc(sb_rows * MAX_TILE_ROWS * MAX_TILE_COLS,
135                               sizeof(*token_info->tplist[0][0])));
136 }
137 
138 // Check if memory allocation has been done for token related info.
is_token_info_allocated(const TokenInfo * token_info)139 static inline bool is_token_info_allocated(const TokenInfo *token_info) {
140   return ((token_info->tile_tok[0][0] != NULL) &&
141           (token_info->tplist[0][0] != NULL));
142 }
143 
144 // Free memory from token related variables.
free_token_info(TokenInfo * token_info)145 static inline void free_token_info(TokenInfo *token_info) {
146   aom_free(token_info->tile_tok[0][0]);
147   token_info->tile_tok[0][0] = NULL;
148 
149   aom_free(token_info->tplist[0][0]);
150   token_info->tplist[0][0] = NULL;
151 
152   token_info->tokens_allocated = 0;
153 }
154 
155 #ifdef __cplusplus
156 }  // extern "C"
157 #endif
158 
159 #endif  // AOM_AV1_ENCODER_TOKENIZE_H_
160