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

Side by Side Diff: webrtc/modules/video_processing/test/video_processing_unittest.cc

Issue 2496153002: Delete all of the video_processing module but the denoiser code. (Closed)
Patch Set: Remove left-over source files frame_preprocessor.* Created 4 years 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
(Empty)
1 /*
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 *
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
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include "webrtc/modules/video_processing/test/video_processing_unittest.h"
12
13 #include <gflags/gflags.h>
14
15 #include <memory>
16 #include <string>
17
18 #include "webrtc/base/keep_ref_until_done.h"
19 #include "webrtc/base/timeutils.h"
20 #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
21 #include "webrtc/test/frame_utils.h"
22 #include "webrtc/test/testsupport/fileutils.h"
23
24 namespace webrtc {
25
26 namespace {
27
28 // Define command line flag 'gen_files' (default value: false).
29 DEFINE_bool(gen_files, false, "Output files for visual inspection.");
30
31 } // namespace
32
33 static void PreprocessFrameAndVerify(const VideoFrame& source,
34 int target_width,
35 int target_height,
36 VideoProcessing* vpm,
37 const VideoFrame** out_frame);
38 static rtc::scoped_refptr<VideoFrameBuffer> CropBuffer(
39 rtc::scoped_refptr<VideoFrameBuffer> source_buffer,
40 int offset_x,
41 int offset_y,
42 int cropped_width,
43 int cropped_height);
44 // The |source_data| is cropped and scaled to |target_width| x |target_height|,
45 // and then scaled back to the expected cropped size. |expected_psnr| is used to
46 // verify basic quality, and is set to be ~0.1/0.05dB lower than actual PSNR
47 // verified under the same conditions.
48 static void TestSize(
49 const VideoFrame& source_frame,
50 const VideoFrameBuffer& cropped_source_buffer,
51 int target_width,
52 int target_height,
53 double expected_psnr,
54 VideoProcessing* vpm);
55 static void WriteProcessedFrameForVisualInspection(const VideoFrame& source,
56 const VideoFrame& processed);
57
58 VideoProcessingTest::VideoProcessingTest()
59 : vp_(NULL),
60 source_file_(NULL),
61 width_(352),
62 half_width_((width_ + 1) / 2),
63 height_(288),
64 size_y_(width_ * height_),
65 size_uv_(half_width_ * ((height_ + 1) / 2)),
66 frame_length_(CalcBufferSize(kI420, width_, height_)) {}
67
68 void VideoProcessingTest::SetUp() {
69 vp_ = VideoProcessing::Create();
70 ASSERT_TRUE(vp_ != NULL);
71
72 const std::string video_file =
73 webrtc::test::ResourcePath("foreman_cif", "yuv");
74 source_file_ = fopen(video_file.c_str(), "rb");
75 ASSERT_TRUE(source_file_ != NULL)
76 << "Cannot read source file: " + video_file + "\n";
77 }
78
79 void VideoProcessingTest::TearDown() {
80 if (source_file_ != NULL) {
81 ASSERT_EQ(0, fclose(source_file_));
82 }
83 source_file_ = NULL;
84 delete vp_;
85 vp_ = NULL;
86 }
87
88 #if defined(WEBRTC_IOS)
89 TEST_F(VideoProcessingTest, DISABLED_PreprocessorLogic) {
90 #else
91 TEST_F(VideoProcessingTest, PreprocessorLogic) {
92 #endif
93 // Disable temporal sampling (frame dropping).
94 vp_->EnableTemporalDecimation(false);
95 int resolution = 100;
96 EXPECT_EQ(VPM_OK, vp_->SetTargetResolution(resolution, resolution, 15));
97 EXPECT_EQ(VPM_OK, vp_->SetTargetResolution(resolution, resolution, 30));
98 // Disable spatial sampling.
99 vp_->SetInputFrameResampleMode(kNoRescaling);
100 EXPECT_EQ(VPM_OK, vp_->SetTargetResolution(resolution, resolution, 30));
101 const VideoFrame* out_frame = NULL;
102 // Set rescaling => output frame != NULL.
103 vp_->SetInputFrameResampleMode(kFastRescaling);
104
105 rtc::scoped_refptr<webrtc::I420Buffer> buffer =
106 I420Buffer::Create(width_, height_, width_, half_width_, half_width_);
107
108 // Clear video frame so DrMemory/Valgrind will allow reads of the buffer.
109 buffer->InitializeData();
110 VideoFrame video_frame(buffer, 0, 0, webrtc::kVideoRotation_0);
111
112 PreprocessFrameAndVerify(video_frame, resolution, resolution, vp_,
113 &out_frame);
114 // No rescaling=> output frame = NULL.
115 vp_->SetInputFrameResampleMode(kNoRescaling);
116 EXPECT_TRUE(vp_->PreprocessFrame(video_frame) != nullptr);
117 }
118
119 #if defined(WEBRTC_IOS)
120 TEST_F(VideoProcessingTest, DISABLED_Resampler) {
121 #else
122 TEST_F(VideoProcessingTest, Resampler) {
123 #endif
124 enum { NumRuns = 1 };
125
126 int64_t min_runtime = 0;
127 int64_t total_runtime = 0;
128
129 rewind(source_file_);
130 ASSERT_TRUE(source_file_ != NULL) << "Cannot read input file \n";
131
132 // no temporal decimation
133 vp_->EnableTemporalDecimation(false);
134
135 // Reading test frame
136 rtc::scoped_refptr<VideoFrameBuffer> video_buffer(
137 test::ReadI420Buffer(width_, height_, source_file_));
138 ASSERT_TRUE(video_buffer);
139
140 for (uint32_t run_idx = 0; run_idx < NumRuns; run_idx++) {
141 // Initiate test timer.
142 const int64_t time_start = rtc::TimeNanos();
143
144 // Init the sourceFrame with a timestamp.
145 int64_t time_start_ms = time_start / rtc::kNumNanosecsPerMillisec;
146 VideoFrame video_frame(video_buffer, time_start_ms * 90, time_start_ms,
147 webrtc::kVideoRotation_0);
148
149 // Test scaling to different sizes: source is of |width|/|height| = 352/288.
150 // Pure scaling:
151 TestSize(video_frame, *video_buffer, width_ / 4, height_ / 4, 25.2, vp_);
152 TestSize(video_frame, *video_buffer, width_ / 2, height_ / 2, 28.1, vp_);
153 // No resampling:
154 TestSize(video_frame, *video_buffer, width_, height_, -1, vp_);
155 TestSize(video_frame, *video_buffer, 2 * width_, 2 * height_, 32.2, vp_);
156
157 // Scaling and cropping. The cropped source frame is the largest center
158 // aligned region that can be used from the source while preserving aspect
159 // ratio.
160 TestSize(video_frame, *CropBuffer(video_buffer, 0, 56, 352, 176),
161 100, 50, 24.0, vp_);
162 TestSize(video_frame, *CropBuffer(video_buffer, 0, 30, 352, 225),
163 400, 256, 31.3, vp_);
164 TestSize(video_frame, *CropBuffer(video_buffer, 68, 0, 216, 288),
165 480, 640, 32.15, vp_);
166 TestSize(video_frame, *CropBuffer(video_buffer, 0, 12, 352, 264),
167 960, 720, 32.2, vp_);
168 TestSize(video_frame, *CropBuffer(video_buffer, 0, 44, 352, 198),
169 1280, 720, 32.15, vp_);
170
171 // Upsampling to odd size.
172 TestSize(video_frame, *CropBuffer(video_buffer, 0, 26, 352, 233),
173 501, 333, 32.05, vp_);
174 // Downsample to odd size.
175 TestSize(video_frame, *CropBuffer(video_buffer, 0, 34, 352, 219),
176 281, 175, 29.3, vp_);
177
178 // Stop timer.
179 const int64_t runtime =
180 (rtc::TimeNanos() - time_start) / rtc::kNumNanosecsPerMicrosec;
181 if (runtime < min_runtime || run_idx == 0) {
182 min_runtime = runtime;
183 }
184 total_runtime += runtime;
185 }
186
187 printf("\nAverage run time = %d us / frame\n",
188 static_cast<int>(total_runtime));
189 printf("Min run time = %d us / frame\n\n", static_cast<int>(min_runtime));
190 }
191
192 void PreprocessFrameAndVerify(const VideoFrame& source,
193 int target_width,
194 int target_height,
195 VideoProcessing* vpm,
196 const VideoFrame** out_frame) {
197 ASSERT_EQ(VPM_OK, vpm->SetTargetResolution(target_width, target_height, 30));
198 *out_frame = vpm->PreprocessFrame(source);
199 EXPECT_TRUE(*out_frame != nullptr);
200
201 // If no resizing is needed, expect the original frame.
202 if (target_width == source.width() && target_height == source.height()) {
203 EXPECT_EQ(&source, *out_frame);
204 return;
205 }
206
207 // Verify the resampled frame.
208 EXPECT_EQ(source.render_time_ms(), (*out_frame)->render_time_ms());
209 EXPECT_EQ(source.timestamp(), (*out_frame)->timestamp());
210 EXPECT_EQ(target_width, (*out_frame)->width());
211 EXPECT_EQ(target_height, (*out_frame)->height());
212 }
213
214 rtc::scoped_refptr<VideoFrameBuffer> CropBuffer(
215 rtc::scoped_refptr<VideoFrameBuffer> source_buffer,
216 int offset_x,
217 int offset_y,
218 int cropped_width,
219 int cropped_height) {
220 // Force even.
221 offset_x &= ~1;
222 offset_y &= ~1;
223
224 size_t y_start = offset_x + offset_y * source_buffer->StrideY();
225 size_t u_start = (offset_x / 2) + (offset_y / 2) * source_buffer->StrideU();
226 size_t v_start = (offset_x / 2) + (offset_y / 2) * source_buffer->StrideV();
227
228 return rtc::scoped_refptr<VideoFrameBuffer>(
229 new rtc::RefCountedObject<WrappedI420Buffer>(
230 cropped_width, cropped_height, source_buffer->DataY() + y_start,
231 source_buffer->StrideY(), source_buffer->DataU() + u_start,
232 source_buffer->StrideU(), source_buffer->DataV() + v_start,
233 source_buffer->StrideV(), rtc::KeepRefUntilDone(source_buffer)));
234 }
235
236 void TestSize(const VideoFrame& source_frame,
237 const VideoFrameBuffer& cropped_source,
238 int target_width,
239 int target_height,
240 double expected_psnr,
241 VideoProcessing* vpm) {
242 // Resample source_frame to out_frame.
243 const VideoFrame* out_frame = NULL;
244 vpm->SetInputFrameResampleMode(kBox);
245 PreprocessFrameAndVerify(source_frame, target_width, target_height, vpm,
246 &out_frame);
247 if (out_frame == NULL)
248 return;
249 WriteProcessedFrameForVisualInspection(source_frame, *out_frame);
250
251 // Scale |resampled_source_frame| back to the source scale.
252 VideoFrame resampled_source_frame(*out_frame);
253 // Compute PSNR against the cropped source frame and check expectation.
254 PreprocessFrameAndVerify(resampled_source_frame,
255 cropped_source.width(),
256 cropped_source.height(), vpm, &out_frame);
257 WriteProcessedFrameForVisualInspection(resampled_source_frame, *out_frame);
258
259 // Compute PSNR against the cropped source frame and check expectation.
260 double psnr =
261 I420PSNR(cropped_source, *out_frame->video_frame_buffer());
262 EXPECT_GT(psnr, expected_psnr);
263 printf(
264 "PSNR: %f. PSNR is between source of size %d %d, and a modified "
265 "source which is scaled down/up to: %d %d, and back to source size \n",
266 psnr, source_frame.width(), source_frame.height(), target_width,
267 target_height);
268 }
269
270 void WriteProcessedFrameForVisualInspection(const VideoFrame& source,
271 const VideoFrame& processed) {
272 // Skip if writing to files is not enabled.
273 if (!FLAGS_gen_files)
274 return;
275 // Write the processed frame to file for visual inspection.
276 std::ostringstream filename;
277 filename << webrtc::test::OutputPath() << "Resampler_from_" << source.width()
278 << "x" << source.height() << "_to_" << processed.width() << "x"
279 << processed.height() << "_30Hz_P420.yuv";
280 std::cout << "Watch " << filename.str() << " and verify that it is okay."
281 << std::endl;
282 FILE* stand_alone_file = fopen(filename.str().c_str(), "wb");
283 if (PrintVideoFrame(processed, stand_alone_file) < 0)
284 std::cerr << "Failed to write: " << filename.str() << std::endl;
285 if (stand_alone_file)
286 fclose(stand_alone_file);
287 }
288
289 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698