From: Jim Bankoski Date: Wed, 13 Jul 2016 14:35:25 +0000 (-0700) Subject: postproc - move filling of noise buffer to vpx_dsp. X-Git-Tag: v1.6.1~424^2~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=2ca24b0075df0623fe44e07ea000e182a1317d33;p=platform%2Fupstream%2Flibvpx.git postproc - move filling of noise buffer to vpx_dsp. Change-Id: I63ba35dc0ae9286c9812367a531e01d79a4c1635 --- diff --git a/test/add_noise_test.cc b/test/add_noise_test.cc index e9945c4..44b8d74 100644 --- a/test/add_noise_test.cc +++ b/test/add_noise_test.cc @@ -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(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(vpx_calloc(image_size, 1)); diff --git a/vp8/common/postproc.c b/vp8/common/postproc.c index cd3bb95..82b6600 100644 --- a/vp8/common/postproc.c +++ b/vp8/common/postproc.c @@ -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 diff --git a/vp9/common/vp9_postproc.c b/vp9/common/vp9_postproc.c index b13a634..265c37f 100644 --- a/vp9/common/vp9_postproc.c +++ b/vp9/common/vp9_postproc.c @@ -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, diff --git a/vpx_dsp/add_noise.c b/vpx_dsp/add_noise.c index 682b444..baede28 100644 --- a/vpx_dsp/add_noise.c +++ b/vpx_dsp/add_noise.c @@ -8,6 +8,7 @@ * be found in the AUTHORS file in the root of the source tree. */ +#include #include #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]; +} diff --git a/vpx_dsp/postproc.h b/vpx_dsp/postproc.h new file mode 100644 index 0000000..389b0ee --- /dev/null +++ b/vpx_dsp/postproc.h @@ -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_ diff --git a/vpx_dsp/vpx_dsp.mk b/vpx_dsp/vpx_dsp.mk index bd6d938..f56483e 100644 --- a/vpx_dsp/vpx_dsp.mk +++ b/vpx_dsp/vpx_dsp.mk @@ -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