1*77c1e3ccSAndroid Build Coastguard Worker /*
2*77c1e3ccSAndroid Build Coastguard Worker * Copyright (c) 2018, 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 #include <assert.h>
13*77c1e3ccSAndroid Build Coastguard Worker #include <stdbool.h>
14*77c1e3ccSAndroid Build Coastguard Worker
15*77c1e3ccSAndroid Build Coastguard Worker #include "config/av1_rtcd.h"
16*77c1e3ccSAndroid Build Coastguard Worker
17*77c1e3ccSAndroid Build Coastguard Worker #include "av1/encoder/block.h"
18*77c1e3ccSAndroid Build Coastguard Worker #include "av1/encoder/hash.h"
19*77c1e3ccSAndroid Build Coastguard Worker #include "av1/encoder/hash_motion.h"
20*77c1e3ccSAndroid Build Coastguard Worker
21*77c1e3ccSAndroid Build Coastguard Worker #define kSrcBits 16
22*77c1e3ccSAndroid Build Coastguard Worker #define kBlockSizeBits 3
23*77c1e3ccSAndroid Build Coastguard Worker #define kMaxAddr (1 << (kSrcBits + kBlockSizeBits))
24*77c1e3ccSAndroid Build Coastguard Worker
25*77c1e3ccSAndroid Build Coastguard Worker // TODO([email protected]): is higher than 8 bits screen content supported?
26*77c1e3ccSAndroid Build Coastguard Worker // If yes, fix this function
get_pixels_in_1D_char_array_by_block_2x2(const uint8_t * y_src,int stride,uint8_t * p_pixels_in1D)27*77c1e3ccSAndroid Build Coastguard Worker static void get_pixels_in_1D_char_array_by_block_2x2(const uint8_t *y_src,
28*77c1e3ccSAndroid Build Coastguard Worker int stride,
29*77c1e3ccSAndroid Build Coastguard Worker uint8_t *p_pixels_in1D) {
30*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *p_pel = y_src;
31*77c1e3ccSAndroid Build Coastguard Worker int index = 0;
32*77c1e3ccSAndroid Build Coastguard Worker for (int i = 0; i < 2; i++) {
33*77c1e3ccSAndroid Build Coastguard Worker for (int j = 0; j < 2; j++) {
34*77c1e3ccSAndroid Build Coastguard Worker p_pixels_in1D[index++] = p_pel[j];
35*77c1e3ccSAndroid Build Coastguard Worker }
36*77c1e3ccSAndroid Build Coastguard Worker p_pel += stride;
37*77c1e3ccSAndroid Build Coastguard Worker }
38*77c1e3ccSAndroid Build Coastguard Worker }
39*77c1e3ccSAndroid Build Coastguard Worker
get_pixels_in_1D_short_array_by_block_2x2(const uint16_t * y_src,int stride,uint16_t * p_pixels_in1D)40*77c1e3ccSAndroid Build Coastguard Worker static void get_pixels_in_1D_short_array_by_block_2x2(const uint16_t *y_src,
41*77c1e3ccSAndroid Build Coastguard Worker int stride,
42*77c1e3ccSAndroid Build Coastguard Worker uint16_t *p_pixels_in1D) {
43*77c1e3ccSAndroid Build Coastguard Worker const uint16_t *p_pel = y_src;
44*77c1e3ccSAndroid Build Coastguard Worker int index = 0;
45*77c1e3ccSAndroid Build Coastguard Worker for (int i = 0; i < 2; i++) {
46*77c1e3ccSAndroid Build Coastguard Worker for (int j = 0; j < 2; j++) {
47*77c1e3ccSAndroid Build Coastguard Worker p_pixels_in1D[index++] = p_pel[j];
48*77c1e3ccSAndroid Build Coastguard Worker }
49*77c1e3ccSAndroid Build Coastguard Worker p_pel += stride;
50*77c1e3ccSAndroid Build Coastguard Worker }
51*77c1e3ccSAndroid Build Coastguard Worker }
52*77c1e3ccSAndroid Build Coastguard Worker
is_block_2x2_row_same_value(const uint8_t * p)53*77c1e3ccSAndroid Build Coastguard Worker static int is_block_2x2_row_same_value(const uint8_t *p) {
54*77c1e3ccSAndroid Build Coastguard Worker if (p[0] != p[1] || p[2] != p[3]) {
55*77c1e3ccSAndroid Build Coastguard Worker return 0;
56*77c1e3ccSAndroid Build Coastguard Worker }
57*77c1e3ccSAndroid Build Coastguard Worker return 1;
58*77c1e3ccSAndroid Build Coastguard Worker }
59*77c1e3ccSAndroid Build Coastguard Worker
is_block16_2x2_row_same_value(const uint16_t * p)60*77c1e3ccSAndroid Build Coastguard Worker static int is_block16_2x2_row_same_value(const uint16_t *p) {
61*77c1e3ccSAndroid Build Coastguard Worker if (p[0] != p[1] || p[2] != p[3]) {
62*77c1e3ccSAndroid Build Coastguard Worker return 0;
63*77c1e3ccSAndroid Build Coastguard Worker }
64*77c1e3ccSAndroid Build Coastguard Worker return 1;
65*77c1e3ccSAndroid Build Coastguard Worker }
66*77c1e3ccSAndroid Build Coastguard Worker
is_block_2x2_col_same_value(const uint8_t * p)67*77c1e3ccSAndroid Build Coastguard Worker static int is_block_2x2_col_same_value(const uint8_t *p) {
68*77c1e3ccSAndroid Build Coastguard Worker if ((p[0] != p[2]) || (p[1] != p[3])) {
69*77c1e3ccSAndroid Build Coastguard Worker return 0;
70*77c1e3ccSAndroid Build Coastguard Worker }
71*77c1e3ccSAndroid Build Coastguard Worker return 1;
72*77c1e3ccSAndroid Build Coastguard Worker }
73*77c1e3ccSAndroid Build Coastguard Worker
is_block16_2x2_col_same_value(const uint16_t * p)74*77c1e3ccSAndroid Build Coastguard Worker static int is_block16_2x2_col_same_value(const uint16_t *p) {
75*77c1e3ccSAndroid Build Coastguard Worker if ((p[0] != p[2]) || (p[1] != p[3])) {
76*77c1e3ccSAndroid Build Coastguard Worker return 0;
77*77c1e3ccSAndroid Build Coastguard Worker }
78*77c1e3ccSAndroid Build Coastguard Worker return 1;
79*77c1e3ccSAndroid Build Coastguard Worker }
80*77c1e3ccSAndroid Build Coastguard Worker
81*77c1e3ccSAndroid Build Coastguard Worker // the hash value (hash_value1 consists two parts, the first 3 bits relate to
82*77c1e3ccSAndroid Build Coastguard Worker // the block size and the remaining 16 bits are the crc values. This fuction
83*77c1e3ccSAndroid Build Coastguard Worker // is used to get the first 3 bits.
hash_block_size_to_index(int block_size)84*77c1e3ccSAndroid Build Coastguard Worker static int hash_block_size_to_index(int block_size) {
85*77c1e3ccSAndroid Build Coastguard Worker switch (block_size) {
86*77c1e3ccSAndroid Build Coastguard Worker case 4: return 0;
87*77c1e3ccSAndroid Build Coastguard Worker case 8: return 1;
88*77c1e3ccSAndroid Build Coastguard Worker case 16: return 2;
89*77c1e3ccSAndroid Build Coastguard Worker case 32: return 3;
90*77c1e3ccSAndroid Build Coastguard Worker case 64: return 4;
91*77c1e3ccSAndroid Build Coastguard Worker case 128: return 5;
92*77c1e3ccSAndroid Build Coastguard Worker default: return -1;
93*77c1e3ccSAndroid Build Coastguard Worker }
94*77c1e3ccSAndroid Build Coastguard Worker }
95*77c1e3ccSAndroid Build Coastguard Worker
av1_hash_table_init(IntraBCHashInfo * intrabc_hash_info)96*77c1e3ccSAndroid Build Coastguard Worker void av1_hash_table_init(IntraBCHashInfo *intrabc_hash_info) {
97*77c1e3ccSAndroid Build Coastguard Worker if (!intrabc_hash_info->g_crc_initialized) {
98*77c1e3ccSAndroid Build Coastguard Worker av1_crc_calculator_init(&intrabc_hash_info->crc_calculator1, 24, 0x5D6DCB);
99*77c1e3ccSAndroid Build Coastguard Worker av1_crc_calculator_init(&intrabc_hash_info->crc_calculator2, 24, 0x864CFB);
100*77c1e3ccSAndroid Build Coastguard Worker intrabc_hash_info->g_crc_initialized = 1;
101*77c1e3ccSAndroid Build Coastguard Worker }
102*77c1e3ccSAndroid Build Coastguard Worker intrabc_hash_info->intrabc_hash_table.p_lookup_table = NULL;
103*77c1e3ccSAndroid Build Coastguard Worker }
104*77c1e3ccSAndroid Build Coastguard Worker
clear_all(hash_table * p_hash_table)105*77c1e3ccSAndroid Build Coastguard Worker static void clear_all(hash_table *p_hash_table) {
106*77c1e3ccSAndroid Build Coastguard Worker if (p_hash_table->p_lookup_table == NULL) {
107*77c1e3ccSAndroid Build Coastguard Worker return;
108*77c1e3ccSAndroid Build Coastguard Worker }
109*77c1e3ccSAndroid Build Coastguard Worker for (int i = 0; i < kMaxAddr; i++) {
110*77c1e3ccSAndroid Build Coastguard Worker if (p_hash_table->p_lookup_table[i] != NULL) {
111*77c1e3ccSAndroid Build Coastguard Worker aom_vector_destroy(p_hash_table->p_lookup_table[i]);
112*77c1e3ccSAndroid Build Coastguard Worker aom_free(p_hash_table->p_lookup_table[i]);
113*77c1e3ccSAndroid Build Coastguard Worker p_hash_table->p_lookup_table[i] = NULL;
114*77c1e3ccSAndroid Build Coastguard Worker }
115*77c1e3ccSAndroid Build Coastguard Worker }
116*77c1e3ccSAndroid Build Coastguard Worker }
117*77c1e3ccSAndroid Build Coastguard Worker
av1_hash_table_destroy(hash_table * p_hash_table)118*77c1e3ccSAndroid Build Coastguard Worker void av1_hash_table_destroy(hash_table *p_hash_table) {
119*77c1e3ccSAndroid Build Coastguard Worker clear_all(p_hash_table);
120*77c1e3ccSAndroid Build Coastguard Worker aom_free(p_hash_table->p_lookup_table);
121*77c1e3ccSAndroid Build Coastguard Worker p_hash_table->p_lookup_table = NULL;
122*77c1e3ccSAndroid Build Coastguard Worker }
123*77c1e3ccSAndroid Build Coastguard Worker
av1_hash_table_create(hash_table * p_hash_table)124*77c1e3ccSAndroid Build Coastguard Worker bool av1_hash_table_create(hash_table *p_hash_table) {
125*77c1e3ccSAndroid Build Coastguard Worker if (p_hash_table->p_lookup_table != NULL) {
126*77c1e3ccSAndroid Build Coastguard Worker clear_all(p_hash_table);
127*77c1e3ccSAndroid Build Coastguard Worker return true;
128*77c1e3ccSAndroid Build Coastguard Worker }
129*77c1e3ccSAndroid Build Coastguard Worker p_hash_table->p_lookup_table =
130*77c1e3ccSAndroid Build Coastguard Worker (Vector **)aom_calloc(kMaxAddr, sizeof(p_hash_table->p_lookup_table[0]));
131*77c1e3ccSAndroid Build Coastguard Worker if (!p_hash_table->p_lookup_table) return false;
132*77c1e3ccSAndroid Build Coastguard Worker return true;
133*77c1e3ccSAndroid Build Coastguard Worker }
134*77c1e3ccSAndroid Build Coastguard Worker
hash_table_add_to_table(hash_table * p_hash_table,uint32_t hash_value,block_hash * curr_block_hash)135*77c1e3ccSAndroid Build Coastguard Worker static bool hash_table_add_to_table(hash_table *p_hash_table,
136*77c1e3ccSAndroid Build Coastguard Worker uint32_t hash_value,
137*77c1e3ccSAndroid Build Coastguard Worker block_hash *curr_block_hash) {
138*77c1e3ccSAndroid Build Coastguard Worker if (p_hash_table->p_lookup_table[hash_value] == NULL) {
139*77c1e3ccSAndroid Build Coastguard Worker p_hash_table->p_lookup_table[hash_value] =
140*77c1e3ccSAndroid Build Coastguard Worker aom_malloc(sizeof(p_hash_table->p_lookup_table[0][0]));
141*77c1e3ccSAndroid Build Coastguard Worker if (p_hash_table->p_lookup_table[hash_value] == NULL) {
142*77c1e3ccSAndroid Build Coastguard Worker return false;
143*77c1e3ccSAndroid Build Coastguard Worker }
144*77c1e3ccSAndroid Build Coastguard Worker if (aom_vector_setup(p_hash_table->p_lookup_table[hash_value], 10,
145*77c1e3ccSAndroid Build Coastguard Worker sizeof(curr_block_hash[0])) == VECTOR_ERROR)
146*77c1e3ccSAndroid Build Coastguard Worker return false;
147*77c1e3ccSAndroid Build Coastguard Worker if (aom_vector_push_back(p_hash_table->p_lookup_table[hash_value],
148*77c1e3ccSAndroid Build Coastguard Worker curr_block_hash) == VECTOR_ERROR)
149*77c1e3ccSAndroid Build Coastguard Worker return false;
150*77c1e3ccSAndroid Build Coastguard Worker } else {
151*77c1e3ccSAndroid Build Coastguard Worker if (aom_vector_push_back(p_hash_table->p_lookup_table[hash_value],
152*77c1e3ccSAndroid Build Coastguard Worker curr_block_hash) == VECTOR_ERROR)
153*77c1e3ccSAndroid Build Coastguard Worker return false;
154*77c1e3ccSAndroid Build Coastguard Worker }
155*77c1e3ccSAndroid Build Coastguard Worker return true;
156*77c1e3ccSAndroid Build Coastguard Worker }
157*77c1e3ccSAndroid Build Coastguard Worker
av1_hash_table_count(const hash_table * p_hash_table,uint32_t hash_value)158*77c1e3ccSAndroid Build Coastguard Worker int32_t av1_hash_table_count(const hash_table *p_hash_table,
159*77c1e3ccSAndroid Build Coastguard Worker uint32_t hash_value) {
160*77c1e3ccSAndroid Build Coastguard Worker if (p_hash_table->p_lookup_table[hash_value] == NULL) {
161*77c1e3ccSAndroid Build Coastguard Worker return 0;
162*77c1e3ccSAndroid Build Coastguard Worker } else {
163*77c1e3ccSAndroid Build Coastguard Worker return (int32_t)(p_hash_table->p_lookup_table[hash_value]->size);
164*77c1e3ccSAndroid Build Coastguard Worker }
165*77c1e3ccSAndroid Build Coastguard Worker }
166*77c1e3ccSAndroid Build Coastguard Worker
av1_hash_get_first_iterator(hash_table * p_hash_table,uint32_t hash_value)167*77c1e3ccSAndroid Build Coastguard Worker Iterator av1_hash_get_first_iterator(hash_table *p_hash_table,
168*77c1e3ccSAndroid Build Coastguard Worker uint32_t hash_value) {
169*77c1e3ccSAndroid Build Coastguard Worker assert(av1_hash_table_count(p_hash_table, hash_value) > 0);
170*77c1e3ccSAndroid Build Coastguard Worker return aom_vector_begin(p_hash_table->p_lookup_table[hash_value]);
171*77c1e3ccSAndroid Build Coastguard Worker }
172*77c1e3ccSAndroid Build Coastguard Worker
av1_generate_block_2x2_hash_value(IntraBCHashInfo * intrabc_hash_info,const YV12_BUFFER_CONFIG * picture,uint32_t * pic_block_hash[2],int8_t * pic_block_same_info[3])173*77c1e3ccSAndroid Build Coastguard Worker void av1_generate_block_2x2_hash_value(IntraBCHashInfo *intrabc_hash_info,
174*77c1e3ccSAndroid Build Coastguard Worker const YV12_BUFFER_CONFIG *picture,
175*77c1e3ccSAndroid Build Coastguard Worker uint32_t *pic_block_hash[2],
176*77c1e3ccSAndroid Build Coastguard Worker int8_t *pic_block_same_info[3]) {
177*77c1e3ccSAndroid Build Coastguard Worker const int width = 2;
178*77c1e3ccSAndroid Build Coastguard Worker const int height = 2;
179*77c1e3ccSAndroid Build Coastguard Worker const int x_end = picture->y_crop_width - width + 1;
180*77c1e3ccSAndroid Build Coastguard Worker const int y_end = picture->y_crop_height - height + 1;
181*77c1e3ccSAndroid Build Coastguard Worker CRC_CALCULATOR *calc_1 = &intrabc_hash_info->crc_calculator1;
182*77c1e3ccSAndroid Build Coastguard Worker CRC_CALCULATOR *calc_2 = &intrabc_hash_info->crc_calculator2;
183*77c1e3ccSAndroid Build Coastguard Worker
184*77c1e3ccSAndroid Build Coastguard Worker const int length = width * 2;
185*77c1e3ccSAndroid Build Coastguard Worker if (picture->flags & YV12_FLAG_HIGHBITDEPTH) {
186*77c1e3ccSAndroid Build Coastguard Worker uint16_t p[4];
187*77c1e3ccSAndroid Build Coastguard Worker int pos = 0;
188*77c1e3ccSAndroid Build Coastguard Worker for (int y_pos = 0; y_pos < y_end; y_pos++) {
189*77c1e3ccSAndroid Build Coastguard Worker for (int x_pos = 0; x_pos < x_end; x_pos++) {
190*77c1e3ccSAndroid Build Coastguard Worker get_pixels_in_1D_short_array_by_block_2x2(
191*77c1e3ccSAndroid Build Coastguard Worker CONVERT_TO_SHORTPTR(picture->y_buffer) + y_pos * picture->y_stride +
192*77c1e3ccSAndroid Build Coastguard Worker x_pos,
193*77c1e3ccSAndroid Build Coastguard Worker picture->y_stride, p);
194*77c1e3ccSAndroid Build Coastguard Worker pic_block_same_info[0][pos] = is_block16_2x2_row_same_value(p);
195*77c1e3ccSAndroid Build Coastguard Worker pic_block_same_info[1][pos] = is_block16_2x2_col_same_value(p);
196*77c1e3ccSAndroid Build Coastguard Worker
197*77c1e3ccSAndroid Build Coastguard Worker pic_block_hash[0][pos] =
198*77c1e3ccSAndroid Build Coastguard Worker av1_get_crc_value(calc_1, (uint8_t *)p, length * sizeof(p[0]));
199*77c1e3ccSAndroid Build Coastguard Worker pic_block_hash[1][pos] =
200*77c1e3ccSAndroid Build Coastguard Worker av1_get_crc_value(calc_2, (uint8_t *)p, length * sizeof(p[0]));
201*77c1e3ccSAndroid Build Coastguard Worker pos++;
202*77c1e3ccSAndroid Build Coastguard Worker }
203*77c1e3ccSAndroid Build Coastguard Worker pos += width - 1;
204*77c1e3ccSAndroid Build Coastguard Worker }
205*77c1e3ccSAndroid Build Coastguard Worker } else {
206*77c1e3ccSAndroid Build Coastguard Worker uint8_t p[4];
207*77c1e3ccSAndroid Build Coastguard Worker int pos = 0;
208*77c1e3ccSAndroid Build Coastguard Worker for (int y_pos = 0; y_pos < y_end; y_pos++) {
209*77c1e3ccSAndroid Build Coastguard Worker for (int x_pos = 0; x_pos < x_end; x_pos++) {
210*77c1e3ccSAndroid Build Coastguard Worker get_pixels_in_1D_char_array_by_block_2x2(
211*77c1e3ccSAndroid Build Coastguard Worker picture->y_buffer + y_pos * picture->y_stride + x_pos,
212*77c1e3ccSAndroid Build Coastguard Worker picture->y_stride, p);
213*77c1e3ccSAndroid Build Coastguard Worker pic_block_same_info[0][pos] = is_block_2x2_row_same_value(p);
214*77c1e3ccSAndroid Build Coastguard Worker pic_block_same_info[1][pos] = is_block_2x2_col_same_value(p);
215*77c1e3ccSAndroid Build Coastguard Worker
216*77c1e3ccSAndroid Build Coastguard Worker pic_block_hash[0][pos] =
217*77c1e3ccSAndroid Build Coastguard Worker av1_get_crc_value(calc_1, p, length * sizeof(p[0]));
218*77c1e3ccSAndroid Build Coastguard Worker pic_block_hash[1][pos] =
219*77c1e3ccSAndroid Build Coastguard Worker av1_get_crc_value(calc_2, p, length * sizeof(p[0]));
220*77c1e3ccSAndroid Build Coastguard Worker pos++;
221*77c1e3ccSAndroid Build Coastguard Worker }
222*77c1e3ccSAndroid Build Coastguard Worker pos += width - 1;
223*77c1e3ccSAndroid Build Coastguard Worker }
224*77c1e3ccSAndroid Build Coastguard Worker }
225*77c1e3ccSAndroid Build Coastguard Worker }
226*77c1e3ccSAndroid Build Coastguard Worker
av1_generate_block_hash_value(IntraBCHashInfo * intrabc_hash_info,const YV12_BUFFER_CONFIG * picture,int block_size,uint32_t * src_pic_block_hash[2],uint32_t * dst_pic_block_hash[2],int8_t * src_pic_block_same_info[3],int8_t * dst_pic_block_same_info[3])227*77c1e3ccSAndroid Build Coastguard Worker void av1_generate_block_hash_value(IntraBCHashInfo *intrabc_hash_info,
228*77c1e3ccSAndroid Build Coastguard Worker const YV12_BUFFER_CONFIG *picture,
229*77c1e3ccSAndroid Build Coastguard Worker int block_size,
230*77c1e3ccSAndroid Build Coastguard Worker uint32_t *src_pic_block_hash[2],
231*77c1e3ccSAndroid Build Coastguard Worker uint32_t *dst_pic_block_hash[2],
232*77c1e3ccSAndroid Build Coastguard Worker int8_t *src_pic_block_same_info[3],
233*77c1e3ccSAndroid Build Coastguard Worker int8_t *dst_pic_block_same_info[3]) {
234*77c1e3ccSAndroid Build Coastguard Worker CRC_CALCULATOR *calc_1 = &intrabc_hash_info->crc_calculator1;
235*77c1e3ccSAndroid Build Coastguard Worker CRC_CALCULATOR *calc_2 = &intrabc_hash_info->crc_calculator2;
236*77c1e3ccSAndroid Build Coastguard Worker
237*77c1e3ccSAndroid Build Coastguard Worker const int pic_width = picture->y_crop_width;
238*77c1e3ccSAndroid Build Coastguard Worker const int x_end = picture->y_crop_width - block_size + 1;
239*77c1e3ccSAndroid Build Coastguard Worker const int y_end = picture->y_crop_height - block_size + 1;
240*77c1e3ccSAndroid Build Coastguard Worker
241*77c1e3ccSAndroid Build Coastguard Worker const int src_size = block_size >> 1;
242*77c1e3ccSAndroid Build Coastguard Worker const int quad_size = block_size >> 2;
243*77c1e3ccSAndroid Build Coastguard Worker
244*77c1e3ccSAndroid Build Coastguard Worker uint32_t p[4];
245*77c1e3ccSAndroid Build Coastguard Worker const int length = sizeof(p);
246*77c1e3ccSAndroid Build Coastguard Worker
247*77c1e3ccSAndroid Build Coastguard Worker int pos = 0;
248*77c1e3ccSAndroid Build Coastguard Worker for (int y_pos = 0; y_pos < y_end; y_pos++) {
249*77c1e3ccSAndroid Build Coastguard Worker for (int x_pos = 0; x_pos < x_end; x_pos++) {
250*77c1e3ccSAndroid Build Coastguard Worker p[0] = src_pic_block_hash[0][pos];
251*77c1e3ccSAndroid Build Coastguard Worker p[1] = src_pic_block_hash[0][pos + src_size];
252*77c1e3ccSAndroid Build Coastguard Worker p[2] = src_pic_block_hash[0][pos + src_size * pic_width];
253*77c1e3ccSAndroid Build Coastguard Worker p[3] = src_pic_block_hash[0][pos + src_size * pic_width + src_size];
254*77c1e3ccSAndroid Build Coastguard Worker dst_pic_block_hash[0][pos] =
255*77c1e3ccSAndroid Build Coastguard Worker av1_get_crc_value(calc_1, (uint8_t *)p, length);
256*77c1e3ccSAndroid Build Coastguard Worker
257*77c1e3ccSAndroid Build Coastguard Worker p[0] = src_pic_block_hash[1][pos];
258*77c1e3ccSAndroid Build Coastguard Worker p[1] = src_pic_block_hash[1][pos + src_size];
259*77c1e3ccSAndroid Build Coastguard Worker p[2] = src_pic_block_hash[1][pos + src_size * pic_width];
260*77c1e3ccSAndroid Build Coastguard Worker p[3] = src_pic_block_hash[1][pos + src_size * pic_width + src_size];
261*77c1e3ccSAndroid Build Coastguard Worker dst_pic_block_hash[1][pos] =
262*77c1e3ccSAndroid Build Coastguard Worker av1_get_crc_value(calc_2, (uint8_t *)p, length);
263*77c1e3ccSAndroid Build Coastguard Worker
264*77c1e3ccSAndroid Build Coastguard Worker dst_pic_block_same_info[0][pos] =
265*77c1e3ccSAndroid Build Coastguard Worker src_pic_block_same_info[0][pos] &&
266*77c1e3ccSAndroid Build Coastguard Worker src_pic_block_same_info[0][pos + quad_size] &&
267*77c1e3ccSAndroid Build Coastguard Worker src_pic_block_same_info[0][pos + src_size] &&
268*77c1e3ccSAndroid Build Coastguard Worker src_pic_block_same_info[0][pos + src_size * pic_width] &&
269*77c1e3ccSAndroid Build Coastguard Worker src_pic_block_same_info[0][pos + src_size * pic_width + quad_size] &&
270*77c1e3ccSAndroid Build Coastguard Worker src_pic_block_same_info[0][pos + src_size * pic_width + src_size];
271*77c1e3ccSAndroid Build Coastguard Worker
272*77c1e3ccSAndroid Build Coastguard Worker dst_pic_block_same_info[1][pos] =
273*77c1e3ccSAndroid Build Coastguard Worker src_pic_block_same_info[1][pos] &&
274*77c1e3ccSAndroid Build Coastguard Worker src_pic_block_same_info[1][pos + src_size] &&
275*77c1e3ccSAndroid Build Coastguard Worker src_pic_block_same_info[1][pos + quad_size * pic_width] &&
276*77c1e3ccSAndroid Build Coastguard Worker src_pic_block_same_info[1][pos + quad_size * pic_width + src_size] &&
277*77c1e3ccSAndroid Build Coastguard Worker src_pic_block_same_info[1][pos + src_size * pic_width] &&
278*77c1e3ccSAndroid Build Coastguard Worker src_pic_block_same_info[1][pos + src_size * pic_width + src_size];
279*77c1e3ccSAndroid Build Coastguard Worker pos++;
280*77c1e3ccSAndroid Build Coastguard Worker }
281*77c1e3ccSAndroid Build Coastguard Worker pos += block_size - 1;
282*77c1e3ccSAndroid Build Coastguard Worker }
283*77c1e3ccSAndroid Build Coastguard Worker
284*77c1e3ccSAndroid Build Coastguard Worker if (block_size >= 4) {
285*77c1e3ccSAndroid Build Coastguard Worker const int size_minus_1 = block_size - 1;
286*77c1e3ccSAndroid Build Coastguard Worker pos = 0;
287*77c1e3ccSAndroid Build Coastguard Worker for (int y_pos = 0; y_pos < y_end; y_pos++) {
288*77c1e3ccSAndroid Build Coastguard Worker for (int x_pos = 0; x_pos < x_end; x_pos++) {
289*77c1e3ccSAndroid Build Coastguard Worker dst_pic_block_same_info[2][pos] =
290*77c1e3ccSAndroid Build Coastguard Worker (!dst_pic_block_same_info[0][pos] &&
291*77c1e3ccSAndroid Build Coastguard Worker !dst_pic_block_same_info[1][pos]) ||
292*77c1e3ccSAndroid Build Coastguard Worker (((x_pos & size_minus_1) == 0) && ((y_pos & size_minus_1) == 0));
293*77c1e3ccSAndroid Build Coastguard Worker pos++;
294*77c1e3ccSAndroid Build Coastguard Worker }
295*77c1e3ccSAndroid Build Coastguard Worker pos += block_size - 1;
296*77c1e3ccSAndroid Build Coastguard Worker }
297*77c1e3ccSAndroid Build Coastguard Worker }
298*77c1e3ccSAndroid Build Coastguard Worker }
299*77c1e3ccSAndroid Build Coastguard Worker
av1_add_to_hash_map_by_row_with_precal_data(hash_table * p_hash_table,uint32_t * pic_hash[2],int8_t * pic_is_same,int pic_width,int pic_height,int block_size)300*77c1e3ccSAndroid Build Coastguard Worker bool av1_add_to_hash_map_by_row_with_precal_data(hash_table *p_hash_table,
301*77c1e3ccSAndroid Build Coastguard Worker uint32_t *pic_hash[2],
302*77c1e3ccSAndroid Build Coastguard Worker int8_t *pic_is_same,
303*77c1e3ccSAndroid Build Coastguard Worker int pic_width, int pic_height,
304*77c1e3ccSAndroid Build Coastguard Worker int block_size) {
305*77c1e3ccSAndroid Build Coastguard Worker const int x_end = pic_width - block_size + 1;
306*77c1e3ccSAndroid Build Coastguard Worker const int y_end = pic_height - block_size + 1;
307*77c1e3ccSAndroid Build Coastguard Worker
308*77c1e3ccSAndroid Build Coastguard Worker const int8_t *src_is_added = pic_is_same;
309*77c1e3ccSAndroid Build Coastguard Worker const uint32_t *src_hash[2] = { pic_hash[0], pic_hash[1] };
310*77c1e3ccSAndroid Build Coastguard Worker
311*77c1e3ccSAndroid Build Coastguard Worker int add_value = hash_block_size_to_index(block_size);
312*77c1e3ccSAndroid Build Coastguard Worker assert(add_value >= 0);
313*77c1e3ccSAndroid Build Coastguard Worker add_value <<= kSrcBits;
314*77c1e3ccSAndroid Build Coastguard Worker const int crc_mask = (1 << kSrcBits) - 1;
315*77c1e3ccSAndroid Build Coastguard Worker
316*77c1e3ccSAndroid Build Coastguard Worker for (int x_pos = 0; x_pos < x_end; x_pos++) {
317*77c1e3ccSAndroid Build Coastguard Worker for (int y_pos = 0; y_pos < y_end; y_pos++) {
318*77c1e3ccSAndroid Build Coastguard Worker const int pos = y_pos * pic_width + x_pos;
319*77c1e3ccSAndroid Build Coastguard Worker // valid data
320*77c1e3ccSAndroid Build Coastguard Worker if (src_is_added[pos]) {
321*77c1e3ccSAndroid Build Coastguard Worker block_hash curr_block_hash;
322*77c1e3ccSAndroid Build Coastguard Worker curr_block_hash.x = x_pos;
323*77c1e3ccSAndroid Build Coastguard Worker curr_block_hash.y = y_pos;
324*77c1e3ccSAndroid Build Coastguard Worker
325*77c1e3ccSAndroid Build Coastguard Worker const uint32_t hash_value1 = (src_hash[0][pos] & crc_mask) + add_value;
326*77c1e3ccSAndroid Build Coastguard Worker curr_block_hash.hash_value2 = src_hash[1][pos];
327*77c1e3ccSAndroid Build Coastguard Worker
328*77c1e3ccSAndroid Build Coastguard Worker if (!hash_table_add_to_table(p_hash_table, hash_value1,
329*77c1e3ccSAndroid Build Coastguard Worker &curr_block_hash)) {
330*77c1e3ccSAndroid Build Coastguard Worker return false;
331*77c1e3ccSAndroid Build Coastguard Worker }
332*77c1e3ccSAndroid Build Coastguard Worker }
333*77c1e3ccSAndroid Build Coastguard Worker }
334*77c1e3ccSAndroid Build Coastguard Worker }
335*77c1e3ccSAndroid Build Coastguard Worker return true;
336*77c1e3ccSAndroid Build Coastguard Worker }
337*77c1e3ccSAndroid Build Coastguard Worker
av1_hash_is_horizontal_perfect(const YV12_BUFFER_CONFIG * picture,int block_size,int x_start,int y_start)338*77c1e3ccSAndroid Build Coastguard Worker int av1_hash_is_horizontal_perfect(const YV12_BUFFER_CONFIG *picture,
339*77c1e3ccSAndroid Build Coastguard Worker int block_size, int x_start, int y_start) {
340*77c1e3ccSAndroid Build Coastguard Worker const int stride = picture->y_stride;
341*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *p = picture->y_buffer + y_start * stride + x_start;
342*77c1e3ccSAndroid Build Coastguard Worker
343*77c1e3ccSAndroid Build Coastguard Worker if (picture->flags & YV12_FLAG_HIGHBITDEPTH) {
344*77c1e3ccSAndroid Build Coastguard Worker const uint16_t *p16 = CONVERT_TO_SHORTPTR(p);
345*77c1e3ccSAndroid Build Coastguard Worker for (int i = 0; i < block_size; i++) {
346*77c1e3ccSAndroid Build Coastguard Worker for (int j = 1; j < block_size; j++) {
347*77c1e3ccSAndroid Build Coastguard Worker if (p16[j] != p16[0]) {
348*77c1e3ccSAndroid Build Coastguard Worker return 0;
349*77c1e3ccSAndroid Build Coastguard Worker }
350*77c1e3ccSAndroid Build Coastguard Worker }
351*77c1e3ccSAndroid Build Coastguard Worker p16 += stride;
352*77c1e3ccSAndroid Build Coastguard Worker }
353*77c1e3ccSAndroid Build Coastguard Worker } else {
354*77c1e3ccSAndroid Build Coastguard Worker for (int i = 0; i < block_size; i++) {
355*77c1e3ccSAndroid Build Coastguard Worker for (int j = 1; j < block_size; j++) {
356*77c1e3ccSAndroid Build Coastguard Worker if (p[j] != p[0]) {
357*77c1e3ccSAndroid Build Coastguard Worker return 0;
358*77c1e3ccSAndroid Build Coastguard Worker }
359*77c1e3ccSAndroid Build Coastguard Worker }
360*77c1e3ccSAndroid Build Coastguard Worker p += stride;
361*77c1e3ccSAndroid Build Coastguard Worker }
362*77c1e3ccSAndroid Build Coastguard Worker }
363*77c1e3ccSAndroid Build Coastguard Worker
364*77c1e3ccSAndroid Build Coastguard Worker return 1;
365*77c1e3ccSAndroid Build Coastguard Worker }
366*77c1e3ccSAndroid Build Coastguard Worker
av1_hash_is_vertical_perfect(const YV12_BUFFER_CONFIG * picture,int block_size,int x_start,int y_start)367*77c1e3ccSAndroid Build Coastguard Worker int av1_hash_is_vertical_perfect(const YV12_BUFFER_CONFIG *picture,
368*77c1e3ccSAndroid Build Coastguard Worker int block_size, int x_start, int y_start) {
369*77c1e3ccSAndroid Build Coastguard Worker const int stride = picture->y_stride;
370*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *p = picture->y_buffer + y_start * stride + x_start;
371*77c1e3ccSAndroid Build Coastguard Worker
372*77c1e3ccSAndroid Build Coastguard Worker if (picture->flags & YV12_FLAG_HIGHBITDEPTH) {
373*77c1e3ccSAndroid Build Coastguard Worker const uint16_t *p16 = CONVERT_TO_SHORTPTR(p);
374*77c1e3ccSAndroid Build Coastguard Worker for (int i = 0; i < block_size; i++) {
375*77c1e3ccSAndroid Build Coastguard Worker for (int j = 1; j < block_size; j++) {
376*77c1e3ccSAndroid Build Coastguard Worker if (p16[j * stride + i] != p16[i]) {
377*77c1e3ccSAndroid Build Coastguard Worker return 0;
378*77c1e3ccSAndroid Build Coastguard Worker }
379*77c1e3ccSAndroid Build Coastguard Worker }
380*77c1e3ccSAndroid Build Coastguard Worker }
381*77c1e3ccSAndroid Build Coastguard Worker } else {
382*77c1e3ccSAndroid Build Coastguard Worker for (int i = 0; i < block_size; i++) {
383*77c1e3ccSAndroid Build Coastguard Worker for (int j = 1; j < block_size; j++) {
384*77c1e3ccSAndroid Build Coastguard Worker if (p[j * stride + i] != p[i]) {
385*77c1e3ccSAndroid Build Coastguard Worker return 0;
386*77c1e3ccSAndroid Build Coastguard Worker }
387*77c1e3ccSAndroid Build Coastguard Worker }
388*77c1e3ccSAndroid Build Coastguard Worker }
389*77c1e3ccSAndroid Build Coastguard Worker }
390*77c1e3ccSAndroid Build Coastguard Worker return 1;
391*77c1e3ccSAndroid Build Coastguard Worker }
392*77c1e3ccSAndroid Build Coastguard Worker
av1_get_block_hash_value(IntraBCHashInfo * intrabc_hash_info,const uint8_t * y_src,int stride,int block_size,uint32_t * hash_value1,uint32_t * hash_value2,int use_highbitdepth)393*77c1e3ccSAndroid Build Coastguard Worker void av1_get_block_hash_value(IntraBCHashInfo *intrabc_hash_info,
394*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *y_src, int stride, int block_size,
395*77c1e3ccSAndroid Build Coastguard Worker uint32_t *hash_value1, uint32_t *hash_value2,
396*77c1e3ccSAndroid Build Coastguard Worker int use_highbitdepth) {
397*77c1e3ccSAndroid Build Coastguard Worker int add_value = hash_block_size_to_index(block_size);
398*77c1e3ccSAndroid Build Coastguard Worker assert(add_value >= 0);
399*77c1e3ccSAndroid Build Coastguard Worker add_value <<= kSrcBits;
400*77c1e3ccSAndroid Build Coastguard Worker const int crc_mask = (1 << kSrcBits) - 1;
401*77c1e3ccSAndroid Build Coastguard Worker
402*77c1e3ccSAndroid Build Coastguard Worker CRC_CALCULATOR *calc_1 = &intrabc_hash_info->crc_calculator1;
403*77c1e3ccSAndroid Build Coastguard Worker CRC_CALCULATOR *calc_2 = &intrabc_hash_info->crc_calculator2;
404*77c1e3ccSAndroid Build Coastguard Worker uint32_t **buf_1 = intrabc_hash_info->hash_value_buffer[0];
405*77c1e3ccSAndroid Build Coastguard Worker uint32_t **buf_2 = intrabc_hash_info->hash_value_buffer[1];
406*77c1e3ccSAndroid Build Coastguard Worker
407*77c1e3ccSAndroid Build Coastguard Worker // 2x2 subblock hash values in current CU
408*77c1e3ccSAndroid Build Coastguard Worker int sub_block_in_width = (block_size >> 1);
409*77c1e3ccSAndroid Build Coastguard Worker if (use_highbitdepth) {
410*77c1e3ccSAndroid Build Coastguard Worker uint16_t pixel_to_hash[4];
411*77c1e3ccSAndroid Build Coastguard Worker uint16_t *y16_src = CONVERT_TO_SHORTPTR(y_src);
412*77c1e3ccSAndroid Build Coastguard Worker for (int y_pos = 0; y_pos < block_size; y_pos += 2) {
413*77c1e3ccSAndroid Build Coastguard Worker for (int x_pos = 0; x_pos < block_size; x_pos += 2) {
414*77c1e3ccSAndroid Build Coastguard Worker int pos = (y_pos >> 1) * sub_block_in_width + (x_pos >> 1);
415*77c1e3ccSAndroid Build Coastguard Worker get_pixels_in_1D_short_array_by_block_2x2(
416*77c1e3ccSAndroid Build Coastguard Worker y16_src + y_pos * stride + x_pos, stride, pixel_to_hash);
417*77c1e3ccSAndroid Build Coastguard Worker assert(pos < AOM_BUFFER_SIZE_FOR_BLOCK_HASH);
418*77c1e3ccSAndroid Build Coastguard Worker buf_1[0][pos] = av1_get_crc_value(calc_1, (uint8_t *)pixel_to_hash,
419*77c1e3ccSAndroid Build Coastguard Worker sizeof(pixel_to_hash));
420*77c1e3ccSAndroid Build Coastguard Worker buf_2[0][pos] = av1_get_crc_value(calc_2, (uint8_t *)pixel_to_hash,
421*77c1e3ccSAndroid Build Coastguard Worker sizeof(pixel_to_hash));
422*77c1e3ccSAndroid Build Coastguard Worker }
423*77c1e3ccSAndroid Build Coastguard Worker }
424*77c1e3ccSAndroid Build Coastguard Worker } else {
425*77c1e3ccSAndroid Build Coastguard Worker uint8_t pixel_to_hash[4];
426*77c1e3ccSAndroid Build Coastguard Worker for (int y_pos = 0; y_pos < block_size; y_pos += 2) {
427*77c1e3ccSAndroid Build Coastguard Worker for (int x_pos = 0; x_pos < block_size; x_pos += 2) {
428*77c1e3ccSAndroid Build Coastguard Worker int pos = (y_pos >> 1) * sub_block_in_width + (x_pos >> 1);
429*77c1e3ccSAndroid Build Coastguard Worker get_pixels_in_1D_char_array_by_block_2x2(y_src + y_pos * stride + x_pos,
430*77c1e3ccSAndroid Build Coastguard Worker stride, pixel_to_hash);
431*77c1e3ccSAndroid Build Coastguard Worker assert(pos < AOM_BUFFER_SIZE_FOR_BLOCK_HASH);
432*77c1e3ccSAndroid Build Coastguard Worker buf_1[0][pos] =
433*77c1e3ccSAndroid Build Coastguard Worker av1_get_crc_value(calc_1, pixel_to_hash, sizeof(pixel_to_hash));
434*77c1e3ccSAndroid Build Coastguard Worker buf_2[0][pos] =
435*77c1e3ccSAndroid Build Coastguard Worker av1_get_crc_value(calc_2, pixel_to_hash, sizeof(pixel_to_hash));
436*77c1e3ccSAndroid Build Coastguard Worker }
437*77c1e3ccSAndroid Build Coastguard Worker }
438*77c1e3ccSAndroid Build Coastguard Worker }
439*77c1e3ccSAndroid Build Coastguard Worker
440*77c1e3ccSAndroid Build Coastguard Worker int src_sub_block_in_width = sub_block_in_width;
441*77c1e3ccSAndroid Build Coastguard Worker sub_block_in_width >>= 1;
442*77c1e3ccSAndroid Build Coastguard Worker
443*77c1e3ccSAndroid Build Coastguard Worker int src_idx = 1;
444*77c1e3ccSAndroid Build Coastguard Worker int dst_idx = 0;
445*77c1e3ccSAndroid Build Coastguard Worker
446*77c1e3ccSAndroid Build Coastguard Worker // 4x4 subblock hash values to current block hash values
447*77c1e3ccSAndroid Build Coastguard Worker uint32_t to_hash[4];
448*77c1e3ccSAndroid Build Coastguard Worker for (int sub_width = 4; sub_width <= block_size; sub_width *= 2) {
449*77c1e3ccSAndroid Build Coastguard Worker src_idx = 1 - src_idx;
450*77c1e3ccSAndroid Build Coastguard Worker dst_idx = 1 - dst_idx;
451*77c1e3ccSAndroid Build Coastguard Worker
452*77c1e3ccSAndroid Build Coastguard Worker int dst_pos = 0;
453*77c1e3ccSAndroid Build Coastguard Worker for (int y_pos = 0; y_pos < sub_block_in_width; y_pos++) {
454*77c1e3ccSAndroid Build Coastguard Worker for (int x_pos = 0; x_pos < sub_block_in_width; x_pos++) {
455*77c1e3ccSAndroid Build Coastguard Worker int srcPos = (y_pos << 1) * src_sub_block_in_width + (x_pos << 1);
456*77c1e3ccSAndroid Build Coastguard Worker
457*77c1e3ccSAndroid Build Coastguard Worker assert(srcPos + 1 < AOM_BUFFER_SIZE_FOR_BLOCK_HASH);
458*77c1e3ccSAndroid Build Coastguard Worker assert(srcPos + src_sub_block_in_width + 1 <
459*77c1e3ccSAndroid Build Coastguard Worker AOM_BUFFER_SIZE_FOR_BLOCK_HASH);
460*77c1e3ccSAndroid Build Coastguard Worker assert(dst_pos < AOM_BUFFER_SIZE_FOR_BLOCK_HASH);
461*77c1e3ccSAndroid Build Coastguard Worker to_hash[0] = buf_1[src_idx][srcPos];
462*77c1e3ccSAndroid Build Coastguard Worker to_hash[1] = buf_1[src_idx][srcPos + 1];
463*77c1e3ccSAndroid Build Coastguard Worker to_hash[2] = buf_1[src_idx][srcPos + src_sub_block_in_width];
464*77c1e3ccSAndroid Build Coastguard Worker to_hash[3] = buf_1[src_idx][srcPos + src_sub_block_in_width + 1];
465*77c1e3ccSAndroid Build Coastguard Worker
466*77c1e3ccSAndroid Build Coastguard Worker buf_1[dst_idx][dst_pos] =
467*77c1e3ccSAndroid Build Coastguard Worker av1_get_crc_value(calc_1, (uint8_t *)to_hash, sizeof(to_hash));
468*77c1e3ccSAndroid Build Coastguard Worker
469*77c1e3ccSAndroid Build Coastguard Worker to_hash[0] = buf_2[src_idx][srcPos];
470*77c1e3ccSAndroid Build Coastguard Worker to_hash[1] = buf_2[src_idx][srcPos + 1];
471*77c1e3ccSAndroid Build Coastguard Worker to_hash[2] = buf_2[src_idx][srcPos + src_sub_block_in_width];
472*77c1e3ccSAndroid Build Coastguard Worker to_hash[3] = buf_2[src_idx][srcPos + src_sub_block_in_width + 1];
473*77c1e3ccSAndroid Build Coastguard Worker buf_2[dst_idx][dst_pos] =
474*77c1e3ccSAndroid Build Coastguard Worker av1_get_crc_value(calc_2, (uint8_t *)to_hash, sizeof(to_hash));
475*77c1e3ccSAndroid Build Coastguard Worker dst_pos++;
476*77c1e3ccSAndroid Build Coastguard Worker }
477*77c1e3ccSAndroid Build Coastguard Worker }
478*77c1e3ccSAndroid Build Coastguard Worker
479*77c1e3ccSAndroid Build Coastguard Worker src_sub_block_in_width = sub_block_in_width;
480*77c1e3ccSAndroid Build Coastguard Worker sub_block_in_width >>= 1;
481*77c1e3ccSAndroid Build Coastguard Worker }
482*77c1e3ccSAndroid Build Coastguard Worker
483*77c1e3ccSAndroid Build Coastguard Worker *hash_value1 = (buf_1[dst_idx][0] & crc_mask) + add_value;
484*77c1e3ccSAndroid Build Coastguard Worker *hash_value2 = buf_2[dst_idx][0];
485*77c1e3ccSAndroid Build Coastguard Worker }
486