• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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   // tile_tok[i][j] is a pointer to the buffer storing palette tokens of the ith
55   // tile row, jth tile column.
56   TokenExtra *tile_tok[MAX_TILE_ROWS][MAX_TILE_COLS];
57   // tplist[i][j][k] holds the start pointer of tile_tok[i][j] and the count of
58   // palette tokens for the kth superblock row of the ith tile row, jth tile
59   // column.
60   TokenList *tplist[MAX_TILE_ROWS][MAX_TILE_COLS];
61 } TokenInfo;
62 
63 struct AV1_COMP;
64 struct ThreadData;
65 struct FRAME_COUNTS;
66 
67 enum {
68   OUTPUT_ENABLED = 0,
69   DRY_RUN_NORMAL,
70   DRY_RUN_COSTCOEFFS,
71 } UENUM1BYTE(RUN_TYPE);
72 
73 struct tokenize_b_args {
74   const struct AV1_COMP *cpi;
75   struct ThreadData *td;
76   int this_rate;
77   uint8_t allow_update_cdf;
78   RUN_TYPE dry_run;
79 };
80 
81 // Note in all the tokenize functions rate if non NULL is incremented
82 // with the coefficient token cost only if dry_run = DRY_RUN_COSTCOEFS,
83 // otherwise rate is not incremented.
84 void av1_tokenize_sb_vartx(const struct AV1_COMP *cpi, struct ThreadData *td,
85                            RUN_TYPE dry_run, BLOCK_SIZE bsize, int *rate,
86                            uint8_t allow_update_cdf);
87 
88 int av1_cost_color_map(const MACROBLOCK *const x, int plane, BLOCK_SIZE bsize,
89                        TX_SIZE tx_size, COLOR_MAP_TYPE type);
90 
91 void av1_tokenize_color_map(const MACROBLOCK *const x, int plane,
92                             TokenExtra **t, BLOCK_SIZE bsize, TX_SIZE tx_size,
93                             COLOR_MAP_TYPE type, int allow_update_cdf,
94                             struct FRAME_COUNTS *counts);
95 
av1_get_tx_eob(const struct segmentation * seg,int segment_id,TX_SIZE tx_size)96 static INLINE int av1_get_tx_eob(const struct segmentation *seg, int segment_id,
97                                  TX_SIZE tx_size) {
98   const int eob_max = av1_get_max_eob(tx_size);
99   return segfeature_active(seg, segment_id, SEG_LVL_SKIP) ? 0 : eob_max;
100 }
101 
102 // 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)103 static INLINE unsigned int get_token_alloc(int mb_rows, int mb_cols,
104                                            int sb_size_log2,
105                                            const int num_planes) {
106   // Calculate the maximum number of max superblocks in the image.
107   const int shift = sb_size_log2 - 4;
108   const int sb_size = 1 << sb_size_log2;
109   const int sb_size_square = sb_size * sb_size;
110   const int sb_rows = ALIGN_POWER_OF_TWO(mb_rows, shift) >> shift;
111   const int sb_cols = ALIGN_POWER_OF_TWO(mb_cols, shift) >> shift;
112 
113   // One palette token for each pixel. There can be palettes on two planes.
114   const int sb_palette_toks = AOMMIN(2, num_planes) * sb_size_square;
115 
116   return sb_rows * sb_cols * sb_palette_toks;
117 }
118 
119 // Allocate memory for token related info.
alloc_token_info(AV1_COMMON * cm,TokenInfo * token_info)120 static AOM_INLINE void alloc_token_info(AV1_COMMON *cm, TokenInfo *token_info) {
121   int mi_rows_aligned_to_sb =
122       ALIGN_POWER_OF_TWO(cm->mi_params.mi_rows, cm->seq_params->mib_size_log2);
123   int sb_rows = mi_rows_aligned_to_sb >> cm->seq_params->mib_size_log2;
124   const int num_planes = av1_num_planes(cm);
125   unsigned int tokens =
126       get_token_alloc(cm->mi_params.mb_rows, cm->mi_params.mb_cols,
127                       MAX_SB_SIZE_LOG2, num_planes);
128   CHECK_MEM_ERROR(
129       cm, token_info->tile_tok[0][0],
130       (TokenExtra *)aom_calloc(tokens, 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 // Free memory from token related variables.
free_token_info(TokenInfo * token_info)139 static AOM_INLINE void free_token_info(TokenInfo *token_info) {
140   aom_free(token_info->tile_tok[0][0]);
141   token_info->tile_tok[0][0] = NULL;
142 
143   aom_free(token_info->tplist[0][0]);
144   token_info->tplist[0][0] = NULL;
145 }
146 
147 #ifdef __cplusplus
148 }  // extern "C"
149 #endif
150 
151 #endif  // AOM_AV1_ENCODER_TOKENIZE_H_
152