mirror of
https://github.com/ultravideo/uvg266.git
synced 2024-12-17 19:04:05 +00:00
[ibc] Implement CRC for 8x8 block and generate a full hashmap at the frame load
This commit is contained in:
parent
4b1f5ca7e2
commit
76d66591c5
|
@ -45,17 +45,20 @@
|
||||||
#include "encode_coding_tree.h"
|
#include "encode_coding_tree.h"
|
||||||
#include "encoder_state-bitstream.h"
|
#include "encoder_state-bitstream.h"
|
||||||
#include "filter.h"
|
#include "filter.h"
|
||||||
|
#include "hashmap.h"
|
||||||
#include "image.h"
|
#include "image.h"
|
||||||
#include "rate_control.h"
|
#include "rate_control.h"
|
||||||
#include "sao.h"
|
#include "sao.h"
|
||||||
#include "search.h"
|
#include "search.h"
|
||||||
#include "tables.h"
|
#include "tables.h"
|
||||||
|
#include "threads.h"
|
||||||
#include "threadqueue.h"
|
#include "threadqueue.h"
|
||||||
#include "alf.h"
|
#include "alf.h"
|
||||||
#include "reshape.h"
|
#include "reshape.h"
|
||||||
|
|
||||||
#include "strategies/strategies-picture.h"
|
#include "strategies/strategies-picture.h"
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Strength of QP adjustments when using adaptive QP for 360 video.
|
* \brief Strength of QP adjustments when using adaptive QP for 360 video.
|
||||||
*
|
*
|
||||||
|
@ -1936,6 +1939,36 @@ static void encoder_state_init_new_frame(encoder_state_t * const state, uvg_pict
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (state->encoder_control->cfg.ibc != 0) {
|
||||||
|
int items = 0;
|
||||||
|
UVG_CLOCK_T hashmap_start_real_time;
|
||||||
|
UVG_CLOCK_T hashmap_end_real_time;
|
||||||
|
UVG_GET_TIME(&hashmap_start_real_time);
|
||||||
|
// Create a new hashmap with UVG_HASHMAP_RATIO buckets per 4x4 block
|
||||||
|
state->tile->frame->ibc_hashmap = uvg_hashmap_create(
|
||||||
|
(int)(((float)(state->tile->frame->width * state->tile->frame->height) /
|
||||||
|
(float)(UVG_HASHMAP_BLOCKSIZE * UVG_HASHMAP_BLOCKSIZE)) * UVG_HASHMAP_RATIO));
|
||||||
|
|
||||||
|
// Fill the hashmap with the current frame's block information
|
||||||
|
for (int y = 0; y < state->tile->frame->height; y += 1) {
|
||||||
|
for (int x = 0; x < state->tile->frame->width; x += 1) {
|
||||||
|
uint32_t crc = uvg_crc32c_8x8(state->tile->frame->source->y + y * state->tile->frame->width + x, state->tile->frame->width);
|
||||||
|
|
||||||
|
//uint32_t found = uvg_hashmap_search_return_first(state->tile->frame->ibc_hashmap, crc);
|
||||||
|
//uvg_hashmap_node_t* found = uvg_hashmap_search(state->tile->frame->ibc_hashmap, crc);
|
||||||
|
|
||||||
|
//if (found != NULL) uvg_hashmap_node_free(found);
|
||||||
|
|
||||||
|
uvg_hashmap_insert(state->tile->frame->ibc_hashmap, crc, ((x&0xffff)<<16) | (y&0xffff));
|
||||||
|
items++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UVG_GET_TIME(&hashmap_end_real_time);
|
||||||
|
double wall_time = UVG_CLOCK_T_AS_DOUBLE(hashmap_end_real_time) -
|
||||||
|
UVG_CLOCK_T_AS_DOUBLE(hashmap_start_real_time);
|
||||||
|
fprintf(stderr, "Hashmap creation time: %f, items: %d, size %d\n", wall_time, items, state->tile->frame->ibc_hashmap->bucket_size);
|
||||||
|
}
|
||||||
|
|
||||||
if (state->encoder_control->cfg.lmcs_enable) {
|
if (state->encoder_control->cfg.lmcs_enable) {
|
||||||
uvg_init_lmcs_aps(state->tile->frame->lmcs_aps, state->encoder_control->cfg.width, state->encoder_control->cfg.height, LCU_CU_WIDTH, LCU_CU_WIDTH, state->encoder_control->bitdepth);
|
uvg_init_lmcs_aps(state->tile->frame->lmcs_aps, state->encoder_control->cfg.width, state->encoder_control->cfg.height, LCU_CU_WIDTH, LCU_CU_WIDTH, state->encoder_control->bitdepth);
|
||||||
|
|
||||||
|
|
|
@ -72,9 +72,11 @@ uvg_hashmap_t* uvg_hashmap_create(uint32_t bucket_size)
|
||||||
* \param bucket_size the size of the hashmap bucket
|
* \param bucket_size the size of the hashmap bucket
|
||||||
* \return the hashed index for the given key and bucket size.
|
* \return the hashed index for the given key and bucket size.
|
||||||
*/
|
*/
|
||||||
uint32_t uvg_hashmap_hash(uint32_t key, uint32_t bucket_size) {
|
static uint32_t uvg_hashmap_hash(uint32_t key, uint32_t bucket_size)
|
||||||
|
{
|
||||||
key ^= (key >> 20) ^ (key >> 12);
|
key ^= (key >> 20) ^ (key >> 12);
|
||||||
return (key ^ (key >> 7) ^ (key >> 4) ^ 2654435769U) % bucket_size;
|
return (key ^ (key >> 7) ^ (key >> 4) ^ 2654435769U) % bucket_size;
|
||||||
|
//return key % bucket_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -99,21 +101,22 @@ void uvg_hashmap_insert(uvg_hashmap_t* map, uint32_t key, uint32_t value) {
|
||||||
* \return uvg_hashmap_node the node with the given key, NULL if not found.
|
* \return uvg_hashmap_node the node with the given key, NULL if not found.
|
||||||
*/
|
*/
|
||||||
uvg_hashmap_node_t* uvg_hashmap_search(uvg_hashmap_t* map, uint32_t key) {
|
uvg_hashmap_node_t* uvg_hashmap_search(uvg_hashmap_t* map, uint32_t key) {
|
||||||
|
uint32_t hashIndex = uvg_hashmap_hash(key, map->bucket_size);
|
||||||
|
return map->table[hashIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t uvg_hashmap_search_return_first(uvg_hashmap_t* map, uint32_t key)
|
||||||
|
{
|
||||||
uint32_t hashIndex = uvg_hashmap_hash(key, map->bucket_size);
|
uint32_t hashIndex = uvg_hashmap_hash(key, map->bucket_size);
|
||||||
uvg_hashmap_node_t* temp = map->table[hashIndex];
|
uvg_hashmap_node_t* temp = map->table[hashIndex];
|
||||||
uvg_hashmap_node_t* return_node = NULL;
|
// Search key in chain and return the first match
|
||||||
// Search key in chain and return all of them
|
|
||||||
while (temp) {
|
while (temp) {
|
||||||
if (temp->key == key) {
|
if (temp->key == key) {
|
||||||
uvg_hashmap_node_t* new_node = uvg_hashmap_create_node(key, temp->value);
|
return temp->value;
|
||||||
if (return_node != NULL) {
|
|
||||||
new_node->next = (void*)return_node;
|
|
||||||
}
|
|
||||||
return_node = new_node;
|
|
||||||
}
|
}
|
||||||
temp = (uvg_hashmap_node_t*)temp->next;
|
temp = (uvg_hashmap_node_t*)temp->next;
|
||||||
}
|
}
|
||||||
return return_node;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -37,9 +37,9 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
// The ratio of the hashmap bucket size to the maximum number of elements
|
// The ratio of the hashmap bucket size to the maximum number of elements
|
||||||
#define UVG_HASHMAP_RATIO 0.35
|
#define UVG_HASHMAP_RATIO 6.0
|
||||||
// Use Hashmap for 4x4 blocks
|
// Use Hashmap for 4x4 blocks
|
||||||
#define UVG_HASHMAP_BLOCKSIZE 4
|
#define UVG_HASHMAP_BLOCKSIZE 8
|
||||||
|
|
||||||
typedef struct uvg_hashmap_node {
|
typedef struct uvg_hashmap_node {
|
||||||
uint32_t key;
|
uint32_t key;
|
||||||
|
@ -56,12 +56,14 @@ uvg_hashmap_node_t* uvg_hashmap_create_node(uint32_t key, uint32_t value);
|
||||||
|
|
||||||
uvg_hashmap_t* uvg_hashmap_create(uint32_t bucket_size);
|
uvg_hashmap_t* uvg_hashmap_create(uint32_t bucket_size);
|
||||||
|
|
||||||
uint32_t uvg_hashmap_hash(uint32_t key, uint32_t bucket_size);
|
//uint32_t uvg_hashmap_hash(uint32_t key, uint32_t bucket_size);
|
||||||
|
|
||||||
void uvg_hashmap_insert(uvg_hashmap_t* map, uint32_t key, uint32_t value);
|
void uvg_hashmap_insert(uvg_hashmap_t* map, uint32_t key, uint32_t value);
|
||||||
|
|
||||||
uvg_hashmap_node_t* uvg_hashmap_search(uvg_hashmap_t* map, uint32_t key);
|
uvg_hashmap_node_t* uvg_hashmap_search(uvg_hashmap_t* map, uint32_t key);
|
||||||
|
|
||||||
|
uint32_t uvg_hashmap_search_return_first(uvg_hashmap_t* map, uint32_t key);
|
||||||
|
|
||||||
void uvg_hashmap_node_free(uvg_hashmap_node_t* node);
|
void uvg_hashmap_node_free(uvg_hashmap_node_t* node);
|
||||||
|
|
||||||
void uvg_hashmap_free(uvg_hashmap_t* map);
|
void uvg_hashmap_free(uvg_hashmap_t* map);
|
||||||
|
|
|
@ -802,6 +802,20 @@ INLINE static uint32_t uvg_crc32c_4_generic(uint32_t crc, const uvg_pixel *buf)
|
||||||
return crc;
|
return crc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
INLINE static uint32_t uvg_crc32c_8_generic(uint32_t crc, const uvg_pixel *buf)
|
||||||
|
{
|
||||||
|
crc = (crc >> 8) ^ uvg_crc_table[(crc ^ buf[0]) & 0xFF];
|
||||||
|
crc = (crc >> 8) ^ uvg_crc_table[(crc ^ buf[1]) & 0xFF];
|
||||||
|
crc = (crc >> 8) ^ uvg_crc_table[(crc ^ buf[2]) & 0xFF];
|
||||||
|
crc = (crc >> 8) ^ uvg_crc_table[(crc ^ buf[3]) & 0xFF];
|
||||||
|
crc = (crc >> 8) ^ uvg_crc_table[(crc ^ buf[4]) & 0xFF];
|
||||||
|
crc = (crc >> 8) ^ uvg_crc_table[(crc ^ buf[5]) & 0xFF];
|
||||||
|
crc = (crc >> 8) ^ uvg_crc_table[(crc ^ buf[6]) & 0xFF];
|
||||||
|
crc = (crc >> 8) ^ uvg_crc_table[(crc ^ buf[7]) & 0xFF];
|
||||||
|
return crc;
|
||||||
|
}
|
||||||
|
|
||||||
static uint32_t uvg_crc32c_4x4_8bit_generic(const uvg_pixel *buf, uint32_t pic_stride)
|
static uint32_t uvg_crc32c_4x4_8bit_generic(const uvg_pixel *buf, uint32_t pic_stride)
|
||||||
{
|
{
|
||||||
uint32_t crc = 0xFFFFFFFF;
|
uint32_t crc = 0xFFFFFFFF;
|
||||||
|
@ -829,11 +843,29 @@ static uint32_t uvg_crc32c_4x4_16bit_generic(const uvg_pixel *buf, uint32_t pic_
|
||||||
return crc ^ 0xFFFFFFFF;
|
return crc ^ 0xFFFFFFFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint32_t uvg_crc32c_8x8_8bit_generic(const uvg_pixel *buf, uint32_t pic_stride)
|
||||||
|
{
|
||||||
|
uint32_t crc = 0xFFFFFFFF;
|
||||||
|
crc = uvg_crc32c_8_generic(crc, &buf[0 * pic_stride]);
|
||||||
|
crc = uvg_crc32c_8_generic(crc, &buf[1 * pic_stride]);
|
||||||
|
|
||||||
|
crc = uvg_crc32c_8_generic(crc, &buf[2 * pic_stride]);
|
||||||
|
crc = uvg_crc32c_8_generic(crc, &buf[3 * pic_stride]);
|
||||||
|
|
||||||
|
crc = uvg_crc32c_8_generic(crc, &buf[4 * pic_stride]);
|
||||||
|
crc = uvg_crc32c_8_generic(crc, &buf[5 * pic_stride]);
|
||||||
|
|
||||||
|
crc = uvg_crc32c_8_generic(crc, &buf[6 * pic_stride]);
|
||||||
|
crc = uvg_crc32c_8_generic(crc, &buf[7 * pic_stride]);
|
||||||
|
return crc ^ 0xFFFFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
int uvg_strategy_register_picture_generic(void* opaque, uint8_t bitdepth)
|
int uvg_strategy_register_picture_generic(void* opaque, uint8_t bitdepth)
|
||||||
{
|
{
|
||||||
bool success = true;
|
bool success = true;
|
||||||
if (bitdepth == 8) {
|
if (bitdepth == 8) {
|
||||||
success &= uvg_strategyselector_register(opaque, "crc32c_4x4", "generic", 0, &uvg_crc32c_4x4_8bit_generic);
|
success &= uvg_strategyselector_register(opaque, "crc32c_4x4", "generic", 0, &uvg_crc32c_4x4_8bit_generic);
|
||||||
|
success &= uvg_strategyselector_register(opaque, "crc32c_8x8", "generic", 0, &uvg_crc32c_8x8_8bit_generic);
|
||||||
} else {
|
} else {
|
||||||
success &= uvg_strategyselector_register(opaque, "crc32c_4x4", "generic", 0, &uvg_crc32c_4x4_16bit_generic);
|
success &= uvg_strategyselector_register(opaque, "crc32c_4x4", "generic", 0, &uvg_crc32c_4x4_16bit_generic);
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,6 +64,20 @@ static uint32_t uvg_crc32c_4x4_16bit_sse42(const uvg_pixel *buf, uint32_t pic_st
|
||||||
return crc ^ 0xFFFFFFFF;
|
return crc ^ 0xFFFFFFFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint32_t uvg_crc32c_8x8_8bit_sse42(const uvg_pixel *buf, uint32_t pic_stride)
|
||||||
|
{
|
||||||
|
uint32_t crc = 0xFFFFFFFF;
|
||||||
|
crc = _mm_crc32_u64(crc, *((uint32_t *)&buf[0 * pic_stride]));
|
||||||
|
crc = _mm_crc32_u64(crc, *((uint32_t *)&buf[1 * pic_stride]));
|
||||||
|
crc = _mm_crc32_u64(crc, *((uint32_t *)&buf[2 * pic_stride]));
|
||||||
|
crc = _mm_crc32_u64(crc, *((uint32_t *)&buf[3 * pic_stride]));
|
||||||
|
crc = _mm_crc32_u64(crc, *((uint32_t *)&buf[4 * pic_stride]));
|
||||||
|
crc = _mm_crc32_u64(crc, *((uint32_t *)&buf[5 * pic_stride]));
|
||||||
|
crc = _mm_crc32_u64(crc, *((uint32_t *)&buf[6 * pic_stride]));
|
||||||
|
crc = _mm_crc32_u64(crc, *((uint32_t *)&buf[7 * pic_stride]));
|
||||||
|
return crc ^ 0xFFFFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif //COMPILE_INTEL_SSE42
|
#endif //COMPILE_INTEL_SSE42
|
||||||
|
|
||||||
|
@ -72,6 +86,7 @@ int uvg_strategy_register_picture_sse42(void* opaque, uint8_t bitdepth) {
|
||||||
#if COMPILE_INTEL_SSE42
|
#if COMPILE_INTEL_SSE42
|
||||||
if (bitdepth == 8){
|
if (bitdepth == 8){
|
||||||
success &= uvg_strategyselector_register(opaque, "crc32c_4x4", "sse42", 0, &uvg_crc32c_4x4_8bit_sse42);
|
success &= uvg_strategyselector_register(opaque, "crc32c_4x4", "sse42", 0, &uvg_crc32c_4x4_8bit_sse42);
|
||||||
|
success &= uvg_strategyselector_register(opaque, "crc32c_8x8", "sse42", 0, &uvg_crc32c_8x8_8bit_sse42);
|
||||||
} else {
|
} else {
|
||||||
success &= uvg_strategyselector_register(opaque, "crc32c_4x4", "sse42", 0, &uvg_crc32c_4x4_16bit_sse42);
|
success &= uvg_strategyselector_register(opaque, "crc32c_4x4", "sse42", 0, &uvg_crc32c_4x4_16bit_sse42);
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,6 +42,7 @@
|
||||||
|
|
||||||
// Define function pointers.
|
// Define function pointers.
|
||||||
crc32c_4x4_func * uvg_crc32c_4x4 = 0;
|
crc32c_4x4_func * uvg_crc32c_4x4 = 0;
|
||||||
|
crc32c_8x8_func * uvg_crc32c_8x8 = 0;
|
||||||
reg_sad_func * uvg_reg_sad = 0;
|
reg_sad_func * uvg_reg_sad = 0;
|
||||||
|
|
||||||
cost_pixel_nxn_func * uvg_sad_4x4 = 0;
|
cost_pixel_nxn_func * uvg_sad_4x4 = 0;
|
||||||
|
|
|
@ -155,9 +155,11 @@ typedef void (generate_residual_func)(const uvg_pixel* ref_in, const uvg_pixel*
|
||||||
extern const uint32_t uvg_crc_table[256];
|
extern const uint32_t uvg_crc_table[256];
|
||||||
|
|
||||||
typedef uint32_t(crc32c_4x4_func)(const uvg_pixel *buf, uint32_t pic_stride);
|
typedef uint32_t(crc32c_4x4_func)(const uvg_pixel *buf, uint32_t pic_stride);
|
||||||
|
typedef uint32_t(crc32c_8x8_func)(const uvg_pixel *buf, uint32_t pic_stride);
|
||||||
|
|
||||||
// Declare function pointers.
|
// Declare function pointers.
|
||||||
extern crc32c_4x4_func * uvg_crc32c_4x4;
|
extern crc32c_4x4_func * uvg_crc32c_4x4;
|
||||||
|
extern crc32c_8x8_func * uvg_crc32c_8x8;
|
||||||
|
|
||||||
extern reg_sad_func * uvg_reg_sad;
|
extern reg_sad_func * uvg_reg_sad;
|
||||||
|
|
||||||
|
@ -206,6 +208,7 @@ cost_pixel_nxn_multi_func * uvg_pixels_get_sad_dual_func(unsigned n);
|
||||||
|
|
||||||
#define STRATEGIES_PICTURE_EXPORTS \
|
#define STRATEGIES_PICTURE_EXPORTS \
|
||||||
{"crc32c_4x4", (void**) &uvg_crc32c_4x4}, \
|
{"crc32c_4x4", (void**) &uvg_crc32c_4x4}, \
|
||||||
|
{"crc32c_8x8", (void **)&uvg_crc32c_8x8}, \
|
||||||
{"reg_sad", (void**) &uvg_reg_sad}, \
|
{"reg_sad", (void**) &uvg_reg_sad}, \
|
||||||
{"sad_4x4", (void**) &uvg_sad_4x4}, \
|
{"sad_4x4", (void**) &uvg_sad_4x4}, \
|
||||||
{"sad_8x8", (void**) &uvg_sad_8x8}, \
|
{"sad_8x8", (void**) &uvg_sad_8x8}, \
|
||||||
|
|
Loading…
Reference in a new issue