OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "base/message_loop/message_loop.h" | 5 #include "base/message_loop/message_loop.h" |
6 #include "base/run_loop.h" | 6 #include "base/run_loop.h" |
7 #include "base/thread_task_runner_handle.h" | 7 #include "base/thread_task_runner_handle.h" |
8 #include "content/child/child_process.h" | 8 #include "content/child/child_process.h" |
9 #include "content/renderer/media/canvas_capture_handler.h" | 9 #include "content/renderer/media/canvas_capture_handler.h" |
10 #include "content/renderer/media/media_stream_video_capturer_source.h" | 10 #include "content/renderer/media/media_stream_video_capturer_source.h" |
11 #include "media/base/limits.h" | 11 #include "media/base/limits.h" |
12 #include "skia/ext/refptr.h" | 12 #include "skia/ext/refptr.h" |
13 #include "testing/gmock/include/gmock/gmock.h" | 13 #include "testing/gmock/include/gmock/gmock.h" |
14 #include "testing/gtest/include/gtest/gtest.h" | 14 #include "testing/gtest/include/gtest/gtest.h" |
15 #include "third_party/WebKit/public/platform/WebMediaStreamSource.h" | 15 #include "third_party/WebKit/public/platform/WebMediaStreamSource.h" |
16 #include "third_party/WebKit/public/platform/WebMediaStreamTrack.h" | 16 #include "third_party/WebKit/public/platform/WebMediaStreamTrack.h" |
17 #include "third_party/WebKit/public/platform/WebSize.h" | 17 #include "third_party/WebKit/public/platform/WebSize.h" |
18 #include "third_party/WebKit/public/web/WebHeap.h" | 18 #include "third_party/WebKit/public/web/WebHeap.h" |
19 | 19 |
20 using ::testing::_; | 20 using ::testing::_; |
21 using ::testing::InSequence; | 21 using ::testing::InSequence; |
22 using ::testing::Mock; | 22 using ::testing::Mock; |
23 using ::testing::SaveArg; | 23 using ::testing::SaveArg; |
24 using ::testing::Test; | 24 using ::testing::Test; |
| 25 using ::testing::TestWithParam; |
25 | 26 |
26 namespace content { | 27 namespace content { |
27 | 28 |
| 29 namespace { |
| 30 |
28 static const int kTestCanvasCaptureWidth = 320; | 31 static const int kTestCanvasCaptureWidth = 320; |
29 static const int kTestCanvasCaptureHeight = 240; | 32 static const int kTestCanvasCaptureHeight = 240; |
30 static const double kTestCanvasCaptureFramesPerSecond = 55.5; | 33 static const double kTestCanvasCaptureFramesPerSecond = 55.5; |
31 | 34 |
32 static const int kTestCanvasCaptureFrameWidth = 2; | 35 static const int kTestCanvasCaptureFrameWidth = 2; |
33 static const int kTestCanvasCaptureFrameHeight = 2; | 36 static const int kTestCanvasCaptureFrameHeight = 2; |
34 static const int kTestCanvasCaptureFrameErrorTolerance = 2; | 37 static const int kTestCanvasCaptureFrameErrorTolerance = 2; |
| 38 static const int kTestAlphaValue = 175; |
35 | 39 |
36 ACTION_P(RunClosure, closure) { | 40 ACTION_P(RunClosure, closure) { |
37 closure.Run(); | 41 closure.Run(); |
38 } | 42 } |
39 | 43 |
40 class CanvasCaptureHandlerTest : public Test { | 44 } // namespace |
| 45 |
| 46 class CanvasCaptureHandlerTest : public TestWithParam<bool> { |
41 public: | 47 public: |
42 CanvasCaptureHandlerTest() {} | 48 CanvasCaptureHandlerTest() {} |
43 | 49 |
44 void SetUp() override { | 50 void SetUp() override { |
45 canvas_capture_handler_.reset( | 51 canvas_capture_handler_.reset( |
46 CanvasCaptureHandler::CreateCanvasCaptureHandler( | 52 CanvasCaptureHandler::CreateCanvasCaptureHandler( |
47 blink::WebSize(kTestCanvasCaptureWidth, kTestCanvasCaptureHeight), | 53 blink::WebSize(kTestCanvasCaptureWidth, kTestCanvasCaptureHeight), |
48 kTestCanvasCaptureFramesPerSecond, message_loop_.task_runner(), | 54 kTestCanvasCaptureFramesPerSecond, message_loop_.task_runner(), |
49 &track_)); | 55 &track_)); |
50 } | 56 } |
(...skipping 18 matching lines...) Expand all Loading... |
69 MOCK_METHOD1(DoOnVideoCaptureDeviceFormats, | 75 MOCK_METHOD1(DoOnVideoCaptureDeviceFormats, |
70 void(const media::VideoCaptureFormats&)); | 76 void(const media::VideoCaptureFormats&)); |
71 void OnVideoCaptureDeviceFormats(const media::VideoCaptureFormats& formats) { | 77 void OnVideoCaptureDeviceFormats(const media::VideoCaptureFormats& formats) { |
72 DoOnVideoCaptureDeviceFormats(formats); | 78 DoOnVideoCaptureDeviceFormats(formats); |
73 } | 79 } |
74 | 80 |
75 MOCK_METHOD1(DoOnRunning, void(bool)); | 81 MOCK_METHOD1(DoOnRunning, void(bool)); |
76 void OnRunning(bool state) { DoOnRunning(state); } | 82 void OnRunning(bool state) { DoOnRunning(state); } |
77 | 83 |
78 // Verify returned frames. | 84 // Verify returned frames. |
79 static skia::RefPtr<SkImage> GenerateTestImage() { | 85 static skia::RefPtr<SkImage> GenerateTestImage(bool opaque) { |
| 86 |
80 SkBitmap testBitmap; | 87 SkBitmap testBitmap; |
81 testBitmap.allocN32Pixels(kTestCanvasCaptureFrameWidth, | 88 testBitmap.allocN32Pixels(kTestCanvasCaptureFrameWidth, |
82 kTestCanvasCaptureFrameHeight); | 89 kTestCanvasCaptureFrameHeight, opaque); |
83 testBitmap.eraseColor(SK_ColorBLUE); | 90 testBitmap.eraseARGB(kTestAlphaValue, 30, 60, 200); |
84 return skia::AdoptRef(SkImage::NewFromBitmap(testBitmap)); | 91 return skia::AdoptRef(SkImage::NewFromBitmap(testBitmap)); |
85 } | 92 } |
86 | 93 |
87 void OnVerifyDeliveredFrame( | 94 void OnVerifyDeliveredFrame( |
| 95 bool opaque, |
88 const scoped_refptr<media::VideoFrame>& video_frame, | 96 const scoped_refptr<media::VideoFrame>& video_frame, |
89 base::TimeTicks estimated_capture_time) { | 97 base::TimeTicks estimated_capture_time) { |
90 EXPECT_EQ(media::PIXEL_FORMAT_I420, video_frame->format()); | 98 if (opaque) |
| 99 EXPECT_EQ(media::PIXEL_FORMAT_I420, video_frame->format()); |
| 100 else |
| 101 EXPECT_EQ(media::PIXEL_FORMAT_YV12A, video_frame->format()); |
| 102 |
91 const gfx::Size& size = video_frame->coded_size(); | 103 const gfx::Size& size = video_frame->coded_size(); |
92 EXPECT_EQ(kTestCanvasCaptureFrameWidth, size.width()); | 104 EXPECT_EQ(kTestCanvasCaptureFrameWidth, size.width()); |
93 EXPECT_EQ(kTestCanvasCaptureFrameHeight, size.height()); | 105 EXPECT_EQ(kTestCanvasCaptureFrameHeight, size.height()); |
94 const uint8_t* y_plane = video_frame->data(0); | 106 const uint8_t* y_plane = video_frame->data(media::VideoFrame::kYPlane); |
95 EXPECT_NEAR(41, y_plane[0], kTestCanvasCaptureFrameErrorTolerance); | 107 EXPECT_NEAR(74, y_plane[0], kTestCanvasCaptureFrameErrorTolerance); |
96 const uint8_t* u_plane = video_frame->data(1); | 108 const uint8_t* u_plane = video_frame->data(media::VideoFrame::kUPlane); |
97 EXPECT_NEAR(239, u_plane[0], kTestCanvasCaptureFrameErrorTolerance); | 109 EXPECT_NEAR(193, u_plane[0], kTestCanvasCaptureFrameErrorTolerance); |
98 const uint8_t* v_plane = video_frame->data(2); | 110 const uint8_t* v_plane = video_frame->data(media::VideoFrame::kVPlane); |
99 EXPECT_NEAR(110, v_plane[0], kTestCanvasCaptureFrameErrorTolerance); | 111 EXPECT_NEAR(105, v_plane[0], kTestCanvasCaptureFrameErrorTolerance); |
| 112 if (!opaque) { |
| 113 const uint8_t* a_plane = video_frame->data(media::VideoFrame::kAPlane); |
| 114 EXPECT_EQ(kTestAlphaValue, a_plane[0]); |
| 115 } |
100 } | 116 } |
101 | 117 |
102 blink::WebMediaStreamTrack track_; | 118 blink::WebMediaStreamTrack track_; |
103 // The Class under test. Needs to be scoped_ptr to force its destruction. | 119 // The Class under test. Needs to be scoped_ptr to force its destruction. |
104 scoped_ptr<CanvasCaptureHandler> canvas_capture_handler_; | 120 scoped_ptr<CanvasCaptureHandler> canvas_capture_handler_; |
105 | 121 |
106 protected: | 122 protected: |
107 media::VideoCapturerSource* GetVideoCapturerSource( | 123 media::VideoCapturerSource* GetVideoCapturerSource( |
108 MediaStreamVideoCapturerSource* ms_source) { | 124 MediaStreamVideoCapturerSource* ms_source) { |
109 return ms_source->source_.get(); | 125 return ms_source->source_.get(); |
110 } | 126 } |
111 | 127 |
112 // A ChildProcess and a MessageLoopForUI are both needed to fool the Tracks | 128 // A ChildProcess and a MessageLoopForUI are both needed to fool the Tracks |
113 // and Sources into believing they are on the right threads. | 129 // and Sources into believing they are on the right threads. |
114 base::MessageLoopForUI message_loop_; | 130 base::MessageLoopForUI message_loop_; |
115 ChildProcess child_process_; | 131 ChildProcess child_process_; |
116 | 132 |
117 private: | 133 private: |
118 DISALLOW_COPY_AND_ASSIGN(CanvasCaptureHandlerTest); | 134 DISALLOW_COPY_AND_ASSIGN(CanvasCaptureHandlerTest); |
119 }; | 135 }; |
120 | 136 |
121 // Checks that the initialization-destruction sequence works fine. | 137 // Checks that the initialization-destruction sequence works fine. |
122 TEST_F(CanvasCaptureHandlerTest, ConstructAndDestruct) { | 138 TEST_F(CanvasCaptureHandlerTest, ConstructAndDestruct) { |
123 EXPECT_TRUE(canvas_capture_handler_->needsNewFrame()); | 139 EXPECT_TRUE(canvas_capture_handler_->needsNewFrame()); |
124 base::RunLoop().RunUntilIdle(); | 140 base::RunLoop().RunUntilIdle(); |
125 } | 141 } |
126 | 142 |
127 // Checks that VideoCapturerSource call sequence works fine. | 143 // Checks that VideoCapturerSource call sequence works fine. |
128 TEST_F(CanvasCaptureHandlerTest, GetFormatsStartAndStop) { | 144 TEST_P(CanvasCaptureHandlerTest, GetFormatsStartAndStop) { |
129 InSequence s; | 145 InSequence s; |
130 const blink::WebMediaStreamSource& web_media_stream_source = track_.source(); | 146 const blink::WebMediaStreamSource& web_media_stream_source = track_.source(); |
131 EXPECT_FALSE(web_media_stream_source.isNull()); | 147 EXPECT_FALSE(web_media_stream_source.isNull()); |
132 MediaStreamVideoCapturerSource* const ms_source = | 148 MediaStreamVideoCapturerSource* const ms_source = |
133 static_cast<MediaStreamVideoCapturerSource*>( | 149 static_cast<MediaStreamVideoCapturerSource*>( |
134 web_media_stream_source.getExtraData()); | 150 web_media_stream_source.getExtraData()); |
135 EXPECT_TRUE(ms_source != nullptr); | 151 EXPECT_TRUE(ms_source != nullptr); |
136 media::VideoCapturerSource* source = GetVideoCapturerSource(ms_source); | 152 media::VideoCapturerSource* source = GetVideoCapturerSource(ms_source); |
137 EXPECT_TRUE(source != nullptr); | 153 EXPECT_TRUE(source != nullptr); |
138 | 154 |
139 media::VideoCaptureFormats formats; | 155 media::VideoCaptureFormats formats; |
140 EXPECT_CALL(*this, DoOnVideoCaptureDeviceFormats(_)) | 156 EXPECT_CALL(*this, DoOnVideoCaptureDeviceFormats(_)) |
141 .Times(1) | 157 .Times(1) |
142 .WillOnce(SaveArg<0>(&formats)); | 158 .WillOnce(SaveArg<0>(&formats)); |
143 source->GetCurrentSupportedFormats( | 159 source->GetCurrentSupportedFormats( |
144 media::limits::kMaxCanvas /* max_requesteed_width */, | 160 media::limits::kMaxCanvas /* max_requesteed_width */, |
145 media::limits::kMaxCanvas /* max_requesteed_height */, | 161 media::limits::kMaxCanvas /* max_requesteed_height */, |
146 media::limits::kMaxFramesPerSecond /* max_requested_frame_rate */, | 162 media::limits::kMaxFramesPerSecond /* max_requested_frame_rate */, |
147 base::Bind(&CanvasCaptureHandlerTest::OnVideoCaptureDeviceFormats, | 163 base::Bind(&CanvasCaptureHandlerTest::OnVideoCaptureDeviceFormats, |
148 base::Unretained(this))); | 164 base::Unretained(this))); |
149 ASSERT_EQ(1u, formats.size()); | 165 ASSERT_EQ(2u, formats.size()); |
150 EXPECT_EQ(kTestCanvasCaptureWidth, formats[0].frame_size.width()); | 166 EXPECT_EQ(kTestCanvasCaptureWidth, formats[0].frame_size.width()); |
151 EXPECT_EQ(kTestCanvasCaptureHeight, formats[0].frame_size.height()); | 167 EXPECT_EQ(kTestCanvasCaptureHeight, formats[0].frame_size.height()); |
152 media::VideoCaptureParams params; | 168 media::VideoCaptureParams params; |
153 params.requested_format = formats[0]; | 169 params.requested_format = formats[0]; |
154 | 170 |
155 base::RunLoop run_loop; | 171 base::RunLoop run_loop; |
156 base::Closure quit_closure = run_loop.QuitClosure(); | 172 base::Closure quit_closure = run_loop.QuitClosure(); |
157 EXPECT_CALL(*this, DoOnRunning(true)).Times(1); | 173 EXPECT_CALL(*this, DoOnRunning(true)).Times(1); |
158 EXPECT_CALL(*this, DoOnDeliverFrame(_, _)) | 174 EXPECT_CALL(*this, DoOnDeliverFrame(_, _)) |
159 .Times(1) | 175 .Times(1) |
160 .WillOnce(RunClosure(quit_closure)); | 176 .WillOnce(RunClosure(quit_closure)); |
161 source->StartCapture( | 177 source->StartCapture( |
162 params, base::Bind(&CanvasCaptureHandlerTest::OnDeliverFrame, | 178 params, base::Bind(&CanvasCaptureHandlerTest::OnDeliverFrame, |
163 base::Unretained(this)), | 179 base::Unretained(this)), |
164 base::Bind(&CanvasCaptureHandlerTest::OnRunning, base::Unretained(this))); | 180 base::Bind(&CanvasCaptureHandlerTest::OnRunning, base::Unretained(this))); |
165 canvas_capture_handler_->sendNewFrame(GenerateTestImage().get()); | 181 canvas_capture_handler_->sendNewFrame(GenerateTestImage(GetParam()).get()); |
166 run_loop.Run(); | 182 run_loop.Run(); |
167 | 183 |
168 source->StopCapture(); | 184 source->StopCapture(); |
169 } | 185 } |
170 | 186 |
171 // Verifies that SkImage is processed and produces VideoFrame as expected. | 187 // Verifies that SkImage is processed and produces VideoFrame as expected. |
172 TEST_F(CanvasCaptureHandlerTest, VerifyFrame) { | 188 TEST_P(CanvasCaptureHandlerTest, VerifyOpaqueFrame) { |
| 189 const bool isOpaque = GetParam(); |
173 InSequence s; | 190 InSequence s; |
174 media::VideoCapturerSource* const source = | 191 media::VideoCapturerSource* const source = |
175 GetVideoCapturerSource(static_cast<MediaStreamVideoCapturerSource*>( | 192 GetVideoCapturerSource(static_cast<MediaStreamVideoCapturerSource*>( |
176 track_.source().getExtraData())); | 193 track_.source().getExtraData())); |
177 EXPECT_TRUE(source != nullptr); | 194 EXPECT_TRUE(source != nullptr); |
178 | 195 |
179 base::RunLoop run_loop; | 196 base::RunLoop run_loop; |
180 EXPECT_CALL(*this, DoOnRunning(true)).Times(1); | 197 EXPECT_CALL(*this, DoOnRunning(true)).Times(1); |
181 media::VideoCaptureParams params; | 198 media::VideoCaptureParams params; |
182 source->StartCapture( | 199 source->StartCapture( |
183 params, base::Bind(&CanvasCaptureHandlerTest::OnVerifyDeliveredFrame, | 200 params, base::Bind(&CanvasCaptureHandlerTest::OnVerifyDeliveredFrame, |
184 base::Unretained(this)), | 201 base::Unretained(this), isOpaque), |
185 base::Bind(&CanvasCaptureHandlerTest::OnRunning, base::Unretained(this))); | 202 base::Bind(&CanvasCaptureHandlerTest::OnRunning, base::Unretained(this))); |
186 canvas_capture_handler_->sendNewFrame(GenerateTestImage().get()); | 203 canvas_capture_handler_->sendNewFrame(GenerateTestImage(isOpaque).get()); |
187 run_loop.RunUntilIdle(); | 204 run_loop.RunUntilIdle(); |
188 } | 205 } |
189 | 206 |
190 // Checks that needsNewFrame() works as expected. | 207 // Checks that needsNewFrame() works as expected. |
191 TEST_F(CanvasCaptureHandlerTest, CheckNeedsNewFrame) { | 208 TEST_F(CanvasCaptureHandlerTest, CheckNeedsNewFrame) { |
192 InSequence s; | 209 InSequence s; |
193 media::VideoCapturerSource* source = | 210 media::VideoCapturerSource* source = |
194 GetVideoCapturerSource(static_cast<MediaStreamVideoCapturerSource*>( | 211 GetVideoCapturerSource(static_cast<MediaStreamVideoCapturerSource*>( |
195 track_.source().getExtraData())); | 212 track_.source().getExtraData())); |
196 EXPECT_TRUE(source != nullptr); | 213 EXPECT_TRUE(source != nullptr); |
197 EXPECT_TRUE(canvas_capture_handler_->needsNewFrame()); | 214 EXPECT_TRUE(canvas_capture_handler_->needsNewFrame()); |
198 source->StopCapture(); | 215 source->StopCapture(); |
199 EXPECT_FALSE(canvas_capture_handler_->needsNewFrame()); | 216 EXPECT_FALSE(canvas_capture_handler_->needsNewFrame()); |
200 } | 217 } |
201 | 218 |
| 219 INSTANTIATE_TEST_CASE_P(, CanvasCaptureHandlerTest, ::testing::Bool()); |
| 220 |
202 } // namespace content | 221 } // namespace content |
OLD | NEW |