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