Chromium Code Reviews| 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_controller.h" |
| 11 #include "content/browser/renderer_host/media/video_capture_manager.h" | 11 #include "content/browser/renderer_host/media/video_capture_manager.h" |
| 12 #include "content/public/common/content_switches.h" | 12 #include "content/public/common/content_switches.h" |
| 13 #include "content/public/test/content_browser_test.h" | 13 #include "content/public/test/content_browser_test.h" |
| 14 #include "media/base/bind_to_current_loop.h" | 14 #include "media/base/bind_to_current_loop.h" |
| 15 #include "media/base/media_switches.h" | 15 #include "media/base/media_switches.h" |
| 16 #include "media/capture/video_capture_types.h" | 16 #include "media/capture/video_capture_types.h" |
| 17 #include "services/video_capture/public/cpp/constants.h" | |
| 17 #include "testing/gmock/include/gmock/gmock.h" | 18 #include "testing/gmock/include/gmock/gmock.h" |
| 18 | 19 |
| 19 using testing::_; | 20 using testing::_; |
| 20 using testing::AtLeast; | 21 using testing::AtLeast; |
| 21 using testing::Invoke; | 22 using testing::Invoke; |
| 22 using testing::InvokeWithoutArgs; | 23 using testing::InvokeWithoutArgs; |
| 23 using testing::Values; | 24 using testing::Values; |
| 24 | 25 |
| 25 namespace content { | 26 namespace content { |
| 26 | 27 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 59 MOCK_METHOD2(Aborted, void(MediaStreamType, int)); | 60 MOCK_METHOD2(Aborted, void(MediaStreamType, int)); |
| 60 }; | 61 }; |
| 61 | 62 |
| 62 struct TestParams { | 63 struct TestParams { |
| 63 std::string fake_device_factory_config_string; | 64 std::string fake_device_factory_config_string; |
| 64 size_t device_index_to_use; | 65 size_t device_index_to_use; |
| 65 media::VideoPixelFormat pixel_format_to_use; | 66 media::VideoPixelFormat pixel_format_to_use; |
| 66 gfx::Size resolution_to_use; | 67 gfx::Size resolution_to_use; |
| 67 float frame_rate_to_use; | 68 float frame_rate_to_use; |
| 68 bool exercise_accelerated_jpeg_decoding; | 69 bool exercise_accelerated_jpeg_decoding; |
| 70 bool use_mojo_service; | |
| 69 }; | 71 }; |
| 70 | 72 |
| 71 struct FrameInfo { | 73 struct FrameInfo { |
| 72 gfx::Size size; | 74 gfx::Size size; |
| 73 media::VideoPixelFormat pixel_format; | 75 media::VideoPixelFormat pixel_format; |
| 74 media::VideoPixelStorage storage_type; | 76 media::VideoPixelStorage storage_type; |
| 75 base::TimeDelta timestamp; | 77 base::TimeDelta timestamp; |
| 76 }; | 78 }; |
| 77 | 79 |
| 80 // Integration test that exercises the VideoCaptureManager instance running in | |
| 81 // the Browser process. | |
| 78 class VideoCaptureBrowserTest | 82 class VideoCaptureBrowserTest |
| 79 : public ContentBrowserTest, | 83 : public ContentBrowserTest, |
| 80 public ::testing::WithParamInterface<TestParams> { | 84 public ::testing::WithParamInterface<TestParams> { |
| 81 public: | 85 public: |
| 82 void SetUpAndStartCaptureDeviceOnIOThread(base::Closure continuation) { | 86 void SetUpAndStartCaptureDeviceOnIOThread(base::Closure continuation) { |
| 83 video_capture_manager_ = media_stream_manager_->video_capture_manager(); | 87 video_capture_manager_ = media_stream_manager_->video_capture_manager(); |
| 84 ASSERT_TRUE(video_capture_manager_); | 88 ASSERT_TRUE(video_capture_manager_); |
| 85 video_capture_manager_->RegisterListener(&mock_stream_provider_listener_); | 89 video_capture_manager_->RegisterListener(&mock_stream_provider_listener_); |
| 86 video_capture_manager_->EnumerateDevices( | 90 video_capture_manager_->EnumerateDevices( |
| 87 base::Bind(&VideoCaptureBrowserTest::OnDeviceDescriptorsReceived, | 91 base::Bind(&VideoCaptureBrowserTest::OnDeviceDescriptorsReceived, |
| 88 base::Unretained(this), std::move(continuation))); | 92 base::Unretained(this), std::move(continuation))); |
| 89 } | 93 } |
| 90 | 94 |
| 91 void TearDownCaptureDeviceOnIOThread(base::Closure continuation, | 95 void TearDownCaptureDeviceOnIOThread(base::Closure continuation, |
| 92 bool post_to_end_of_message_queue) { | 96 bool post_to_end_of_message_queue) { |
| 93 // StopCaptureForClient must not be called synchronously from either the | 97 // DisconnectClient() must not be called synchronously from either the |
| 94 // |done_cb| passed to StartCaptureForClient() nor any callback made to a | 98 // |done_cb| passed to StartCaptureForClient() nor any callback made to a |
| 95 // VideoCaptureControllerEventHandler. To satisfy this, we have to post our | 99 // VideoCaptureControllerEventHandler. To satisfy this, we have to post our |
| 96 // invocation to the end of the IO message queue. | 100 // invocation to the end of the IO message queue. |
| 97 if (post_to_end_of_message_queue) { | 101 if (post_to_end_of_message_queue) { |
| 98 base::ThreadTaskRunnerHandle::Get()->PostTask( | 102 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 99 FROM_HERE, | 103 FROM_HERE, |
| 100 base::Bind(&VideoCaptureBrowserTest::TearDownCaptureDeviceOnIOThread, | 104 base::Bind(&VideoCaptureBrowserTest::TearDownCaptureDeviceOnIOThread, |
| 101 base::Unretained(this), continuation, false)); | 105 base::Unretained(this), continuation, false)); |
| 102 return; | 106 return; |
| 103 } | 107 } |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 118 switches::kUseFakeDeviceForMediaStream, | 122 switches::kUseFakeDeviceForMediaStream, |
| 119 GetParam().fake_device_factory_config_string); | 123 GetParam().fake_device_factory_config_string); |
| 120 command_line->AppendSwitch(switches::kUseFakeUIForMediaStream); | 124 command_line->AppendSwitch(switches::kUseFakeUIForMediaStream); |
| 121 if (GetParam().exercise_accelerated_jpeg_decoding) { | 125 if (GetParam().exercise_accelerated_jpeg_decoding) { |
| 122 base::CommandLine::ForCurrentProcess()->AppendSwitch( | 126 base::CommandLine::ForCurrentProcess()->AppendSwitch( |
| 123 switches::kUseFakeJpegDecodeAccelerator); | 127 switches::kUseFakeJpegDecodeAccelerator); |
| 124 } else { | 128 } else { |
| 125 base::CommandLine::ForCurrentProcess()->AppendSwitch( | 129 base::CommandLine::ForCurrentProcess()->AppendSwitch( |
| 126 switches::kDisableAcceleratedMjpegDecode); | 130 switches::kDisableAcceleratedMjpegDecode); |
| 127 } | 131 } |
| 132 if (GetParam().use_mojo_service) { | |
| 133 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII( | |
| 134 switches::kEnableFeatures, video_capture::kMojoVideoCapture.name); | |
| 135 } | |
| 128 } | 136 } |
| 129 | 137 |
| 130 // This cannot be part of an override of SetUp(), because at the time when | 138 // This cannot be part of an override of SetUp(), because at the time when |
| 131 // SetUp() is invoked, the BrowserMainLoop does not exist yet. | 139 // SetUp() is invoked, the BrowserMainLoop does not exist yet. |
| 132 void SetUpRequiringBrowserMainLoopOnMainThread() { | 140 void SetUpRequiringBrowserMainLoopOnMainThread() { |
| 133 BrowserMainLoop* browser_main_loop = BrowserMainLoop::GetInstance(); | 141 BrowserMainLoop* browser_main_loop = BrowserMainLoop::GetInstance(); |
| 134 ASSERT_TRUE(browser_main_loop); | 142 ASSERT_TRUE(browser_main_loop); |
| 135 media_stream_manager_ = browser_main_loop->media_stream_manager(); | 143 media_stream_manager_ = browser_main_loop->media_stream_manager(); |
| 136 ASSERT_TRUE(media_stream_manager_); | 144 ASSERT_TRUE(media_stream_manager_); |
| 137 } | 145 } |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 170 MediaStreamManager* media_stream_manager_ = nullptr; | 178 MediaStreamManager* media_stream_manager_ = nullptr; |
| 171 VideoCaptureManager* video_capture_manager_ = nullptr; | 179 VideoCaptureManager* video_capture_manager_ = nullptr; |
| 172 int session_id_ = 0; | 180 int session_id_ = 0; |
| 173 const VideoCaptureControllerID stub_client_id_ = 123; | 181 const VideoCaptureControllerID stub_client_id_ = 123; |
| 174 MockMediaStreamProviderListener mock_stream_provider_listener_; | 182 MockMediaStreamProviderListener mock_stream_provider_listener_; |
| 175 MockVideoCaptureControllerEventHandler mock_controller_event_handler_; | 183 MockVideoCaptureControllerEventHandler mock_controller_event_handler_; |
| 176 base::WeakPtr<VideoCaptureController> controller_; | 184 base::WeakPtr<VideoCaptureController> controller_; |
| 177 }; | 185 }; |
| 178 | 186 |
| 179 IN_PROC_BROWSER_TEST_P(VideoCaptureBrowserTest, StartAndImmediatelyStop) { | 187 IN_PROC_BROWSER_TEST_P(VideoCaptureBrowserTest, StartAndImmediatelyStop) { |
| 188 #if defined(OS_ANDROID) | |
| 189 // Mojo video capture is currently not supported on Android | |
|
mcasas
2017/05/10 02:33:32
This sounds pretty bad: at least a TODO() and a bu
chfremer
2017/05/10 17:59:39
Done.
| |
| 190 if (GetParam().use_mojo_service) | |
| 191 return; | |
| 192 #endif | |
| 193 | |
| 180 SetUpRequiringBrowserMainLoopOnMainThread(); | 194 SetUpRequiringBrowserMainLoopOnMainThread(); |
| 181 base::RunLoop run_loop; | 195 base::RunLoop run_loop; |
| 182 auto quit_run_loop_on_current_thread_cb = | 196 auto quit_run_loop_on_current_thread_cb = |
| 183 media::BindToCurrentLoop(run_loop.QuitClosure()); | 197 media::BindToCurrentLoop(run_loop.QuitClosure()); |
| 184 auto after_start_continuation = | 198 auto after_start_continuation = |
| 185 base::Bind(&VideoCaptureBrowserTest::TearDownCaptureDeviceOnIOThread, | 199 base::Bind(&VideoCaptureBrowserTest::TearDownCaptureDeviceOnIOThread, |
| 186 base::Unretained(this), | 200 base::Unretained(this), |
| 187 std::move(quit_run_loop_on_current_thread_cb), true); | 201 std::move(quit_run_loop_on_current_thread_cb), true); |
| 188 BrowserThread::PostTask( | 202 BrowserThread::PostTask( |
| 189 content::BrowserThread::IO, FROM_HERE, | 203 content::BrowserThread::IO, FROM_HERE, |
| 190 base::Bind(&VideoCaptureBrowserTest::SetUpAndStartCaptureDeviceOnIOThread, | 204 base::Bind(&VideoCaptureBrowserTest::SetUpAndStartCaptureDeviceOnIOThread, |
| 191 base::Unretained(this), std::move(after_start_continuation))); | 205 base::Unretained(this), std::move(after_start_continuation))); |
| 192 run_loop.Run(); | 206 run_loop.Run(); |
| 193 } | 207 } |
| 194 | 208 |
| 195 IN_PROC_BROWSER_TEST_P(VideoCaptureBrowserTest, | 209 IN_PROC_BROWSER_TEST_P(VideoCaptureBrowserTest, |
| 196 ReceiveFramesFromFakeCaptureDevice) { | 210 ReceiveFramesFromFakeCaptureDevice) { |
| 197 // TODO(chfremer): This test case is flaky on Android. Find out cause of | |
| 198 // flakiness and then re-enable. See crbug.com/709039. | |
| 199 #if defined(OS_ANDROID) | 211 #if defined(OS_ANDROID) |
| 212 // TODO(chfremer): This test case is flaky on Android. Find out cause of | |
| 213 // flakiness and then re-enable. See crbug.com/709039. | |
| 200 if (GetParam().exercise_accelerated_jpeg_decoding) | 214 if (GetParam().exercise_accelerated_jpeg_decoding) |
| 201 return; | 215 return; |
| 216 // Mojo video capture is currently not supported on Android | |
| 217 if (GetParam().use_mojo_service) | |
| 218 return; | |
| 202 #endif | 219 #endif |
| 203 | 220 |
| 204 SetUpRequiringBrowserMainLoopOnMainThread(); | 221 SetUpRequiringBrowserMainLoopOnMainThread(); |
| 205 | 222 |
| 206 std::vector<FrameInfo> received_frame_infos; | 223 std::vector<FrameInfo> received_frame_infos; |
| 207 static const size_t kMinFramesToReceive = 5; | 224 static const size_t kMinFramesToReceive = 5; |
| 208 static const size_t kMaxFramesToReceive = 300; | 225 static const size_t kMaxFramesToReceive = 300; |
| 209 base::RunLoop run_loop; | 226 base::RunLoop run_loop; |
| 210 | 227 |
| 211 auto quit_run_loop_on_current_thread_cb = | 228 auto quit_run_loop_on_current_thread_cb = |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 274 EXPECT_GT(frame_info.timestamp, previous_timestamp); | 291 EXPECT_GT(frame_info.timestamp, previous_timestamp); |
| 275 first_frame = false; | 292 first_frame = false; |
| 276 previous_timestamp = frame_info.timestamp; | 293 previous_timestamp = frame_info.timestamp; |
| 277 } | 294 } |
| 278 } | 295 } |
| 279 | 296 |
| 280 INSTANTIATE_TEST_CASE_P( | 297 INSTANTIATE_TEST_CASE_P( |
| 281 , | 298 , |
| 282 VideoCaptureBrowserTest, | 299 VideoCaptureBrowserTest, |
| 283 Values(TestParams{"fps=25,device-count=2", 0, media::PIXEL_FORMAT_I420, | 300 Values(TestParams{"fps=25,device-count=2", 0, media::PIXEL_FORMAT_I420, |
| 284 gfx::Size(1280, 720), 25.0f, false}, | 301 gfx::Size(1280, 720), 25.0f, false, false}, |
| 302 TestParams{"fps=25,device-count=2", 0, media::PIXEL_FORMAT_I420, | |
| 303 gfx::Size(1280, 720), 25.0f, false, true}, | |
| 285 // The 2nd device outputs Y16 | 304 // The 2nd device outputs Y16 |
| 286 TestParams{"fps=25,device-count=2", 1, media::PIXEL_FORMAT_Y16, | 305 TestParams{"fps=25,device-count=2", 1, media::PIXEL_FORMAT_Y16, |
| 287 gfx::Size(1280, 720), 25.0f, false}, | 306 gfx::Size(1280, 720), 25.0f, false, false}, |
| 307 TestParams{"fps=25,device-count=2", 1, media::PIXEL_FORMAT_Y16, | |
| 308 gfx::Size(1280, 720), 25.0f, false, true}, | |
| 288 TestParams{"fps=15,device-count=2", 1, media::PIXEL_FORMAT_Y16, | 309 TestParams{"fps=15,device-count=2", 1, media::PIXEL_FORMAT_Y16, |
| 289 gfx::Size(640, 480), 15.0f, false}, | 310 gfx::Size(640, 480), 15.0f, false, false}, |
| 290 // The 3rd device outputs MJPEG, which is converted to I420. | 311 // The 3rd device outputs MJPEG, which is converted to I420. |
| 291 TestParams{"fps=15,device-count=3", 2, media::PIXEL_FORMAT_I420, | 312 TestParams{"fps=15,device-count=3", 2, media::PIXEL_FORMAT_I420, |
| 292 gfx::Size(640, 480), 25.0f, false}, | 313 gfx::Size(640, 480), 25.0f, false, false}, |
| 314 TestParams{"fps=15,device-count=3", 2, media::PIXEL_FORMAT_I420, | |
| 315 gfx::Size(640, 480), 25.0f, false, true}, | |
| 293 TestParams{"fps=6,device-count=3", 2, media::PIXEL_FORMAT_I420, | 316 TestParams{"fps=6,device-count=3", 2, media::PIXEL_FORMAT_I420, |
| 294 gfx::Size(640, 480), 6.0f, true})); | 317 gfx::Size(640, 480), 6.0f, true, false})); |
|
mcasas
2017/05/10 02:33:33
Consider using ::testing::Combine to simplify all
chfremer
2017/05/10 17:59:39
I prefer to not use ::testing::Combine() here, bec
mcasas
2017/05/10 18:15:43
Why not? It should be made explicit here why not,
chfremer
2017/05/10 21:08:05
Done.
| |
| 295 | 318 |
| 296 } // namespace content | 319 } // namespace content |
| OLD | NEW |