Merge "postproc - move filling of noise buffer to vpx_dsp."
This commit is contained in:
commit
e93f2fdb83
@ -13,6 +13,7 @@
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
#include "./vpx_dsp_rtcd.h"
|
||||
#include "vpx/vpx_integer.h"
|
||||
#include "vpx_dsp/postproc.h"
|
||||
#include "vpx_mem/vpx_mem.h"
|
||||
|
||||
namespace {
|
||||
@ -40,50 +41,6 @@ double stddev6(char a, char b, char c, char d, char e, char f) {
|
||||
return sqrt(v);
|
||||
}
|
||||
|
||||
// TODO(jimbankoski): The following 2 functions are duplicated in each codec.
|
||||
// For now the vp9 one has been copied into the test as is. We should normalize
|
||||
// these in vpx_dsp and not have 3 copies of these unless there is different
|
||||
// noise we add for each codec.
|
||||
|
||||
double gaussian(double sigma, double mu, double x) {
|
||||
return 1 / (sigma * sqrt(2.0 * 3.14159265)) *
|
||||
(exp(-(x - mu) * (x - mu) / (2 * sigma * sigma)));
|
||||
}
|
||||
|
||||
int setup_noise(int size_noise, char *noise) {
|
||||
char char_dist[300];
|
||||
const int ai = 4;
|
||||
const int qi = 24;
|
||||
const double sigma = ai + .5 + .6 * (63 - qi) / 63.0;
|
||||
|
||||
/* set up a lookup table of 256 entries that matches
|
||||
* a gaussian distribution with sigma determined by q.
|
||||
*/
|
||||
int next = 0;
|
||||
|
||||
for (int i = -32; i < 32; i++) {
|
||||
int a_i = (int) (0.5 + 256 * gaussian(sigma, 0, i));
|
||||
|
||||
if (a_i) {
|
||||
for (int j = 0; j < a_i; j++) {
|
||||
char_dist[next + j] = (char)(i);
|
||||
}
|
||||
|
||||
next = next + a_i;
|
||||
}
|
||||
}
|
||||
|
||||
for (; next < 256; next++)
|
||||
char_dist[next] = 0;
|
||||
|
||||
for (int i = 0; i < size_noise; i++) {
|
||||
noise[i] = char_dist[rand() & 0xff]; // NOLINT
|
||||
}
|
||||
|
||||
// Returns the most negative value in distribution.
|
||||
return char_dist[0];
|
||||
}
|
||||
|
||||
TEST_P(AddNoiseTest, CheckNoiseAdded) {
|
||||
DECLARE_ALIGNED(16, char, blackclamp[16]);
|
||||
DECLARE_ALIGNED(16, char, whiteclamp[16]);
|
||||
@ -92,12 +49,12 @@ TEST_P(AddNoiseTest, CheckNoiseAdded) {
|
||||
const int height = 64;
|
||||
const int image_size = width * height;
|
||||
char noise[3072];
|
||||
const int clamp = vpx_setup_noise(sizeof(noise), 4.4, noise);
|
||||
|
||||
const int clamp = setup_noise(3072, noise);
|
||||
for (int i = 0; i < 16; i++) {
|
||||
blackclamp[i] = -clamp;
|
||||
whiteclamp[i] = -clamp;
|
||||
bothclamp[i] = -2 * clamp;
|
||||
blackclamp[i] = clamp;
|
||||
whiteclamp[i] = clamp;
|
||||
bothclamp[i] = 2 * clamp;
|
||||
}
|
||||
|
||||
uint8_t *const s = reinterpret_cast<uint8_t *>(vpx_calloc(image_size, 1));
|
||||
@ -127,7 +84,7 @@ TEST_P(AddNoiseTest, CheckNoiseAdded) {
|
||||
|
||||
// Check to make sure don't roll over.
|
||||
for (int i = 0; i < image_size; ++i) {
|
||||
EXPECT_GT((int)s[i], 10) << "i = " << i;
|
||||
EXPECT_GT((int)s[i], clamp) << "i = " << i;
|
||||
}
|
||||
|
||||
// Initialize pixels in the image to 0 and check for roll under.
|
||||
@ -138,7 +95,7 @@ TEST_P(AddNoiseTest, CheckNoiseAdded) {
|
||||
|
||||
// Check to make sure don't roll under.
|
||||
for (int i = 0; i < image_size; ++i) {
|
||||
EXPECT_LT((int)s[i], 245) << "i = " << i;
|
||||
EXPECT_LT((int)s[i], 255 - clamp) << "i = " << i;
|
||||
}
|
||||
|
||||
vpx_free(s);
|
||||
@ -153,11 +110,12 @@ TEST_P(AddNoiseTest, CheckCvsAssembly) {
|
||||
const int image_size = width * height;
|
||||
char noise[3072];
|
||||
|
||||
const int clamp = setup_noise(3072, noise);
|
||||
const int clamp = vpx_setup_noise(sizeof(noise), 4.4, noise);
|
||||
|
||||
for (int i = 0; i < 16; i++) {
|
||||
blackclamp[i] = -clamp;
|
||||
whiteclamp[i] = -clamp;
|
||||
bothclamp[i] = -2 * clamp;
|
||||
blackclamp[i] = clamp;
|
||||
whiteclamp[i] = clamp;
|
||||
bothclamp[i] = 2 * clamp;
|
||||
}
|
||||
|
||||
uint8_t *const s = reinterpret_cast<uint8_t *>(vpx_calloc(image_size, 1));
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "vpx_config.h"
|
||||
#include "vpx_dsp_rtcd.h"
|
||||
#include "vp8_rtcd.h"
|
||||
#include "vpx_dsp/postproc.h"
|
||||
#include "vpx_scale_rtcd.h"
|
||||
#include "vpx_scale/yv12config.h"
|
||||
#include "postproc.h"
|
||||
@ -202,69 +203,6 @@ void vp8_de_noise(VP8_COMMON *cm,
|
||||
}
|
||||
}
|
||||
|
||||
static double gaussian(double sigma, double mu, double x)
|
||||
{
|
||||
return 1 / (sigma * sqrt(2.0 * 3.14159265)) *
|
||||
(exp(-(x - mu) * (x - mu) / (2 * sigma * sigma)));
|
||||
}
|
||||
|
||||
static void fillrd(struct postproc_state *state, int q, int a)
|
||||
{
|
||||
char char_dist[300];
|
||||
|
||||
double sigma;
|
||||
int i;
|
||||
|
||||
vp8_clear_system_state();
|
||||
|
||||
|
||||
sigma = a + .5 + .6 * (63 - q) / 63.0;
|
||||
|
||||
/* set up a lookup table of 256 entries that matches
|
||||
* a gaussian distribution with sigma determined by q.
|
||||
*/
|
||||
{
|
||||
int next, j;
|
||||
|
||||
next = 0;
|
||||
|
||||
for (i = -32; i < 32; i++)
|
||||
{
|
||||
const int v = (int)(.5 + 256 * gaussian(sigma, 0, i));
|
||||
|
||||
if (v)
|
||||
{
|
||||
for (j = 0; j < v; j++)
|
||||
{
|
||||
char_dist[next+j] = (char) i;
|
||||
}
|
||||
|
||||
next = next + j;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for (; next < 256; next++)
|
||||
char_dist[next] = 0;
|
||||
|
||||
}
|
||||
|
||||
for (i = 0; i < 3072; i++)
|
||||
{
|
||||
state->noise[i] = char_dist[rand() & 0xff];
|
||||
}
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
state->blackclamp[i] = -char_dist[0];
|
||||
state->whiteclamp[i] = -char_dist[0];
|
||||
state->bothclamp[i] = -2 * char_dist[0];
|
||||
}
|
||||
|
||||
state->last_q = q;
|
||||
state->last_noise = a;
|
||||
}
|
||||
|
||||
/* Blend the macro block with a solid colored square. Leave the
|
||||
* edges unblended to give distinction to macro blocks in areas
|
||||
* filled with the same color block.
|
||||
@ -552,7 +490,22 @@ int vp8_post_proc_frame(VP8_COMMON *oci, YV12_BUFFER_CONFIG *dest, vp8_ppflags_t
|
||||
if (oci->postproc_state.last_q != q
|
||||
|| oci->postproc_state.last_noise != noise_level)
|
||||
{
|
||||
fillrd(&oci->postproc_state, 63 - q, noise_level);
|
||||
double sigma;
|
||||
int clamp, i;
|
||||
struct postproc_state *ppstate = &oci->postproc_state;
|
||||
vp8_clear_system_state();
|
||||
sigma = noise_level + .5 + .6 * q / 63.0;
|
||||
clamp = vpx_setup_noise(sizeof(ppstate->noise), sigma,
|
||||
ppstate->noise);
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
ppstate->blackclamp[i] = clamp;
|
||||
ppstate->whiteclamp[i] = clamp;
|
||||
ppstate->bothclamp[i] = 2 * clamp;
|
||||
}
|
||||
|
||||
ppstate->last_q = q;
|
||||
ppstate->last_noise = noise_level;
|
||||
}
|
||||
|
||||
vpx_plane_add_noise
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "./vp9_rtcd.h"
|
||||
|
||||
#include "vpx_dsp/vpx_dsp_common.h"
|
||||
#include "vpx_dsp/postproc.h"
|
||||
#include "vpx_ports/mem.h"
|
||||
#include "vpx_ports/system_state.h"
|
||||
#include "vpx_scale/vpx_scale.h"
|
||||
@ -294,59 +295,6 @@ void vp9_denoise(const YV12_BUFFER_CONFIG *src, YV12_BUFFER_CONFIG *dst,
|
||||
vp9_deblock(src, dst, q, limits);
|
||||
}
|
||||
|
||||
static double gaussian(double sigma, double mu, double x) {
|
||||
return 1 / (sigma * sqrt(2.0 * 3.14159265)) *
|
||||
(exp(-(x - mu) * (x - mu) / (2 * sigma * sigma)));
|
||||
}
|
||||
|
||||
static void fillrd(struct postproc_state *state, int q, int a) {
|
||||
char char_dist[300];
|
||||
|
||||
double sigma;
|
||||
int ai = a, qi = q, i;
|
||||
|
||||
vpx_clear_system_state();
|
||||
|
||||
sigma = ai + .5 + .6 * (63 - qi) / 63.0;
|
||||
|
||||
/* set up a lookup table of 256 entries that matches
|
||||
* a gaussian distribution with sigma determined by q.
|
||||
*/
|
||||
{
|
||||
int next, j;
|
||||
|
||||
next = 0;
|
||||
|
||||
for (i = -32; i < 32; i++) {
|
||||
int a_i = (int)(0.5 + 256 * gaussian(sigma, 0, i));
|
||||
|
||||
if (a_i) {
|
||||
for (j = 0; j < a_i; j++) {
|
||||
char_dist[next + j] = (char) i;
|
||||
}
|
||||
|
||||
next = next + j;
|
||||
}
|
||||
}
|
||||
|
||||
for (; next < 256; next++)
|
||||
char_dist[next] = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < 3072; i++) {
|
||||
state->noise[i] = char_dist[rand() & 0xff]; // NOLINT
|
||||
}
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
state->blackclamp[i] = -char_dist[0];
|
||||
state->whiteclamp[i] = -char_dist[0];
|
||||
state->bothclamp[i] = -2 * char_dist[0];
|
||||
}
|
||||
|
||||
state->last_q = q;
|
||||
state->last_noise = a;
|
||||
}
|
||||
|
||||
static void swap_mi_and_prev_mi(VP9_COMMON *cm) {
|
||||
// Current mip will be the prev_mip for the next frame.
|
||||
MODE_INFO *temp = cm->postproc_state.prev_mip;
|
||||
@ -469,7 +417,20 @@ int vp9_post_proc_frame(struct VP9Common *cm,
|
||||
const int noise_level = ppflags->noise_level;
|
||||
if (ppstate->last_q != q ||
|
||||
ppstate->last_noise != noise_level) {
|
||||
fillrd(ppstate, 63 - q, noise_level);
|
||||
double sigma;
|
||||
int clamp, i;
|
||||
vpx_clear_system_state();
|
||||
sigma = noise_level + .5 + .6 * q / 63.0;
|
||||
clamp = vpx_setup_noise(sizeof(ppstate->noise), sigma,
|
||||
ppstate->noise);
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
ppstate->blackclamp[i] = clamp;
|
||||
ppstate->whiteclamp[i] = clamp;
|
||||
ppstate->bothclamp[i] = 2 * clamp;
|
||||
}
|
||||
ppstate->last_q = q;
|
||||
ppstate->last_noise = noise_level;
|
||||
}
|
||||
vpx_plane_add_noise(ppbuf->y_buffer, ppstate->noise, ppstate->blackclamp,
|
||||
ppstate->whiteclamp, ppstate->bothclamp,
|
||||
|
@ -8,6 +8,7 @@
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "./vpx_config.h"
|
||||
@ -38,3 +39,37 @@ void vpx_plane_add_noise_c(uint8_t *start, char *noise,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static double gaussian(double sigma, double mu, double x) {
|
||||
return 1 / (sigma * sqrt(2.0 * 3.14159265)) *
|
||||
(exp(-(x - mu) * (x - mu) / (2 * sigma * sigma)));
|
||||
}
|
||||
|
||||
int vpx_setup_noise(int size, double sigma, char *noise) {
|
||||
char char_dist[256];
|
||||
int next, i, j;
|
||||
|
||||
next = 0;
|
||||
|
||||
// set up a 256 entry lookup that matches gaussian distribution
|
||||
for (i = -32; i < 32; i++) {
|
||||
int a_i = (int) (0.5 + 256 * gaussian(sigma, 0, i));
|
||||
if (a_i) {
|
||||
for (j = 0; j < a_i; j++) {
|
||||
char_dist[next + j] = (char) (i);
|
||||
}
|
||||
next = next + j;
|
||||
}
|
||||
}
|
||||
|
||||
// Rounding error - might mean we have less than 256.
|
||||
for (; next < 256; next++)
|
||||
char_dist[next] = 0;
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
noise[i] = char_dist[rand() & 0xff]; // NOLINT
|
||||
}
|
||||
|
||||
// Returns the highest non 0 value used in distribution.
|
||||
return -char_dist[0];
|
||||
}
|
||||
|
24
vpx_dsp/postproc.h
Normal file
24
vpx_dsp/postproc.h
Normal file
@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright (c) 2016 The WebM project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef VPX_DSP_POSTPROC_H_
|
||||
#define VPX_DSP_POSTPROC_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int vpx_setup_noise(int size, double sigma, char *noise);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // VPX_DSP_POSTPROC_H_
|
@ -53,6 +53,7 @@ endif # CONFIG_VP9_HIGHBITDEPTH
|
||||
ifneq ($(filter yes,$(CONFIG_POSTPROC) $(CONFIG_VP9_POSTPROC)),)
|
||||
DSP_SRCS-yes += add_noise.c
|
||||
DSP_SRCS-yes += deblock.c
|
||||
DSP_SRCS-yes += postproc.h
|
||||
DSP_SRCS-$(HAVE_MSA) += mips/add_noise_msa.c
|
||||
DSP_SRCS-$(HAVE_MSA) += mips/deblock_msa.c
|
||||
DSP_SRCS-$(HAVE_SSE2) += x86/add_noise_sse2.asm
|
||||
|
Loading…
Reference in New Issue
Block a user