diff options
author | yurys@chromium.org <yurys@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-04-08 14:55:35 +0000 |
---|---|---|
committer | yurys@chromium.org <yurys@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-04-08 14:55:35 +0000 |
commit | caa70d180ff72cbf5f5ffd542b97de86794d5e00 (patch) | |
tree | 13434c6afece9f4af0f74ce3dd712fde7321bc66 /content/renderer/media | |
parent | d1b794e7d5911d9225f2ec0055bcf9b969f12ee7 (diff) | |
download | chromium_src-caa70d180ff72cbf5f5ffd542b97de86794d5e00.zip chromium_src-caa70d180ff72cbf5f5ffd542b97de86794d5e00.tar.gz chromium_src-caa70d180ff72cbf5f5ffd542b97de86794d5e00.tar.bz2 |
Revert of Only create webrtc MediaStreams when added to a PeerConnection (https://codereview.chromium.org/227163007/)
Reason for revert:
This change caused 16 tests under LayoutTests/fast/mediastream/ to crash
http://test-results.appspot.com/dashboards/flakiness_dashboard.html#group=%40ToT%20Blink&tests=fast/mediastream/RTCPeerConnection-AddRemoveStream.html,fast/mediastream/RTCPeerConnection-createAnswer.html,fast/mediastream/RTCPeerConnection-createOffer.html,fast/mediastream/RTCPeerConnection-datachannel.html,fast/mediastream/RTCPeerConnection-dtmf.html,fast/mediastream/RTCPeerConnection-events.html,fast/mediastream/RTCPeerConnection-ice.html,fast/mediastream/RTCPeerConnection-lifetime.html,fast/mediastream/RTCPeerConnection-localDescription.html,fast/mediastream/RTCPeerConnection-onnegotiationneeded.html,fast/mediastream/RTCPeerConnection-remoteDescription.html,fast/mediastream/RTCPeerConnection-state.html,fast/mediastream/RTCPeerConnection-stats.html,fast/mediastream/RTCPeerConnection-statsSelector.html,fast/mediastream/RTCPeerConnection.html,fast/mediastream/constructors.html
Original issue's description:
> This cl adds a new class WebRtcMediaStreamAdapter. The responsibility of the class is to create and own a representation of a webrtc MediaStream that can be added and removed from a PeerConnection.
> An instance of WebRtcMediaStreamAdapter is created when a MediaStream is added to RTCPeerConnection object.
>
> The purpose is to clean up the the webrtc specific use of MediaStreams.
>
> BUG=323223
>
> Committed: https://src.chromium.org/viewvc/chrome?view=rev&revision=262395
TBR=xians@chromium.org,ronghuawu@chromium.org,perkj@chromium.org
NOTREECHECKS=true
NOTRY=true
BUG=323223
Review URL: https://codereview.chromium.org/228733002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@262403 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content/renderer/media')
16 files changed, 499 insertions, 361 deletions
diff --git a/content/renderer/media/media_stream.cc b/content/renderer/media/media_stream.cc index b85a353..9a8f143 100644 --- a/content/renderer/media/media_stream.cc +++ b/content/renderer/media/media_stream.cc @@ -5,6 +5,7 @@ #include "content/renderer/media/media_stream.h" #include "base/logging.h" +#include "content/renderer/media/media_stream_dependency_factory.h" #include "third_party/WebKit/public/platform/WebString.h" #include "third_party/libjingle/source/talk/app/webrtc/mediastreaminterface.h" @@ -24,16 +25,22 @@ webrtc::MediaStreamInterface* MediaStream::GetAdapter( return native_stream->GetWebRtcAdapter(stream); } -MediaStream::MediaStream(StreamStopCallback stream_stop, +MediaStream::MediaStream(MediaStreamDependencyFactory* factory, + StreamStopCallback stream_stop, const blink::WebMediaStream& stream) : stream_stop_callback_(stream_stop), + stream_adapter_(NULL), is_local_(true), - label_(stream.id().utf8()) { + label_(stream.id().utf8()), + factory_(factory) { + DCHECK(factory_); } -MediaStream::MediaStream(webrtc::MediaStreamInterface* webrtc_stream) - : is_local_(false), - webrtc_media_stream_(webrtc_stream) { +MediaStream::MediaStream(webrtc::MediaStreamInterface* stream) + : stream_adapter_(stream), + is_local_(false), + factory_(NULL) { + DCHECK(stream); } MediaStream::~MediaStream() { @@ -46,22 +53,32 @@ void MediaStream::OnStreamStopped() { webrtc::MediaStreamInterface* MediaStream::GetWebRtcAdapter( const blink::WebMediaStream& stream) { - DCHECK(webrtc_media_stream_); - return webrtc_media_stream_.get(); + if (!stream_adapter_) { + DCHECK(is_local_); + stream_adapter_ = factory_->CreateNativeLocalMediaStream(stream); + } + DCHECK(stream_adapter_); + return stream_adapter_.get(); } -bool MediaStream::AddTrack(const blink::WebMediaStreamTrack& track) { - // This method can be implemented if any clients need to know that a track - // has been added to a MediaStream. - NOTIMPLEMENTED(); - return true; +bool MediaStream::AddTrack(const blink::WebMediaStream& stream, + const blink::WebMediaStreamTrack& track) { + // If the libjingle representation of the stream has not been created, it + // does not matter if the tracks are added or removed. Once the + // libjingle representation is created, a libjingle track representation will + // be created for all blink tracks. + if (!stream_adapter_) + return true; + return factory_->AddNativeMediaStreamTrack(stream, track); } -bool MediaStream::RemoveTrack(const blink::WebMediaStreamTrack& track) { - // This method can be implemented if any clients need to know that a track - // has been removed from a MediaStream. - NOTIMPLEMENTED(); - return true; +bool MediaStream::RemoveTrack(const blink::WebMediaStream& stream, + const blink::WebMediaStreamTrack& track) { + // If the libjingle representation of the stream has not been created, it + // does not matter if the tracks are added or removed. + if (!stream_adapter_) + return true; + return factory_->RemoveNativeMediaStreamTrack(stream, track); } } // namespace content diff --git a/content/renderer/media/media_stream.h b/content/renderer/media/media_stream.h index ec75bc3..2281043 100644 --- a/content/renderer/media/media_stream.h +++ b/content/renderer/media/media_stream.h @@ -9,15 +9,18 @@ #include "base/callback.h" #include "base/compiler_specific.h" +#include "base/memory/ref_counted.h" #include "content/common/content_export.h" #include "third_party/WebKit/public/platform/WebMediaStream.h" namespace webrtc { class MediaStreamInterface; -} +} // namespace webrtc namespace content { +class MediaStreamDependencyFactory; + // MediaStream is the Chrome representation of blink::WebMediaStream. // It is owned by blink::WebMediaStream as blink::WebMediaStream::ExtraData. class CONTENT_EXPORT MediaStream @@ -26,13 +29,11 @@ class CONTENT_EXPORT MediaStream typedef base::Callback<void(const std::string& label)> StreamStopCallback; // Constructor for local MediaStreams. - MediaStream(StreamStopCallback stream_stop, + MediaStream(MediaStreamDependencyFactory* factory, + StreamStopCallback stream_stop, const blink::WebMediaStream& stream); - // Constructor for remote MediaStreams. - // TODO(xians): Remove once the audio renderer don't separate between local - // and remotely generated streams. - explicit MediaStream(webrtc::MediaStreamInterface* webrtc_stream); + explicit MediaStream(webrtc::MediaStreamInterface* stream); virtual ~MediaStream(); @@ -40,9 +41,9 @@ class CONTENT_EXPORT MediaStream static MediaStream* GetMediaStream( const blink::WebMediaStream& stream); - // Returns a libjingle representation of a remote MediaStream. - // TODO(xians): Remove once the audio renderer don't separate between local - // and remotely generated streams. + // Returns a libjingle representation of a MediaStream. If a representation + // does not exist- the libjingle stream is created. This method will never + // return NULL. static webrtc::MediaStreamInterface* GetAdapter( const blink::WebMediaStream& stream); @@ -57,12 +58,14 @@ class CONTENT_EXPORT MediaStream // Called by MediaStreamCenter when a track has been added to a stream stream. // If a libjingle representation of |stream| exist, the track is added to // the libjingle MediaStream. - bool AddTrack(const blink::WebMediaStreamTrack& track); + bool AddTrack(const blink::WebMediaStream& stream, + const blink::WebMediaStreamTrack& track); // Called by MediaStreamCenter when a track has been removed from |stream| // If a libjingle representation or |stream| exist, the track is removed // from the libjingle MediaStream. - bool RemoveTrack(const blink::WebMediaStreamTrack& track); + bool RemoveTrack(const blink::WebMediaStream& stream, + const blink::WebMediaStreamTrack& track); protected: virtual webrtc::MediaStreamInterface* GetWebRtcAdapter( @@ -70,12 +73,13 @@ class CONTENT_EXPORT MediaStream private: StreamStopCallback stream_stop_callback_; + scoped_refptr<webrtc::MediaStreamInterface> stream_adapter_; const bool is_local_; const std::string label_; - // TODO(xians): Remove once the audio renderer don't separate between local - // and remotely generated streams. - scoped_refptr<webrtc::MediaStreamInterface> webrtc_media_stream_; + // Weak ref to a MediaStreamDependencyFactory, owned by the RenderThread. + // It's valid for the lifetime of RenderThread. + MediaStreamDependencyFactory* factory_; DISALLOW_COPY_AND_ASSIGN(MediaStream); }; diff --git a/content/renderer/media/media_stream_center.cc b/content/renderer/media/media_stream_center.cc index dfe3cc1..e568567 100644 --- a/content/renderer/media/media_stream_center.cc +++ b/content/renderer/media/media_stream_center.cc @@ -185,7 +185,9 @@ void MediaStreamCenter::didCreateMediaStream(blink::WebMediaStream& stream) { DVLOG(1) << "MediaStreamCenter::didCreateMediaStream"; blink::WebMediaStream writable_stream(stream); MediaStream* native_stream( - new MediaStream(MediaStream::StreamStopCallback(), stream)); + new MediaStream(rtc_factory_, + MediaStream::StreamStopCallback(), + stream)); writable_stream.setExtraData(native_stream); blink::WebVector<blink::WebMediaStreamTrack> video_tracks; @@ -202,7 +204,7 @@ bool MediaStreamCenter::didAddMediaStreamTrack( const blink::WebMediaStreamTrack& track) { DVLOG(1) << "MediaStreamCenter::didAddMediaStreamTrack"; MediaStream* native_stream = MediaStream::GetMediaStream(stream); - return native_stream->AddTrack(track); + return native_stream->AddTrack(stream, track); } bool MediaStreamCenter::didRemoveMediaStreamTrack( @@ -210,7 +212,7 @@ bool MediaStreamCenter::didRemoveMediaStreamTrack( const blink::WebMediaStreamTrack& track) { DVLOG(1) << "MediaStreamCenter::didRemoveMediaStreamTrack"; MediaStream* native_stream = MediaStream::GetMediaStream(stream); - return native_stream->RemoveTrack(track); + return native_stream->RemoveTrack(stream, track); } bool MediaStreamCenter::OnControlMessageReceived(const IPC::Message& message) { diff --git a/content/renderer/media/media_stream_dependency_factory.cc b/content/renderer/media/media_stream_dependency_factory.cc index 84565ff..70f3d06 100644 --- a/content/renderer/media/media_stream_dependency_factory.cc +++ b/content/renderer/media/media_stream_dependency_factory.cc @@ -243,6 +243,97 @@ WebRtcVideoCapturerAdapter* MediaStreamDependencyFactory::CreateVideoCapturer( return new WebRtcVideoCapturerAdapter(is_screeencast); } +scoped_refptr<webrtc::MediaStreamInterface> +MediaStreamDependencyFactory::CreateNativeLocalMediaStream( + const blink::WebMediaStream& web_stream) { + DCHECK(web_stream.extraData()); + DVLOG(1) << "MediaStreamDependencyFactory::CreateNativeLocalMediaStream()"; + + std::string label = web_stream.id().utf8(); + scoped_refptr<webrtc::MediaStreamInterface> native_stream = + CreateLocalMediaStream(label); + + // Add audio tracks. + blink::WebVector<blink::WebMediaStreamTrack> audio_tracks; + web_stream.audioTracks(audio_tracks); + for (size_t i = 0; i < audio_tracks.size(); ++i) { + MediaStreamTrack* native_track = + MediaStreamTrack::GetTrack(audio_tracks[i]); + if (!native_track) { + // TODO(perkj): Implement. + // This can happen if the blink track uses a source from a remote track. + NOTIMPLEMENTED(); + continue; + } + native_stream->AddTrack(native_track->GetAudioAdapter()); + } + + // Add video tracks. + blink::WebVector<blink::WebMediaStreamTrack> video_tracks; + web_stream.videoTracks(video_tracks); + for (size_t i = 0; i < video_tracks.size(); ++i) { + MediaStreamTrack* native_track = + MediaStreamTrack::GetTrack(video_tracks[i]); + if (!native_track) { + // TODO(perkj): Implement. + // This can happen if the blink track uses a source from a remote track. + NOTIMPLEMENTED(); + continue; + } + native_stream->AddTrack(native_track->GetVideoAdapter()); + } + return native_stream; +} + +bool MediaStreamDependencyFactory::AddNativeMediaStreamTrack( + const blink::WebMediaStream& stream, + const blink::WebMediaStreamTrack& track) { + DVLOG(1) << "AddNativeMediaStreamTrack"; + webrtc::MediaStreamInterface* webrtc_stream = + MediaStream::GetAdapter(stream); + + MediaStreamTrack* native_track = + MediaStreamTrack::GetTrack(track); + if (!native_track) { + // TODO(perkj): Implement. + // This can happen if the blink track uses a source from a remote track. + NOTIMPLEMENTED(); + return false; + } + + switch (track.source().type()) { + case blink::WebMediaStreamSource::TypeAudio: { + webrtc::AudioTrackInterface* webrtc_audio_track = + native_track->GetAudioAdapter(); + return webrtc_audio_track && webrtc_stream->AddTrack(webrtc_audio_track); + } + case blink::WebMediaStreamSource::TypeVideo: { + webrtc::VideoTrackInterface* webrtc_video_track = + native_track->GetVideoAdapter(); + return webrtc_video_track && webrtc_stream->AddTrack(webrtc_video_track); + } + } + return false; +} + +bool MediaStreamDependencyFactory::RemoveNativeMediaStreamTrack( + const blink::WebMediaStream& stream, + const blink::WebMediaStreamTrack& track) { + webrtc::MediaStreamInterface* native_stream = + MediaStream::GetAdapter(stream); + DCHECK(native_stream); + std::string track_id = track.id().utf8(); + switch (track.source().type()) { + case blink::WebMediaStreamSource::TypeAudio: + return native_stream->RemoveTrack( + native_stream->FindAudioTrack(track_id)); + case blink::WebMediaStreamSource::TypeVideo: + return native_stream->RemoveTrack( + native_stream->FindVideoTrack(track_id)); + } + return false; +} + scoped_refptr<webrtc::VideoSourceInterface> MediaStreamDependencyFactory::CreateVideoSource( cricket::VideoCapturer* capturer, diff --git a/content/renderer/media/media_stream_dependency_factory.h b/content/renderer/media/media_stream_dependency_factory.h index 14507fb..5986abb 100644 --- a/content/renderer/media/media_stream_dependency_factory.h +++ b/content/renderer/media/media_stream_dependency_factory.h @@ -70,10 +70,6 @@ class CONTENT_EXPORT MediaStreamDependencyFactory blink::WebRTCPeerConnectionHandler* CreateRTCPeerConnectionHandler( blink::WebRTCPeerConnectionHandlerClient* client); - // Asks the PeerConnection factory to create a Local MediaStream object. - virtual scoped_refptr<webrtc::MediaStreamInterface> - CreateLocalMediaStream(const std::string& label); - // InitializeMediaStreamAudioSource initialize a MediaStream source object // for audio input. bool InitializeMediaStreamAudioSource( @@ -86,6 +82,10 @@ class CONTENT_EXPORT MediaStreamDependencyFactory virtual WebRtcVideoCapturerAdapter* CreateVideoCapturer( bool is_screen_capture); + // Creates a libjingle representation of a MediaStream. + scoped_refptr<webrtc::MediaStreamInterface> CreateNativeLocalMediaStream( + const blink::WebMediaStream& web_stream); + // Create an instance of WebRtcLocalAudioTrack and store it // in the extraData field of |track|. void CreateLocalAudioTrack(const blink::WebMediaStreamTrack& track); @@ -95,6 +95,16 @@ class CONTENT_EXPORT MediaStreamDependencyFactory CreateLocalVideoTrack(const std::string& id, webrtc::VideoSourceInterface* source); + // Adds a libjingle representation of a MediaStreamTrack to the libjingle + // Representation of |stream|. + bool AddNativeMediaStreamTrack(const blink::WebMediaStream& stream, + const blink::WebMediaStreamTrack& track); + + // Removes a libjingle MediaStreamTrack from the libjingle representation of + // |stream|. + bool RemoveNativeMediaStreamTrack(const blink::WebMediaStream& stream, + const blink::WebMediaStreamTrack& track); + // Asks the PeerConnection factory to create a Video Source. // The video source takes ownership of |capturer|. virtual scoped_refptr<webrtc::VideoSourceInterface> @@ -132,6 +142,10 @@ class CONTENT_EXPORT MediaStreamDependencyFactory bool is_local_track); protected: + // Asks the PeerConnection factory to create a Local MediaStream object. + virtual scoped_refptr<webrtc::MediaStreamInterface> + CreateLocalMediaStream(const std::string& label); + // Asks the PeerConnection factory to create a Local Audio Source. virtual scoped_refptr<webrtc::AudioSourceInterface> CreateLocalAudioSource( diff --git a/content/renderer/media/media_stream_dependency_factory_unittest.cc b/content/renderer/media/media_stream_dependency_factory_unittest.cc index e0e71ab..9236c23 100644 --- a/content/renderer/media/media_stream_dependency_factory_unittest.cc +++ b/content/renderer/media/media_stream_dependency_factory_unittest.cc @@ -2,21 +2,145 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "base/memory/scoped_ptr.h" +#include "content/common/media/media_stream_options.h" +#include "content/renderer/media/media_stream.h" +#include "content/renderer/media/media_stream_audio_source.h" +#include "content/renderer/media/media_stream_video_source.h" +#include "content/renderer/media/media_stream_video_track.h" #include "content/renderer/media/mock_media_stream_dependency_factory.h" +#include "content/renderer/media/mock_media_stream_video_source.h" #include "content/renderer/media/mock_web_rtc_peer_connection_handler_client.h" +#include "content/renderer/media/webrtc/webrtc_local_audio_track_adapter.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/WebKit/public/platform/WebMediaConstraints.h" +#include "third_party/WebKit/public/platform/WebMediaStream.h" +#include "third_party/WebKit/public/platform/WebMediaStreamSource.h" +#include "third_party/WebKit/public/platform/WebMediaStreamTrack.h" #include "third_party/WebKit/public/platform/WebRTCPeerConnectionHandler.h" +#include "third_party/WebKit/public/platform/WebVector.h" namespace content { +class MediaSourceCreatedObserver { + public: + MediaSourceCreatedObserver() + : result_(false), + description_(NULL) { + } + + void OnCreateNativeSourcesComplete( + blink::WebMediaStream* description, + bool request_succeeded) { + result_ = request_succeeded; + description_ = description; + } + + blink::WebMediaStream* description() const { + return description_; + } + bool result() const { return result_; } + + private: + bool result_; + blink::WebMediaStream* description_; +}; + class MediaStreamDependencyFactoryTest : public ::testing::Test { public: virtual void SetUp() { dependency_factory_.reset(new MockMediaStreamDependencyFactory()); } + blink::WebMediaStream CreateWebKitMediaStream(bool audio, bool video) { + blink::WebVector<blink::WebMediaStreamSource> audio_sources( + audio ? static_cast<size_t>(1) : 0); + blink::WebVector<blink::WebMediaStreamSource> video_sources( + video ? static_cast<size_t>(1) : 0); + MediaStreamSource::SourceStoppedCallback dummy_callback; + + if (audio) { + StreamDeviceInfo info; + info.device.type = MEDIA_DEVICE_AUDIO_CAPTURE; + info.device.name = "audio"; + info.session_id = 99; + audio_sources[0].initialize("audio", + blink::WebMediaStreamSource::TypeAudio, + "audio"); + audio_sources[0].setExtraData( + new MediaStreamAudioSource()); + + audio_sources_.assign(audio_sources); + } + if (video) { + StreamDeviceInfo info; + info.device.type = MEDIA_DEVICE_VIDEO_CAPTURE; + info.device.name = "video"; + info.session_id = 98; + video_sources[0].initialize("video", + blink::WebMediaStreamSource::TypeVideo, + "video"); + + video_sources[0].setExtraData( + new MockMediaStreamVideoSource(dependency_factory_.get(), false)); + video_sources_.assign(video_sources); + } + blink::WebMediaStream stream_desc; + blink::WebVector<blink::WebMediaStreamTrack> audio_track_vector( + audio_sources.size()); + for (size_t i = 0; i < audio_track_vector.size(); ++i) { + audio_track_vector[i].initialize(audio_sources[i].id(), + audio_sources[i]); + MediaStreamTrack* native_track = + new MediaStreamTrack( + WebRtcLocalAudioTrackAdapter::Create( + audio_track_vector[i].id().utf8(), NULL), + true); + + audio_track_vector[i].setExtraData(native_track); + } + + blink::WebMediaConstraints constraints; + constraints.initialize(); + blink::WebVector<blink::WebMediaStreamTrack> video_track_vector( + video_sources.size()); + for (size_t i = 0; i < video_track_vector.size(); ++i) { + MediaStreamVideoSource* native_source = + MediaStreamVideoSource::GetVideoSource(video_sources[i]); + video_track_vector[i] = MediaStreamVideoTrack::CreateVideoTrack( + native_source, constraints, + MediaStreamVideoSource::ConstraintsCallback(), true, + dependency_factory_.get()); + } + + stream_desc.initialize("media stream", audio_track_vector, + video_track_vector); + stream_desc.setExtraData( + new content::MediaStream(dependency_factory_.get(), + content::MediaStream::StreamStopCallback(), + stream_desc)); + return stream_desc; + } + + void VerifyMediaStream(const blink::WebMediaStream& stream_desc, + size_t num_audio_tracks, + size_t num_video_tracks) { + content::MediaStream* native_stream = + content::MediaStream::GetMediaStream(stream_desc); + ASSERT_TRUE(native_stream); + EXPECT_TRUE(native_stream->is_local()); + + webrtc::MediaStreamInterface* webrtc_stream = + MediaStream::GetAdapter(stream_desc); + ASSERT_TRUE(webrtc_stream); + EXPECT_EQ(num_audio_tracks, webrtc_stream->GetAudioTracks().size()); + EXPECT_EQ(num_video_tracks, webrtc_stream->GetVideoTracks().size()); + } + protected: scoped_ptr<MockMediaStreamDependencyFactory> dependency_factory_; + blink::WebVector<blink::WebMediaStreamSource> audio_sources_; + blink::WebVector<blink::WebMediaStreamSource> video_sources_; }; TEST_F(MediaStreamDependencyFactoryTest, CreateRTCPeerConnectionHandler) { @@ -26,4 +150,67 @@ TEST_F(MediaStreamDependencyFactoryTest, CreateRTCPeerConnectionHandler) { EXPECT_TRUE(pc_handler.get() != NULL); } +TEST_F(MediaStreamDependencyFactoryTest, CreateNativeMediaStream) { + blink::WebMediaStream stream_desc = CreateWebKitMediaStream(true, true); + + VerifyMediaStream(stream_desc, 1, 1); +} + +// Test that we don't crash if a MediaStream is created in WebKit with unknown +// sources. This can for example happen if a MediaStream is created with +// remote tracks. +TEST_F(MediaStreamDependencyFactoryTest, CreateNativeMediaStreamWithoutSource) { + // Create a WebKit MediaStream description. + blink::WebMediaStreamSource audio_source; + audio_source.initialize("audio source", + blink::WebMediaStreamSource::TypeAudio, + "something"); + blink::WebMediaStreamSource video_source; + video_source.initialize("video source", + blink::WebMediaStreamSource::TypeVideo, + "something"); + + blink::WebVector<blink::WebMediaStreamTrack> audio_tracks( + static_cast<size_t>(1)); + audio_tracks[0].initialize(audio_source.id(), audio_source); + blink::WebVector<blink::WebMediaStreamTrack> video_tracks( + static_cast<size_t>(1)); + video_tracks[0].initialize(video_source.id(), video_source); + + blink::WebMediaStream stream_desc; + stream_desc.initialize("new stream", audio_tracks, video_tracks); + stream_desc.setExtraData( + new content::MediaStream(dependency_factory_.get(), + content::MediaStream::StreamStopCallback(), + stream_desc)); + + VerifyMediaStream(stream_desc, 0, 0); +} + +TEST_F(MediaStreamDependencyFactoryTest, AddAndRemoveNativeTrack) { + blink::WebMediaStream stream_desc = CreateWebKitMediaStream(true, true); + + VerifyMediaStream(stream_desc, 1, 1); + + blink::WebVector<blink::WebMediaStreamTrack> audio_tracks; + stream_desc.audioTracks(audio_tracks); + EXPECT_TRUE(dependency_factory_->RemoveNativeMediaStreamTrack( + stream_desc, audio_tracks[0])); + VerifyMediaStream(stream_desc, 0, 1); + + EXPECT_TRUE(dependency_factory_->AddNativeMediaStreamTrack( + stream_desc, audio_tracks[0])); + VerifyMediaStream(stream_desc, 1, 1); + + blink::WebVector<blink::WebMediaStreamTrack> video_tracks; + stream_desc.videoTracks(video_tracks); + EXPECT_TRUE(dependency_factory_->RemoveNativeMediaStreamTrack( + stream_desc, video_tracks[0])); + VerifyMediaStream(stream_desc, 1, 0); + + EXPECT_TRUE(dependency_factory_->AddNativeMediaStreamTrack( + stream_desc, video_tracks[0])); + VerifyMediaStream(stream_desc, 1, 1); +} + } // namespace content diff --git a/content/renderer/media/media_stream_impl.cc b/content/renderer/media/media_stream_impl.cc index 5500823..9c6d33b 100644 --- a/content/renderer/media/media_stream_impl.cc +++ b/content/renderer/media/media_stream_impl.cc @@ -341,6 +341,7 @@ void MediaStreamImpl::OnStreamGenerated( video_track_vector); web_stream->setExtraData( new MediaStream( + dependency_factory_, base::Bind(&MediaStreamImpl::OnLocalMediaStreamStop, AsWeakPtr()), *web_stream)); diff --git a/content/renderer/media/mock_media_stream_registry.cc b/content/renderer/media/mock_media_stream_registry.cc index f63e7c8..6b990bc 100644 --- a/content/renderer/media/mock_media_stream_registry.cc +++ b/content/renderer/media/mock_media_stream_registry.cc @@ -28,7 +28,8 @@ void MockMediaStreamRegistry::Init(const std::string& stream_url) { blink::WebVector<blink::WebMediaStreamTrack> webkit_video_tracks; blink::WebString label(kTestStreamLabel); test_stream_.initialize(label, webkit_audio_tracks, webkit_video_tracks); - test_stream_.setExtraData(new MediaStream(MediaStream::StreamStopCallback(), + test_stream_.setExtraData(new MediaStream(&dependency_factory_, + MediaStream::StreamStopCallback(), test_stream_)); } diff --git a/content/renderer/media/peer_connection_handler_base.cc b/content/renderer/media/peer_connection_handler_base.cc new file mode 100644 index 0000000..4aeb6e6 --- /dev/null +++ b/content/renderer/media/peer_connection_handler_base.cc @@ -0,0 +1,41 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/renderer/media/peer_connection_handler_base.h" + +#include "base/logging.h" +#include "base/strings/utf_string_conversions.h" +#include "content/renderer/media/media_stream.h" +#include "third_party/WebKit/public/platform/WebMediaStream.h" +#include "third_party/WebKit/public/platform/WebMediaStreamSource.h" +#include "third_party/WebKit/public/platform/WebMediaStreamTrack.h" +#include "third_party/WebKit/public/platform/WebString.h" + +namespace content { + +PeerConnectionHandlerBase::PeerConnectionHandlerBase( + MediaStreamDependencyFactory* dependency_factory) + : dependency_factory_(dependency_factory), + message_loop_proxy_(base::MessageLoopProxy::current()) { +} + +PeerConnectionHandlerBase::~PeerConnectionHandlerBase() { +} + +bool PeerConnectionHandlerBase::AddStream( + const blink::WebMediaStream& stream, + const webrtc::MediaConstraintsInterface* constraints) { + webrtc::MediaStreamInterface* native_stream = + MediaStream::GetMediaStream(stream)->GetAdapter(stream); + return native_peer_connection_->AddStream(native_stream, constraints); +} + +void PeerConnectionHandlerBase::RemoveStream( + const blink::WebMediaStream& stream) { + webrtc::MediaStreamInterface* native_stream = + MediaStream::GetMediaStream(stream)->GetAdapter(stream); + native_peer_connection_->RemoveStream(native_stream); +} + +} // namespace content diff --git a/content/renderer/media/peer_connection_handler_base.h b/content/renderer/media/peer_connection_handler_base.h new file mode 100644 index 0000000..df02721 --- /dev/null +++ b/content/renderer/media/peer_connection_handler_base.h @@ -0,0 +1,61 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_RENDERER_MEDIA_PEER_CONNECTION_HANDLER_BASE_H_ +#define CONTENT_RENDERER_MEDIA_PEER_CONNECTION_HANDLER_BASE_H_ + +#include <map> +#include <string> + +#include "base/memory/ref_counted.h" +#include "base/message_loop/message_loop_proxy.h" +#include "content/common/content_export.h" +#include "third_party/WebKit/public/platform/WebMediaStream.h" +#include "third_party/WebKit/public/platform/WebMediaStreamTrack.h" +#include "third_party/libjingle/source/talk/app/webrtc/mediastream.h" +#include "third_party/libjingle/source/talk/app/webrtc/peerconnectioninterface.h" + +namespace content { +class MediaStreamDependencyFactory; +class RemoteMediaStreamImpl; + +// PeerConnectionHandlerBase is the base class of a delegate for the +// PeerConnection API messages going between WebKit and native +// PeerConnection in libjingle. +class CONTENT_EXPORT PeerConnectionHandlerBase + : NON_EXPORTED_BASE(public webrtc::PeerConnectionObserver) { + public: + PeerConnectionHandlerBase( + MediaStreamDependencyFactory* dependency_factory); + + protected: + virtual ~PeerConnectionHandlerBase(); + + void AddStream(const blink::WebMediaStream& stream); + bool AddStream(const blink::WebMediaStream& stream, + const webrtc::MediaConstraintsInterface* constraints); + void RemoveStream(const blink::WebMediaStream& stream); + + // dependency_factory_ is a raw pointer, and is valid for the lifetime of + // MediaStreamImpl. + MediaStreamDependencyFactory* dependency_factory_; + + // native_peer_connection_ is the native PeerConnection object, + // it handles the ICE processing and media engine. + scoped_refptr<webrtc::PeerConnectionInterface> native_peer_connection_; + + typedef std::map<webrtc::MediaStreamInterface*, + content::RemoteMediaStreamImpl*> RemoteStreamMap; + RemoteStreamMap remote_streams_; + + // The message loop we are created on and on which to make calls to WebKit. + // This should be the render thread message loop. + scoped_refptr<base::MessageLoopProxy> message_loop_proxy_; + + DISALLOW_COPY_AND_ASSIGN(PeerConnectionHandlerBase); +}; + +} // namespace content + +#endif // CONTENT_RENDERER_MEDIA_PEER_CONNECTION_HANDLER_BASE_H_ diff --git a/content/renderer/media/rtc_peer_connection_handler.cc b/content/renderer/media/rtc_peer_connection_handler.cc index bdfe3ec..3b94de7 100644 --- a/content/renderer/media/rtc_peer_connection_handler.cc +++ b/content/renderer/media/rtc_peer_connection_handler.cc @@ -16,6 +16,8 @@ #include "base/stl_util.h" #include "base/strings/utf_string_conversions.h" #include "content/public/common/content_switches.h" +#include "content/renderer/media/media_stream.h" +#include "content/renderer/media/media_stream_audio_source.h" #include "content/renderer/media/media_stream_dependency_factory.h" #include "content/renderer/media/media_stream_track.h" #include "content/renderer/media/peer_connection_tracker.h" @@ -23,7 +25,6 @@ #include "content/renderer/media/rtc_data_channel_handler.h" #include "content/renderer/media/rtc_dtmf_sender_handler.h" #include "content/renderer/media/rtc_media_constraints.h" -#include "content/renderer/media/webrtc/webrtc_media_stream_adapter.h" #include "content/renderer/media/webrtc_audio_capturer.h" #include "content/renderer/media/webrtc_audio_device_impl.h" #include "content/renderer/media/webrtc_uma_histograms.h" @@ -319,8 +320,8 @@ void LocalRTCStatsResponse::addStatistic(size_t report, RTCPeerConnectionHandler::RTCPeerConnectionHandler( blink::WebRTCPeerConnectionHandlerClient* client, MediaStreamDependencyFactory* dependency_factory) - : client_(client), - dependency_factory_(dependency_factory), + : PeerConnectionHandlerBase(dependency_factory), + client_(client), frame_(NULL), peer_connection_tracker_(NULL), num_data_channels_created_(0) { @@ -547,16 +548,7 @@ void RTCPeerConnectionHandler::OnaddICECandidateResult( bool RTCPeerConnectionHandler::addStream( const blink::WebMediaStream& stream, const blink::WebMediaConstraints& options) { - - for (ScopedVector<WebRtcMediaStreamAdapter>::iterator adapter_it = - local_streams_.begin(); adapter_it != local_streams_.end(); - ++adapter_it) { - if ((*adapter_it)->IsEqual(stream)) { - DVLOG(1) << "RTCPeerConnectionHandler::addStream called with the same " - << "stream twice. id=" << stream.id().utf8(); - return false; - } - } + RTCMediaConstraints constraints(options); if (peer_connection_tracker_) peer_connection_tracker_->TrackAddStream( @@ -564,40 +556,47 @@ bool RTCPeerConnectionHandler::addStream( PerSessionWebRTCAPIMetrics::GetInstance()->IncrementStreamCounter(); - WebRtcMediaStreamAdapter* adapter = - new WebRtcMediaStreamAdapter(stream, dependency_factory_); - local_streams_.push_back(adapter); - - webrtc::MediaStreamInterface* webrtc_stream = adapter->webrtc_media_stream(); track_metrics_.AddStream(MediaStreamTrackMetrics::SENT_STREAM, - webrtc_stream); + MediaStream::GetAdapter(stream)); - RTCMediaConstraints constraints(options); - return native_peer_connection_->AddStream(webrtc_stream, &constraints); + // A media stream is connected to a peer connection, enable the + // peer connection mode for the sources. + blink::WebVector<blink::WebMediaStreamTrack> audio_tracks; + stream.audioTracks(audio_tracks); + for (size_t i = 0; i < audio_tracks.size(); ++i) { + MediaStreamTrack* native_track = + MediaStreamTrack::GetTrack(audio_tracks[i]); + if (!native_track || !native_track->is_local_track()) { + // We don't support connecting remote audio tracks to PeerConnection yet. + // See issue http://crbug/344303. + // TODO(xians): Remove this after we support connecting remote audio track + // to PeerConnection. + DLOG(ERROR) << "addStream() failed because we don't support connecting" + << " remote audio track to PeerConnection"; + NOTIMPLEMENTED(); + return false; + } + + // This is a local audio track. + const blink::WebMediaStreamSource& source = audio_tracks[i].source(); + MediaStreamAudioSource* audio_source = + static_cast<MediaStreamAudioSource*>(source.extraData()); + if (audio_source && audio_source->GetAudioCapturer()) + audio_source->GetAudioCapturer()->EnablePeerConnectionMode(); + } + + return AddStream(stream, &constraints); } void RTCPeerConnectionHandler::removeStream( const blink::WebMediaStream& stream) { - // Find the webrtc stream. - scoped_refptr<webrtc::MediaStreamInterface> webrtc_stream; - for (ScopedVector<WebRtcMediaStreamAdapter>::iterator adapter_it = - local_streams_.begin(); adapter_it != local_streams_.end(); - ++adapter_it) { - if ((*adapter_it)->IsEqual(stream)) { - webrtc_stream = (*adapter_it)->webrtc_media_stream(); - local_streams_.erase(adapter_it); - break; - } - } - DCHECK(webrtc_stream); - native_peer_connection_->RemoveStream(webrtc_stream); - + RemoveStream(stream); if (peer_connection_tracker_) peer_connection_tracker_->TrackRemoveStream( this, stream, PeerConnectionTracker::SOURCE_LOCAL); PerSessionWebRTCAPIMetrics::GetInstance()->DecrementStreamCounter(); track_metrics_.RemoveStream(MediaStreamTrackMetrics::SENT_STREAM, - webrtc_stream); + MediaStream::GetAdapter(stream)); } void RTCPeerConnectionHandler::getStats( diff --git a/content/renderer/media/rtc_peer_connection_handler.h b/content/renderer/media/rtc_peer_connection_handler.h index 2634224..3944376 100644 --- a/content/renderer/media/rtc_peer_connection_handler.h +++ b/content/renderer/media/rtc_peer_connection_handler.h @@ -5,13 +5,10 @@ #ifndef CONTENT_RENDERER_MEDIA_RTC_PEER_CONNECTION_HANDLER_H_ #define CONTENT_RENDERER_MEDIA_RTC_PEER_CONNECTION_HANDLER_H_ -#include <map> -#include <string> - #include "base/basictypes.h" #include "base/compiler_specific.h" -#include "base/memory/ref_counted.h" #include "content/common/content_export.h" +#include "content/renderer/media/peer_connection_handler_base.h" #include "content/renderer/media/webrtc/media_stream_track_metrics.h" #include "third_party/WebKit/public/platform/WebRTCPeerConnectionHandler.h" #include "third_party/WebKit/public/platform/WebRTCStatsRequest.h" @@ -24,10 +21,7 @@ class WebRTCDataChannelHandler; namespace content { -class MediaStreamDependencyFactory; class PeerConnectionTracker; -class RemoteMediaStreamImpl; -class WebRtcMediaStreamAdapter; // Mockable wrapper for blink::WebRTCStatsResponse class CONTENT_EXPORT LocalRTCStatsResponse @@ -80,8 +74,8 @@ class CONTENT_EXPORT LocalRTCStatsRequest // Callbacks to the webrtc::PeerConnectionObserver implementation also occur on // the main render thread. class CONTENT_EXPORT RTCPeerConnectionHandler - : NON_EXPORTED_BASE(public blink::WebRTCPeerConnectionHandler), - NON_EXPORTED_BASE(public webrtc::PeerConnectionObserver) { + : public PeerConnectionHandlerBase, + NON_EXPORTED_BASE(public blink::WebRTCPeerConnectionHandler) { public: RTCPeerConnectionHandler( blink::WebRTCPeerConnectionHandlerClient* client, @@ -174,11 +168,6 @@ class CONTENT_EXPORT RTCPeerConnectionHandler PeerConnectionTracker* peer_connection_tracker(); - protected: - webrtc::PeerConnectionInterface* native_peer_connection() { - return native_peer_connection_.get(); - } - private: webrtc::SessionDescriptionInterface* CreateNativeSessionDescription( const blink::WebRTCSessionDescription& description, @@ -187,14 +176,8 @@ class CONTENT_EXPORT RTCPeerConnectionHandler // |client_| is a weak pointer, and is valid until stop() has returned. blink::WebRTCPeerConnectionHandlerClient* client_; - // |dependency_factory_| is a raw pointer, and is valid for the lifetime of - // RenderThreadImpl. - MediaStreamDependencyFactory* dependency_factory_; - blink::WebFrame* frame_; - ScopedVector<WebRtcMediaStreamAdapter> local_streams_; - PeerConnectionTracker* peer_connection_tracker_; MediaStreamTrackMetrics track_metrics_; @@ -202,13 +185,6 @@ class CONTENT_EXPORT RTCPeerConnectionHandler // Counter for a UMA stat reported at destruction time. int num_data_channels_created_; - // |native_peer_connection_| is the libjingle native PeerConnection object. - scoped_refptr<webrtc::PeerConnectionInterface> native_peer_connection_; - - typedef std::map<webrtc::MediaStreamInterface*, - content::RemoteMediaStreamImpl*> RemoteStreamMap; - RemoteStreamMap remote_streams_; - DISALLOW_COPY_AND_ASSIGN(RTCPeerConnectionHandler); }; diff --git a/content/renderer/media/rtc_peer_connection_handler_unittest.cc b/content/renderer/media/rtc_peer_connection_handler_unittest.cc index ebcc0bf..17cf4e8 100644 --- a/content/renderer/media/rtc_peer_connection_handler_unittest.cc +++ b/content/renderer/media/rtc_peer_connection_handler_unittest.cc @@ -190,8 +190,7 @@ class RTCPeerConnectionHandlerUnderTest : public RTCPeerConnectionHandler { } MockPeerConnectionImpl* native_peer_connection() { - return static_cast<MockPeerConnectionImpl*>( - RTCPeerConnectionHandler::native_peer_connection()); + return static_cast<MockPeerConnectionImpl*>(native_peer_connection_.get()); } }; @@ -258,7 +257,8 @@ class RTCPeerConnectionHandlerTest : public ::testing::Test { local_stream.initialize(base::UTF8ToUTF16(stream_label), audio_tracks, video_tracks); local_stream.setExtraData( - new MediaStream(MediaStream::StreamStopCallback(), + new MediaStream(mock_dependency_factory_.get(), + MediaStream::StreamStopCallback(), local_stream)); return local_stream; } @@ -422,8 +422,6 @@ TEST_F(RTCPeerConnectionHandlerTest, addAndRemoveStream) { EXPECT_EQ(1u, mock_peer_connection_->local_streams()->at(0)->GetVideoTracks().size()); - EXPECT_FALSE(pc_handler_->addStream(local_stream, constraints)); - pc_handler_->removeStream(local_stream); EXPECT_EQ(0u, mock_peer_connection_->local_streams()->count()); } diff --git a/content/renderer/media/webrtc/webrtc_media_stream_adapter.cc b/content/renderer/media/webrtc/webrtc_media_stream_adapter.cc deleted file mode 100644 index 2adac1b..0000000 --- a/content/renderer/media/webrtc/webrtc_media_stream_adapter.cc +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "content/renderer/media/webrtc/webrtc_media_stream_adapter.h" - -#include "base/logging.h" -#include "content/renderer/media/media_stream_audio_source.h" -#include "content/renderer/media/media_stream_dependency_factory.h" -#include "content/renderer/media/media_stream_track.h" -#include "content/renderer/media/media_stream_video_track.h" -#include "third_party/WebKit/public/platform/WebMediaStreamSource.h" -#include "third_party/WebKit/public/platform/WebMediaStreamTrack.h" -#include "third_party/WebKit/public/platform/WebString.h" - -namespace content { - -WebRtcMediaStreamAdapter::WebRtcMediaStreamAdapter( - const blink::WebMediaStream& web_stream, - MediaStreamDependencyFactory* factory) - : web_stream_(web_stream), - factory_(factory) { - webrtc_media_stream_ = - factory_->CreateLocalMediaStream(web_stream.id().utf8()); - CreateAudioTracks(); - CreateVideoTracks(); -} - -WebRtcMediaStreamAdapter::~WebRtcMediaStreamAdapter() { -} - -void WebRtcMediaStreamAdapter::CreateAudioTracks() { - // A media stream is connected to a peer connection, enable the - // peer connection mode for the sources. - blink::WebVector<blink::WebMediaStreamTrack> audio_tracks; - web_stream_.audioTracks(audio_tracks); - for (size_t i = 0; i < audio_tracks.size(); ++i) { - MediaStreamTrack* native_track = - MediaStreamTrack::GetTrack(audio_tracks[i]); - if (!native_track || !native_track->is_local_track()) { - // We don't support connecting remote audio tracks to PeerConnection yet. - // See issue http://crbug/344303. - // TODO(xians): Remove this after we support connecting remote audio track - // to PeerConnection. - DLOG(ERROR) << "webrtc audio track can not be created with a source " - "from a remote audio track."; - NOTIMPLEMENTED(); - continue; - } - - // This is a local audio track. - const blink::WebMediaStreamSource& source = audio_tracks[i].source(); - MediaStreamAudioSource* audio_source = - static_cast<MediaStreamAudioSource*>(source.extraData()); - if (audio_source && audio_source->GetAudioCapturer()) - audio_source->GetAudioCapturer()->EnablePeerConnectionMode(); - - webrtc_media_stream_->AddTrack(native_track->GetAudioAdapter()); - } -} - -void WebRtcMediaStreamAdapter::CreateVideoTracks() { - blink::WebVector<blink::WebMediaStreamTrack> video_tracks; - web_stream_.videoTracks(video_tracks); - for (size_t i = 0; i < video_tracks.size(); ++i) { - MediaStreamVideoTrack* native_track = - MediaStreamVideoTrack::GetVideoTrack(video_tracks[i]); - webrtc_media_stream_->AddTrack(native_track->GetVideoAdapter()); - } -} - -} // namespace content diff --git a/content/renderer/media/webrtc/webrtc_media_stream_adapter.h b/content/renderer/media/webrtc/webrtc_media_stream_adapter.h deleted file mode 100644 index 69aed95..0000000 --- a/content/renderer/media/webrtc/webrtc_media_stream_adapter.h +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CONTENT_RENDERER_MEDIA_WEBRTC_WEBRTC_MEDIA_STREAM_ADAPTER_H_ -#define CONTENT_RENDERER_MEDIA_WEBRTC_WEBRTC_MEDIA_STREAM_ADAPTER_H_ - -#include "base/macros.h" -#include "base/memory/ref_counted.h" -#include "content/common/content_export.h" -#include "third_party/WebKit/public/platform/WebMediaStream.h" -#include "third_party/libjingle/source/talk/app/webrtc/mediastreaminterface.h" - -namespace content { - -class MediaStreamDependencyFactory; - -// WebRtcMediaStreamAdapter is an adapter between a blink::WebMediaStream -// object and a webrtc MediaStreams that is currently sent on a PeerConnection. -// The responsibility of the class is to create and own a representation of a -// webrtc MediaStream that can be added and removed from a RTCPeerConnection. -// An instance of WebRtcMediaStreamAdapter is created when a MediaStream is -// added to an RTCPeerConnection object -// Instances of this class is owned by the RTCPeerConnectionHandler object that -// created it. -class CONTENT_EXPORT WebRtcMediaStreamAdapter { - public: - WebRtcMediaStreamAdapter(const blink::WebMediaStream& web_stream, - MediaStreamDependencyFactory* factory); - virtual ~WebRtcMediaStreamAdapter(); - - bool IsEqual(const blink::WebMediaStream& web_stream) { - return web_stream_.extraData() == web_stream.extraData(); - } - - webrtc::MediaStreamInterface* webrtc_media_stream() { - return webrtc_media_stream_.get(); - } - - private: - void CreateAudioTracks(); - void CreateVideoTracks(); - - blink::WebMediaStream web_stream_; - - // Pointer to a MediaStreamDependencyFactory, owned by the RenderThread. - // It's valid for the lifetime of RenderThread. - MediaStreamDependencyFactory* factory_; - - scoped_refptr<webrtc::MediaStreamInterface> webrtc_media_stream_; - - DISALLOW_COPY_AND_ASSIGN (WebRtcMediaStreamAdapter); -}; - -} // namespace content - -#endif // CONTENT_RENDERER_MEDIA_WEBRTC_WEBRTC_MEDIA_STREAM_ADAPTER_H_ diff --git a/content/renderer/media/webrtc/webrtc_media_stream_adapter_unittest.cc b/content/renderer/media/webrtc/webrtc_media_stream_adapter_unittest.cc deleted file mode 100644 index 3af9c42..0000000 --- a/content/renderer/media/webrtc/webrtc_media_stream_adapter_unittest.cc +++ /dev/null @@ -1,125 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/memory/scoped_ptr.h" -#include "content/renderer/media/media_stream.h" -#include "content/renderer/media/media_stream_audio_source.h" -#include "content/renderer/media/media_stream_video_source.h" -#include "content/renderer/media/media_stream_video_track.h" -#include "content/renderer/media/mock_media_stream_dependency_factory.h" -#include "content/renderer/media/mock_media_stream_video_source.h" -#include "content/renderer/media/webrtc/webrtc_local_audio_track_adapter.h" -#include "content/renderer/media/webrtc/webrtc_media_stream_adapter.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "third_party/WebKit/public/platform/WebMediaStream.h" -#include "third_party/WebKit/public/platform/WebMediaStreamSource.h" -#include "third_party/WebKit/public/platform/WebMediaStreamTrack.h" -#include "third_party/WebKit/public/platform/WebVector.h" - -namespace content { - -class WebRtcMediaStreamAdapterTest : public ::testing::Test { - public: - virtual void SetUp() { - dependency_factory_.reset(new MockMediaStreamDependencyFactory()); - } - - blink::WebMediaStream CreateBlinkMediaStream(bool audio, bool video) { - blink::WebVector<blink::WebMediaStreamTrack> audio_track_vector( - audio ? static_cast<size_t>(1) : 0); - if (audio) { - blink::WebMediaStreamSource audio_source; - audio_source.initialize("audio", - blink::WebMediaStreamSource::TypeAudio, - "audio"); - audio_source.setExtraData(new MediaStreamAudioSource()); - - audio_track_vector[0].initialize(audio_source); - MediaStreamTrack* native_track = - new MediaStreamTrack( - WebRtcLocalAudioTrackAdapter::Create( - audio_track_vector[0].id().utf8(), NULL), - true); - audio_track_vector[0].setExtraData(native_track); - } - - blink::WebVector<blink::WebMediaStreamTrack> video_track_vector( - video ? static_cast<size_t>(1) : 0); - MediaStreamSource::SourceStoppedCallback dummy_callback; - if (video) { - blink::WebMediaStreamSource video_source; - video_source.initialize("video", - blink::WebMediaStreamSource::TypeVideo, - "video"); - MediaStreamVideoSource* native_source = - new MockMediaStreamVideoSource(dependency_factory_.get(), false); - video_source.setExtraData(native_source); - blink::WebMediaConstraints constraints; - constraints.initialize(); - video_track_vector[0] = MediaStreamVideoTrack::CreateVideoTrack( - native_source, constraints, - MediaStreamVideoSource::ConstraintsCallback(), true, - dependency_factory_.get()); - } - - blink::WebMediaStream stream_desc; - stream_desc.initialize("media stream", - audio_track_vector, - video_track_vector); - stream_desc.setExtraData( - new content::MediaStream(content::MediaStream::StreamStopCallback(), - stream_desc)); - return stream_desc; - } - - void CreateWebRtcMediaStream(const blink::WebMediaStream& blink_stream, - size_t expected_number_of_audio_tracks, - size_t expected_number_of_video_tracks) { - scoped_ptr<WebRtcMediaStreamAdapter> adapter( - new WebRtcMediaStreamAdapter(blink_stream, - dependency_factory_.get())); - - EXPECT_EQ(expected_number_of_audio_tracks, - adapter->webrtc_media_stream()->GetAudioTracks().size()); - EXPECT_EQ(expected_number_of_video_tracks, - adapter->webrtc_media_stream()->GetVideoTracks().size()); - EXPECT_EQ(blink_stream.id().utf8(), - adapter->webrtc_media_stream()->label()); - } - - protected: - scoped_ptr<MockMediaStreamDependencyFactory> dependency_factory_; -}; - -TEST_F(WebRtcMediaStreamAdapterTest, CreateWebRtcMediaStream) { - blink::WebMediaStream blink_stream = CreateBlinkMediaStream(true, true); - CreateWebRtcMediaStream(blink_stream, 1, 1); -} - -// Test that we don't crash if a MediaStream is created in Blink with an unknown -// audio sources. This can happen if a MediaStream is created with -// remote audio track. -TEST_F(WebRtcMediaStreamAdapterTest, - CreateWebRtcMediaStreamWithoutAudioSource) { - // Create a blink MediaStream description. - blink::WebMediaStreamSource audio_source; - audio_source.initialize("audio source", - blink::WebMediaStreamSource::TypeAudio, - "something"); - - blink::WebVector<blink::WebMediaStreamTrack> audio_tracks( - static_cast<size_t>(1)); - audio_tracks[0].initialize(audio_source.id(), audio_source); - blink::WebVector<blink::WebMediaStreamTrack> video_tracks( - static_cast<size_t>(0)); - - blink::WebMediaStream blink_stream; - blink_stream.initialize("new stream", audio_tracks, video_tracks); - blink_stream.setExtraData( - new content::MediaStream(content::MediaStream::StreamStopCallback(), - blink_stream)); - CreateWebRtcMediaStream(blink_stream, 0, 0); -} - -} // namespace content |