blob: 1c2af68abc0367951bcca6aaab8f93ac993cf778 [file]
/*
* Copyright (c) 2016, Alliance for Open Media. All rights reserved.
*
* This source code is subject to the terms of the BSD 2 Clause License and
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
* was not distributed with this source code in the LICENSE file, you can
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
* Media Patent License 1.0 was not distributed with this source code in the
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
*/
#ifndef AOM_AV1_ENCODER_HASH_MOTION_H_
#define AOM_AV1_ENCODER_HASH_MOTION_H_
#include <stdbool.h>
#include "aom/aom_integer.h"
#include "aom_scale/yv12config.h"
#include "av1/encoder/hash.h"
#ifdef __cplusplus
extern "C" {
#endif
// Block size used for force_integer_mv decisions
#define FORCE_INT_MV_DECISION_BLOCK_SIZE 8
// store a block's hash info.
// x and y are the position from the top left of the picture
// hash_value2 is used to store the second hash value
typedef struct _block_hash {
int16_t x;
int16_t y;
uint32_t hash_value2;
} block_hash;
// The rectangle of the frame, in luma pixels, that a hash table takes its
// blocks from. The end values are exclusive.
typedef struct {
int x_start;
int y_start;
int x_end;
int y_end;
} IntraBCHashRegion;
// The most tables built for a frame, to keep the memory down. Frames with more
// tiles than this let neighboring tiles share a table.
#define MAX_INTRABC_HASH_TABLES 16
// A table keeps its buffers from frame to frame. cpi->td.mb owns it and frees
// it with the encoder. The encoder threads build the tables before the tiles
// are encoded, one table at a time per thread. After that they only read them
// through the tile_tables pointer in their own MACROBLOCK, so a table must not
// change while the tiles are encoded.
typedef struct _hash_table {
// For each block size from 4x4 to 128x128, the number of entries in each
// bucket and the index of the first one. Each array has 1 << 16 elements,
// one for each bucket. NULL for the sizes not built.
uint16_t *bucket_count[6];
uint32_t *bucket_start[6];
// The entries of each block size, stored bucket after bucket, and how many
// entries each array has room for.
block_hash *block_hashes[6];
uint32_t block_hashes_size[6];
} hash_table;
struct intrabc_hash_info;
typedef struct intrabc_hash_info {
// buffer for hash value calculation of a block
// used only in av1_get_block_hash_value()
// [two buffers used ping-pong]
// buffers are AOM_BUFFER_SIZE_FOR_BLOCK_HASH elements long
uint32_t *hash_value_buffer[2];
// The tables in raster order, table_cols x table_rows of them. Each one
// covers a rectangle of tile_cols_per_table x tile_rows_per_table tiles.
// Every tile has its own table unless the frame has more than
// MAX_INTRABC_HASH_TABLES tiles.
hash_table *tile_tables;
int num_tile_tables;
int table_cols;
int table_rows;
int tile_cols_per_table;
int tile_rows_per_table;
// Hash values of every position of the frame, only needed while the tables
// are built. The first buffer holds the 8x8 hashes. The second one holds the
// 4x4 hashes when the 4x4 table is built, and the two are used alternately
// for the sizes above 8x8. It is NULL when neither is needed. Both cover
// the luma size of the source frame they were allocated for,
// frame_hash_width x frame_hash_height. Both sizes are 0 when the buffers
// are freed.
uint32_t *frame_hash_buffer[2];
int frame_hash_width;
int frame_hash_height;
CRC32C crc_calculator;
int crc_initialized;
} IntraBCHashInfo;
// Returns the index of the table that covers the given tile.
static inline int av1_intrabc_hash_table_idx(
const IntraBCHashInfo *intra_bc_hash_info, int tile_row, int tile_col) {
return tile_row / intra_bc_hash_info->tile_rows_per_table *
intra_bc_hash_info->table_cols +
tile_col / intra_bc_hash_info->tile_cols_per_table;
}
void av1_hash_table_init(IntraBCHashInfo *intra_bc_hash_info);
// Makes num_tables empty tables. Their buffers are kept for the next frame
// while the number of tables stays the same.
bool av1_hash_tables_create(IntraBCHashInfo *intra_bc_hash_info,
int num_tables);
// Frees the tables and the frame hash buffers.
void av1_hash_tables_destroy(IntraBCHashInfo *intra_bc_hash_info);
int32_t av1_hash_table_count(const hash_table *p_hash_table,
uint32_t hash_value);
// Returns the first of the av1_hash_table_count() entries for hash_value.
const block_hash *av1_hash_get_first_block_hash(const hash_table *p_hash_table,
uint32_t hash_value);
// These fill the hash values of the blocks that lie inside region. The stride
// parameters give the distance in values between rows of the hash buffers.
// av1_generate_block_8x8_hash_value() hashes the picture into hash_8x8, and
// into hash_4x4 too unless it is NULL. It returns false if it runs out of
// memory.
bool av1_generate_block_8x8_hash_value(IntraBCHashInfo *intrabc_hash_info,
const YV12_BUFFER_CONFIG *picture,
const IntraBCHashRegion *region,
uint32_t *hash_4x4, uint32_t *hash_8x8,
int pic_block_hash_stride);
// Hashes block_size blocks from the block_size / 2 hashes in src.
void av1_generate_block_hash_value(IntraBCHashInfo *intra_bc_hash_info,
const IntraBCHashRegion *region,
int block_size,
const uint32_t *src_pic_block_hash,
uint32_t *dst_pic_block_hash,
int pic_block_hash_stride);
bool av1_add_to_hash_map_by_row_with_precal_data(
hash_table *p_hash_table, const uint32_t *pic_hash, int pic_hash_stride,
const IntraBCHashRegion *region, int block_size);
// check whether the block starts from (x_start, y_start) with the size of
// block_size x block_size has the same color in all rows
int av1_hash_is_horizontal_perfect(const YV12_BUFFER_CONFIG *picture,
int block_size, int x_start, int y_start);
// check whether the block starts from (x_start, y_start) with the size of
// block_size x block_size has the same color in all columns
int av1_hash_is_vertical_perfect(const YV12_BUFFER_CONFIG *picture,
int block_size, int x_start, int y_start);
void av1_get_block_hash_value(IntraBCHashInfo *intra_bc_hash_info,
const uint8_t *y_src, int stride, int block_size,
uint32_t *hash_value1, uint32_t *hash_value2,
int use_highbitdepth);
#ifdef __cplusplus
} // extern "C"
#endif
#endif // AOM_AV1_ENCODER_HASH_MOTION_H_