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