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

Side by Side Diff: remoting/codec/codec_test.cc

Issue 1264743002: Make video encoder/decoder test faster (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix ASan failure Created 5 years, 4 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
« no previous file with comments | « no previous file | remoting/codec/video_encoder_vpx_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <deque> 5 #include <deque>
6 #include <stdlib.h> 6 #include <stdlib.h>
7 7
8 #include "base/bind.h" 8 #include "base/bind.h"
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/memory/scoped_ptr.h" 10 #include "base/memory/scoped_ptr.h"
11 #include "media/base/video_frame.h" 11 #include "media/base/video_frame.h"
12 #include "remoting/codec/codec_test.h" 12 #include "remoting/codec/codec_test.h"
13 #include "remoting/codec/video_decoder.h" 13 #include "remoting/codec/video_decoder.h"
14 #include "remoting/codec/video_encoder.h" 14 #include "remoting/codec/video_encoder.h"
15 #include "remoting/base/util.h" 15 #include "remoting/base/util.h"
16 #include "testing/gtest/include/gtest/gtest.h" 16 #include "testing/gtest/include/gtest/gtest.h"
17 #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h" 17 #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h"
18 18
19 using webrtc::BasicDesktopFrame; 19 using webrtc::BasicDesktopFrame;
20 using webrtc::DesktopFrame; 20 using webrtc::DesktopFrame;
21 using webrtc::DesktopRect; 21 using webrtc::DesktopRect;
22 using webrtc::DesktopRegion; 22 using webrtc::DesktopRegion;
23 using webrtc::DesktopSize; 23 using webrtc::DesktopSize;
24 24
25 namespace { 25 namespace {
26 26
27 const int kBytesPerPixel = 4; 27 const int kBytesPerPixel = 4;
28 28
29 // Some sample rects for testing. 29 // Some sample rects for testing.
30 std::vector<std::vector<DesktopRect> > MakeTestRectLists(DesktopSize size) { 30 std::vector<DesktopRegion> MakeTestRegionLists(DesktopSize size) {
31 std::vector<std::vector<DesktopRect> > rect_lists; 31 std::vector<DesktopRegion> region_lists;
32 std::vector<DesktopRect> rects; 32 DesktopRegion region;
33 rects.push_back(DesktopRect::MakeXYWH(0, 0, size.width(), size.height())); 33 region.AddRect(DesktopRect::MakeXYWH(0, 0, size.width(), size.height()));
34 rect_lists.push_back(rects); 34 region_lists.push_back(region);
35 rects.clear(); 35 region.Clear();
36 rects.push_back(DesktopRect::MakeXYWH( 36 region.AddRect(
37 0, 0, size.width() / 2, size.height() / 2)); 37 DesktopRect::MakeXYWH(0, 0, size.width() / 2, size.height() / 2));
38 rect_lists.push_back(rects); 38 region_lists.push_back(region);
39 rects.clear(); 39 region.Clear();
40 rects.push_back(DesktopRect::MakeXYWH( 40 region.AddRect(DesktopRect::MakeXYWH(size.width() / 2, size.height() / 2,
41 size.width() / 2, size.height() / 2, 41 size.width() / 2, size.height() / 2));
42 size.width() / 2, size.height() / 2)); 42 region_lists.push_back(region);
43 rect_lists.push_back(rects); 43 region.Clear();
44 rects.clear(); 44 region.AddRect(DesktopRect::MakeXYWH(16, 16, 16, 16));
45 rects.push_back(DesktopRect::MakeXYWH(16, 16, 16, 16)); 45 region.AddRect(DesktopRect::MakeXYWH(32, 32, 32, 32));
46 rects.push_back(DesktopRect::MakeXYWH(128, 64, 32, 32)); 46 region.IntersectWith(DesktopRect::MakeSize(size));
47 rect_lists.push_back(rects); 47 region_lists.push_back(region);
48 return rect_lists; 48 return region_lists;
49 } 49 }
50 50
51 } // namespace 51 } // namespace
52 52
53 namespace remoting { 53 namespace remoting {
54 54
55 class VideoDecoderTester { 55 class VideoDecoderTester {
56 public: 56 public:
57 VideoDecoderTester(VideoDecoder* decoder, 57 VideoDecoderTester(VideoDecoder* decoder,
58 const DesktopSize& screen_size, 58 const DesktopSize& screen_size,
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
98 } 98 }
99 99
100 void set_strict(bool strict) { 100 void set_strict(bool strict) {
101 strict_ = strict; 101 strict_ = strict;
102 } 102 }
103 103
104 void set_frame(DesktopFrame* frame) { 104 void set_frame(DesktopFrame* frame) {
105 frame_ = frame; 105 frame_ = frame;
106 } 106 }
107 107
108 void AddRects(const DesktopRect* rects, int count) {
109 for (int i = 0; i < count; ++i) {
110 expected_region_.AddRect(rects[i]);
111 }
112 }
113
114 void AddRegion(const DesktopRegion& region) { 108 void AddRegion(const DesktopRegion& region) {
115 expected_region_.AddRegion(region); 109 expected_region_.AddRegion(region);
116 } 110 }
117 111
118 void VerifyResults() { 112 void VerifyResults() {
119 if (!strict_) 113 if (!strict_)
120 return; 114 return;
121 115
122 ASSERT_TRUE(frame_); 116 ASSERT_TRUE(frame_);
123 117
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
238 for (int i = 0; i < memory_size; ++i) { 232 for (int i = 0; i < memory_size; ++i) {
239 frame->data()[i] = rand() % 256; 233 frame->data()[i] = rand() % 256;
240 } 234 }
241 235
242 return frame.Pass(); 236 return frame.Pass();
243 } 237 }
244 238
245 static void TestEncodingRects(VideoEncoder* encoder, 239 static void TestEncodingRects(VideoEncoder* encoder,
246 VideoEncoderTester* tester, 240 VideoEncoderTester* tester,
247 DesktopFrame* frame, 241 DesktopFrame* frame,
248 const DesktopRect* rects, 242 const DesktopRegion& region) {
249 int count) { 243 *frame->mutable_updated_region() = region;
250 frame->mutable_updated_region()->Clear();
251 for (int i = 0; i < count; ++i) {
252 frame->mutable_updated_region()->AddRect(rects[i]);
253 }
254
255 scoped_ptr<VideoPacket> packet = encoder->Encode(*frame); 244 scoped_ptr<VideoPacket> packet = encoder->Encode(*frame);
256 tester->DataAvailable(packet.Pass()); 245 tester->DataAvailable(packet.Pass());
257 } 246 }
258 247
259 void TestVideoEncoder(VideoEncoder* encoder, bool strict) { 248 void TestVideoEncoder(VideoEncoder* encoder, bool strict) {
260 const int kSizes[] = {320, 319, 317, 150}; 249 const int kSizes[] = {80, 79, 77, 54};
261 250
262 VideoEncoderTester tester; 251 VideoEncoderTester tester;
263 252
264 for (size_t xi = 0; xi < arraysize(kSizes); ++xi) { 253 for (size_t xi = 0; xi < arraysize(kSizes); ++xi) {
265 for (size_t yi = 0; yi < arraysize(kSizes); ++yi) { 254 for (size_t yi = 0; yi < arraysize(kSizes); ++yi) {
266 DesktopSize size = DesktopSize(kSizes[xi], kSizes[yi]); 255 DesktopSize size(kSizes[xi], kSizes[yi]);
267 scoped_ptr<DesktopFrame> frame = PrepareFrame(size); 256 scoped_ptr<DesktopFrame> frame = PrepareFrame(size);
268 std::vector<std::vector<DesktopRect> > test_rect_lists = 257 for (const DesktopRegion& region : MakeTestRegionLists(size)) {
269 MakeTestRectLists(size); 258 TestEncodingRects(encoder, &tester, frame.get(), region);
270 for (size_t i = 0; i < test_rect_lists.size(); ++i) {
271 const std::vector<DesktopRect>& test_rects = test_rect_lists[i];
272 TestEncodingRects(encoder, &tester, frame.get(),
273 &test_rects[0], test_rects.size());
274 } 259 }
275 260
276 // Pass some empty frames through the encoder. 261 // Pass some empty frames through the encoder.
277 for (int i = 0; i < 10; ++i) { 262 for (int i = 0; i < 5; ++i) {
278 TestEncodingRects(encoder, &tester, frame.get(), nullptr, 0); 263 TestEncodingRects(encoder, &tester, frame.get(), DesktopRegion());
279 } 264 }
280 } 265 }
281 } 266 }
282 } 267 }
283 268
284 void TestVideoEncoderEmptyFrames(VideoEncoder* encoder, 269 void TestVideoEncoderEmptyFrames(VideoEncoder* encoder,
285 int max_topoff_frames) { 270 int max_topoff_frames) {
286 const DesktopSize kSize(640, 480); 271 const DesktopSize kSize(100, 100);
287 scoped_ptr<DesktopFrame> frame(PrepareFrame(kSize)); 272 scoped_ptr<DesktopFrame> frame(PrepareFrame(kSize));
288 273
289 frame->mutable_updated_region()->SetRect( 274 frame->mutable_updated_region()->SetRect(
290 webrtc::DesktopRect::MakeSize(kSize)); 275 webrtc::DesktopRect::MakeSize(kSize));
291 EXPECT_TRUE(encoder->Encode(*frame)); 276 EXPECT_TRUE(encoder->Encode(*frame));
292 277
293 int topoff_frames = 0; 278 int topoff_frames = 0;
294 frame->mutable_updated_region()->Clear(); 279 frame->mutable_updated_region()->Clear();
295 for (int i = 0; i < max_topoff_frames + 1; ++i) { 280 for (int i = 0; i < max_topoff_frames + 1; ++i) {
296 if (!encoder->Encode(*frame)) 281 if (!encoder->Encode(*frame))
297 break; 282 break;
298 topoff_frames++; 283 topoff_frames++;
299 } 284 }
300 285
301 // If top-off is enabled then our random frame contents should always 286 // If top-off is enabled then our random frame contents should always
302 // trigger it, so expect at least one top-off frame - strictly, though, 287 // trigger it, so expect at least one top-off frame - strictly, though,
303 // an encoder may not always need to top-off. 288 // an encoder may not always need to top-off.
304 EXPECT_GE(topoff_frames, max_topoff_frames ? 1 : 0); 289 EXPECT_GE(topoff_frames, max_topoff_frames ? 1 : 0);
305 EXPECT_LE(topoff_frames, max_topoff_frames); 290 EXPECT_LE(topoff_frames, max_topoff_frames);
306 } 291 }
307 292
308 static void TestEncodeDecodeRects(VideoEncoder* encoder, 293 static void TestEncodeDecodeRects(VideoEncoder* encoder,
309 VideoEncoderTester* encoder_tester, 294 VideoEncoderTester* encoder_tester,
310 VideoDecoderTester* decoder_tester, 295 VideoDecoderTester* decoder_tester,
311 DesktopFrame* frame, 296 DesktopFrame* frame,
312 const DesktopRect* rects, int count) { 297 const DesktopRegion& region) {
313 frame->mutable_updated_region()->Clear(); 298 *frame->mutable_updated_region() = region;
314 for (int i = 0; i < count; ++i) { 299 decoder_tester->AddRegion(region);
315 frame->mutable_updated_region()->AddRect(rects[i]);
316 }
317 decoder_tester->AddRects(rects, count);
318 300
319 // Generate random data for the updated region. 301 // Generate random data for the updated region.
320 srand(0); 302 srand(0);
321 for (int i = 0; i < count; ++i) { 303 for (DesktopRegion::Iterator i(region); !i.IsAtEnd(); i.Advance()) {
322 const int row_size = 304 const int row_size = DesktopFrame::kBytesPerPixel * i.rect().width();
323 DesktopFrame::kBytesPerPixel * rects[i].width(); 305 uint8* memory = frame->data() + frame->stride() * i.rect().top() +
324 uint8* memory = frame->data() + 306 DesktopFrame::kBytesPerPixel * i.rect().left();
325 frame->stride() * rects[i].top() + 307 for (int y = 0; y < i.rect().height(); ++y) {
326 DesktopFrame::kBytesPerPixel * rects[i].left();
327 for (int y = 0; y < rects[i].height(); ++y) {
328 for (int x = 0; x < row_size; ++x) 308 for (int x = 0; x < row_size; ++x)
329 memory[x] = rand() % 256; 309 memory[x] = rand() % 256;
330 memory += frame->stride(); 310 memory += frame->stride();
331 } 311 }
332 } 312 }
333 313
334 scoped_ptr<VideoPacket> packet = encoder->Encode(*frame); 314 scoped_ptr<VideoPacket> packet = encoder->Encode(*frame);
335 encoder_tester->DataAvailable(packet.Pass()); 315 encoder_tester->DataAvailable(packet.Pass());
336 decoder_tester->VerifyResults(); 316 decoder_tester->VerifyResults();
337 decoder_tester->Reset(); 317 decoder_tester->Reset();
338 } 318 }
339 319
340 void TestVideoEncoderDecoder( 320 void TestVideoEncoderDecoder(VideoEncoder* encoder,
341 VideoEncoder* encoder, VideoDecoder* decoder, bool strict) { 321 VideoDecoder* decoder,
342 DesktopSize kSize = DesktopSize(320, 240); 322 bool strict) {
323 DesktopSize kSize = DesktopSize(160, 120);
343 324
344 VideoEncoderTester encoder_tester; 325 VideoEncoderTester encoder_tester;
345 326
346 scoped_ptr<DesktopFrame> frame = PrepareFrame(kSize); 327 scoped_ptr<DesktopFrame> frame = PrepareFrame(kSize);
347 328
348 VideoDecoderTester decoder_tester(decoder, kSize, kSize); 329 VideoDecoderTester decoder_tester(decoder, kSize, kSize);
349 decoder_tester.set_strict(strict); 330 decoder_tester.set_strict(strict);
350 decoder_tester.set_frame(frame.get()); 331 decoder_tester.set_frame(frame.get());
351 encoder_tester.set_decoder_tester(&decoder_tester); 332 encoder_tester.set_decoder_tester(&decoder_tester);
352 333
353 std::vector<std::vector<DesktopRect> > test_rect_lists = 334 for (const DesktopRegion& region : MakeTestRegionLists(kSize)) {
354 MakeTestRectLists(kSize);
355 for (size_t i = 0; i < test_rect_lists.size(); ++i) {
356 const std::vector<DesktopRect> test_rects = test_rect_lists[i];
357 TestEncodeDecodeRects(encoder, &encoder_tester, &decoder_tester, 335 TestEncodeDecodeRects(encoder, &encoder_tester, &decoder_tester,
358 frame.get(), &test_rects[0], test_rects.size()); 336 frame.get(), region);
359 } 337 }
360 } 338 }
361 339
362 static void FillWithGradient(DesktopFrame* frame) { 340 static void FillWithGradient(DesktopFrame* frame) {
363 for (int j = 0; j < frame->size().height(); ++j) { 341 for (int j = 0; j < frame->size().height(); ++j) {
364 uint8* p = frame->data() + j * frame->stride(); 342 uint8* p = frame->data() + j * frame->stride();
365 for (int i = 0; i < frame->size().width(); ++i) { 343 for (int i = 0; i < frame->size().width(); ++i) {
366 *p++ = (255.0 * i) / frame->size().width(); 344 *p++ = (255.0 * i) / frame->size().width();
367 *p++ = (164.0 * j) / frame->size().height(); 345 *p++ = (164.0 * j) / frame->size().height();
368 *p++ = (82.0 * (i + j)) / 346 *p++ = (82.0 * (i + j)) /
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
447 425
448 if (frame_count >= kWarmUpFrameCount) { 426 if (frame_count >= kWarmUpFrameCount) {
449 elapsed = base::TimeTicks::Now() - start_time; 427 elapsed = base::TimeTicks::Now() - start_time;
450 } 428 }
451 } 429 }
452 430
453 return (frame_count * base::TimeDelta::FromSeconds(1)) / elapsed; 431 return (frame_count * base::TimeDelta::FromSeconds(1)) / elapsed;
454 } 432 }
455 433
456 } // namespace remoting 434 } // namespace remoting
OLDNEW
« no previous file with comments | « no previous file | remoting/codec/video_encoder_vpx_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698