| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |