Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "content/browser/renderer_host/media/video_capture_host.h" | 5 #include "content/browser/renderer_host/media/video_capture_host.h" |
| 6 | 6 |
| 7 #include <stdint.h> | 7 #include <stdint.h> |
| 8 | 8 |
| 9 #include <map> | 9 #include <map> |
| 10 #include <memory> | 10 #include <memory> |
| 11 #include <string> | 11 #include <string> |
| 12 | 12 |
| 13 #include "base/bind.h" | 13 #include "base/bind.h" |
| 14 #include "base/command_line.h" | 14 #include "base/command_line.h" |
| 15 #include "base/files/file_util.h" | |
| 16 #include "base/files/scoped_file.h" | |
| 17 #include "base/location.h" | 15 #include "base/location.h" |
| 18 #include "base/macros.h" | 16 #include "base/macros.h" |
| 19 #include "base/memory/ptr_util.h" | 17 #include "base/memory/ptr_util.h" |
| 20 #include "base/run_loop.h" | 18 #include "base/run_loop.h" |
| 21 #include "base/single_thread_task_runner.h" | 19 #include "base/single_thread_task_runner.h" |
| 22 #include "base/strings/stringprintf.h" | |
| 23 #include "base/threading/thread_task_runner_handle.h" | 20 #include "base/threading/thread_task_runner_handle.h" |
| 24 #include "build/build_config.h" | 21 #include "build/build_config.h" |
| 25 #include "content/browser/browser_thread_impl.h" | 22 #include "content/browser/browser_thread_impl.h" |
| 26 #include "content/browser/renderer_host/media/media_stream_manager.h" | 23 #include "content/browser/renderer_host/media/media_stream_manager.h" |
| 27 #include "content/browser/renderer_host/media/media_stream_requester.h" | 24 #include "content/browser/renderer_host/media/media_stream_requester.h" |
| 28 #include "content/browser/renderer_host/media/media_stream_ui_proxy.h" | |
| 29 #include "content/browser/renderer_host/media/video_capture_manager.h" | 25 #include "content/browser/renderer_host/media/video_capture_manager.h" |
| 30 #include "content/common/media/video_capture_messages.h" | 26 #include "content/common/media/video_capture_messages.h" |
| 31 #include "content/public/common/content_switches.h" | 27 #include "content/public/common/content_switches.h" |
| 32 #include "content/public/test/mock_resource_context.h" | 28 #include "content/public/test/mock_resource_context.h" |
| 33 #include "content/public/test/test_browser_context.h" | 29 #include "content/public/test/test_browser_context.h" |
| 34 #include "content/public/test/test_browser_thread_bundle.h" | 30 #include "content/public/test/test_browser_thread_bundle.h" |
| 35 #include "content/test/test_content_browser_client.h" | 31 #include "content/test/test_content_browser_client.h" |
| 36 #include "media/audio/audio_manager.h" | 32 #include "media/audio/audio_manager.h" |
| 37 #include "media/base/media_switches.h" | 33 #include "media/base/media_switches.h" |
| 38 #include "media/base/video_capture_types.h" | 34 #include "media/base/video_capture_types.h" |
| 39 #include "media/base/video_frame.h" | |
| 40 #include "net/url_request/url_request_context.h" | 35 #include "net/url_request/url_request_context.h" |
| 41 #include "testing/gmock/include/gmock/gmock.h" | 36 #include "testing/gmock/include/gmock/gmock.h" |
| 42 #include "testing/gtest/include/gtest/gtest.h" | 37 #include "testing/gtest/include/gtest/gtest.h" |
| 43 | 38 |
| 44 #if defined(OS_CHROMEOS) | 39 #if defined(OS_CHROMEOS) |
| 45 #include "chromeos/audio/cras_audio_handler.h" | 40 #include "chromeos/audio/cras_audio_handler.h" |
| 46 #endif | 41 #endif |
| 47 | 42 |
| 48 using ::testing::_; | 43 using ::testing::_; |
| 49 using ::testing::AnyNumber; | 44 using ::testing::AnyNumber; |
| 50 using ::testing::DoAll; | 45 using ::testing::DoAll; |
| 51 using ::testing::InSequence; | 46 using ::testing::InSequence; |
| 52 using ::testing::Mock; | 47 using ::testing::Mock; |
| 53 using ::testing::Return; | 48 using ::testing::Return; |
| 54 using ::testing::SaveArg; | 49 using ::testing::SaveArg; |
| 55 using ::testing::StrictMock; | 50 using ::testing::StrictMock; |
| 56 | 51 |
| 57 namespace content { | 52 namespace content { |
| 58 | 53 |
| 59 // Id used to identify the capture session between renderer and | 54 // Id used to identify the capture session between renderer and |
| 60 // video_capture_host. This is an arbitrary value. | 55 // video_capture_host. This is an arbitrary value. |
| 61 static const int kDeviceId = 555; | 56 static const int kDeviceId = 555; |
| 62 | 57 |
| 63 // Define to enable test where video is dumped to file. | |
| 64 // #define DUMP_VIDEO | |
| 65 | |
| 66 // Define to use a real video capture device. | |
| 67 // #define TEST_REAL_CAPTURE_DEVICE | |
| 68 | |
| 69 // Simple class used for dumping video to a file. This can be used for verifying | |
| 70 // the output. | |
| 71 class DumpVideo { | |
| 72 public: | |
| 73 DumpVideo() {} | |
| 74 const gfx::Size& coded_size() const { return coded_size_; } | |
| 75 void StartDump(const gfx::Size& coded_size) { | |
| 76 base::FilePath file_name = base::FilePath(base::StringPrintf( | |
| 77 FILE_PATH_LITERAL("dump_w%d_h%d.yuv"), | |
| 78 coded_size.width(), | |
| 79 coded_size.height())); | |
| 80 file_.reset(base::OpenFile(file_name, "wb")); | |
| 81 coded_size_ = coded_size; | |
| 82 } | |
| 83 void NewVideoFrame(const void* buffer) { | |
| 84 if (file_.get() != NULL) { | |
| 85 const int size = media::VideoFrame::AllocationSize( | |
| 86 media::PIXEL_FORMAT_I420, coded_size_); | |
| 87 ASSERT_EQ(1U, fwrite(buffer, size, 1, file_.get())); | |
| 88 } | |
| 89 } | |
| 90 | |
| 91 private: | |
| 92 base::ScopedFILE file_; | |
| 93 gfx::Size coded_size_; | |
| 94 }; | |
| 95 | |
| 96 class MockMediaStreamRequester : public MediaStreamRequester { | 58 class MockMediaStreamRequester : public MediaStreamRequester { |
| 97 public: | 59 public: |
| 98 MockMediaStreamRequester() {} | 60 MockMediaStreamRequester() {} |
| 99 virtual ~MockMediaStreamRequester() {} | 61 virtual ~MockMediaStreamRequester() {} |
| 100 | 62 |
| 101 // MediaStreamRequester implementation. | 63 // MediaStreamRequester implementation. |
| 102 MOCK_METHOD5(StreamGenerated, | 64 MOCK_METHOD5(StreamGenerated, |
| 103 void(int render_frame_id, | 65 void(int render_frame_id, |
| 104 int page_request_id, | 66 int page_request_id, |
| 105 const std::string& label, | 67 const std::string& label, |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 122 const StreamDeviceInfo& device_info)); | 84 const StreamDeviceInfo& device_info)); |
| 123 MOCK_METHOD1(DevicesChanged, void(MediaStreamType type)); | 85 MOCK_METHOD1(DevicesChanged, void(MediaStreamType type)); |
| 124 | 86 |
| 125 private: | 87 private: |
| 126 DISALLOW_COPY_AND_ASSIGN(MockMediaStreamRequester); | 88 DISALLOW_COPY_AND_ASSIGN(MockMediaStreamRequester); |
| 127 }; | 89 }; |
| 128 | 90 |
| 129 class MockVideoCaptureHost : public VideoCaptureHost { | 91 class MockVideoCaptureHost : public VideoCaptureHost { |
| 130 public: | 92 public: |
| 131 MockVideoCaptureHost(MediaStreamManager* manager) | 93 MockVideoCaptureHost(MediaStreamManager* manager) |
| 132 : VideoCaptureHost(manager), | 94 : VideoCaptureHost(manager), return_buffers_immediately_(false) {} |
| 133 return_buffers_(false), | |
| 134 dump_video_(false) {} | |
| 135 | 95 |
| 136 // A list of mock methods. | |
| 137 MOCK_METHOD4(OnNewBufferCreated, | 96 MOCK_METHOD4(OnNewBufferCreated, |
| 138 void(int device_id, | 97 void(int device_id, |
| 139 base::SharedMemoryHandle handle, | 98 base::SharedMemoryHandle handle, |
| 140 int length, | 99 int length, |
| 141 int buffer_id)); | 100 int buffer_id)); |
| 142 MOCK_METHOD2(OnBufferFreed, void(int device_id, int buffer_id)); | 101 MOCK_METHOD2(OnBufferFreed, void(int device_id, int buffer_id)); |
| 143 MOCK_METHOD1(OnBufferFilled, void(int device_id)); | 102 MOCK_METHOD1(OnBufferFilled, void(int device_id)); |
| 144 MOCK_METHOD2(OnStateChanged, void(int device_id, VideoCaptureState state)); | 103 MOCK_METHOD2(OnStateChanged, void(int device_id, VideoCaptureState state)); |
| 145 | 104 |
| 146 // Use class DumpVideo to write I420 video to file. | 105 void SetReturnReceivedBuffersImmediately(bool enable) { |
| 147 void SetDumpVideo(bool enable) { | 106 return_buffers_immediately_ = enable; |
| 148 dump_video_ = enable; | |
| 149 } | 107 } |
| 150 | 108 |
| 151 void SetReturnReceivedDibs(bool enable) { | 109 void ReturnReceivedBuffers(int device_id) { |
| 152 return_buffers_ = enable; | 110 while (!buffer_ids_.empty()) { |
| 153 } | 111 int buffer_id = *buffer_ids_.begin(); |
|
xianglu
2016/10/07 19:35:08
Might be better to use buffer_ids_.front() so no n
mcasas
2016/10/07 21:41:51
Done.
| |
| 154 | 112 buffer_ids_.pop_front(); |
| 155 // Return Dibs we currently have received. | 113 this->OnRendererFinishedWithBuffer(device_id, buffer_id, gpu::SyncToken(), |
| 156 void ReturnReceivedDibs(int device_id) { | |
| 157 int handle = GetReceivedDib(); | |
| 158 while (handle) { | |
| 159 this->OnRendererFinishedWithBuffer(device_id, handle, gpu::SyncToken(), | |
| 160 -1.0); | 114 -1.0); |
| 161 handle = GetReceivedDib(); | |
| 162 } | 115 } |
| 163 } | 116 } |
| 164 | 117 |
| 165 int GetReceivedDib() { | |
| 166 if (filled_dib_.empty()) | |
| 167 return 0; | |
| 168 auto it = filled_dib_.begin(); | |
| 169 int h = it->first; | |
| 170 filled_dib_.erase(it); | |
| 171 | |
| 172 return h; | |
| 173 } | |
| 174 | |
| 175 private: | 118 private: |
| 176 ~MockVideoCaptureHost() override { | 119 ~MockVideoCaptureHost() override {} |
| 177 } | |
| 178 | 120 |
| 179 // This method is used to dispatch IPC messages to the renderer. We intercept | 121 // This method is used to dispatch IPC messages to the renderer. We intercept |
| 180 // these messages here and dispatch to our mock methods to verify the | 122 // some of these messages here to MOCK them and to map/unmap buffers. |
| 181 // conversation between this object and the renderer. | |
| 182 bool Send(IPC::Message* message) override { | 123 bool Send(IPC::Message* message) override { |
| 183 CHECK(message); | 124 CHECK(message); |
| 184 | 125 |
| 185 // In this method we dispatch the messages to the according handlers as if | 126 // In this method we dispatch the messages to the according handlers as if |
| 186 // we are the renderer. | 127 // we are the renderer. |
| 187 bool handled = true; | 128 bool handled = true; |
| 188 IPC_BEGIN_MESSAGE_MAP(MockVideoCaptureHost, *message) | 129 IPC_BEGIN_MESSAGE_MAP(MockVideoCaptureHost, *message) |
| 189 IPC_MESSAGE_HANDLER(VideoCaptureMsg_NewBuffer, OnNewBufferCreatedDispatch) | 130 IPC_MESSAGE_HANDLER(VideoCaptureMsg_NewBuffer, OnNewBufferCreatedDispatch) |
| 190 IPC_MESSAGE_HANDLER(VideoCaptureMsg_FreeBuffer, OnBufferFreedDispatch) | 131 IPC_MESSAGE_HANDLER(VideoCaptureMsg_FreeBuffer, OnBufferFreedDispatch) |
| 191 IPC_MESSAGE_HANDLER(VideoCaptureMsg_BufferReady, OnBufferFilledDispatch) | 132 IPC_MESSAGE_HANDLER(VideoCaptureMsg_BufferReady, OnBufferFilledDispatch) |
| 192 IPC_MESSAGE_HANDLER(VideoCaptureMsg_StateChanged, OnStateChangedDispatch) | 133 IPC_MESSAGE_HANDLER(VideoCaptureMsg_StateChanged, OnStateChanged) |
| 193 IPC_MESSAGE_UNHANDLED(handled = false) | 134 IPC_MESSAGE_UNHANDLED(handled = false) |
| 194 IPC_END_MESSAGE_MAP() | 135 IPC_END_MESSAGE_MAP() |
| 195 EXPECT_TRUE(handled); | 136 EXPECT_TRUE(handled); |
| 196 | 137 |
| 197 delete message; | 138 delete message; |
| 198 return true; | 139 return true; |
| 199 } | 140 } |
| 200 | 141 |
| 201 // These handler methods do minimal things and delegate to the mock methods. | 142 // These handler methods do minimal things and delegate to the mock methods. |
| 202 void OnNewBufferCreatedDispatch(int device_id, | 143 void OnNewBufferCreatedDispatch(int device_id, |
| 203 base::SharedMemoryHandle handle, | 144 base::SharedMemoryHandle handle, |
| 204 uint32_t length, | 145 uint32_t length, |
| 205 int buffer_id) { | 146 int buffer_id) { |
| 206 OnNewBufferCreated(device_id, handle, length, buffer_id); | 147 OnNewBufferCreated(device_id, handle, length, buffer_id); |
| 207 std::unique_ptr<base::SharedMemory> dib = | 148 buffer_ids_.push_back(buffer_id); |
| 208 base::MakeUnique<base::SharedMemory>(handle, false); | |
| 209 dib->Map(length); | |
| 210 filled_dib_[buffer_id] = std::move(dib); | |
| 211 } | 149 } |
| 212 | 150 |
| 213 void OnBufferFreedDispatch(int device_id, int buffer_id) { | 151 void OnBufferFreedDispatch(int device_id, int buffer_id) { |
| 214 OnBufferFreed(device_id, buffer_id); | 152 OnBufferFreed(device_id, buffer_id); |
| 215 | 153 |
| 216 auto it = filled_dib_.find(buffer_id); | 154 auto buffer = std::find(buffer_ids_.begin(), buffer_ids_.end(), buffer_id); |
| 217 ASSERT_TRUE(it != filled_dib_.end()); | 155 ASSERT_TRUE(buffer != buffer_ids_.end()); |
| 218 filled_dib_.erase(it); | 156 buffer_ids_.erase(buffer); |
| 219 } | 157 } |
| 220 | 158 |
| 221 void OnBufferFilledDispatch( | 159 void OnBufferFilledDispatch( |
| 222 const VideoCaptureMsg_BufferReady_Params& params) { | 160 const VideoCaptureMsg_BufferReady_Params& params) { |
| 223 base::SharedMemory* dib = filled_dib_[params.buffer_id].get(); | 161 OnBufferFilled(params.device_id); |
| 224 ASSERT_TRUE(dib != NULL); | 162 if (!return_buffers_immediately_) |
| 225 if (dump_video_) { | 163 return; |
| 226 if (dumper_.coded_size().IsEmpty()) | |
| 227 dumper_.StartDump(params.coded_size); | |
| 228 ASSERT_TRUE(dumper_.coded_size() == params.coded_size) | |
| 229 << "Dump format does not handle variable resolution."; | |
| 230 dumper_.NewVideoFrame(dib->memory()); | |
| 231 } | |
| 232 | 164 |
| 233 OnBufferFilled(params.device_id); | 165 VideoCaptureHost::OnRendererFinishedWithBuffer( |
| 234 if (return_buffers_) { | 166 params.device_id, params.buffer_id, gpu::SyncToken(), -1.0); |
| 235 VideoCaptureHost::OnRendererFinishedWithBuffer( | |
| 236 params.device_id, params.buffer_id, gpu::SyncToken(), -1.0); | |
| 237 } | |
| 238 } | 167 } |
| 239 | 168 |
| 240 void OnStateChangedDispatch(int device_id, VideoCaptureState state) { | 169 std::list<int> buffer_ids_; |
| 241 OnStateChanged(device_id, state); | 170 bool return_buffers_immediately_; |
| 242 } | |
| 243 | |
| 244 std::map<int, std::unique_ptr<base::SharedMemory>> filled_dib_; | |
| 245 bool return_buffers_; | |
| 246 bool dump_video_; | |
| 247 media::VideoCaptureFormat format_; | |
| 248 DumpVideo dumper_; | |
| 249 }; | 171 }; |
| 250 | 172 |
| 251 ACTION_P2(ExitMessageLoop, task_runner, quit_closure) { | 173 ACTION_P2(ExitMessageLoop, task_runner, quit_closure) { |
| 252 task_runner->PostTask(FROM_HERE, quit_closure); | 174 task_runner->PostTask(FROM_HERE, quit_closure); |
| 253 } | 175 } |
| 254 | 176 |
| 255 // This is an integration test of VideoCaptureHost in conjunction with | 177 // This is an integration test of VideoCaptureHost in conjunction with |
| 256 // MediaStreamManager, VideoCaptureManager, VideoCaptureController, and | 178 // MediaStreamManager, VideoCaptureManager, VideoCaptureController, and |
| 257 // VideoCaptureDevice. | 179 // VideoCaptureDevice. |
| 258 class VideoCaptureHostTest : public testing::Test { | 180 class VideoCaptureHostTest : public testing::Test { |
| 259 public: | 181 public: |
| 260 VideoCaptureHostTest() | 182 VideoCaptureHostTest() |
| 261 : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP), | 183 : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP), |
| 262 task_runner_(base::ThreadTaskRunnerHandle::Get()), | 184 task_runner_(base::ThreadTaskRunnerHandle::Get()), |
| 263 opened_session_id_(kInvalidMediaCaptureSessionId) {} | 185 opened_session_id_(kInvalidMediaCaptureSessionId) {} |
| 264 | 186 |
| 265 void SetUp() override { | 187 void SetUp() override { |
| 266 SetBrowserClientForTesting(&browser_client_); | 188 SetBrowserClientForTesting(&browser_client_); |
| 267 | 189 |
| 268 #if defined(OS_CHROMEOS) | 190 #if defined(OS_CHROMEOS) |
| 269 chromeos::CrasAudioHandler::InitializeForTesting(); | 191 chromeos::CrasAudioHandler::InitializeForTesting(); |
| 270 #endif | 192 #endif |
| 271 | 193 |
| 272 // Create our own MediaStreamManager. | |
| 273 audio_manager_ = media::AudioManager::CreateForTesting(task_runner_); | 194 audio_manager_ = media::AudioManager::CreateForTesting(task_runner_); |
| 274 #ifndef TEST_REAL_CAPTURE_DEVICE | |
| 275 base::CommandLine::ForCurrentProcess()->AppendSwitch( | 195 base::CommandLine::ForCurrentProcess()->AppendSwitch( |
| 276 switches::kUseFakeDeviceForMediaStream); | 196 switches::kUseFakeDeviceForMediaStream); |
| 277 #endif | 197 base::CommandLine::ForCurrentProcess()->AppendSwitch( |
| 198 switches::kUseFakeUIForMediaStream); | |
| 278 media_stream_manager_.reset(new MediaStreamManager(audio_manager_.get())); | 199 media_stream_manager_.reset(new MediaStreamManager(audio_manager_.get())); |
| 279 media_stream_manager_->UseFakeUIForTests( | |
| 280 std::unique_ptr<FakeMediaStreamUIProxy>()); | |
| 281 | 200 |
| 282 // Create a Host and connect it to a simulated IPC channel. | 201 // Create a Host and connect it to a simulated IPC channel. |
| 283 host_ = new MockVideoCaptureHost(media_stream_manager_.get()); | 202 host_ = new MockVideoCaptureHost(media_stream_manager_.get()); |
| 284 host_->OnChannelConnected(base::GetCurrentProcId()); | 203 host_->OnChannelConnected(base::GetCurrentProcId()); |
| 285 | 204 |
| 286 OpenSession(); | 205 OpenSession(); |
| 287 } | 206 } |
| 288 | 207 |
| 289 void TearDown() override { | 208 void TearDown() override { |
| 290 // Verifies and removes the expectations on host_ and | |
| 291 // returns true iff successful. | |
| 292 Mock::VerifyAndClearExpectations(host_.get()); | 209 Mock::VerifyAndClearExpectations(host_.get()); |
| 293 EXPECT_TRUE(host_->controllers_.empty()); | 210 EXPECT_TRUE(host_->controllers_.empty()); |
| 294 | 211 |
| 295 CloseSession(); | 212 CloseSession(); |
| 296 | 213 |
| 297 // Simulate closing the IPC sender. | 214 // Simulate closing the IPC sender. |
| 298 host_->OnChannelClosing(); | 215 host_->OnChannelClosing(); |
| 299 | 216 |
| 300 // Release the reference to the mock object. The object will be destructed | 217 // Release the reference to the mock object. The object will be destructed |
| 301 // on the current message loop. | 218 // on the current message loop. |
| 302 host_ = NULL; | 219 host_ = nullptr; |
| 303 | 220 |
| 304 #if defined(OS_CHROMEOS) | 221 #if defined(OS_CHROMEOS) |
| 305 chromeos::CrasAudioHandler::Shutdown(); | 222 chromeos::CrasAudioHandler::Shutdown(); |
| 306 #endif | 223 #endif |
| 307 } | 224 } |
| 308 | 225 |
| 309 void OpenSession() { | 226 void OpenSession() { |
| 310 const int render_process_id = 1; | 227 const int render_process_id = 1; |
| 311 const int render_frame_id = 1; | 228 const int render_frame_id = 1; |
| 312 const int page_request_id = 1; | 229 const int page_request_id = 1; |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 416 EXPECT_CALL(*host_.get(), | 333 EXPECT_CALL(*host_.get(), |
| 417 OnStateChanged(kDeviceId, VIDEO_CAPTURE_STATE_RESUMED)); | 334 OnStateChanged(kDeviceId, VIDEO_CAPTURE_STATE_RESUMED)); |
| 418 media::VideoCaptureParams params; | 335 media::VideoCaptureParams params; |
| 419 params.requested_format = media::VideoCaptureFormat( | 336 params.requested_format = media::VideoCaptureFormat( |
| 420 gfx::Size(352, 288), 30, media::PIXEL_FORMAT_I420); | 337 gfx::Size(352, 288), 30, media::PIXEL_FORMAT_I420); |
| 421 host_->Resume(kDeviceId, opened_session_id_, params); | 338 host_->Resume(kDeviceId, opened_session_id_, params); |
| 422 run_loop.RunUntilIdle(); | 339 run_loop.RunUntilIdle(); |
| 423 WaitForVideoDeviceThread(); | 340 WaitForVideoDeviceThread(); |
| 424 } | 341 } |
| 425 | 342 |
| 426 #ifdef DUMP_VIDEO | |
| 427 void CaptureAndDumpVideo(int width, int height, int frame_rate) { | |
| 428 InSequence s; | |
| 429 EXPECT_CALL(*host_.get(), OnNewBufferCreated(kDeviceId, _, _, _)) | |
| 430 .Times(AnyNumber()).WillRepeatedly(Return()); | |
| 431 | |
| 432 base::RunLoop run_loop; | |
| 433 EXPECT_CALL(*host_, OnBufferFilled(kDeviceId, _, _, _, _, _, _, _, _, _)) | |
| 434 .Times(AnyNumber()) | |
| 435 .WillOnce(ExitMessageLoop(message_loop_, run_loop.QuitClosure())); | |
| 436 | |
| 437 media::VideoCaptureParams params; | |
| 438 params.requested_format = | |
| 439 media::VideoCaptureFormat(gfx::Size(width, height), frame_rate); | |
| 440 host_->SetDumpVideo(true); | |
| 441 host_->Start(kDeviceId, opened_session_id_, params); | |
| 442 run_loop.Run(); | |
| 443 } | |
| 444 #endif | |
| 445 | |
| 446 void StopCapture() { | 343 void StopCapture() { |
| 447 base::RunLoop run_loop; | 344 base::RunLoop run_loop; |
| 448 EXPECT_CALL(*host_.get(), | 345 EXPECT_CALL(*host_.get(), |
| 449 OnStateChanged(kDeviceId, VIDEO_CAPTURE_STATE_STOPPED)) | 346 OnStateChanged(kDeviceId, VIDEO_CAPTURE_STATE_STOPPED)) |
| 450 .WillOnce(ExitMessageLoop(task_runner_, run_loop.QuitClosure())); | 347 .WillOnce(ExitMessageLoop(task_runner_, run_loop.QuitClosure())); |
| 451 | 348 |
| 452 host_->Stop(kDeviceId); | 349 host_->Stop(kDeviceId); |
| 453 host_->SetReturnReceivedDibs(true); | 350 host_->SetReturnReceivedBuffersImmediately(true); |
| 454 host_->ReturnReceivedDibs(kDeviceId); | 351 host_->ReturnReceivedBuffers(kDeviceId); |
| 455 | 352 |
| 456 run_loop.Run(); | 353 run_loop.Run(); |
| 457 | 354 |
| 458 host_->SetReturnReceivedDibs(false); | |
| 459 // Expect the VideoCaptureDevice has been stopped | 355 // Expect the VideoCaptureDevice has been stopped |
| 460 EXPECT_TRUE(host_->controllers_.empty()); | 356 EXPECT_TRUE(host_->controllers_.empty()); |
| 461 } | 357 } |
| 462 | 358 |
| 463 void NotifyPacketReady() { | 359 void NotifyPacketReady() { |
| 464 base::RunLoop run_loop; | 360 base::RunLoop run_loop; |
| 465 EXPECT_CALL(*host_.get(), OnBufferFilled(kDeviceId)) | 361 EXPECT_CALL(*host_.get(), OnBufferFilled(kDeviceId)) |
| 466 .Times(AnyNumber()) | 362 .Times(AnyNumber()) |
| 467 .WillOnce(ExitMessageLoop(task_runner_, run_loop.QuitClosure())) | 363 .WillOnce(ExitMessageLoop(task_runner_, run_loop.QuitClosure())) |
| 468 .RetiresOnSaturation(); | 364 .RetiresOnSaturation(); |
| 469 run_loop.Run(); | 365 run_loop.Run(); |
| 470 } | 366 } |
| 471 | 367 |
| 472 void ReturnReceivedPackets() { | 368 void ReturnReceivedPackets() { |
| 473 host_->ReturnReceivedDibs(kDeviceId); | 369 host_->ReturnReceivedBuffers(kDeviceId); |
| 474 } | 370 } |
| 475 | 371 |
| 476 void SimulateError() { | 372 void SimulateError() { |
| 477 // Expect a change state to error state sent through IPC. | 373 // Expect a change state to error state sent through IPC. |
| 478 EXPECT_CALL(*host_.get(), | 374 EXPECT_CALL(*host_.get(), |
| 479 OnStateChanged(kDeviceId, VIDEO_CAPTURE_STATE_ERROR)).Times(1); | 375 OnStateChanged(kDeviceId, VIDEO_CAPTURE_STATE_ERROR)).Times(1); |
| 480 VideoCaptureControllerID id(kDeviceId); | 376 VideoCaptureControllerID id(kDeviceId); |
| 481 host_->OnError(id); | 377 host_->OnError(id); |
| 482 // Wait for the error callback. | 378 // Wait for the error callback. |
| 483 base::RunLoop().RunUntilIdle(); | 379 base::RunLoop().RunUntilIdle(); |
| 484 } | 380 } |
| 485 | 381 |
| 486 void WaitForVideoDeviceThread() { | 382 void WaitForVideoDeviceThread() { |
| 487 base::RunLoop run_loop; | 383 base::RunLoop run_loop; |
| 488 media_stream_manager_->video_capture_manager()->device_task_runner() | 384 media_stream_manager_->video_capture_manager()->device_task_runner() |
| 489 ->PostTaskAndReply( | 385 ->PostTaskAndReply( |
| 490 FROM_HERE, | 386 FROM_HERE, |
| 491 base::Bind(&base::DoNothing), | 387 base::Bind(&base::DoNothing), |
| 492 run_loop.QuitClosure()); | 388 run_loop.QuitClosure()); |
| 493 run_loop.Run(); | 389 run_loop.Run(); |
| 494 } | 390 } |
| 495 | 391 |
| 496 scoped_refptr<MockVideoCaptureHost> host_; | 392 scoped_refptr<MockVideoCaptureHost> host_; |
| 497 | 393 |
| 498 private: | 394 private: |
| 499 // |media_stream_manager_| needs to outlive |thread_bundle_| because it is a | 395 // |media_stream_manager_| needs to outlive |thread_bundle_| because it is a |
| 500 // MessageLoop::DestructionObserver. |audio_manager_| needs to outlive | 396 // MessageLoop::DestructionObserver. |
| 501 // |thread_bundle_| because it uses the underlying message loop. | |
| 502 StrictMock<MockMediaStreamRequester> stream_requester_; | 397 StrictMock<MockMediaStreamRequester> stream_requester_; |
| 503 std::unique_ptr<MediaStreamManager> media_stream_manager_; | 398 std::unique_ptr<MediaStreamManager> media_stream_manager_; |
| 504 const content::TestBrowserThreadBundle thread_bundle_; | 399 const content::TestBrowserThreadBundle thread_bundle_; |
| 400 //|audio_manager_| needs to outlive |thread_bundle_| because it uses the | |
|
xianglu
2016/10/07 19:35:08
nit: missing one space
mcasas
2016/10/07 21:41:51
Done.
| |
| 401 // underlying message loop. | |
| 505 media::ScopedAudioManagerPtr audio_manager_; | 402 media::ScopedAudioManagerPtr audio_manager_; |
| 506 content::TestBrowserContext browser_context_; | 403 content::TestBrowserContext browser_context_; |
| 507 content::TestContentBrowserClient browser_client_; | 404 content::TestContentBrowserClient browser_client_; |
| 508 const scoped_refptr<base::SingleThreadTaskRunner> task_runner_; | 405 const scoped_refptr<base::SingleThreadTaskRunner> task_runner_; |
| 509 int opened_session_id_; | 406 int opened_session_id_; |
| 510 std::string opened_device_label_; | 407 std::string opened_device_label_; |
| 511 | 408 |
| 512 DISALLOW_COPY_AND_ASSIGN(VideoCaptureHostTest); | 409 DISALLOW_COPY_AND_ASSIGN(VideoCaptureHostTest); |
| 513 }; | 410 }; |
| 514 | 411 |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 543 | 440 |
| 544 TEST_F(VideoCaptureHostTest, StartCaptureError) { | 441 TEST_F(VideoCaptureHostTest, StartCaptureError) { |
| 545 EXPECT_CALL(*host_.get(), | 442 EXPECT_CALL(*host_.get(), |
| 546 OnStateChanged(kDeviceId, VIDEO_CAPTURE_STATE_STOPPED)).Times(0); | 443 OnStateChanged(kDeviceId, VIDEO_CAPTURE_STATE_STOPPED)).Times(0); |
| 547 StartCapture(); | 444 StartCapture(); |
| 548 NotifyPacketReady(); | 445 NotifyPacketReady(); |
| 549 SimulateError(); | 446 SimulateError(); |
| 550 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(200)); | 447 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(200)); |
| 551 } | 448 } |
| 552 | 449 |
| 553 #ifdef DUMP_VIDEO | |
| 554 TEST_F(VideoCaptureHostTest, CaptureAndDumpVideoVga) { | |
| 555 CaptureAndDumpVideo(640, 480, 30); | |
| 556 } | |
| 557 TEST_F(VideoCaptureHostTest, CaptureAndDump720P) { | |
| 558 CaptureAndDumpVideo(1280, 720, 30); | |
| 559 } | |
| 560 #endif | |
| 561 | |
| 562 TEST_F(VideoCaptureHostTest, PauseResumeCapture) { | 450 TEST_F(VideoCaptureHostTest, PauseResumeCapture) { |
| 563 StartCapture(); | 451 StartCapture(); |
| 564 PauseResumeCapture(); | 452 PauseResumeCapture(); |
| 565 StopCapture(); | 453 StopCapture(); |
| 566 } | 454 } |
| 567 | 455 |
| 568 } // namespace content | 456 } // namespace content |
| OLD | NEW |