| 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 |