mirror of
https://github.com/ultravideo/uvg266.git
synced 2024-11-30 12:44:07 +00:00
Strategy selector for array_checksum, basic implementation using precomputed 256*256 block with larger accesses than byte
This commit is contained in:
parent
a483e8cb0f
commit
5ed69b063b
35
src/nal.c
35
src/nal.c
|
@ -22,6 +22,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "nal.h"
|
#include "nal.h"
|
||||||
|
#include "strategyselector.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -64,40 +65,6 @@ void nal_write(bitstream * const bitstream, const uint8_t nal_type,
|
||||||
bitstream_writebyte(bitstream, byte);
|
bitstream_writebyte(bitstream, byte);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Calculate checksum for one color of the picture.
|
|
||||||
* \param data Beginning of the pixel data for the picture.
|
|
||||||
* \param height Height of the picture.
|
|
||||||
* \param width Width of the picture.
|
|
||||||
* \param stride Width of one row in the pixel array.
|
|
||||||
*/
|
|
||||||
static void array_checksum(const pixel* data,
|
|
||||||
const int height, const int width,
|
|
||||||
const int stride,
|
|
||||||
unsigned char checksum_out[SEI_HASH_MAX_LENGTH])
|
|
||||||
{
|
|
||||||
uint8_t mask;
|
|
||||||
uint32_t checksum = 0;
|
|
||||||
int y, x;
|
|
||||||
|
|
||||||
assert(SEI_HASH_MAX_LENGTH >= 4);
|
|
||||||
|
|
||||||
for (y = 0; y < height; ++y) {
|
|
||||||
for (x = 0; x < width; ++x) {
|
|
||||||
mask = (uint8_t)((x & 0xff) ^ (y & 0xff) ^ (x >> 8) ^ (y >> 8));
|
|
||||||
checksum += (data[(y * stride) + x] & 0xff) ^ mask;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unpack uint into byte-array.
|
|
||||||
checksum_out[0] = (checksum >> 24) & 0xff;
|
|
||||||
checksum_out[1] = (checksum >> 16) & 0xff;
|
|
||||||
checksum_out[2] = (checksum >> 8) & 0xff;
|
|
||||||
checksum_out[3] = (checksum) & 0xff;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Calculate checksums for all colors of the picture.
|
\brief Calculate checksums for all colors of the picture.
|
||||||
\param pic The picture that checksum is calculated for.
|
\param pic The picture that checksum is calculated for.
|
||||||
|
|
145
src/strategies/nal-generic.c
Normal file
145
src/strategies/nal-generic.c
Normal file
|
@ -0,0 +1,145 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
* This file is part of Kvazaar HEVC encoder.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013-2014 Tampere University of Technology and others (see
|
||||||
|
* COPYING file).
|
||||||
|
*
|
||||||
|
* Kvazaar is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as published
|
||||||
|
* by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* Kvazaar is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Kvazaar. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* \file
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "nal.h"
|
||||||
|
#include <assert.h>
|
||||||
|
#include "../strategyselector.h"
|
||||||
|
|
||||||
|
|
||||||
|
static void array_checksum_generic(const pixel* data,
|
||||||
|
const int height, const int width,
|
||||||
|
const int stride,
|
||||||
|
unsigned char checksum_out[SEI_HASH_MAX_LENGTH]) {
|
||||||
|
int x, y;
|
||||||
|
int checksum = 0;
|
||||||
|
|
||||||
|
assert(SEI_HASH_MAX_LENGTH >= 4);
|
||||||
|
|
||||||
|
for (y = 0; y < height; ++y) {
|
||||||
|
for (x = 0; x < width; ++x) {
|
||||||
|
const uint8_t mask = (uint8_t)((x & 0xff) ^ (y & 0xff) ^ (x >> 8) ^ (y >> 8));
|
||||||
|
checksum += (data[(y * stride) + x] & 0xff) ^ mask;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unpack uint into byte-array.
|
||||||
|
checksum_out[0] = (checksum >> 24) & 0xff;
|
||||||
|
checksum_out[1] = (checksum >> 16) & 0xff;
|
||||||
|
checksum_out[2] = (checksum >> 8) & 0xff;
|
||||||
|
checksum_out[3] = (checksum) & 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void array_checksum_generic4(const pixel* data,
|
||||||
|
const int height, const int width,
|
||||||
|
const int stride,
|
||||||
|
unsigned char checksum_out[SEI_HASH_MAX_LENGTH]) {
|
||||||
|
uint32_t checksum = 0;
|
||||||
|
int y, x, xp;
|
||||||
|
|
||||||
|
static uint8_t ckmap_initialized = 0;
|
||||||
|
static uint32_t ckmap[64*256];
|
||||||
|
|
||||||
|
if (!ckmap_initialized) {
|
||||||
|
uint8_t * const ckmap_uint8 = (uint8_t*)&ckmap;
|
||||||
|
int x, y;
|
||||||
|
for (y = 0; y < 256; ++y) {
|
||||||
|
for (x = 0; x < 256; ++x) {
|
||||||
|
ckmap_uint8[y*256+x] = x^y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ckmap_initialized = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(SEI_HASH_MAX_LENGTH >= 4);
|
||||||
|
|
||||||
|
for (y = 0; y < height; ++y) {
|
||||||
|
for (xp = 0; xp < width/4; ++xp) {
|
||||||
|
const int x = xp * 4;
|
||||||
|
const uint32_t mask = ckmap[(xp&63)+64*(y&255)] ^ (((x >> 8) ^ (y >> 8)) * 0x1010101);
|
||||||
|
const uint32_t cksumbytes = (*((uint32_t*)(&data[(y * stride) + x]))) ^ mask;
|
||||||
|
checksum += ((cksumbytes >> 24) & 0xff) + ((cksumbytes >> 16) & 0xff) + ((cksumbytes >> 8) & 0xff) + (cksumbytes & 0xff);
|
||||||
|
}
|
||||||
|
for (x = xp*4; x < width; ++x) {
|
||||||
|
uint8_t mask = (uint8_t)((x & 0xff) ^ (y & 0xff) ^ (x >> 8) ^ (y >> 8));
|
||||||
|
checksum += (data[(y * stride) + x] & 0xff) ^ mask;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unpack uint into byte-array.
|
||||||
|
checksum_out[0] = (checksum >> 24) & 0xff;
|
||||||
|
checksum_out[1] = (checksum >> 16) & 0xff;
|
||||||
|
checksum_out[2] = (checksum >> 8) & 0xff;
|
||||||
|
checksum_out[3] = (checksum) & 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void array_checksum_generic8(const pixel* data,
|
||||||
|
const int height, const int width,
|
||||||
|
const int stride,
|
||||||
|
unsigned char checksum_out[SEI_HASH_MAX_LENGTH]) {
|
||||||
|
uint32_t checksum = 0;
|
||||||
|
int y, x, xp;
|
||||||
|
|
||||||
|
static uint8_t ckmap_initialized = 0;
|
||||||
|
static uint64_t ckmap[32*256];
|
||||||
|
|
||||||
|
if (!ckmap_initialized) {
|
||||||
|
uint8_t * const ckmap_uint8 = (uint8_t*)&ckmap;
|
||||||
|
int x, y;
|
||||||
|
for (y = 0; y < 256; ++y) {
|
||||||
|
for (x = 0; x < 256; ++x) {
|
||||||
|
ckmap_uint8[y*256+x] = x^y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ckmap_initialized = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(SEI_HASH_MAX_LENGTH >= 4);
|
||||||
|
|
||||||
|
for (y = 0; y < height; ++y) {
|
||||||
|
for (xp = 0; xp < width/8; ++xp) {
|
||||||
|
const int x = xp * 8;
|
||||||
|
const uint64_t mask = ckmap[(xp&31)+32*(y&255)] ^ ((uint64_t)((x >> 8) ^ (y >> 8)) * 0x101010101010101);
|
||||||
|
const uint64_t cksumbytes = (*((uint64_t*)(&data[(y * stride) + x]))) ^ mask;
|
||||||
|
checksum += ((cksumbytes >> 56) & 0xff) + ((cksumbytes >> 48) & 0xff) + ((cksumbytes >> 40) & 0xff) + ((cksumbytes >> 32) & 0xff) + ((cksumbytes >> 24) & 0xff) + ((cksumbytes >> 16) & 0xff) + ((cksumbytes >> 8) & 0xff) + (cksumbytes & 0xff);
|
||||||
|
}
|
||||||
|
for (x = xp*8; x < width; ++x) {
|
||||||
|
uint8_t mask = (uint8_t)((x & 0xff) ^ (y & 0xff) ^ (x >> 8) ^ (y >> 8));
|
||||||
|
checksum += (data[(y * stride) + x] & 0xff) ^ mask;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unpack uint into byte-array.
|
||||||
|
checksum_out[0] = (checksum >> 24) & 0xff;
|
||||||
|
checksum_out[1] = (checksum >> 16) & 0xff;
|
||||||
|
checksum_out[2] = (checksum >> 8) & 0xff;
|
||||||
|
checksum_out[3] = (checksum) & 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int strategy_register_nal_generic(void* opaque) {
|
||||||
|
if (!strategyselector_register(opaque, "array_checksum", "generic", 0, &array_checksum_generic)) return 0;
|
||||||
|
if (!strategyselector_register(opaque, "array_checksum", "generic4", 1, &array_checksum_generic4)) return 0;
|
||||||
|
if (!strategyselector_register(opaque, "array_checksum", "generic8", 2, &array_checksum_generic8)) return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
14
src/strategies/nal.c
Normal file
14
src/strategies/nal.c
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
#include "nal.h"
|
||||||
|
#include "nal-generic.c"
|
||||||
|
|
||||||
|
void (*array_checksum)(const pixel* data,
|
||||||
|
const int height, const int width,
|
||||||
|
const int stride,
|
||||||
|
unsigned char checksum_out[SEI_HASH_MAX_LENGTH]);
|
||||||
|
|
||||||
|
|
||||||
|
static int strategy_register_nal(void* opaque) {
|
||||||
|
if (!strategy_register_nal_generic(opaque)) return 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
39
src/strategies/nal.h
Normal file
39
src/strategies/nal.h
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
#ifndef STRATEGIES_NAL_H_
|
||||||
|
#define STRATEGIES_NAL_H_
|
||||||
|
/*****************************************************************************
|
||||||
|
* This file is part of Kvazaar HEVC encoder.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013-2014 Tampere University of Technology and others (see
|
||||||
|
* COPYING file).
|
||||||
|
*
|
||||||
|
* Kvazaar is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as published
|
||||||
|
* by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* Kvazaar is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Kvazaar. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include "../nal.h"
|
||||||
|
|
||||||
|
//Function pointer to array_checksum
|
||||||
|
/**
|
||||||
|
* \brief Calculate checksum for one color of the picture.
|
||||||
|
* \param data Beginning of the pixel data for the picture.
|
||||||
|
* \param height Height of the picture.
|
||||||
|
* \param width Width of the picture.
|
||||||
|
* \param stride Width of one row in the pixel array.
|
||||||
|
*/
|
||||||
|
extern void (*array_checksum)(const pixel* data,
|
||||||
|
const int height, const int width,
|
||||||
|
const int stride,
|
||||||
|
unsigned char checksum_out[SEI_HASH_MAX_LENGTH]);
|
||||||
|
|
||||||
|
#define STRATEGIES_NAL_EXPORTS {"array_checksum", (void**) &array_checksum}
|
||||||
|
|
||||||
|
#endif //STRATEGIES_NAL_H_
|
|
@ -33,6 +33,7 @@ static void* strategyselector_choose_for(const strategy_list * const strategies,
|
||||||
|
|
||||||
//Strategies to include (add new file here)
|
//Strategies to include (add new file here)
|
||||||
#include "strategies/picture.c"
|
#include "strategies/picture.c"
|
||||||
|
#include "strategies/nal.c"
|
||||||
|
|
||||||
//Returns 1 if successful
|
//Returns 1 if successful
|
||||||
int strategyselector_init() {
|
int strategyselector_init() {
|
||||||
|
@ -51,6 +52,11 @@ int strategyselector_init() {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!strategy_register_nal(&strategies)) {
|
||||||
|
fprintf(stderr, "strategy_register_nal failed!\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
while(cur_strategy_to_select->fptr) {
|
while(cur_strategy_to_select->fptr) {
|
||||||
*(cur_strategy_to_select->fptr) = strategyselector_choose_for(&strategies, cur_strategy_to_select->strategy_type);
|
*(cur_strategy_to_select->fptr) = strategyselector_choose_for(&strategies, cur_strategy_to_select->strategy_type);
|
||||||
|
|
||||||
|
|
|
@ -127,9 +127,11 @@ int strategyselector_register(void *opaque, const char *type, const char *strate
|
||||||
|
|
||||||
|
|
||||||
//Strategy to include
|
//Strategy to include
|
||||||
|
#include "strategies/nal.h"
|
||||||
#include "strategies/picture.h"
|
#include "strategies/picture.h"
|
||||||
|
|
||||||
static const strategy_to_select strategies_to_select[] = {
|
static const strategy_to_select strategies_to_select[] = {
|
||||||
|
STRATEGIES_NAL_EXPORTS,
|
||||||
STRATEGIES_PICTURE_EXPORTS,
|
STRATEGIES_PICTURE_EXPORTS,
|
||||||
{NULL, NULL},
|
{NULL, NULL},
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue