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

Side by Side Diff: webrtc/modules/video_processing/video_denoiser.cc

Issue 2005733003: Refactor VideoDenoiser to work with I420Buffer, not VideoFrame. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Trivial rebase. Created 4 years, 6 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
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2015 The WebRTC 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 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
66 } 66 }
67 } 67 }
68 #endif 68 #endif
69 69
70 VideoDenoiser::VideoDenoiser(bool runtime_cpu_detection) 70 VideoDenoiser::VideoDenoiser(bool runtime_cpu_detection)
71 : width_(0), 71 : width_(0),
72 height_(0), 72 height_(0),
73 filter_(DenoiserFilter::Create(runtime_cpu_detection, &cpu_type_)), 73 filter_(DenoiserFilter::Create(runtime_cpu_detection, &cpu_type_)),
74 ne_(new NoiseEstimation()) {} 74 ne_(new NoiseEstimation()) {}
75 75
76 void VideoDenoiser::DenoiserReset(const VideoFrame& frame, 76 void VideoDenoiser::DenoiserReset(
77 VideoFrame* denoised_frame, 77 const rtc::scoped_refptr<VideoFrameBuffer>& frame,
78 VideoFrame* denoised_frame_prev) { 78 rtc::scoped_refptr<I420Buffer>* denoised_frame,
79 width_ = frame.width(); 79 rtc::scoped_refptr<I420Buffer>* denoised_frame_prev) {
80 height_ = frame.height(); 80 width_ = frame->width();
81 height_ = frame->height();
81 mb_cols_ = width_ >> 4; 82 mb_cols_ = width_ >> 4;
82 mb_rows_ = height_ >> 4; 83 mb_rows_ = height_ >> 4;
83 stride_y_ = frame.video_frame_buffer()->StrideY(); 84 stride_y_ = frame->StrideY();
84 stride_u_ = frame.video_frame_buffer()->StrideU(); 85 stride_u_ = frame->StrideU();
85 stride_v_ = frame.video_frame_buffer()->StrideV(); 86 stride_v_ = frame->StrideV();
86 87
87 // Allocate an empty buffer for denoised_frame_prev. 88 // Allocate an empty buffer for denoised_frame_prev.
88 denoised_frame_prev->CreateEmptyFrame(width_, height_, stride_y_, stride_u_, 89 *denoised_frame_prev = new rtc::RefCountedObject<I420Buffer>(
89 stride_v_); 90 width_, height_, stride_y_, stride_u_, stride_v_);
90 // Allocate and initialize denoised_frame with key frame. 91 // Allocate and initialize denoised_frame with key frame.
91 denoised_frame->CreateFrame( 92 *denoised_frame = I420Buffer::CopyKeepStride(frame);
92 frame.video_frame_buffer()->DataY(),
93 frame.video_frame_buffer()->DataU(),
94 frame.video_frame_buffer()->DataV(),
95 width_, height_, stride_y_, stride_u_, stride_v_, kVideoRotation_0);
96 // Set time parameters to the output frame.
97 denoised_frame->set_timestamp(frame.timestamp());
98 denoised_frame->set_render_time_ms(frame.render_time_ms());
99 93
100 // Init noise estimator and allocate buffers. 94 // Init noise estimator and allocate buffers.
101 ne_->Init(width_, height_, cpu_type_); 95 ne_->Init(width_, height_, cpu_type_);
102 moving_edge_.reset(new uint8_t[mb_cols_ * mb_rows_]); 96 moving_edge_.reset(new uint8_t[mb_cols_ * mb_rows_]);
103 mb_filter_decision_.reset(new DenoiserDecision[mb_cols_ * mb_rows_]); 97 mb_filter_decision_.reset(new DenoiserDecision[mb_cols_ * mb_rows_]);
104 x_density_.reset(new uint8_t[mb_cols_]); 98 x_density_.reset(new uint8_t[mb_cols_]);
105 y_density_.reset(new uint8_t[mb_rows_]); 99 y_density_.reset(new uint8_t[mb_rows_]);
106 moving_object_.reset(new uint8_t[mb_cols_ * mb_rows_]); 100 moving_object_.reset(new uint8_t[mb_cols_ * mb_rows_]);
107 } 101 }
108 102
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
218 const uint8_t* margin_y_src = y_src + (mb_cols_ << 4); 212 const uint8_t* margin_y_src = y_src + (mb_cols_ << 4);
219 uint8_t* margin_y_dst = y_dst + (mb_cols_ << 4); 213 uint8_t* margin_y_dst = y_dst + (mb_cols_ << 4);
220 for (int i = 0; i < height_; ++i) { 214 for (int i = 0; i < height_; ++i) {
221 for (int j = mb_cols_ << 4; j < width_; ++j) { 215 for (int j = mb_cols_ << 4; j < width_; ++j) {
222 margin_y_dst[i * stride_y_ + j] = margin_y_src[i * stride_y_ + j]; 216 margin_y_dst[i * stride_y_ + j] = margin_y_src[i * stride_y_ + j];
223 } 217 }
224 } 218 }
225 } 219 }
226 } 220 }
227 221
228 void VideoDenoiser::DenoiseFrame(const VideoFrame& frame, 222 void VideoDenoiser::DenoiseFrame(
229 VideoFrame* denoised_frame, 223 const rtc::scoped_refptr<VideoFrameBuffer>& frame,
230 VideoFrame* denoised_frame_prev, 224 rtc::scoped_refptr<I420Buffer>* denoised_frame,
231 bool noise_estimation_enabled) { 225 rtc::scoped_refptr<I420Buffer>* denoised_frame_prev,
226 bool noise_estimation_enabled) {
232 // If previous width and height are different from current frame's, need to 227 // If previous width and height are different from current frame's, need to
233 // reallocate the buffers and no denoising for the current frame. 228 // reallocate the buffers and no denoising for the current frame.
234 if (width_ != frame.width() || height_ != frame.height()) { 229 if (width_ != frame->width() || height_ != frame->height()) {
235 DenoiserReset(frame, denoised_frame, denoised_frame_prev); 230 DenoiserReset(frame, denoised_frame, denoised_frame_prev);
236 return; 231 return;
237 } 232 }
238 233
239 // Set buffer pointers. 234 // Set buffer pointers.
240 const uint8_t* y_src = frame.video_frame_buffer()->DataY(); 235 const uint8_t* y_src = frame->DataY();
241 const uint8_t* u_src = frame.video_frame_buffer()->DataU(); 236 const uint8_t* u_src = frame->DataU();
242 const uint8_t* v_src = frame.video_frame_buffer()->DataV(); 237 const uint8_t* v_src = frame->DataV();
243 uint8_t* y_dst = denoised_frame->video_frame_buffer()->MutableDataY(); 238 uint8_t* y_dst = (*denoised_frame)->MutableDataY();
244 uint8_t* u_dst = denoised_frame->video_frame_buffer()->MutableDataU(); 239 uint8_t* u_dst = (*denoised_frame)->MutableDataU();
245 uint8_t* v_dst = denoised_frame->video_frame_buffer()->MutableDataV(); 240 uint8_t* v_dst = (*denoised_frame)->MutableDataV();
246 uint8_t* y_dst_prev = 241 uint8_t* y_dst_prev = (*denoised_frame_prev)->MutableDataY();
247 denoised_frame_prev->video_frame_buffer()->MutableDataY();
248 memset(x_density_.get(), 0, mb_cols_); 242 memset(x_density_.get(), 0, mb_cols_);
249 memset(y_density_.get(), 0, mb_rows_); 243 memset(y_density_.get(), 0, mb_rows_);
250 memset(moving_object_.get(), 1, mb_cols_ * mb_rows_); 244 memset(moving_object_.get(), 1, mb_cols_ * mb_rows_);
251 245
252 uint8_t noise_level = noise_estimation_enabled ? ne_->GetNoiseLevel() : 0; 246 uint8_t noise_level = noise_estimation_enabled ? ne_->GetNoiseLevel() : 0;
253 int thr_var_base = 16 * 16 * 2; 247 int thr_var_base = 16 * 16 * 2;
254 // Loop over blocks to accumulate/extract noise level and update x/y_density 248 // Loop over blocks to accumulate/extract noise level and update x/y_density
255 // factors for moving object detection. 249 // factors for moving object detection.
256 for (int mb_row = 0; mb_row < mb_rows_; ++mb_row) { 250 for (int mb_row = 0; mb_row < mb_rows_; ++mb_row) {
257 const int mb_index_base = mb_row * mb_cols_; 251 const int mb_index_base = mb_row * mb_cols_;
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
331 // When frame width/height not divisible by 16, copy the margin to 325 // When frame width/height not divisible by 16, copy the margin to
332 // denoised_frame. 326 // denoised_frame.
333 if ((mb_rows_ << 4) != height_ || (mb_cols_ << 4) != width_) 327 if ((mb_rows_ << 4) != height_ || (mb_cols_ << 4) != width_)
334 CopyLumaOnMargin(y_src, y_dst); 328 CopyLumaOnMargin(y_src, y_dst);
335 329
336 // TODO(jackychen): Need SSE2/NEON opt. 330 // TODO(jackychen): Need SSE2/NEON opt.
337 // Copy u/v planes. 331 // Copy u/v planes.
338 memcpy(u_dst, u_src, (height_ >> 1) * stride_u_); 332 memcpy(u_dst, u_src, (height_ >> 1) * stride_u_);
339 memcpy(v_dst, v_src, (height_ >> 1) * stride_v_); 333 memcpy(v_dst, v_src, (height_ >> 1) * stride_v_);
340 334
341 // Set time parameters to the output frame.
342 denoised_frame->set_timestamp(frame.timestamp());
343 denoised_frame->set_render_time_ms(frame.render_time_ms());
344
345 #if DISPLAY || DISPLAYNEON 335 #if DISPLAY || DISPLAYNEON
346 // Show rectangular region 336 // Show rectangular region
347 ShowRect(filter_, moving_edge_, moving_object_, x_density_, y_density_, u_src, 337 ShowRect(filter_, moving_edge_, moving_object_, x_density_, y_density_, u_src,
348 v_src, u_dst, v_dst, mb_rows_, mb_cols_, stride_u_, stride_v_); 338 v_src, u_dst, v_dst, mb_rows_, mb_cols_, stride_u_, stride_v_);
349 #endif 339 #endif
350 } 340 }
351 341
352 } // namespace webrtc 342 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698