1 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "base/message_loop/message_loop.h" 6 #include "base/run_loop.h" 7 #include "base/strings/utf_string_conversions.h" 8 #include "content/child/child_process.h" 9 #include "content/renderer/media/media_stream_video_track.h" 10 #include "content/renderer/media/mock_media_stream_video_sink.h" 11 #include "content/renderer/media/webrtc/media_stream_remote_video_source.h" 12 #include "content/renderer/media/webrtc/mock_peer_connection_dependency_factory.h" 13 #include "media/base/video_frame.h" 14 #include "testing/gtest/include/gtest/gtest.h" 15 #include "third_party/libjingle/source/talk/media/webrtc/webrtcvideoframe.h" 16 17 namespace content { 18 19 ACTION_P(RunClosure, closure) { 20 closure.Run(); 21 } 22 23 class MediaStreamRemoteVideoSourceUnderTest 24 : public MediaStreamRemoteVideoSource { 25 public: 26 MediaStreamRemoteVideoSourceUnderTest(webrtc::VideoTrackInterface* track) 27 : MediaStreamRemoteVideoSource(track) { 28 } 29 using MediaStreamRemoteVideoSource::RenderInterfaceForTest; 30 }; 31 32 class MediaStreamRemoteVideoSourceTest 33 : public ::testing::Test { 34 public: 35 MediaStreamRemoteVideoSourceTest() 36 : child_process_(new ChildProcess()), 37 mock_factory_(new MockPeerConnectionDependencyFactory()), 38 webrtc_video_track_( 39 mock_factory_->CreateLocalVideoTrack( 40 "test", 41 static_cast<cricket::VideoCapturer*>(NULL))), 42 remote_source_( 43 new MediaStreamRemoteVideoSourceUnderTest(webrtc_video_track_)), 44 number_of_successful_constraints_applied_(0), 45 number_of_failed_constraints_applied_(0) { 46 webkit_source_.initialize(base::UTF8ToUTF16("dummy_source_id"), 47 blink::WebMediaStreamSource::TypeVideo, 48 base::UTF8ToUTF16("dummy_source_name")); 49 webkit_source_.setExtraData(remote_source_); 50 } 51 52 MediaStreamRemoteVideoSourceUnderTest* source() { 53 return remote_source_; 54 } 55 56 MediaStreamVideoTrack* CreateTrack() { 57 bool enabled = true; 58 blink::WebMediaConstraints constraints; 59 constraints.initialize(); 60 return new MediaStreamVideoTrack( 61 source(), 62 constraints, 63 base::Bind( 64 &MediaStreamRemoteVideoSourceTest::OnConstraintsApplied, 65 base::Unretained(this)), 66 enabled); 67 } 68 69 int NumberOfSuccessConstraintsCallbacks() const { 70 return number_of_successful_constraints_applied_; 71 } 72 73 int NumberOfFailedConstraintsCallbacks() const { 74 return number_of_failed_constraints_applied_; 75 } 76 77 void StopWebRtcTrack() { 78 static_cast<MockWebRtcVideoTrack*>(webrtc_video_track_.get())->set_state( 79 webrtc::MediaStreamTrackInterface::kEnded); 80 } 81 82 const blink::WebMediaStreamSource& webkit_source() const { 83 return webkit_source_; 84 } 85 86 private: 87 void OnConstraintsApplied(MediaStreamSource* source, bool success) { 88 ASSERT_EQ(source, remote_source_); 89 if (success) 90 ++number_of_successful_constraints_applied_; 91 else 92 ++number_of_failed_constraints_applied_; 93 } 94 95 base::MessageLoopForUI message_loop_; 96 scoped_ptr<ChildProcess> child_process_; 97 scoped_ptr<MockPeerConnectionDependencyFactory> mock_factory_; 98 scoped_refptr<webrtc::VideoTrackInterface> webrtc_video_track_; 99 // |remote_source_| is owned by |webkit_source_|. 100 MediaStreamRemoteVideoSourceUnderTest* remote_source_; 101 blink::WebMediaStreamSource webkit_source_; 102 int number_of_successful_constraints_applied_; 103 int number_of_failed_constraints_applied_; 104 }; 105 106 TEST_F(MediaStreamRemoteVideoSourceTest, StartTrack) { 107 scoped_ptr<MediaStreamVideoTrack> track(CreateTrack()); 108 EXPECT_EQ(1, NumberOfSuccessConstraintsCallbacks()); 109 110 MockMediaStreamVideoSink sink; 111 track->AddSink(&sink, sink.GetDeliverFrameCB()); 112 base::RunLoop run_loop; 113 base::Closure quit_closure = run_loop.QuitClosure(); 114 EXPECT_CALL(sink, OnVideoFrame()).WillOnce( 115 RunClosure(quit_closure)); 116 cricket::WebRtcVideoFrame webrtc_frame; 117 webrtc_frame.InitToBlack(320, 240, 1, 1, 0, 1); 118 source()->RenderInterfaceForTest()->RenderFrame(&webrtc_frame); 119 run_loop.Run(); 120 121 EXPECT_EQ(1, sink.number_of_frames()); 122 track->RemoveSink(&sink); 123 } 124 125 TEST_F(MediaStreamRemoteVideoSourceTest, RemoteTrackStop) { 126 scoped_ptr<MediaStreamVideoTrack> track(CreateTrack()); 127 128 MockMediaStreamVideoSink sink; 129 track->AddSink(&sink, sink.GetDeliverFrameCB()); 130 EXPECT_EQ(blink::WebMediaStreamSource::ReadyStateLive, sink.state()); 131 EXPECT_EQ(blink::WebMediaStreamSource::ReadyStateLive, 132 webkit_source().readyState()); 133 StopWebRtcTrack(); 134 EXPECT_EQ(blink::WebMediaStreamSource::ReadyStateEnded, 135 webkit_source().readyState()); 136 EXPECT_EQ(blink::WebMediaStreamSource::ReadyStateEnded, sink.state()); 137 138 track->RemoveSink(&sink); 139 } 140 141 } // namespace content 142