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