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> |
(...skipping 28 matching lines...) Expand all Loading... |
39 #include "media/base/video_frame.h" | 39 #include "media/base/video_frame.h" |
40 #include "net/url_request/url_request_context.h" | 40 #include "net/url_request/url_request_context.h" |
41 #include "testing/gmock/include/gmock/gmock.h" | 41 #include "testing/gmock/include/gmock/gmock.h" |
42 #include "testing/gtest/include/gtest/gtest.h" | 42 #include "testing/gtest/include/gtest/gtest.h" |
43 | 43 |
44 #if defined(OS_CHROMEOS) | 44 #if defined(OS_CHROMEOS) |
45 #include "chromeos/audio/cras_audio_handler.h" | 45 #include "chromeos/audio/cras_audio_handler.h" |
46 #endif | 46 #endif |
47 | 47 |
48 using ::testing::_; | 48 using ::testing::_; |
49 using ::testing::AtLeast; | |
50 using ::testing::AnyNumber; | 49 using ::testing::AnyNumber; |
51 using ::testing::DoAll; | 50 using ::testing::DoAll; |
52 using ::testing::InSequence; | 51 using ::testing::InSequence; |
53 using ::testing::Mock; | 52 using ::testing::Mock; |
54 using ::testing::Return; | 53 using ::testing::Return; |
55 using ::testing::SaveArg; | 54 using ::testing::SaveArg; |
56 using ::testing::StrictMock; | 55 using ::testing::StrictMock; |
57 | 56 |
58 namespace content { | 57 namespace content { |
59 | 58 |
60 // Id used to identify the capture session between renderer and | 59 // Id used to identify the capture session between renderer and |
61 // video_capture_host. This is an arbitrary value. | 60 // video_capture_host. This is an arbitrary value. |
62 static const int kDeviceId = 555; | 61 static const int kDeviceId = 555; |
63 | 62 |
64 // Define to enable test where video is dumped to file. | 63 // Define to enable test where video is dumped to file. |
65 // #define DUMP_VIDEO | 64 // #define DUMP_VIDEO |
66 | 65 |
67 // Define to use a real video capture device. | 66 // Define to use a real video capture device. |
68 // #define TEST_REAL_CAPTURE_DEVICE | 67 // #define TEST_REAL_CAPTURE_DEVICE |
69 | 68 |
70 // Simple class used for dumping video to a file. This can be used for | 69 // Simple class used for dumping video to a file. This can be used for verifying |
71 // verifying the output. | 70 // the output. |
72 class DumpVideo { | 71 class DumpVideo { |
73 public: | 72 public: |
74 DumpVideo() {} | 73 DumpVideo() {} |
75 const gfx::Size& coded_size() const { return coded_size_; } | 74 const gfx::Size& coded_size() const { return coded_size_; } |
76 void StartDump(const gfx::Size& coded_size) { | 75 void StartDump(const gfx::Size& coded_size) { |
77 base::FilePath file_name = base::FilePath(base::StringPrintf( | 76 base::FilePath file_name = base::FilePath(base::StringPrintf( |
78 FILE_PATH_LITERAL("dump_w%d_h%d.yuv"), | 77 FILE_PATH_LITERAL("dump_w%d_h%d.yuv"), |
79 coded_size.width(), | 78 coded_size.width(), |
80 coded_size.height())); | 79 coded_size.height())); |
81 file_.reset(base::OpenFile(file_name, "wb")); | 80 file_.reset(base::OpenFile(file_name, "wb")); |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
284 host_ = new MockVideoCaptureHost(media_stream_manager_.get()); | 283 host_ = new MockVideoCaptureHost(media_stream_manager_.get()); |
285 host_->OnChannelConnected(base::GetCurrentProcId()); | 284 host_->OnChannelConnected(base::GetCurrentProcId()); |
286 | 285 |
287 OpenSession(); | 286 OpenSession(); |
288 } | 287 } |
289 | 288 |
290 void TearDown() override { | 289 void TearDown() override { |
291 // Verifies and removes the expectations on host_ and | 290 // Verifies and removes the expectations on host_ and |
292 // returns true iff successful. | 291 // returns true iff successful. |
293 Mock::VerifyAndClearExpectations(host_.get()); | 292 Mock::VerifyAndClearExpectations(host_.get()); |
294 EXPECT_EQ(0u, host_->entries_.size()); | 293 EXPECT_TRUE(host_->controllers_.empty()); |
295 | 294 |
296 CloseSession(); | 295 CloseSession(); |
297 | 296 |
298 // Simulate closing the IPC sender. | 297 // Simulate closing the IPC sender. |
299 host_->OnChannelClosing(); | 298 host_->OnChannelClosing(); |
300 | 299 |
301 // Release the reference to the mock object. The object will be destructed | 300 // Release the reference to the mock object. The object will be destructed |
302 // on the current message loop. | 301 // on the current message loop. |
303 host_ = NULL; | 302 host_ = NULL; |
304 | 303 |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
395 // Quickly start and then stop capture, without giving much chance for | 394 // Quickly start and then stop capture, without giving much chance for |
396 // asynchronous start operations to complete. | 395 // asynchronous start operations to complete. |
397 InSequence s; | 396 InSequence s; |
398 base::RunLoop run_loop; | 397 base::RunLoop run_loop; |
399 EXPECT_CALL(*host_.get(), | 398 EXPECT_CALL(*host_.get(), |
400 OnStateChanged(kDeviceId, VIDEO_CAPTURE_STATE_STOPPED)); | 399 OnStateChanged(kDeviceId, VIDEO_CAPTURE_STATE_STOPPED)); |
401 media::VideoCaptureParams params; | 400 media::VideoCaptureParams params; |
402 params.requested_format = media::VideoCaptureFormat( | 401 params.requested_format = media::VideoCaptureFormat( |
403 gfx::Size(352, 288), 30, media::PIXEL_FORMAT_I420); | 402 gfx::Size(352, 288), 30, media::PIXEL_FORMAT_I420); |
404 host_->OnStartCapture(kDeviceId, opened_session_id_, params); | 403 host_->OnStartCapture(kDeviceId, opened_session_id_, params); |
405 host_->OnStopCapture(kDeviceId); | 404 host_->Stop(kDeviceId); |
406 run_loop.RunUntilIdle(); | 405 run_loop.RunUntilIdle(); |
407 WaitForVideoDeviceThread(); | 406 WaitForVideoDeviceThread(); |
408 } | 407 } |
| 408 |
| 409 void PauseResumeCapture() { |
| 410 InSequence s; |
| 411 base::RunLoop run_loop; |
| 412 EXPECT_CALL(*host_.get(), |
| 413 OnStateChanged(kDeviceId, VIDEO_CAPTURE_STATE_PAUSED)); |
| 414 host_->Pause(kDeviceId); |
| 415 |
| 416 EXPECT_CALL(*host_.get(), |
| 417 OnStateChanged(kDeviceId, VIDEO_CAPTURE_STATE_RESUMED)); |
| 418 media::VideoCaptureParams params; |
| 419 params.requested_format = media::VideoCaptureFormat( |
| 420 gfx::Size(352, 288), 30, media::PIXEL_FORMAT_I420); |
| 421 host_->OnResumeCapture(kDeviceId, opened_session_id_, params); |
| 422 run_loop.RunUntilIdle(); |
| 423 WaitForVideoDeviceThread(); |
| 424 } |
409 | 425 |
410 #ifdef DUMP_VIDEO | 426 #ifdef DUMP_VIDEO |
411 void CaptureAndDumpVideo(int width, int height, int frame_rate) { | 427 void CaptureAndDumpVideo(int width, int height, int frame_rate) { |
412 InSequence s; | 428 InSequence s; |
413 EXPECT_CALL(*host_.get(), OnNewBufferCreated(kDeviceId, _, _, _)) | 429 EXPECT_CALL(*host_.get(), OnNewBufferCreated(kDeviceId, _, _, _)) |
414 .Times(AnyNumber()).WillRepeatedly(Return()); | 430 .Times(AnyNumber()).WillRepeatedly(Return()); |
415 | 431 |
416 base::RunLoop run_loop; | 432 base::RunLoop run_loop; |
417 EXPECT_CALL(*host_, OnBufferFilled(kDeviceId, _, _, _, _, _, _, _, _, _)) | 433 EXPECT_CALL(*host_, OnBufferFilled(kDeviceId, _, _, _, _, _, _, _, _, _)) |
418 .Times(AnyNumber()) | 434 .Times(AnyNumber()) |
419 .WillOnce(ExitMessageLoop(message_loop_, run_loop.QuitClosure())); | 435 .WillOnce(ExitMessageLoop(message_loop_, run_loop.QuitClosure())); |
420 | 436 |
421 media::VideoCaptureParams params; | 437 media::VideoCaptureParams params; |
422 params.requested_format = | 438 params.requested_format = |
423 media::VideoCaptureFormat(gfx::Size(width, height), frame_rate); | 439 media::VideoCaptureFormat(gfx::Size(width, height), frame_rate); |
424 host_->SetDumpVideo(true); | 440 host_->SetDumpVideo(true); |
425 host_->OnStartCapture(kDeviceId, opened_session_id_, params); | 441 host_->OnStartCapture(kDeviceId, opened_session_id_, params); |
426 run_loop.Run(); | 442 run_loop.Run(); |
427 } | 443 } |
428 #endif | 444 #endif |
429 | 445 |
430 void StopCapture() { | 446 void StopCapture() { |
431 base::RunLoop run_loop; | 447 base::RunLoop run_loop; |
432 EXPECT_CALL(*host_.get(), | 448 EXPECT_CALL(*host_.get(), |
433 OnStateChanged(kDeviceId, VIDEO_CAPTURE_STATE_STOPPED)) | 449 OnStateChanged(kDeviceId, VIDEO_CAPTURE_STATE_STOPPED)) |
434 .WillOnce(ExitMessageLoop(task_runner_, run_loop.QuitClosure())); | 450 .WillOnce(ExitMessageLoop(task_runner_, run_loop.QuitClosure())); |
435 | 451 |
436 host_->OnStopCapture(kDeviceId); | 452 host_->Stop(kDeviceId); |
437 host_->SetReturnReceivedDibs(true); | 453 host_->SetReturnReceivedDibs(true); |
438 host_->ReturnReceivedDibs(kDeviceId); | 454 host_->ReturnReceivedDibs(kDeviceId); |
439 | 455 |
440 run_loop.Run(); | 456 run_loop.Run(); |
441 | 457 |
442 host_->SetReturnReceivedDibs(false); | 458 host_->SetReturnReceivedDibs(false); |
443 // Expect the VideoCaptureDevice has been stopped | 459 // Expect the VideoCaptureDevice has been stopped |
444 EXPECT_EQ(0u, host_->entries_.size()); | 460 EXPECT_TRUE(host_->controllers_.empty()); |
445 } | 461 } |
446 | 462 |
447 void NotifyPacketReady() { | 463 void NotifyPacketReady() { |
448 base::RunLoop run_loop; | 464 base::RunLoop run_loop; |
449 EXPECT_CALL(*host_.get(), OnBufferFilled(kDeviceId)) | 465 EXPECT_CALL(*host_.get(), OnBufferFilled(kDeviceId)) |
450 .Times(AnyNumber()) | 466 .Times(AnyNumber()) |
451 .WillOnce(ExitMessageLoop(task_runner_, run_loop.QuitClosure())) | 467 .WillOnce(ExitMessageLoop(task_runner_, run_loop.QuitClosure())) |
452 .RetiresOnSaturation(); | 468 .RetiresOnSaturation(); |
453 run_loop.Run(); | 469 run_loop.Run(); |
454 } | 470 } |
(...skipping 18 matching lines...) Expand all Loading... |
473 ->PostTaskAndReply( | 489 ->PostTaskAndReply( |
474 FROM_HERE, | 490 FROM_HERE, |
475 base::Bind(&base::DoNothing), | 491 base::Bind(&base::DoNothing), |
476 run_loop.QuitClosure()); | 492 run_loop.QuitClosure()); |
477 run_loop.Run(); | 493 run_loop.Run(); |
478 } | 494 } |
479 | 495 |
480 scoped_refptr<MockVideoCaptureHost> host_; | 496 scoped_refptr<MockVideoCaptureHost> host_; |
481 | 497 |
482 private: | 498 private: |
483 // media_stream_manager_ needs to outlive thread_bundle_ because it is a | 499 // |media_stream_manager_| needs to outlive |thread_bundle_| because it is a |
484 // MessageLoop::DestructionObserver. audio_manager_ needs to outlive | 500 // MessageLoop::DestructionObserver. |audio_manager_| needs to outlive |
485 // thread_bundle_ because it uses the underlying message loop. | 501 // |thread_bundle_| because it uses the underlying message loop. |
486 StrictMock<MockMediaStreamRequester> stream_requester_; | 502 StrictMock<MockMediaStreamRequester> stream_requester_; |
487 std::unique_ptr<MediaStreamManager> media_stream_manager_; | 503 std::unique_ptr<MediaStreamManager> media_stream_manager_; |
488 content::TestBrowserThreadBundle thread_bundle_; | 504 const content::TestBrowserThreadBundle thread_bundle_; |
489 media::ScopedAudioManagerPtr audio_manager_; | 505 media::ScopedAudioManagerPtr audio_manager_; |
490 content::TestBrowserContext browser_context_; | 506 content::TestBrowserContext browser_context_; |
491 content::TestContentBrowserClient browser_client_; | 507 content::TestContentBrowserClient browser_client_; |
492 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; | 508 const scoped_refptr<base::SingleThreadTaskRunner> task_runner_; |
493 int opened_session_id_; | 509 int opened_session_id_; |
494 std::string opened_device_label_; | 510 std::string opened_device_label_; |
495 | 511 |
496 DISALLOW_COPY_AND_ASSIGN(VideoCaptureHostTest); | 512 DISALLOW_COPY_AND_ASSIGN(VideoCaptureHostTest); |
497 }; | 513 }; |
498 | 514 |
499 TEST_F(VideoCaptureHostTest, CloseSessionWithoutStopping) { | 515 TEST_F(VideoCaptureHostTest, CloseSessionWithoutStopping) { |
500 StartCapture(); | 516 StartCapture(); |
501 | 517 |
502 // When the session is closed via the stream without stopping capture, the | 518 // When the session is closed via the stream without stopping capture, the |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
536 | 552 |
537 #ifdef DUMP_VIDEO | 553 #ifdef DUMP_VIDEO |
538 TEST_F(VideoCaptureHostTest, CaptureAndDumpVideoVga) { | 554 TEST_F(VideoCaptureHostTest, CaptureAndDumpVideoVga) { |
539 CaptureAndDumpVideo(640, 480, 30); | 555 CaptureAndDumpVideo(640, 480, 30); |
540 } | 556 } |
541 TEST_F(VideoCaptureHostTest, CaptureAndDump720P) { | 557 TEST_F(VideoCaptureHostTest, CaptureAndDump720P) { |
542 CaptureAndDumpVideo(1280, 720, 30); | 558 CaptureAndDumpVideo(1280, 720, 30); |
543 } | 559 } |
544 #endif | 560 #endif |
545 | 561 |
| 562 TEST_F(VideoCaptureHostTest, PauseResumeCapture) { |
| 563 StartCapture(); |
| 564 PauseResumeCapture(); |
| 565 StopCapture(); |
| 566 } |
| 567 |
546 } // namespace content | 568 } // namespace content |
OLD | NEW |