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

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

Issue 812033011: libvpx: Pull from upstream (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/deps/third_party/libvpx/
Patch Set: Created 5 years, 11 months 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.h » ('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 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
42 return 4; 42 return 4;
43 } 43 }
44 44
45 static int noise_motion_thresh(BLOCK_SIZE bs, int increase_denoising) { 45 static int noise_motion_thresh(BLOCK_SIZE bs, int increase_denoising) {
46 (void)bs; 46 (void)bs;
47 (void)increase_denoising; 47 (void)increase_denoising;
48 return 25 * 25; 48 return 25 * 25;
49 } 49 }
50 50
51 static unsigned int sse_thresh(BLOCK_SIZE bs, int increase_denoising) { 51 static unsigned int sse_thresh(BLOCK_SIZE bs, int increase_denoising) {
52 return (4 << b_width_log2_lookup[bs]) * 52 return (1 << num_pels_log2_lookup[bs]) * (increase_denoising ? 60 : 40);
53 (4 << b_height_log2_lookup[bs]) *
54 (increase_denoising ? 60 : 40);
55 } 53 }
56 54
57 static int sse_diff_thresh(BLOCK_SIZE bs, int increase_denoising, 55 static int sse_diff_thresh(BLOCK_SIZE bs, int increase_denoising,
58 int mv_row, int mv_col) { 56 int mv_row, int mv_col) {
59 if (mv_row * mv_row + mv_col * mv_col > 57 if (mv_row * mv_row + mv_col * mv_col >
60 noise_motion_thresh(bs, increase_denoising)) { 58 noise_motion_thresh(bs, increase_denoising)) {
61 return 0; 59 return 0;
62 } else { 60 } else {
63 return (4 << b_width_log2_lookup[bs]) * 61 return (1 << num_pels_log2_lookup[bs]) * 20;
64 (4 << b_height_log2_lookup[bs]) * 20;
65 } 62 }
66 } 63 }
67 64
68 int total_adj_strong_thresh(BLOCK_SIZE bs, int increase_denoising) { 65 int total_adj_strong_thresh(BLOCK_SIZE bs, int increase_denoising) {
69 return (4 << b_width_log2_lookup[bs]) * 66 return (1 << num_pels_log2_lookup[bs]) * (increase_denoising ? 3 : 2);
70 (4 << b_height_log2_lookup[bs]) * (increase_denoising ? 3 : 2);
71 } 67 }
72 68
73 static int total_adj_weak_thresh(BLOCK_SIZE bs, int increase_denoising) { 69 static int total_adj_weak_thresh(BLOCK_SIZE bs, int increase_denoising) {
74 return (4 << b_width_log2_lookup[bs]) * 70 return (1 << num_pels_log2_lookup[bs]) * (increase_denoising ? 3 : 2);
75 (4 << b_height_log2_lookup[bs]) * (increase_denoising ? 3 : 2);
76 } 71 }
77 72
78 // TODO(jackychen): If increase_denoising is enabled in the future, 73 // TODO(jackychen): If increase_denoising is enabled in the future,
79 // we might need to update the code for calculating 'total_adj' in 74 // we might need to update the code for calculating 'total_adj' in
80 // case the C code is not bit-exact with corresponding sse2 code. 75 // case the C code is not bit-exact with corresponding sse2 code.
81 int vp9_denoiser_filter_c(const uint8_t *sig, int sig_stride, 76 int vp9_denoiser_filter_c(const uint8_t *sig, int sig_stride,
82 const uint8_t *mc_avg, 77 const uint8_t *mc_avg,
83 int mc_avg_stride, 78 int mc_avg_stride,
84 uint8_t *avg, int avg_stride, 79 uint8_t *avg, int avg_stride,
85 int increase_denoising, 80 int increase_denoising,
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
188 return FILTER_BLOCK; 183 return FILTER_BLOCK;
189 } 184 }
190 return COPY_BLOCK; 185 return COPY_BLOCK;
191 } 186 }
192 187
193 static uint8_t *block_start(uint8_t *framebuf, int stride, 188 static uint8_t *block_start(uint8_t *framebuf, int stride,
194 int mi_row, int mi_col) { 189 int mi_row, int mi_col) {
195 return framebuf + (stride * mi_row * 8) + (mi_col * 8); 190 return framebuf + (stride * mi_row * 8) + (mi_col * 8);
196 } 191 }
197 192
198 static void copy_block(uint8_t *dest, int dest_stride,
199 const uint8_t *src, int src_stride, BLOCK_SIZE bs) {
200 int r;
201 for (r = 0; r < (4 << b_height_log2_lookup[bs]); ++r) {
202 vpx_memcpy(dest, src, (4 << b_width_log2_lookup[bs]));
203 dest += dest_stride;
204 src += src_stride;
205 }
206 }
207
208 static VP9_DENOISER_DECISION perform_motion_compensation(VP9_DENOISER *denoiser, 193 static VP9_DENOISER_DECISION perform_motion_compensation(VP9_DENOISER *denoiser,
209 MACROBLOCK *mb, 194 MACROBLOCK *mb,
210 BLOCK_SIZE bs, 195 BLOCK_SIZE bs,
211 int increase_denoising, 196 int increase_denoising,
212 int mi_row, 197 int mi_row,
213 int mi_col, 198 int mi_col,
214 PICK_MODE_CONTEXT *ctx, 199 PICK_MODE_CONTEXT *ctx,
215 int *motion_magnitude 200 int *motion_magnitude
216 ) { 201 ) {
217 int mv_col, mv_row; 202 int mv_col, mv_row;
218 int sse_diff = ctx->zeromv_sse - ctx->newmv_sse; 203 int sse_diff = ctx->zeromv_sse - ctx->newmv_sse;
219 MV_REFERENCE_FRAME frame; 204 MV_REFERENCE_FRAME frame;
220 MACROBLOCKD *filter_mbd = &mb->e_mbd; 205 MACROBLOCKD *filter_mbd = &mb->e_mbd;
221 MB_MODE_INFO *mbmi = &filter_mbd->mi[0].src_mi->mbmi; 206 MB_MODE_INFO *mbmi = &filter_mbd->mi[0].src_mi->mbmi;
222
223 MB_MODE_INFO saved_mbmi; 207 MB_MODE_INFO saved_mbmi;
224 int i, j; 208 int i, j;
225 struct buf_2d saved_dst[MAX_MB_PLANE]; 209 struct buf_2d saved_dst[MAX_MB_PLANE];
226 struct buf_2d saved_pre[MAX_MB_PLANE][2]; // 2 pre buffers 210 struct buf_2d saved_pre[MAX_MB_PLANE][2]; // 2 pre buffers
227 211
228 // We will restore these after motion compensation.
229 saved_mbmi = *mbmi;
230 for (i = 0; i < MAX_MB_PLANE; ++i) {
231 for (j = 0; j < 2; ++j) {
232 saved_pre[i][j] = filter_mbd->plane[i].pre[j];
233 }
234 saved_dst[i] = filter_mbd->plane[i].dst;
235 }
236
237 mv_col = ctx->best_sse_mv.as_mv.col; 212 mv_col = ctx->best_sse_mv.as_mv.col;
238 mv_row = ctx->best_sse_mv.as_mv.row; 213 mv_row = ctx->best_sse_mv.as_mv.row;
214 *motion_magnitude = mv_row * mv_row + mv_col * mv_col;
215 frame = ctx->best_reference_frame;
239 216
240 *motion_magnitude = mv_row * mv_row + mv_col * mv_col; 217 saved_mbmi = *mbmi;
241
242 frame = ctx->best_reference_frame;
243 218
244 // If the best reference frame uses inter-prediction and there is enough of a 219 // If the best reference frame uses inter-prediction and there is enough of a
245 // difference in sum-squared-error, use it. 220 // difference in sum-squared-error, use it.
246 if (frame != INTRA_FRAME && 221 if (frame != INTRA_FRAME &&
247 sse_diff > sse_diff_thresh(bs, increase_denoising, mv_row, mv_col)) { 222 sse_diff > sse_diff_thresh(bs, increase_denoising, mv_row, mv_col)) {
248 mbmi->ref_frame[0] = ctx->best_reference_frame; 223 mbmi->ref_frame[0] = ctx->best_reference_frame;
249 mbmi->mode = ctx->best_sse_inter_mode; 224 mbmi->mode = ctx->best_sse_inter_mode;
250 mbmi->mv[0] = ctx->best_sse_mv; 225 mbmi->mv[0] = ctx->best_sse_mv;
251 } else { 226 } else {
252 // Otherwise, use the zero reference frame. 227 // Otherwise, use the zero reference frame.
253 frame = ctx->best_zeromv_reference_frame; 228 frame = ctx->best_zeromv_reference_frame;
254 229
255 mbmi->ref_frame[0] = ctx->best_zeromv_reference_frame; 230 mbmi->ref_frame[0] = ctx->best_zeromv_reference_frame;
256 mbmi->mode = ZEROMV; 231 mbmi->mode = ZEROMV;
257 mbmi->mv[0].as_int = 0; 232 mbmi->mv[0].as_int = 0;
258 233
259 ctx->best_sse_inter_mode = ZEROMV; 234 ctx->best_sse_inter_mode = ZEROMV;
260 ctx->best_sse_mv.as_int = 0; 235 ctx->best_sse_mv.as_int = 0;
261 ctx->newmv_sse = ctx->zeromv_sse; 236 ctx->newmv_sse = ctx->zeromv_sse;
262 } 237 }
263 238
239 if (ctx->newmv_sse > sse_thresh(bs, increase_denoising)) {
240 // Restore everything to its original state
241 *mbmi = saved_mbmi;
242 return COPY_BLOCK;
243 }
244 if (mv_row * mv_row + mv_col * mv_col >
245 8 * noise_motion_thresh(bs, increase_denoising)) {
246 // Restore everything to its original state
247 *mbmi = saved_mbmi;
248 return COPY_BLOCK;
249 }
250
251 // We will restore these after motion compensation.
252 for (i = 0; i < MAX_MB_PLANE; ++i) {
253 for (j = 0; j < 2; ++j) {
254 saved_pre[i][j] = filter_mbd->plane[i].pre[j];
255 }
256 saved_dst[i] = filter_mbd->plane[i].dst;
257 }
258
264 // Set the pointers in the MACROBLOCKD to point to the buffers in the denoiser 259 // Set the pointers in the MACROBLOCKD to point to the buffers in the denoiser
265 // struct. 260 // struct.
266 for (j = 0; j < 2; ++j) { 261 for (j = 0; j < 2; ++j) {
267 filter_mbd->plane[0].pre[j].buf = 262 filter_mbd->plane[0].pre[j].buf =
268 block_start(denoiser->running_avg_y[frame].y_buffer, 263 block_start(denoiser->running_avg_y[frame].y_buffer,
269 denoiser->running_avg_y[frame].y_stride, 264 denoiser->running_avg_y[frame].y_stride,
270 mi_row, mi_col); 265 mi_row, mi_col);
271 filter_mbd->plane[0].pre[j].stride = 266 filter_mbd->plane[0].pre[j].stride =
272 denoiser->running_avg_y[frame].y_stride; 267 denoiser->running_avg_y[frame].y_stride;
273 filter_mbd->plane[1].pre[j].buf = 268 filter_mbd->plane[1].pre[j].buf =
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
306 for (i = 0; i < MAX_MB_PLANE; ++i) { 301 for (i = 0; i < MAX_MB_PLANE; ++i) {
307 for (j = 0; j < 2; ++j) { 302 for (j = 0; j < 2; ++j) {
308 filter_mbd->plane[i].pre[j] = saved_pre[i][j]; 303 filter_mbd->plane[i].pre[j] = saved_pre[i][j];
309 } 304 }
310 filter_mbd->plane[i].dst = saved_dst[i]; 305 filter_mbd->plane[i].dst = saved_dst[i];
311 } 306 }
312 307
313 mv_row = ctx->best_sse_mv.as_mv.row; 308 mv_row = ctx->best_sse_mv.as_mv.row;
314 mv_col = ctx->best_sse_mv.as_mv.col; 309 mv_col = ctx->best_sse_mv.as_mv.col;
315 310
316 if (ctx->newmv_sse > sse_thresh(bs, increase_denoising)) {
317 return COPY_BLOCK;
318 }
319 if (mv_row * mv_row + mv_col * mv_col >
320 8 * noise_motion_thresh(bs, increase_denoising)) {
321 return COPY_BLOCK;
322 }
323 return FILTER_BLOCK; 311 return FILTER_BLOCK;
324 } 312 }
325 313
326 void vp9_denoiser_denoise(VP9_DENOISER *denoiser, MACROBLOCK *mb, 314 void vp9_denoiser_denoise(VP9_DENOISER *denoiser, MACROBLOCK *mb,
327 int mi_row, int mi_col, BLOCK_SIZE bs, 315 int mi_row, int mi_col, BLOCK_SIZE bs,
328 PICK_MODE_CONTEXT *ctx) { 316 PICK_MODE_CONTEXT *ctx) {
329 int motion_magnitude = 0; 317 int motion_magnitude = 0;
330 VP9_DENOISER_DECISION decision = FILTER_BLOCK; 318 VP9_DENOISER_DECISION decision = FILTER_BLOCK;
331 YV12_BUFFER_CONFIG avg = denoiser->running_avg_y[INTRA_FRAME]; 319 YV12_BUFFER_CONFIG avg = denoiser->running_avg_y[INTRA_FRAME];
332 YV12_BUFFER_CONFIG mc_avg = denoiser->mc_running_avg_y; 320 YV12_BUFFER_CONFIG mc_avg = denoiser->mc_running_avg_y;
333 uint8_t *avg_start = block_start(avg.y_buffer, avg.y_stride, mi_row, mi_col); 321 uint8_t *avg_start = block_start(avg.y_buffer, avg.y_stride, mi_row, mi_col);
334 uint8_t *mc_avg_start = block_start(mc_avg.y_buffer, mc_avg.y_stride, 322 uint8_t *mc_avg_start = block_start(mc_avg.y_buffer, mc_avg.y_stride,
335 mi_row, mi_col); 323 mi_row, mi_col);
336 struct buf_2d src = mb->plane[0].src; 324 struct buf_2d src = mb->plane[0].src;
337 325
338 decision = perform_motion_compensation(denoiser, mb, bs, 326 decision = perform_motion_compensation(denoiser, mb, bs,
339 denoiser->increase_denoising, 327 denoiser->increase_denoising,
340 mi_row, mi_col, ctx, 328 mi_row, mi_col, ctx,
341 &motion_magnitude); 329 &motion_magnitude);
342 330
343 if (decision == FILTER_BLOCK) { 331 if (decision == FILTER_BLOCK) {
344 decision = vp9_denoiser_filter(src.buf, src.stride, 332 decision = vp9_denoiser_filter(src.buf, src.stride,
345 mc_avg_start, mc_avg.y_stride, 333 mc_avg_start, mc_avg.y_stride,
346 avg_start, avg.y_stride, 334 avg_start, avg.y_stride,
347 0, bs, motion_magnitude); 335 0, bs, motion_magnitude);
348 } 336 }
349 337
350 if (decision == FILTER_BLOCK) { 338 if (decision == FILTER_BLOCK) {
351 copy_block(src.buf, src.stride, avg_start, avg.y_stride, bs); 339 vp9_convolve_copy(avg_start, avg.y_stride, src.buf, src.stride,
340 NULL, 0, NULL, 0,
341 num_4x4_blocks_wide_lookup[bs] << 2,
342 num_4x4_blocks_high_lookup[bs] << 2);
352 } else { // COPY_BLOCK 343 } else { // COPY_BLOCK
353 copy_block(avg_start, avg.y_stride, src.buf, src.stride, bs); 344 vp9_convolve_copy(src.buf, src.stride, avg_start, avg.y_stride,
345 NULL, 0, NULL, 0,
346 num_4x4_blocks_wide_lookup[bs] << 2,
347 num_4x4_blocks_high_lookup[bs] << 2);
354 } 348 }
355 } 349 }
356 350
357 static void copy_frame(YV12_BUFFER_CONFIG dest, const YV12_BUFFER_CONFIG src) { 351 static void copy_frame(YV12_BUFFER_CONFIG dest, const YV12_BUFFER_CONFIG src) {
358 int r; 352 int r;
359 const uint8_t *srcbuf = src.y_buffer; 353 const uint8_t *srcbuf = src.y_buffer;
360 uint8_t *destbuf = dest.y_buffer; 354 uint8_t *destbuf = dest.y_buffer;
361 assert(dest.y_width == src.y_width); 355 assert(dest.y_width == src.y_width);
362 assert(dest.y_height == src.y_height); 356 assert(dest.y_height == src.y_height);
363 357
364 for (r = 0; r < dest.y_height; ++r) { 358 for (r = 0; r < dest.y_height; ++r) {
365 vpx_memcpy(destbuf, srcbuf, dest.y_width); 359 vpx_memcpy(destbuf, srcbuf, dest.y_width);
366 destbuf += dest.y_stride; 360 destbuf += dest.y_stride;
367 srcbuf += src.y_stride; 361 srcbuf += src.y_stride;
368 } 362 }
369 } 363 }
370 364
365 static void swap_frame_buffer(YV12_BUFFER_CONFIG dest,
366 YV12_BUFFER_CONFIG src) {
367 uint8_t *tmp_buf = dest.y_buffer;
368 assert(dest.y_width == src.y_width);
369 assert(dest.y_height == src.y_height);
370 dest.y_buffer = src.y_buffer;
371 src.y_buffer = tmp_buf;
372 }
373
371 void vp9_denoiser_update_frame_info(VP9_DENOISER *denoiser, 374 void vp9_denoiser_update_frame_info(VP9_DENOISER *denoiser,
372 YV12_BUFFER_CONFIG src, 375 YV12_BUFFER_CONFIG src,
373 FRAME_TYPE frame_type, 376 FRAME_TYPE frame_type,
374 int refresh_alt_ref_frame, 377 int refresh_alt_ref_frame,
375 int refresh_golden_frame, 378 int refresh_golden_frame,
376 int refresh_last_frame) { 379 int refresh_last_frame) {
377 if (frame_type == KEY_FRAME) { 380 if (frame_type == KEY_FRAME) {
378 int i; 381 int i;
379 // Start at 1 so as not to overwrite the INTRA_FRAME 382 // Start at 1 so as not to overwrite the INTRA_FRAME
380 for (i = 1; i < MAX_REF_FRAMES; ++i) { 383 for (i = 1; i < MAX_REF_FRAMES; ++i)
381 copy_frame(denoiser->running_avg_y[i], src); 384 copy_frame(denoiser->running_avg_y[i], src);
382 } 385 return;
383 } else { /* For non key frames */ 386 }
384 if (refresh_alt_ref_frame) { 387
385 copy_frame(denoiser->running_avg_y[ALTREF_FRAME], 388 /* For non key frames */
386 denoiser->running_avg_y[INTRA_FRAME]); 389 if (refresh_alt_ref_frame) {
387 } 390 swap_frame_buffer(denoiser->running_avg_y[ALTREF_FRAME],
388 if (refresh_golden_frame) { 391 denoiser->running_avg_y[INTRA_FRAME]);
389 copy_frame(denoiser->running_avg_y[GOLDEN_FRAME], 392 }
390 denoiser->running_avg_y[INTRA_FRAME]); 393 if (refresh_golden_frame) {
391 } 394 swap_frame_buffer(denoiser->running_avg_y[GOLDEN_FRAME],
392 if (refresh_last_frame) { 395 denoiser->running_avg_y[INTRA_FRAME]);
393 copy_frame(denoiser->running_avg_y[LAST_FRAME], 396 }
394 denoiser->running_avg_y[INTRA_FRAME]); 397 if (refresh_last_frame) {
395 } 398 swap_frame_buffer(denoiser->running_avg_y[LAST_FRAME],
399 denoiser->running_avg_y[INTRA_FRAME]);
396 } 400 }
397 } 401 }
398 402
399 void vp9_denoiser_reset_frame_stats(PICK_MODE_CONTEXT *ctx) { 403 void vp9_denoiser_reset_frame_stats(PICK_MODE_CONTEXT *ctx) {
400 ctx->zeromv_sse = UINT_MAX; 404 ctx->zeromv_sse = UINT_MAX;
401 ctx->newmv_sse = UINT_MAX; 405 // This should be initialized as zero since mode search stage might skip
406 // NEWMV mode if inferred motion vector modes provide sufficiently good
407 // prediction quality.
408 ctx->newmv_sse = 0;
402 } 409 }
403 410
404 void vp9_denoiser_update_frame_stats(MB_MODE_INFO *mbmi, unsigned int sse, 411 void vp9_denoiser_update_frame_stats(MB_MODE_INFO *mbmi, unsigned int sse,
405 PREDICTION_MODE mode, 412 PREDICTION_MODE mode,
406 PICK_MODE_CONTEXT *ctx) { 413 PICK_MODE_CONTEXT *ctx) {
407 // TODO(tkopp): Use both MVs if possible 414 // TODO(tkopp): Use both MVs if possible
408 if (mbmi->mv[0].as_int == 0 && sse < ctx->zeromv_sse) { 415 if (mbmi->mv[0].as_int == 0 && sse < ctx->zeromv_sse) {
409 ctx->zeromv_sse = sse; 416 ctx->zeromv_sse = sse;
410 ctx->best_zeromv_reference_frame = mbmi->ref_frame[0]; 417 ctx->best_zeromv_reference_frame = mbmi->ref_frame[0];
411 } 418 }
412 419
413 if (mode == NEWMV) { 420 if (mode == NEWMV) {
414 ctx->newmv_sse = sse; 421 ctx->newmv_sse = sse;
415 ctx->best_sse_inter_mode = mode; 422 ctx->best_sse_inter_mode = mode;
416 ctx->best_sse_mv = mbmi->mv[0]; 423 ctx->best_sse_mv = mbmi->mv[0];
417 ctx->best_reference_frame = mbmi->ref_frame[0]; 424 ctx->best_reference_frame = mbmi->ref_frame[0];
418 } 425 }
419 } 426 }
420 427
421 int vp9_denoiser_alloc(VP9_DENOISER *denoiser, int width, int height, 428 int vp9_denoiser_alloc(VP9_DENOISER *denoiser, int width, int height,
422 int ssx, int ssy, 429 int ssx, int ssy,
423 #if CONFIG_VP9_HIGHBITDEPTH 430 #if CONFIG_VP9_HIGHBITDEPTH
424 int use_highbitdepth, 431 int use_highbitdepth,
425 #endif 432 #endif
426 int border) { 433 int border) {
427 int i, fail; 434 int i, fail;
435 const int legacy_byte_alignment = 0;
428 assert(denoiser != NULL); 436 assert(denoiser != NULL);
429 437
430 for (i = 0; i < MAX_REF_FRAMES; ++i) { 438 for (i = 0; i < MAX_REF_FRAMES; ++i) {
431 fail = vp9_alloc_frame_buffer(&denoiser->running_avg_y[i], width, height, 439 fail = vp9_alloc_frame_buffer(&denoiser->running_avg_y[i], width, height,
432 ssx, ssy, 440 ssx, ssy,
433 #if CONFIG_VP9_HIGHBITDEPTH 441 #if CONFIG_VP9_HIGHBITDEPTH
434 use_highbitdepth, 442 use_highbitdepth,
435 #endif 443 #endif
436 border); 444 border, legacy_byte_alignment);
437 if (fail) { 445 if (fail) {
438 vp9_denoiser_free(denoiser); 446 vp9_denoiser_free(denoiser);
439 return 1; 447 return 1;
440 } 448 }
441 #ifdef OUTPUT_YUV_DENOISED 449 #ifdef OUTPUT_YUV_DENOISED
442 make_grayscale(&denoiser->running_avg_y[i]); 450 make_grayscale(&denoiser->running_avg_y[i]);
443 #endif 451 #endif
444 } 452 }
445 453
446 fail = vp9_alloc_frame_buffer(&denoiser->mc_running_avg_y, width, height, 454 fail = vp9_alloc_frame_buffer(&denoiser->mc_running_avg_y, width, height,
447 ssx, ssy, 455 ssx, ssy,
448 #if CONFIG_VP9_HIGHBITDEPTH 456 #if CONFIG_VP9_HIGHBITDEPTH
449 use_highbitdepth, 457 use_highbitdepth,
450 #endif 458 #endif
451 border); 459 border, legacy_byte_alignment);
452 if (fail) { 460 if (fail) {
453 vp9_denoiser_free(denoiser); 461 vp9_denoiser_free(denoiser);
454 return 1; 462 return 1;
455 } 463 }
456 #ifdef OUTPUT_YUV_DENOISED 464 #ifdef OUTPUT_YUV_DENOISED
457 make_grayscale(&denoiser->running_avg_y[i]); 465 make_grayscale(&denoiser->running_avg_y[i]);
458 #endif 466 #endif
459 denoiser->increase_denoising = 0; 467 denoiser->increase_denoising = 0;
468 denoiser->frame_buffer_initialized = 1;
460 469
461 return 0; 470 return 0;
462 } 471 }
463 472
464 void vp9_denoiser_free(VP9_DENOISER *denoiser) { 473 void vp9_denoiser_free(VP9_DENOISER *denoiser) {
465 int i; 474 int i;
475 denoiser->frame_buffer_initialized = 0;
466 if (denoiser == NULL) { 476 if (denoiser == NULL) {
467 return; 477 return;
468 } 478 }
469 for (i = 0; i < MAX_REF_FRAMES; ++i) { 479 for (i = 0; i < MAX_REF_FRAMES; ++i) {
470 if (&denoiser->running_avg_y[i] != NULL) { 480 if (&denoiser->running_avg_y[i] != NULL) {
471 vp9_free_frame_buffer(&denoiser->running_avg_y[i]); 481 vp9_free_frame_buffer(&denoiser->running_avg_y[i]);
472 } 482 }
473 } 483 }
474 if (&denoiser->mc_running_avg_y != NULL) { 484 if (&denoiser->mc_running_avg_y != NULL) {
475 vp9_free_frame_buffer(&denoiser->mc_running_avg_y); 485 vp9_free_frame_buffer(&denoiser->mc_running_avg_y);
476 } 486 }
477 } 487 }
478 488
479 #ifdef OUTPUT_YUV_DENOISED 489 #ifdef OUTPUT_YUV_DENOISED
480 static void make_grayscale(YV12_BUFFER_CONFIG *yuv) { 490 static void make_grayscale(YV12_BUFFER_CONFIG *yuv) {
481 int r, c; 491 int r, c;
482 uint8_t *u = yuv->u_buffer; 492 uint8_t *u = yuv->u_buffer;
483 uint8_t *v = yuv->v_buffer; 493 uint8_t *v = yuv->v_buffer;
484 494
485 // The '/2's are there because we have a 440 buffer, but we want to output 495 for (r = 0; r < yuv->uv_height; ++r) {
486 // 420. 496 for (c = 0; c < yuv->uv_width; ++c) {
487 for (r = 0; r < yuv->uv_height / 2; ++r) {
488 for (c = 0; c < yuv->uv_width / 2; ++c) {
489 u[c] = UINT8_MAX / 2; 497 u[c] = UINT8_MAX / 2;
490 v[c] = UINT8_MAX / 2; 498 v[c] = UINT8_MAX / 2;
491 } 499 }
492 u += yuv->uv_stride + yuv->uv_width / 2; 500 u += yuv->uv_stride;
493 v += yuv->uv_stride + yuv->uv_width / 2; 501 v += yuv->uv_stride;
494 } 502 }
495 } 503 }
496 #endif 504 #endif
OLDNEW
« no previous file with comments | « source/libvpx/vp9/encoder/vp9_denoiser.h ('k') | source/libvpx/vp9/encoder/vp9_encodeframe.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698