Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(415)

Side by Side Diff: source/libvpx/vp9/encoder/vp9_denoiser.c

Issue 668403002: libvpx: Pull from upstream (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/deps/third_party/libvpx/
Patch Set: Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « source/libvpx/vp9/encoder/vp9_denoiser.h ('k') | source/libvpx/vp9/encoder/vp9_encodeframe.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2012 The WebM project authors. All Rights Reserved. 2 * Copyright (c) 2012 The WebM project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 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 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 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
(...skipping 13 matching lines...) Expand all
24 * The implementation is very similar to that of the VP8 denoiser. While 24 * The implementation is very similar to that of the VP8 denoiser. While
25 * choosing the motion vectors / reference frames, the denoiser is run, and if 25 * choosing the motion vectors / reference frames, the denoiser is run, and if
26 * it did not modify the signal to much, the denoised block is copied to the 26 * it did not modify the signal to much, the denoised block is copied to the
27 * signal. 27 * signal.
28 */ 28 */
29 29
30 #ifdef OUTPUT_YUV_DENOISED 30 #ifdef OUTPUT_YUV_DENOISED
31 static void make_grayscale(YV12_BUFFER_CONFIG *yuv); 31 static void make_grayscale(YV12_BUFFER_CONFIG *yuv);
32 #endif 32 #endif
33 33
34 static const int widths[] = {4, 4, 8, 8, 8, 16, 16, 16, 32, 32, 32, 64, 64};
35 static const int heights[] = {4, 8, 4, 8, 16, 8, 16, 32, 16, 32, 64, 32, 64};
36
37 static int absdiff_thresh(BLOCK_SIZE bs, int increase_denoising) { 34 static int absdiff_thresh(BLOCK_SIZE bs, int increase_denoising) {
38 (void)bs; 35 (void)bs;
39 return 3 + (increase_denoising ? 1 : 0); 36 return 3 + (increase_denoising ? 1 : 0);
40 } 37 }
41 38
42 static int delta_thresh(BLOCK_SIZE bs, int increase_denoising) { 39 static int delta_thresh(BLOCK_SIZE bs, int increase_denoising) {
43 (void)bs; 40 (void)bs;
44 (void)increase_denoising; 41 (void)increase_denoising;
45 return 4; 42 return 4;
46 } 43 }
47 44
48 static int noise_motion_thresh(BLOCK_SIZE bs, int increase_denoising) { 45 static int noise_motion_thresh(BLOCK_SIZE bs, int increase_denoising) {
49 (void)bs; 46 (void)bs;
50 (void)increase_denoising; 47 (void)increase_denoising;
51 return 25 * 25; 48 return 25 * 25;
52 } 49 }
53 50
54 static unsigned int sse_thresh(BLOCK_SIZE bs, int increase_denoising) { 51 static unsigned int sse_thresh(BLOCK_SIZE bs, int increase_denoising) {
55 return widths[bs] * heights[bs] * (increase_denoising ? 60 : 40); 52 return (4 << b_width_log2_lookup[bs]) *
53 (4 << b_height_log2_lookup[bs]) *
54 (increase_denoising ? 60 : 40);
56 } 55 }
57 56
58 static int sse_diff_thresh(BLOCK_SIZE bs, int increase_denoising, 57 static int sse_diff_thresh(BLOCK_SIZE bs, int increase_denoising,
59 int mv_row, int mv_col) { 58 int mv_row, int mv_col) {
60 if (mv_row * mv_row + mv_col * mv_col > 59 if (mv_row * mv_row + mv_col * mv_col >
61 noise_motion_thresh(bs, increase_denoising)) { 60 noise_motion_thresh(bs, increase_denoising)) {
62 return 0; 61 return 0;
63 } else { 62 } else {
64 return widths[bs] * heights[bs] * 20; 63 return (4 << b_width_log2_lookup[bs]) *
64 (4 << b_height_log2_lookup[bs]) * 20;
65 } 65 }
66 } 66 }
67 67
68 static int total_adj_strong_thresh(BLOCK_SIZE bs, int increase_denoising) { 68 int total_adj_strong_thresh(BLOCK_SIZE bs, int increase_denoising) {
69 return widths[bs] * heights[bs] * (increase_denoising ? 3 : 2); 69 return (4 << b_width_log2_lookup[bs]) *
70 (4 << b_height_log2_lookup[bs]) * (increase_denoising ? 3 : 2);
70 } 71 }
71 72
72 static int total_adj_weak_thresh(BLOCK_SIZE bs, int increase_denoising) { 73 static int total_adj_weak_thresh(BLOCK_SIZE bs, int increase_denoising) {
73 return widths[bs] * heights[bs] * (increase_denoising ? 3 : 2); 74 return (4 << b_width_log2_lookup[bs]) *
75 (4 << b_height_log2_lookup[bs]) * (increase_denoising ? 3 : 2);
74 } 76 }
75 77
76 static VP9_DENOISER_DECISION denoiser_filter(const uint8_t *sig, int sig_stride, 78 // TODO(jackychen): If increase_denoising is enabled in the future,
77 const uint8_t *mc_avg, 79 // we might need to update the code for calculating 'total_adj' in
78 int mc_avg_stride, 80 // case the C code is not bit-exact with corresponding sse2 code.
79 uint8_t *avg, int avg_stride, 81 int vp9_denoiser_filter_c(const uint8_t *sig, int sig_stride,
80 int increase_denoising, 82 const uint8_t *mc_avg,
81 BLOCK_SIZE bs, 83 int mc_avg_stride,
82 int motion_magnitude) { 84 uint8_t *avg, int avg_stride,
85 int increase_denoising,
86 BLOCK_SIZE bs,
87 int motion_magnitude) {
83 int r, c; 88 int r, c;
84 const uint8_t *sig_start = sig; 89 const uint8_t *sig_start = sig;
85 const uint8_t *mc_avg_start = mc_avg; 90 const uint8_t *mc_avg_start = mc_avg;
86 uint8_t *avg_start = avg; 91 uint8_t *avg_start = avg;
87 int diff, adj, absdiff, delta; 92 int diff, adj, absdiff, delta;
88 int adj_val[] = {3, 4, 6}; 93 int adj_val[] = {3, 4, 6};
89 int total_adj = 0; 94 int total_adj = 0;
90 int shift_inc = 1; 95 int shift_inc = 1;
91 96
92 // If motion_magnitude is small, making the denoiser more aggressive by 97 // If motion_magnitude is small, making the denoiser more aggressive by
93 // increasing the adjustment for each level. Add another increment for 98 // increasing the adjustment for each level. Add another increment for
94 // blocks that are labeled for increase denoising. 99 // blocks that are labeled for increase denoising.
95 if (motion_magnitude <= MOTION_MAGNITUDE_THRESHOLD) { 100 if (motion_magnitude <= MOTION_MAGNITUDE_THRESHOLD) {
96 if (increase_denoising) { 101 if (increase_denoising) {
97 shift_inc = 2; 102 shift_inc = 2;
98 } 103 }
99 adj_val[0] += shift_inc; 104 adj_val[0] += shift_inc;
100 adj_val[1] += shift_inc; 105 adj_val[1] += shift_inc;
101 adj_val[2] += shift_inc; 106 adj_val[2] += shift_inc;
102 } 107 }
103 108
104 // First attempt to apply a strong temporal denoising filter. 109 // First attempt to apply a strong temporal denoising filter.
105 for (r = 0; r < heights[bs]; ++r) { 110 for (r = 0; r < (4 << b_height_log2_lookup[bs]); ++r) {
106 for (c = 0; c < widths[bs]; ++c) { 111 for (c = 0; c < (4 << b_width_log2_lookup[bs]); ++c) {
107 diff = mc_avg[c] - sig[c]; 112 diff = mc_avg[c] - sig[c];
108 absdiff = abs(diff); 113 absdiff = abs(diff);
109 114
110 if (absdiff <= absdiff_thresh(bs, increase_denoising)) { 115 if (absdiff <= absdiff_thresh(bs, increase_denoising)) {
111 avg[c] = mc_avg[c]; 116 avg[c] = mc_avg[c];
112 total_adj += diff; 117 total_adj += diff;
113 } else { 118 } else {
114 switch (absdiff) { 119 switch (absdiff) {
115 case 4: case 5: case 6: case 7: 120 case 4: case 5: case 6: case 7:
116 adj = adj_val[0]; 121 adj = adj_val[0];
(...skipping 19 matching lines...) Expand all
136 mc_avg += mc_avg_stride; 141 mc_avg += mc_avg_stride;
137 } 142 }
138 143
139 // If the strong filter did not modify the signal too much, we're all set. 144 // If the strong filter did not modify the signal too much, we're all set.
140 if (abs(total_adj) <= total_adj_strong_thresh(bs, increase_denoising)) { 145 if (abs(total_adj) <= total_adj_strong_thresh(bs, increase_denoising)) {
141 return FILTER_BLOCK; 146 return FILTER_BLOCK;
142 } 147 }
143 148
144 // Otherwise, we try to dampen the filter if the delta is not too high. 149 // Otherwise, we try to dampen the filter if the delta is not too high.
145 delta = ((abs(total_adj) - total_adj_strong_thresh(bs, increase_denoising)) 150 delta = ((abs(total_adj) - total_adj_strong_thresh(bs, increase_denoising))
146 >> 8) + 1; 151 >> num_pels_log2_lookup[bs]) + 1;
147 152
148 if (delta >= delta_thresh(bs, increase_denoising)) { 153 if (delta >= delta_thresh(bs, increase_denoising)) {
149 return COPY_BLOCK; 154 return COPY_BLOCK;
150 } 155 }
151 156
152 mc_avg = mc_avg_start; 157 mc_avg = mc_avg_start;
153 avg = avg_start; 158 avg = avg_start;
154 sig = sig_start; 159 sig = sig_start;
155 for (r = 0; r < heights[bs]; ++r) { 160 for (r = 0; r < (4 << b_height_log2_lookup[bs]); ++r) {
156 for (c = 0; c < widths[bs]; ++c) { 161 for (c = 0; c < (4 << b_width_log2_lookup[bs]); ++c) {
157 diff = mc_avg[c] - sig[c]; 162 diff = mc_avg[c] - sig[c];
158 adj = abs(diff); 163 adj = abs(diff);
159 if (adj > delta) { 164 if (adj > delta) {
160 adj = delta; 165 adj = delta;
161 } 166 }
162 if (diff > 0) { 167 if (diff > 0) {
163 // Diff positive means we made positive adjustment above 168 // Diff positive means we made positive adjustment above
164 // (in first try/attempt), so now make negative adjustment to bring 169 // (in first try/attempt), so now make negative adjustment to bring
165 // denoised signal down. 170 // denoised signal down.
166 avg[c] = MAX(0, avg[c] - adj); 171 avg[c] = MAX(0, avg[c] - adj);
(...skipping 19 matching lines...) Expand all
186 } 191 }
187 192
188 static uint8_t *block_start(uint8_t *framebuf, int stride, 193 static uint8_t *block_start(uint8_t *framebuf, int stride,
189 int mi_row, int mi_col) { 194 int mi_row, int mi_col) {
190 return framebuf + (stride * mi_row * 8) + (mi_col * 8); 195 return framebuf + (stride * mi_row * 8) + (mi_col * 8);
191 } 196 }
192 197
193 static void copy_block(uint8_t *dest, int dest_stride, 198 static void copy_block(uint8_t *dest, int dest_stride,
194 const uint8_t *src, int src_stride, BLOCK_SIZE bs) { 199 const uint8_t *src, int src_stride, BLOCK_SIZE bs) {
195 int r; 200 int r;
196 for (r = 0; r < heights[bs]; ++r) { 201 for (r = 0; r < (4 << b_height_log2_lookup[bs]); ++r) {
197 vpx_memcpy(dest, src, widths[bs]); 202 vpx_memcpy(dest, src, (4 << b_width_log2_lookup[bs]));
198 dest += dest_stride; 203 dest += dest_stride;
199 src += src_stride; 204 src += src_stride;
200 } 205 }
201 } 206 }
202 207
203 static VP9_DENOISER_DECISION perform_motion_compensation(VP9_DENOISER *denoiser, 208 static VP9_DENOISER_DECISION perform_motion_compensation(VP9_DENOISER *denoiser,
204 MACROBLOCK *mb, 209 MACROBLOCK *mb,
205 BLOCK_SIZE bs, 210 BLOCK_SIZE bs,
206 int increase_denoising, 211 int increase_denoising,
207 int mi_row, 212 int mi_row,
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
329 uint8_t *mc_avg_start = block_start(mc_avg.y_buffer, mc_avg.y_stride, 334 uint8_t *mc_avg_start = block_start(mc_avg.y_buffer, mc_avg.y_stride,
330 mi_row, mi_col); 335 mi_row, mi_col);
331 struct buf_2d src = mb->plane[0].src; 336 struct buf_2d src = mb->plane[0].src;
332 337
333 decision = perform_motion_compensation(denoiser, mb, bs, 338 decision = perform_motion_compensation(denoiser, mb, bs,
334 denoiser->increase_denoising, 339 denoiser->increase_denoising,
335 mi_row, mi_col, ctx, 340 mi_row, mi_col, ctx,
336 &motion_magnitude); 341 &motion_magnitude);
337 342
338 if (decision == FILTER_BLOCK) { 343 if (decision == FILTER_BLOCK) {
339 decision = denoiser_filter(src.buf, src.stride, 344 decision = vp9_denoiser_filter(src.buf, src.stride,
340 mc_avg_start, mc_avg.y_stride, 345 mc_avg_start, mc_avg.y_stride,
341 avg_start, avg.y_stride, 346 avg_start, avg.y_stride,
342 0, bs, motion_magnitude); 347 0, bs, motion_magnitude);
343 } 348 }
344 349
345 if (decision == FILTER_BLOCK) { 350 if (decision == FILTER_BLOCK) {
346 copy_block(src.buf, src.stride, avg_start, avg.y_stride, bs); 351 copy_block(src.buf, src.stride, avg_start, avg.y_stride, bs);
347 } else { // COPY_BLOCK 352 } else { // COPY_BLOCK
348 copy_block(avg_start, avg.y_stride, src.buf, src.stride, bs); 353 copy_block(avg_start, avg.y_stride, src.buf, src.stride, bs);
349 } 354 }
350 } 355 }
351 356
352 static void copy_frame(YV12_BUFFER_CONFIG dest, const YV12_BUFFER_CONFIG src) { 357 static void copy_frame(YV12_BUFFER_CONFIG dest, const YV12_BUFFER_CONFIG src) {
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
482 for (r = 0; r < yuv->uv_height / 2; ++r) { 487 for (r = 0; r < yuv->uv_height / 2; ++r) {
483 for (c = 0; c < yuv->uv_width / 2; ++c) { 488 for (c = 0; c < yuv->uv_width / 2; ++c) {
484 u[c] = UINT8_MAX / 2; 489 u[c] = UINT8_MAX / 2;
485 v[c] = UINT8_MAX / 2; 490 v[c] = UINT8_MAX / 2;
486 } 491 }
487 u += yuv->uv_stride + yuv->uv_width / 2; 492 u += yuv->uv_stride + yuv->uv_width / 2;
488 v += yuv->uv_stride + yuv->uv_width / 2; 493 v += yuv->uv_stride + yuv->uv_width / 2;
489 } 494 }
490 } 495 }
491 #endif 496 #endif
OLDNEW
« no previous file with comments | « source/libvpx/vp9/encoder/vp9_denoiser.h ('k') | source/libvpx/vp9/encoder/vp9_encodeframe.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698