From 6650d6d1f6a67080fd566747844a939e9f468151 Mon Sep 17 00:00:00 2001 From: jackychen Date: Mon, 25 Apr 2016 16:53:59 -0700 Subject: [PATCH] Fix an issue in external VNR when width or height not divisible by 16. When frame width or height not divisible by 16, copy the margin to denoised frame, otherwise, the margin block (smaller than 16x16) will not be updated for non-keyframe. Review URL: https://codereview.webrtc.org/1917703002 Cr-Commit-Position: refs/heads/master@{#12497} --- .../video_processing/video_denoiser.cc | 22 +++++++++++++++++++ .../modules/video_processing/video_denoiser.h | 3 +++ 2 files changed, 25 insertions(+) diff --git a/webrtc/modules/video_processing/video_denoiser.cc b/webrtc/modules/video_processing/video_denoiser.cc index e48bf5b8cd..c1cab8187d 100644 --- a/webrtc/modules/video_processing/video_denoiser.cc +++ b/webrtc/modules/video_processing/video_denoiser.cc @@ -207,6 +207,23 @@ void VideoDenoiser::CopySrcOnMOB(const uint8_t* y_src, uint8_t* y_dst) { } } +void VideoDenoiser::CopyLumaOnMargin(const uint8_t* y_src, uint8_t* y_dst) { + if ((mb_rows_ << 4) != height_) { + const uint8_t* margin_y_src = y_src + (mb_rows_ << 4) * stride_y_; + uint8_t* margin_y_dst = y_dst + (mb_rows_ << 4) * stride_y_; + memcpy(margin_y_dst, margin_y_src, (height_ - (mb_rows_ << 4)) * stride_y_); + } + if ((mb_cols_ << 4) != width_) { + const uint8_t* margin_y_src = y_src + (mb_cols_ << 4); + uint8_t* margin_y_dst = y_dst + (mb_cols_ << 4); + for (int i = 0; i < height_; ++i) { + for (int j = mb_cols_ << 4; j < width_; ++j) { + margin_y_dst[i * stride_y_ + j] = margin_y_src[i * stride_y_ + j]; + } + } + } +} + void VideoDenoiser::DenoiseFrame(const VideoFrame& frame, VideoFrame* denoised_frame, VideoFrame* denoised_frame_prev, @@ -309,6 +326,11 @@ void VideoDenoiser::DenoiseFrame(const VideoFrame& frame, CopySrcOnMOB(y_src, y_dst); + // When frame width/height not divisible by 16, copy the margin to + // denoised_frame. + if ((mb_rows_ << 4) != height_ || (mb_cols_ << 4) != width_) + CopyLumaOnMargin(y_src, y_dst); + // TODO(jackychen): Need SSE2/NEON opt. // Copy u/v planes. memcpy(u_dst, u_src, (height_ >> 1) * stride_u_); diff --git a/webrtc/modules/video_processing/video_denoiser.h b/webrtc/modules/video_processing/video_denoiser.h index 319845bf2d..114f663c03 100644 --- a/webrtc/modules/video_processing/video_denoiser.h +++ b/webrtc/modules/video_processing/video_denoiser.h @@ -52,6 +52,9 @@ class VideoDenoiser { // Copy input blocks to dst buffer on moving object blocks (MOB). void CopySrcOnMOB(const uint8_t* y_src, uint8_t* y_dst); + // Copy luma margin blocks when frame width/height not divisible by 16. + void CopyLumaOnMargin(const uint8_t* y_src, uint8_t* y_dst); + int width_; int height_; int mb_rows_;