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

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

Powered by Google App Engine
This is Rietveld 408576698