OLD | NEW |
1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 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/command_line.h" | 5 #include "base/command_line.h" |
6 #include "base/run_loop.h" | 6 #include "base/run_loop.h" |
7 #include "build/build_config.h" | 7 #include "build/build_config.h" |
8 #include "content/browser/browser_main_loop.h" | 8 #include "content/browser/browser_main_loop.h" |
9 #include "content/browser/renderer_host/media/media_stream_manager.h" | 9 #include "content/browser/renderer_host/media/media_stream_manager.h" |
| 10 #include "content/browser/renderer_host/media/video_capture_controller.h" |
10 #include "content/browser/renderer_host/media/video_capture_manager.h" | 11 #include "content/browser/renderer_host/media/video_capture_manager.h" |
11 #include "content/public/common/content_switches.h" | 12 #include "content/public/common/content_switches.h" |
12 #include "content/public/test/content_browser_test.h" | 13 #include "content/public/test/content_browser_test.h" |
13 #include "media/base/bind_to_current_loop.h" | 14 #include "media/base/bind_to_current_loop.h" |
14 #include "media/base/media_switches.h" | 15 #include "media/base/media_switches.h" |
15 #include "media/capture/video_capture_types.h" | 16 #include "media/capture/video_capture_types.h" |
16 #include "testing/gmock/include/gmock/gmock.h" | 17 #include "testing/gmock/include/gmock/gmock.h" |
17 | 18 |
18 using testing::_; | 19 using testing::_; |
19 using testing::AtLeast; | 20 using testing::AtLeast; |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
57 MOCK_METHOD2(Closed, void(MediaStreamType, int)); | 58 MOCK_METHOD2(Closed, void(MediaStreamType, int)); |
58 MOCK_METHOD2(Aborted, void(MediaStreamType, int)); | 59 MOCK_METHOD2(Aborted, void(MediaStreamType, int)); |
59 }; | 60 }; |
60 | 61 |
61 struct TestParams { | 62 struct TestParams { |
62 std::string fake_device_factory_config_string; | 63 std::string fake_device_factory_config_string; |
63 size_t device_index_to_use; | 64 size_t device_index_to_use; |
64 media::VideoPixelFormat pixel_format_to_use; | 65 media::VideoPixelFormat pixel_format_to_use; |
65 gfx::Size resolution_to_use; | 66 gfx::Size resolution_to_use; |
66 float frame_rate_to_use; | 67 float frame_rate_to_use; |
| 68 bool exercise_accelerated_jpeg_decoding; |
67 }; | 69 }; |
68 | 70 |
69 struct FrameInfo { | 71 struct FrameInfo { |
70 gfx::Size size; | 72 gfx::Size size; |
71 media::VideoPixelFormat pixel_format; | 73 media::VideoPixelFormat pixel_format; |
72 media::VideoPixelStorage storage_type; | 74 media::VideoPixelStorage storage_type; |
73 base::TimeDelta timestamp; | 75 base::TimeDelta timestamp; |
74 }; | 76 }; |
75 | 77 |
76 class VideoCaptureBrowserTest | 78 class VideoCaptureBrowserTest |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
109 | 111 |
110 video_capture_manager_->Close(session_id_); | 112 video_capture_manager_->Close(session_id_); |
111 } | 113 } |
112 | 114 |
113 protected: | 115 protected: |
114 void SetUpCommandLine(base::CommandLine* command_line) override { | 116 void SetUpCommandLine(base::CommandLine* command_line) override { |
115 command_line->AppendSwitchASCII( | 117 command_line->AppendSwitchASCII( |
116 switches::kUseFakeDeviceForMediaStream, | 118 switches::kUseFakeDeviceForMediaStream, |
117 GetParam().fake_device_factory_config_string); | 119 GetParam().fake_device_factory_config_string); |
118 command_line->AppendSwitch(switches::kUseFakeUIForMediaStream); | 120 command_line->AppendSwitch(switches::kUseFakeUIForMediaStream); |
| 121 if (GetParam().exercise_accelerated_jpeg_decoding) { |
| 122 base::CommandLine::ForCurrentProcess()->AppendSwitch( |
| 123 switches::kUseFakeJpegDecodeAccelerator); |
| 124 } else { |
| 125 base::CommandLine::ForCurrentProcess()->AppendSwitch( |
| 126 switches::kDisableAcceleratedMjpegDecode); |
| 127 } |
119 } | 128 } |
120 | 129 |
121 // This cannot be part of an override of SetUp(), because at the time when | 130 // This cannot be part of an override of SetUp(), because at the time when |
122 // SetUp() is invoked, the BrowserMainLoop does not exist yet. | 131 // SetUp() is invoked, the BrowserMainLoop does not exist yet. |
123 void SetUpRequiringBrowserMainLoopOnMainThread() { | 132 void SetUpRequiringBrowserMainLoopOnMainThread() { |
124 BrowserMainLoop* browser_main_loop = BrowserMainLoop::GetInstance(); | 133 BrowserMainLoop* browser_main_loop = BrowserMainLoop::GetInstance(); |
125 ASSERT_TRUE(browser_main_loop); | 134 ASSERT_TRUE(browser_main_loop); |
126 media_stream_manager_ = browser_main_loop->media_stream_manager(); | 135 media_stream_manager_ = browser_main_loop->media_stream_manager(); |
127 ASSERT_TRUE(media_stream_manager_); | 136 ASSERT_TRUE(media_stream_manager_); |
128 } | 137 } |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
181 base::Bind(&VideoCaptureBrowserTest::SetUpAndStartCaptureDeviceOnIOThread, | 190 base::Bind(&VideoCaptureBrowserTest::SetUpAndStartCaptureDeviceOnIOThread, |
182 base::Unretained(this), std::move(after_start_continuation))); | 191 base::Unretained(this), std::move(after_start_continuation))); |
183 run_loop.Run(); | 192 run_loop.Run(); |
184 } | 193 } |
185 | 194 |
186 IN_PROC_BROWSER_TEST_P(VideoCaptureBrowserTest, | 195 IN_PROC_BROWSER_TEST_P(VideoCaptureBrowserTest, |
187 ReceiveFramesFromFakeCaptureDevice) { | 196 ReceiveFramesFromFakeCaptureDevice) { |
188 SetUpRequiringBrowserMainLoopOnMainThread(); | 197 SetUpRequiringBrowserMainLoopOnMainThread(); |
189 | 198 |
190 std::vector<FrameInfo> received_frame_infos; | 199 std::vector<FrameInfo> received_frame_infos; |
191 static const size_t kNumFramesToReceive = 3; | 200 static const size_t kMinFramesToReceive = 5; |
| 201 static const size_t kMaxFramesToReceive = 300; |
192 base::RunLoop run_loop; | 202 base::RunLoop run_loop; |
193 | 203 |
194 auto quit_run_loop_on_current_thread_cb = | 204 auto quit_run_loop_on_current_thread_cb = |
195 media::BindToCurrentLoop(run_loop.QuitClosure()); | 205 media::BindToCurrentLoop(run_loop.QuitClosure()); |
196 auto finish_test_cb = | 206 auto finish_test_cb = |
197 base::Bind(&VideoCaptureBrowserTest::TearDownCaptureDeviceOnIOThread, | 207 base::Bind(&VideoCaptureBrowserTest::TearDownCaptureDeviceOnIOThread, |
198 base::Unretained(this), | 208 base::Unretained(this), |
199 std::move(quit_run_loop_on_current_thread_cb), true); | 209 std::move(quit_run_loop_on_current_thread_cb), true); |
200 | 210 |
| 211 bool must_wait_for_gpu_decode_to_start = false; |
| 212 if (GetParam().exercise_accelerated_jpeg_decoding) { |
| 213 // Since the GPU jpeg decoder is created asynchronously while decoding |
| 214 // in software is ongoing, we have to keep pushing frames until a message |
| 215 // arrives that tells us that the GPU decoder is being used. Otherwise, |
| 216 // it may happen that all test frames are decoded using the non-GPU |
| 217 // decoding path before the GPU decoder has started getting used. |
| 218 must_wait_for_gpu_decode_to_start = true; |
| 219 EXPECT_CALL(mock_controller_event_handler_, OnStartedUsingGpuDecode(_)) |
| 220 .WillOnce(InvokeWithoutArgs([&must_wait_for_gpu_decode_to_start]() { |
| 221 must_wait_for_gpu_decode_to_start = false; |
| 222 })); |
| 223 } |
201 EXPECT_CALL(mock_controller_event_handler_, DoOnBufferCreated(_, _, _, _)) | 224 EXPECT_CALL(mock_controller_event_handler_, DoOnBufferCreated(_, _, _, _)) |
202 .Times(AtLeast(1)); | 225 .Times(AtLeast(1)); |
203 EXPECT_CALL(mock_controller_event_handler_, OnBufferReady(_, _, _)) | 226 EXPECT_CALL(mock_controller_event_handler_, OnBufferReady(_, _, _)) |
204 .WillRepeatedly( | 227 .WillRepeatedly(Invoke( |
205 Invoke([&received_frame_infos, &finish_test_cb]( | 228 [this, &received_frame_infos, &must_wait_for_gpu_decode_to_start, |
206 VideoCaptureControllerID id, int buffer_id, | 229 &finish_test_cb](VideoCaptureControllerID id, int buffer_id, |
207 const media::mojom::VideoFrameInfoPtr& frame_info) { | 230 const media::mojom::VideoFrameInfoPtr& frame_info) { |
208 FrameInfo received_frame_info; | 231 FrameInfo received_frame_info; |
209 received_frame_info.pixel_format = frame_info->pixel_format; | 232 received_frame_info.pixel_format = frame_info->pixel_format; |
210 received_frame_info.storage_type = frame_info->storage_type; | 233 received_frame_info.storage_type = frame_info->storage_type; |
211 received_frame_info.size = frame_info->coded_size; | 234 received_frame_info.size = frame_info->coded_size; |
212 received_frame_info.timestamp = frame_info->timestamp; | 235 received_frame_info.timestamp = frame_info->timestamp; |
213 received_frame_infos.emplace_back(received_frame_info); | 236 received_frame_infos.emplace_back(received_frame_info); |
214 if (received_frame_infos.size() >= kNumFramesToReceive) { | 237 |
| 238 const double kArbitraryUtilization = 0.5; |
| 239 controller_->ReturnBuffer(id, &mock_controller_event_handler_, |
| 240 buffer_id, kArbitraryUtilization); |
| 241 |
| 242 if ((received_frame_infos.size() >= kMinFramesToReceive && |
| 243 !must_wait_for_gpu_decode_to_start) || |
| 244 (received_frame_infos.size() == kMaxFramesToReceive)) { |
215 finish_test_cb.Run(); | 245 finish_test_cb.Run(); |
216 } | 246 } |
217 })); | 247 })); |
218 | 248 |
219 base::Closure do_nothing; | 249 base::Closure do_nothing; |
220 BrowserThread::PostTask( | 250 BrowserThread::PostTask( |
221 content::BrowserThread::IO, FROM_HERE, | 251 content::BrowserThread::IO, FROM_HERE, |
222 base::Bind(&VideoCaptureBrowserTest::SetUpAndStartCaptureDeviceOnIOThread, | 252 base::Bind(&VideoCaptureBrowserTest::SetUpAndStartCaptureDeviceOnIOThread, |
223 base::Unretained(this), std::move(do_nothing))); | 253 base::Unretained(this), std::move(do_nothing))); |
224 run_loop.Run(); | 254 run_loop.Run(); |
225 | 255 |
226 EXPECT_GE(received_frame_infos.size(), kNumFramesToReceive); | 256 EXPECT_FALSE(must_wait_for_gpu_decode_to_start); |
| 257 EXPECT_GE(received_frame_infos.size(), kMinFramesToReceive); |
| 258 EXPECT_LT(received_frame_infos.size(), kMaxFramesToReceive); |
227 base::TimeDelta previous_timestamp; | 259 base::TimeDelta previous_timestamp; |
228 bool first_frame = true; | 260 bool first_frame = true; |
229 for (const auto& frame_info : received_frame_infos) { | 261 for (const auto& frame_info : received_frame_infos) { |
230 EXPECT_EQ(GetParam().pixel_format_to_use, frame_info.pixel_format); | 262 EXPECT_EQ(GetParam().pixel_format_to_use, frame_info.pixel_format); |
231 EXPECT_EQ(media::PIXEL_STORAGE_CPU, frame_info.storage_type); | 263 EXPECT_EQ(media::PIXEL_STORAGE_CPU, frame_info.storage_type); |
232 EXPECT_EQ(GetParam().resolution_to_use, frame_info.size); | 264 EXPECT_EQ(GetParam().resolution_to_use, frame_info.size); |
233 // Timestamps are expected to increase | 265 // Timestamps are expected to increase |
234 if (!first_frame) | 266 if (!first_frame) |
235 EXPECT_GT(frame_info.timestamp, previous_timestamp); | 267 EXPECT_GT(frame_info.timestamp, previous_timestamp); |
236 first_frame = false; | 268 first_frame = false; |
237 previous_timestamp = frame_info.timestamp; | 269 previous_timestamp = frame_info.timestamp; |
238 } | 270 } |
239 } | 271 } |
240 | 272 |
241 INSTANTIATE_TEST_CASE_P( | 273 INSTANTIATE_TEST_CASE_P( |
242 , | 274 , |
243 VideoCaptureBrowserTest, | 275 VideoCaptureBrowserTest, |
244 Values(TestParams{"fps=25,device-count=2", 0, media::PIXEL_FORMAT_I420, | 276 Values(TestParams{"fps=25,device-count=2", 0, media::PIXEL_FORMAT_I420, |
245 gfx::Size(1280, 720), 25.0f}, | 277 gfx::Size(1280, 720), 25.0f, false}, |
246 // The 2nd device outputs Y16 | 278 // The 2nd device outputs Y16 |
247 TestParams{"fps=25,device-count=2", 1, media::PIXEL_FORMAT_Y16, | 279 TestParams{"fps=25,device-count=2", 1, media::PIXEL_FORMAT_Y16, |
248 gfx::Size(1280, 720), 25.0f}, | 280 gfx::Size(1280, 720), 25.0f, false}, |
249 TestParams{"fps=15,device-count=2", 1, media::PIXEL_FORMAT_Y16, | 281 TestParams{"fps=15,device-count=2", 1, media::PIXEL_FORMAT_Y16, |
250 gfx::Size(640, 480), 15.0f}, | 282 gfx::Size(640, 480), 15.0f, false}, |
251 // The 3rd device outputs MJPEG, which is converted to I420. | 283 // The 3rd device outputs MJPEG, which is converted to I420. |
252 TestParams{"fps=15,device-count=3", 2, media::PIXEL_FORMAT_I420, | 284 TestParams{"fps=15,device-count=3", 2, media::PIXEL_FORMAT_I420, |
253 gfx::Size(640, 480), 25.0f})); | 285 gfx::Size(640, 480), 25.0f, false}, |
| 286 TestParams{"fps=6,device-count=3", 2, media::PIXEL_FORMAT_I420, |
| 287 gfx::Size(640, 480), 6.0f, true})); |
254 | 288 |
255 } // namespace content | 289 } // namespace content |
OLD | NEW |