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

Side by Side Diff: content/browser/renderer_host/media/web_contents_video_capture_device_unittest.cc

Issue 12093070: WebContentsVideoCaptureDevice: Recover after errors. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Merge with upstream. Created 7 years, 10 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 | Annotate | Revision Log
« no previous file with comments | « content/browser/renderer_host/media/web_contents_video_capture_device.cc ('k') | no next file » | 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 "content/browser/renderer_host/media/web_contents_video_capture_device. h" 5 #include "content/browser/renderer_host/media/web_contents_video_capture_device. h"
6 6
7 #include "base/bind_helpers.h" 7 #include "base/bind_helpers.h"
8 #include "base/synchronization/condition_variable.h" 8 #include "base/synchronization/condition_variable.h"
9 #include "base/synchronization/waitable_event.h" 9 #include "base/synchronization/waitable_event.h"
10 #include "base/time.h"
10 #include "content/browser/browser_thread_impl.h" 11 #include "content/browser/browser_thread_impl.h"
11 #include "content/browser/renderer_host/render_widget_host_delegate.h" 12 #include "content/browser/renderer_host/render_widget_host_delegate.h"
12 #include "content/browser/renderer_host/render_widget_host_impl.h" 13 #include "content/browser/renderer_host/render_widget_host_impl.h"
13 #include "content/public/test/mock_render_process_host.h" 14 #include "content/public/test/mock_render_process_host.h"
14 #include "content/public/test/test_browser_context.h" 15 #include "content/public/test/test_browser_context.h"
15 #include "media/video/capture/video_capture_types.h" 16 #include "media/video/capture/video_capture_types.h"
16 #include "skia/ext/platform_canvas.h" 17 #include "skia/ext/platform_canvas.h"
17 #include "testing/gtest/include/gtest/gtest.h" 18 #include "testing/gtest/include/gtest/gtest.h"
18 #include "third_party/skia/include/core/SkColor.h" 19 #include "third_party/skia/include/core/SkColor.h"
19 20
20 namespace content { 21 namespace content {
21 namespace { 22 namespace {
22 const int kTestWidth = 1280; 23 const int kTestWidth = 1280;
23 const int kTestHeight = 720; 24 const int kTestHeight = 720;
24 const int kBytesPerPixel = 4; 25 const int kBytesPerPixel = 4;
25 const int kTestFramesPerSecond = 8; 26 const int kTestFramesPerSecond = 8;
27 const base::TimeDelta kWaitTimeout =
28 base::TimeDelta::FromMilliseconds(2000);
26 const SkColor kNothingYet = 0xdeadbeef; 29 const SkColor kNothingYet = 0xdeadbeef;
27 const SkColor kNotInterested = ~kNothingYet; 30 const SkColor kNotInterested = ~kNothingYet;
28 } 31 }
29 32
30 // A stub implementation which returns solid-color bitmaps in calls to 33 // A stub implementation which returns solid-color bitmaps in calls to
31 // CopyFromBackingStore(). The unit tests can change the color for successive 34 // CopyFromBackingStore(). The unit tests can change the color for successive
32 // captures. 35 // captures.
33 class StubRenderWidgetHost : public RenderWidgetHostImpl { 36 class StubRenderWidgetHost : public RenderWidgetHostImpl {
34 public: 37 public:
35 StubRenderWidgetHost(RenderProcessHost* process, int routing_id) 38 StubRenderWidgetHost(RenderProcessHost* process, int routing_id)
36 : RenderWidgetHostImpl(&delegate_, process, routing_id), 39 : RenderWidgetHostImpl(&delegate_, process, routing_id),
37 color_(kNothingYet) {} 40 color_(kNothingYet),
41 copy_result_size_(kTestWidth, kTestHeight),
42 copy_event_(false, false) {}
38 43
39 void SetSolidColor(SkColor color) { 44 void SetSolidColor(SkColor color) {
40 base::AutoLock guard(lock_); 45 base::AutoLock guard(lock_);
41 color_ = color; 46 color_ = color;
42 } 47 }
43 48
49 void SetCopyResultSize(int width, int height) {
50 base::AutoLock guard(lock_);
51 copy_result_size_ = gfx::Size(width, height);
52 }
53
54 bool WaitForNextBackingStoreCopy() {
55 if (!copy_event_.TimedWait(kWaitTimeout)) {
56 ADD_FAILURE() << "WaitForNextBackingStoreCopy: wait deadline exceeded";
57 return false;
58 }
59 return true;
60 }
61
62 // RenderWidgetHostImpl overrides.
44 virtual void CopyFromBackingStore( 63 virtual void CopyFromBackingStore(
45 const gfx::Rect& src_rect, 64 const gfx::Rect& src_rect,
46 const gfx::Size& accelerated_dst_size, 65 const gfx::Size& accelerated_dst_size,
47 const base::Callback<void(bool, const SkBitmap&)>& callback) OVERRIDE { 66 const base::Callback<void(bool, const SkBitmap&)>& callback) OVERRIDE {
48 // Although it's not necessary, use a PlatformBitmap here (instead of a 67 // Although it's not necessary, use a PlatformBitmap here (instead of a
49 // regular SkBitmap) to exercise possible threading issues. 68 // regular SkBitmap) to exercise possible threading issues.
50 scoped_ptr<skia::PlatformBitmap> platform_bitmap(new skia::PlatformBitmap); 69 scoped_ptr<skia::PlatformBitmap> platform_bitmap(new skia::PlatformBitmap);
51 EXPECT_TRUE(platform_bitmap->Allocate(kTestWidth, kTestHeight, false)); 70 EXPECT_TRUE(platform_bitmap->Allocate(
71 copy_result_size_.width(), copy_result_size_.height(), false));
52 { 72 {
53 SkAutoLockPixels locker(platform_bitmap->GetBitmap()); 73 SkAutoLockPixels locker(platform_bitmap->GetBitmap());
54 base::AutoLock guard(lock_); 74 base::AutoLock guard(lock_);
55 platform_bitmap->GetBitmap().eraseColor(color_); 75 platform_bitmap->GetBitmap().eraseColor(color_);
56 } 76 }
57 77
58 callback.Run(true, platform_bitmap->GetBitmap()); 78 callback.Run(true, platform_bitmap->GetBitmap());
79 copy_event_.Signal();
59 } 80 }
60 81
61 private: 82 private:
62 class StubRenderWidgetHostDelegate : public RenderWidgetHostDelegate { 83 class StubRenderWidgetHostDelegate : public RenderWidgetHostDelegate {
63 public: 84 public:
64 StubRenderWidgetHostDelegate() {} 85 StubRenderWidgetHostDelegate() {}
65 virtual ~StubRenderWidgetHostDelegate() {} 86 virtual ~StubRenderWidgetHostDelegate() {}
66 87
67 private: 88 private:
68 DISALLOW_COPY_AND_ASSIGN(StubRenderWidgetHostDelegate); 89 DISALLOW_COPY_AND_ASSIGN(StubRenderWidgetHostDelegate);
69 }; 90 };
70 91
71 StubRenderWidgetHostDelegate delegate_; 92 StubRenderWidgetHostDelegate delegate_;
72 base::Lock lock_; // Guards changes to color_. 93 base::Lock lock_; // Guards changes to color_.
73 SkColor color_; 94 SkColor color_;
95 gfx::Size copy_result_size_;
96 base::WaitableEvent copy_event_;
74 97
75 DISALLOW_IMPLICIT_CONSTRUCTORS(StubRenderWidgetHost); 98 DISALLOW_IMPLICIT_CONSTRUCTORS(StubRenderWidgetHost);
76 }; 99 };
77 100
78 // A stub consumer of captured video frames, which checks the output of 101 // A stub consumer of captured video frames, which checks the output of
79 // WebContentsVideoCaptureDevice. 102 // WebContentsVideoCaptureDevice.
80 class StubConsumer : public media::VideoCaptureDevice::EventHandler { 103 class StubConsumer : public media::VideoCaptureDevice::EventHandler {
81 public: 104 public:
82 StubConsumer() : output_changed_(&lock_), 105 StubConsumer() : output_changed_(&lock_),
83 picture_color_(kNothingYet), 106 picture_color_(kNothingYet),
84 error_encountered_(false) {} 107 error_encountered_(false) {}
85 virtual ~StubConsumer() {} 108 virtual ~StubConsumer() {}
86 109
87 // Returns false if an error was encountered. 110 // Returns false if an error was encountered.
88 bool WaitForNextColorOrError(SkColor expected_color) { 111 bool WaitForNextColorOrError(SkColor expected_color) {
112 base::TimeTicks deadline = base::TimeTicks::Now() + kWaitTimeout;
89 base::AutoLock guard(lock_); 113 base::AutoLock guard(lock_);
90 while (picture_color_ != expected_color && !error_encountered_) { 114 while (picture_color_ != expected_color && !error_encountered_) {
91 output_changed_.Wait(); 115 output_changed_.TimedWait(kWaitTimeout);
116 if (base::TimeTicks::Now() >= deadline) {
117 ADD_FAILURE() << "WaitForNextColorOrError: wait deadline exceeded";
118 return false;
119 }
92 } 120 }
93 if (!error_encountered_) { 121 if (!error_encountered_) {
94 EXPECT_EQ(expected_color, picture_color_); 122 EXPECT_EQ(expected_color, picture_color_);
95 return true; 123 return true;
96 } else { 124 } else {
97 return false; 125 return false;
98 } 126 }
99 } 127 }
100 128
101 virtual void OnIncomingCapturedFrame(const uint8* data, int length, 129 virtual void OnIncomingCapturedFrame(const uint8* data, int length,
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
224 EXPECT_TRUE(consumer()->WaitForNextColorOrError(SK_ColorBLACK)); 252 EXPECT_TRUE(consumer()->WaitForNextColorOrError(SK_ColorBLACK));
225 253
226 device()->DeAllocate(); 254 device()->DeAllocate();
227 } 255 }
228 256
229 TEST_F(WebContentsVideoCaptureDeviceTest, RejectsInvalidAllocateParams) { 257 TEST_F(WebContentsVideoCaptureDeviceTest, RejectsInvalidAllocateParams) {
230 device()->Allocate(1280, 720, -2, consumer()); 258 device()->Allocate(1280, 720, -2, consumer());
231 EXPECT_FALSE(consumer()->WaitForNextColorOrError(kNotInterested)); 259 EXPECT_FALSE(consumer()->WaitForNextColorOrError(kNotInterested));
232 } 260 }
233 261
262 TEST_F(WebContentsVideoCaptureDeviceTest, BadFramesGoodFrames) {
263 device()->Allocate(kTestWidth, kTestHeight, kTestFramesPerSecond,
264 consumer());
265
266
267 // 1x1 is too small to process; we intend for this to result in an error.
268 source()->SetCopyResultSize(1, 1);
269 source()->SetSolidColor(SK_ColorRED);
270 device()->Start();
271
272 // These frames ought to be dropped during the Render stage. Let
273 // several captures to happen.
274 ASSERT_TRUE(source()->WaitForNextBackingStoreCopy());
275 ASSERT_TRUE(source()->WaitForNextBackingStoreCopy());
276 ASSERT_TRUE(source()->WaitForNextBackingStoreCopy());
277 ASSERT_TRUE(source()->WaitForNextBackingStoreCopy());
278 ASSERT_TRUE(source()->WaitForNextBackingStoreCopy());
279
280 // Now push some good frames through; they should be processed normally.
281 source()->SetCopyResultSize(kTestWidth, kTestHeight);
282 source()->SetSolidColor(SK_ColorGREEN);
283 EXPECT_TRUE(consumer()->WaitForNextColorOrError(SK_ColorGREEN));
284 source()->SetSolidColor(SK_ColorRED);
285 EXPECT_TRUE(consumer()->WaitForNextColorOrError(SK_ColorRED));
286 device()->DeAllocate();
287 }
288
234 } // namespace content 289 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/renderer_host/media/web_contents_video_capture_device.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698