| 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 <map> | 5 #include <map> |
| 6 #include <string> | 6 #include <string> |
| 7 | 7 |
| 8 #include "base/bind.h" | 8 #include "base/bind.h" |
| 9 #include "base/file_util.h" | 9 #include "base/file_util.h" |
| 10 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 99 public: | 99 public: |
| 100 MockVideoCaptureHost(MediaStreamManager* manager) | 100 MockVideoCaptureHost(MediaStreamManager* manager) |
| 101 : VideoCaptureHost(manager), | 101 : VideoCaptureHost(manager), |
| 102 return_buffers_(false), | 102 return_buffers_(false), |
| 103 dump_video_(false) {} | 103 dump_video_(false) {} |
| 104 | 104 |
| 105 // A list of mock methods. | 105 // A list of mock methods. |
| 106 MOCK_METHOD4(OnNewBufferCreated, | 106 MOCK_METHOD4(OnNewBufferCreated, |
| 107 void(int device_id, base::SharedMemoryHandle handle, | 107 void(int device_id, base::SharedMemoryHandle handle, |
| 108 int length, int buffer_id)); | 108 int length, int buffer_id)); |
| 109 MOCK_METHOD3(OnBufferFilled, | 109 MOCK_METHOD2(OnBufferFreed, |
| 110 void(int device_id, int buffer_id, base::Time timestamp)); | 110 void(int device_id, int buffer_id)); |
| 111 MOCK_METHOD4(OnBufferFilled, |
| 112 void(int device_id, int buffer_id, base::Time timestamp, |
| 113 const media::VideoCaptureFormat& format)); |
| 111 MOCK_METHOD2(OnStateChanged, void(int device_id, VideoCaptureState state)); | 114 MOCK_METHOD2(OnStateChanged, void(int device_id, VideoCaptureState state)); |
| 112 MOCK_METHOD1(OnDeviceInfo, void(int device_id)); | |
| 113 | 115 |
| 114 // Use class DumpVideo to write I420 video to file. | 116 // Use class DumpVideo to write I420 video to file. |
| 115 void SetDumpVideo(bool enable) { | 117 void SetDumpVideo(bool enable) { |
| 116 dump_video_ = enable; | 118 dump_video_ = enable; |
| 117 } | 119 } |
| 118 | 120 |
| 119 void SetReturnReceviedDibs(bool enable) { | 121 void SetReturnReceivedDibs(bool enable) { |
| 120 return_buffers_ = enable; | 122 return_buffers_ = enable; |
| 121 } | 123 } |
| 122 | 124 |
| 123 // Return Dibs we currently have received. | 125 // Return Dibs we currently have received. |
| 124 void ReturnReceivedDibs(int device_id) { | 126 void ReturnReceivedDibs(int device_id) { |
| 125 int handle = GetReceivedDib(); | 127 int handle = GetReceivedDib(); |
| 126 while (handle) { | 128 while (handle) { |
| 127 this->OnReceiveEmptyBuffer(device_id, handle); | 129 this->OnReceiveEmptyBuffer(device_id, handle); |
| 128 handle = GetReceivedDib(); | 130 handle = GetReceivedDib(); |
| 129 } | 131 } |
| (...skipping 20 matching lines...) Expand all Loading... |
| 150 // these messages here and dispatch to our mock methods to verify the | 152 // these messages here and dispatch to our mock methods to verify the |
| 151 // conversation between this object and the renderer. | 153 // conversation between this object and the renderer. |
| 152 virtual bool Send(IPC::Message* message) OVERRIDE { | 154 virtual bool Send(IPC::Message* message) OVERRIDE { |
| 153 CHECK(message); | 155 CHECK(message); |
| 154 | 156 |
| 155 // In this method we dispatch the messages to the according handlers as if | 157 // In this method we dispatch the messages to the according handlers as if |
| 156 // we are the renderer. | 158 // we are the renderer. |
| 157 bool handled = true; | 159 bool handled = true; |
| 158 IPC_BEGIN_MESSAGE_MAP(MockVideoCaptureHost, *message) | 160 IPC_BEGIN_MESSAGE_MAP(MockVideoCaptureHost, *message) |
| 159 IPC_MESSAGE_HANDLER(VideoCaptureMsg_NewBuffer, OnNewBufferCreatedDispatch) | 161 IPC_MESSAGE_HANDLER(VideoCaptureMsg_NewBuffer, OnNewBufferCreatedDispatch) |
| 162 IPC_MESSAGE_HANDLER(VideoCaptureMsg_FreeBuffer, OnBufferFreedDispatch) |
| 160 IPC_MESSAGE_HANDLER(VideoCaptureMsg_BufferReady, OnBufferFilledDispatch) | 163 IPC_MESSAGE_HANDLER(VideoCaptureMsg_BufferReady, OnBufferFilledDispatch) |
| 161 IPC_MESSAGE_HANDLER(VideoCaptureMsg_StateChanged, OnStateChangedDispatch) | 164 IPC_MESSAGE_HANDLER(VideoCaptureMsg_StateChanged, OnStateChangedDispatch) |
| 162 IPC_MESSAGE_HANDLER(VideoCaptureMsg_DeviceInfo, OnDeviceInfoDispatch) | |
| 163 IPC_MESSAGE_UNHANDLED(handled = false) | 165 IPC_MESSAGE_UNHANDLED(handled = false) |
| 164 IPC_END_MESSAGE_MAP() | 166 IPC_END_MESSAGE_MAP() |
| 165 EXPECT_TRUE(handled); | 167 EXPECT_TRUE(handled); |
| 166 | 168 |
| 167 delete message; | 169 delete message; |
| 168 return true; | 170 return true; |
| 169 } | 171 } |
| 170 | 172 |
| 171 // These handler methods do minimal things and delegate to the mock methods. | 173 // These handler methods do minimal things and delegate to the mock methods. |
| 172 void OnNewBufferCreatedDispatch(int device_id, | 174 void OnNewBufferCreatedDispatch(int device_id, |
| 173 base::SharedMemoryHandle handle, | 175 base::SharedMemoryHandle handle, |
| 174 uint32 length, | 176 uint32 length, |
| 175 int buffer_id) { | 177 int buffer_id) { |
| 176 OnNewBufferCreated(device_id, handle, length, buffer_id); | 178 OnNewBufferCreated(device_id, handle, length, buffer_id); |
| 177 base::SharedMemory* dib = new base::SharedMemory(handle, false); | 179 base::SharedMemory* dib = new base::SharedMemory(handle, false); |
| 178 dib->Map(length); | 180 dib->Map(length); |
| 179 filled_dib_[buffer_id] = dib; | 181 filled_dib_[buffer_id] = dib; |
| 180 } | 182 } |
| 181 | 183 |
| 182 void OnBufferFilledDispatch(int device_id, int buffer_id, | 184 void OnBufferFreedDispatch(int device_id, int buffer_id) { |
| 183 base::Time timestamp) { | 185 OnBufferFreed(device_id, buffer_id); |
| 186 |
| 187 std::map<int, base::SharedMemory*>::iterator it = |
| 188 filled_dib_.find(buffer_id); |
| 189 ASSERT_TRUE(it != filled_dib_.end()); |
| 190 delete it->second; |
| 191 filled_dib_.erase(it); |
| 192 } |
| 193 |
| 194 void OnBufferFilledDispatch(int device_id, |
| 195 int buffer_id, |
| 196 base::Time timestamp, |
| 197 const media::VideoCaptureFormat& frame_format) { |
| 198 base::SharedMemory* dib = filled_dib_[buffer_id]; |
| 199 ASSERT_TRUE(dib != NULL); |
| 184 if (dump_video_) { | 200 if (dump_video_) { |
| 185 base::SharedMemory* dib = filled_dib_[buffer_id]; | 201 if (!format_.IsValid()) { |
| 186 ASSERT_TRUE(dib != NULL); | 202 dumper_.StartDump(frame_format.width, frame_format.height); |
| 203 format_ = frame_format; |
| 204 } |
| 205 ASSERT_EQ(format_.width, frame_format.width) |
| 206 << "Dump format does not handle variable resolution."; |
| 207 ASSERT_EQ(format_.height, frame_format.height) |
| 208 << "Dump format does not handle variable resolution.";; |
| 187 dumper_.NewVideoFrame(dib->memory()); | 209 dumper_.NewVideoFrame(dib->memory()); |
| 188 } | 210 } |
| 189 | 211 |
| 190 OnBufferFilled(device_id, buffer_id, timestamp); | 212 OnBufferFilled(device_id, buffer_id, timestamp, frame_format); |
| 191 if (return_buffers_) { | 213 if (return_buffers_) { |
| 192 VideoCaptureHost::OnReceiveEmptyBuffer(device_id, buffer_id); | 214 VideoCaptureHost::OnReceiveEmptyBuffer(device_id, buffer_id); |
| 193 } | 215 } |
| 194 } | 216 } |
| 195 | 217 |
| 196 void OnStateChangedDispatch(int device_id, VideoCaptureState state) { | 218 void OnStateChangedDispatch(int device_id, VideoCaptureState state) { |
| 197 OnStateChanged(device_id, state); | 219 OnStateChanged(device_id, state); |
| 198 } | 220 } |
| 199 | 221 |
| 200 void OnDeviceInfoDispatch(int device_id, | |
| 201 media::VideoCaptureParams params) { | |
| 202 if (dump_video_) { | |
| 203 dumper_.StartDump(params.width, params.height); | |
| 204 } | |
| 205 OnDeviceInfo(device_id); | |
| 206 } | |
| 207 | |
| 208 std::map<int, base::SharedMemory*> filled_dib_; | 222 std::map<int, base::SharedMemory*> filled_dib_; |
| 209 bool return_buffers_; | 223 bool return_buffers_; |
| 210 bool dump_video_; | 224 bool dump_video_; |
| 225 media::VideoCaptureFormat format_; |
| 211 DumpVideo dumper_; | 226 DumpVideo dumper_; |
| 212 }; | 227 }; |
| 213 | 228 |
| 214 ACTION_P2(ExitMessageLoop, message_loop, quit_closure) { | 229 ACTION_P2(ExitMessageLoop, message_loop, quit_closure) { |
| 215 message_loop->PostTask(FROM_HERE, quit_closure); | 230 message_loop->PostTask(FROM_HERE, quit_closure); |
| 216 } | 231 } |
| 217 | 232 |
| 218 // This is an integration test of VideoCaptureHost in conjunction with | 233 // This is an integration test of VideoCaptureHost in conjunction with |
| 219 // MediaStreamManager, VideoCaptureManager, VideoCaptureController, and | 234 // MediaStreamManager, VideoCaptureManager, VideoCaptureController, and |
| 220 // VideoCaptureDevice. | 235 // VideoCaptureDevice. |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 315 void CloseSession() { | 330 void CloseSession() { |
| 316 if (opened_device_label_.empty()) | 331 if (opened_device_label_.empty()) |
| 317 return; | 332 return; |
| 318 media_stream_manager_->CancelRequest(opened_device_label_); | 333 media_stream_manager_->CancelRequest(opened_device_label_); |
| 319 opened_device_label_.clear(); | 334 opened_device_label_.clear(); |
| 320 opened_session_id_ = kInvalidMediaCaptureSessionId; | 335 opened_session_id_ = kInvalidMediaCaptureSessionId; |
| 321 } | 336 } |
| 322 | 337 |
| 323 protected: | 338 protected: |
| 324 void StartCapture() { | 339 void StartCapture() { |
| 325 InSequence s; | |
| 326 // 1. First - get info about the new resolution | |
| 327 EXPECT_CALL(*host_, OnDeviceInfo(kDeviceId)); | |
| 328 | |
| 329 // 2. Change state to started | |
| 330 EXPECT_CALL(*host_, OnStateChanged(kDeviceId, VIDEO_CAPTURE_STATE_STARTED)); | |
| 331 | |
| 332 // 3. Newly created buffers will arrive. | |
| 333 EXPECT_CALL(*host_, OnNewBufferCreated(kDeviceId, _, _, _)) | 340 EXPECT_CALL(*host_, OnNewBufferCreated(kDeviceId, _, _, _)) |
| 334 .Times(AnyNumber()).WillRepeatedly(Return()); | 341 .Times(AnyNumber()).WillRepeatedly(Return()); |
| 335 | 342 |
| 336 // 4. First filled buffer will arrive. | |
| 337 base::RunLoop run_loop; | 343 base::RunLoop run_loop; |
| 338 EXPECT_CALL(*host_, OnBufferFilled(kDeviceId, _, _)) | 344 EXPECT_CALL(*host_, OnBufferFilled(kDeviceId, _, _, _)) |
| 339 .Times(AnyNumber()).WillOnce(ExitMessageLoop( | 345 .Times(AnyNumber()).WillOnce(ExitMessageLoop( |
| 340 message_loop_, run_loop.QuitClosure())); | 346 message_loop_, run_loop.QuitClosure())); |
| 341 | 347 |
| 342 media::VideoCaptureParams params; | 348 media::VideoCaptureParams params; |
| 343 params.width = 352; | 349 params.requested_format = media::VideoCaptureFormat( |
| 344 params.height = 288; | 350 352, 288, 30, media::ConstantResolutionVideoCaptureDevice); |
| 345 params.frame_rate = 30; | |
| 346 params.session_id = opened_session_id_; | 351 params.session_id = opened_session_id_; |
| 347 host_->OnStartCapture(kDeviceId, params); | 352 host_->OnStartCapture(kDeviceId, params); |
| 348 run_loop.Run(); | 353 run_loop.Run(); |
| 349 } | 354 } |
| 350 | 355 |
| 351 void StartStopCapture() { | 356 void StartStopCapture() { |
| 352 // Quickly start and then stop capture, without giving much chance for | 357 // Quickly start and then stop capture, without giving much chance for |
| 353 // asynchronous start operations to complete. | 358 // asynchronous start operations to complete. |
| 354 InSequence s; | 359 InSequence s; |
| 355 base::RunLoop run_loop; | 360 base::RunLoop run_loop; |
| 356 EXPECT_CALL(*host_, OnStateChanged(kDeviceId, VIDEO_CAPTURE_STATE_STOPPED)); | 361 EXPECT_CALL(*host_, OnStateChanged(kDeviceId, VIDEO_CAPTURE_STATE_STOPPED)); |
| 357 media::VideoCaptureParams params; | 362 media::VideoCaptureParams params; |
| 358 params.width = 352; | 363 params.requested_format = media::VideoCaptureFormat( |
| 359 params.height = 288; | 364 352, 288, 30, media::ConstantResolutionVideoCaptureDevice); |
| 360 params.frame_rate = 30; | |
| 361 params.session_id = opened_session_id_; | 365 params.session_id = opened_session_id_; |
| 362 host_->OnStartCapture(kDeviceId, params); | 366 host_->OnStartCapture(kDeviceId, params); |
| 363 host_->OnStopCapture(kDeviceId); | 367 host_->OnStopCapture(kDeviceId); |
| 364 run_loop.RunUntilIdle(); | 368 run_loop.RunUntilIdle(); |
| 365 } | 369 } |
| 366 | 370 |
| 367 #ifdef DUMP_VIDEO | 371 #ifdef DUMP_VIDEO |
| 368 void CaptureAndDumpVideo(int width, int height, int frame_rate) { | 372 void CaptureAndDumpVideo(int width, int height, int frame_rate) { |
| 369 InSequence s; | 373 InSequence s; |
| 370 // 1. First - get info about the new resolution | 374 EXPECT_CALL(*host_.get(), OnNewBufferCreated(kDeviceId, _, _, _)) |
| 371 EXPECT_CALL(*host_, OnDeviceInfo(kDeviceId)); | 375 .Times(AnyNumber()).WillRepeatedly(Return()); |
| 372 | 376 |
| 373 // 2. Change state to started | |
| 374 EXPECT_CALL(*host_, OnStateChanged(kDeviceId, VIDEO_CAPTURE_STATE_STARTED)); | |
| 375 | |
| 376 // 3. First filled buffer will arrive. | |
| 377 base::RunLoop run_loop; | 377 base::RunLoop run_loop; |
| 378 EXPECT_CALL(*host_, OnBufferFilled(kDeviceId, _, _)) | 378 EXPECT_CALL(*host_, OnBufferFilled(kDeviceId, _, _, _)) |
| 379 .Times(AnyNumber()) | 379 .Times(AnyNumber()) |
| 380 .WillOnce(ExitMessageLoop(message_loop_, run_loop.QuitClosure())); | 380 .WillOnce(ExitMessageLoop(message_loop_, run_loop.QuitClosure())); |
| 381 | 381 |
| 382 media::VideoCaptureParams params; | 382 media::VideoCaptureParams params; |
| 383 params.width = width; | 383 params.requested_format = media::VideoCaptureFormat( |
| 384 params.height = height; | 384 width, height, frame_rate, media::ConstantResolutionVideoCaptureDevice); |
| 385 params.frame_rate = frame_rate; | |
| 386 params.session_id = opened_session_id_; | 385 params.session_id = opened_session_id_; |
| 387 host_->SetDumpVideo(true); | 386 host_->SetDumpVideo(true); |
| 388 host_->OnStartCapture(kDeviceId, params); | 387 host_->OnStartCapture(kDeviceId, params); |
| 389 run_loop.Run(); | 388 run_loop.Run(); |
| 390 } | 389 } |
| 391 #endif | 390 #endif |
| 392 | 391 |
| 393 void StopCapture() { | 392 void StopCapture() { |
| 394 base::RunLoop run_loop; | 393 base::RunLoop run_loop; |
| 395 EXPECT_CALL(*host_, OnStateChanged(kDeviceId, VIDEO_CAPTURE_STATE_STOPPED)) | 394 EXPECT_CALL(*host_, OnStateChanged(kDeviceId, VIDEO_CAPTURE_STATE_STOPPED)) |
| 396 .WillOnce(ExitMessageLoop(message_loop_, run_loop.QuitClosure())); | 395 .WillOnce(ExitMessageLoop(message_loop_, run_loop.QuitClosure())); |
| 397 | 396 |
| 398 host_->OnStopCapture(kDeviceId); | 397 host_->OnStopCapture(kDeviceId); |
| 399 host_->SetReturnReceviedDibs(true); | 398 host_->SetReturnReceivedDibs(true); |
| 400 host_->ReturnReceivedDibs(kDeviceId); | 399 host_->ReturnReceivedDibs(kDeviceId); |
| 401 | 400 |
| 402 run_loop.Run(); | 401 run_loop.Run(); |
| 403 | 402 |
| 404 host_->SetReturnReceviedDibs(false); | 403 host_->SetReturnReceivedDibs(false); |
| 405 // Expect the VideoCaptureDevice has been stopped | 404 // Expect the VideoCaptureDevice has been stopped |
| 406 EXPECT_EQ(0u, host_->entries_.size()); | 405 EXPECT_EQ(0u, host_->entries_.size()); |
| 407 } | 406 } |
| 408 | 407 |
| 409 void NotifyPacketReady() { | 408 void NotifyPacketReady() { |
| 410 base::RunLoop run_loop; | 409 base::RunLoop run_loop; |
| 411 EXPECT_CALL(*host_, OnBufferFilled(kDeviceId, _, _)) | 410 EXPECT_CALL(*host_, OnBufferFilled(kDeviceId, _, _, _)) |
| 412 .Times(AnyNumber()).WillOnce(ExitMessageLoop( | 411 .Times(AnyNumber()).WillOnce(ExitMessageLoop( |
| 413 message_loop_, run_loop.QuitClosure())) | 412 message_loop_, run_loop.QuitClosure())) |
| 414 .RetiresOnSaturation(); | 413 .RetiresOnSaturation(); |
| 415 run_loop.Run(); | 414 run_loop.Run(); |
| 416 } | 415 } |
| 417 | 416 |
| 418 void ReturnReceivedPackets() { | 417 void ReturnReceivedPackets() { |
| 419 host_->ReturnReceivedDibs(kDeviceId); | 418 host_->ReturnReceivedDibs(kDeviceId); |
| 420 } | 419 } |
| 421 | 420 |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 484 #ifdef DUMP_VIDEO | 483 #ifdef DUMP_VIDEO |
| 485 TEST_F(VideoCaptureHostTest, CaptureAndDumpVideoVga) { | 484 TEST_F(VideoCaptureHostTest, CaptureAndDumpVideoVga) { |
| 486 CaptureAndDumpVideo(640, 480, 30); | 485 CaptureAndDumpVideo(640, 480, 30); |
| 487 } | 486 } |
| 488 TEST_F(VideoCaptureHostTest, CaptureAndDump720P) { | 487 TEST_F(VideoCaptureHostTest, CaptureAndDump720P) { |
| 489 CaptureAndDumpVideo(1280, 720, 30); | 488 CaptureAndDumpVideo(1280, 720, 30); |
| 490 } | 489 } |
| 491 #endif | 490 #endif |
| 492 | 491 |
| 493 } // namespace content | 492 } // namespace content |
| OLD | NEW |