Line data Source code
1 : /*
2 : * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
3 : *
4 : * Use of this source code is governed by a BSD-style license
5 : * that can be found in the LICENSE file in the root of the source
6 : * tree. An additional intellectual property rights grant can be found
7 : * in the file PATENTS. All contributing project authors may
8 : * be found in the AUTHORS file in the root of the source tree.
9 : */
10 :
11 : #include <stdlib.h>
12 :
13 : #include "webrtc/modules/video_processing/util/denoiser_filter_c.h"
14 :
15 : namespace webrtc {
16 :
17 0 : void DenoiserFilterC::CopyMem16x16(const uint8_t* src,
18 : int src_stride,
19 : uint8_t* dst,
20 : int dst_stride) {
21 0 : for (int i = 0; i < 16; i++) {
22 0 : memcpy(dst, src, 16);
23 0 : src += src_stride;
24 0 : dst += dst_stride;
25 : }
26 0 : }
27 :
28 0 : uint32_t DenoiserFilterC::Variance16x8(const uint8_t* a,
29 : int a_stride,
30 : const uint8_t* b,
31 : int b_stride,
32 : uint32_t* sse) {
33 0 : int sum = 0;
34 0 : *sse = 0;
35 0 : a_stride <<= 1;
36 0 : b_stride <<= 1;
37 :
38 0 : for (int i = 0; i < 8; i++) {
39 0 : for (int j = 0; j < 16; j++) {
40 0 : const int diff = a[j] - b[j];
41 0 : sum += diff;
42 0 : *sse += diff * diff;
43 : }
44 :
45 0 : a += a_stride;
46 0 : b += b_stride;
47 : }
48 0 : return *sse - ((static_cast<int64_t>(sum) * sum) >> 7);
49 : }
50 :
51 0 : DenoiserDecision DenoiserFilterC::MbDenoise(const uint8_t* mc_running_avg_y,
52 : int mc_avg_y_stride,
53 : uint8_t* running_avg_y,
54 : int avg_y_stride,
55 : const uint8_t* sig,
56 : int sig_stride,
57 : uint8_t motion_magnitude,
58 : int increase_denoising) {
59 0 : int sum_diff_thresh = 0;
60 0 : int sum_diff = 0;
61 0 : int adj_val[3] = {3, 4, 6};
62 0 : int shift_inc1 = 0;
63 0 : int shift_inc2 = 1;
64 0 : int col_sum[16] = {0};
65 0 : if (motion_magnitude <= kMotionMagnitudeThreshold) {
66 0 : if (increase_denoising) {
67 0 : shift_inc1 = 1;
68 0 : shift_inc2 = 2;
69 : }
70 0 : adj_val[0] += shift_inc2;
71 0 : adj_val[1] += shift_inc2;
72 0 : adj_val[2] += shift_inc2;
73 : }
74 :
75 0 : for (int r = 0; r < 16; ++r) {
76 0 : for (int c = 0; c < 16; ++c) {
77 0 : int diff = 0;
78 0 : int adjustment = 0;
79 0 : int absdiff = 0;
80 :
81 0 : diff = mc_running_avg_y[c] - sig[c];
82 0 : absdiff = abs(diff);
83 :
84 : // When |diff| <= |3 + shift_inc1|, use pixel value from
85 : // last denoised raw.
86 0 : if (absdiff <= 3 + shift_inc1) {
87 0 : running_avg_y[c] = mc_running_avg_y[c];
88 0 : col_sum[c] += diff;
89 : } else {
90 0 : if (absdiff >= 4 + shift_inc1 && absdiff <= 7)
91 0 : adjustment = adj_val[0];
92 0 : else if (absdiff >= 8 && absdiff <= 15)
93 0 : adjustment = adj_val[1];
94 : else
95 0 : adjustment = adj_val[2];
96 :
97 0 : if (diff > 0) {
98 0 : if ((sig[c] + adjustment) > 255)
99 0 : running_avg_y[c] = 255;
100 : else
101 0 : running_avg_y[c] = sig[c] + adjustment;
102 :
103 0 : col_sum[c] += adjustment;
104 : } else {
105 0 : if ((sig[c] - adjustment) < 0)
106 0 : running_avg_y[c] = 0;
107 : else
108 0 : running_avg_y[c] = sig[c] - adjustment;
109 :
110 0 : col_sum[c] -= adjustment;
111 : }
112 : }
113 : }
114 :
115 : // Update pointers for next iteration.
116 0 : sig += sig_stride;
117 0 : mc_running_avg_y += mc_avg_y_stride;
118 0 : running_avg_y += avg_y_stride;
119 : }
120 :
121 0 : for (int c = 0; c < 16; ++c) {
122 0 : if (col_sum[c] >= 128) {
123 0 : col_sum[c] = 127;
124 : }
125 0 : sum_diff += col_sum[c];
126 : }
127 :
128 0 : sum_diff_thresh =
129 0 : increase_denoising ? kSumDiffThresholdHigh : kSumDiffThreshold;
130 0 : if (abs(sum_diff) > sum_diff_thresh)
131 0 : return COPY_BLOCK;
132 :
133 0 : return FILTER_BLOCK;
134 : }
135 :
136 : } // namespace webrtc
|