| Index: content/renderer/media/media_stream_impl.cc
|
| diff --git a/content/renderer/media/media_stream_impl.cc b/content/renderer/media/media_stream_impl.cc
|
| index e0b911f043615c5f1186b625b6b280ce30213240..a1b1504de1e5f1a20dc94acc82323d82b59b250d 100644
|
| --- a/content/renderer/media/media_stream_impl.cc
|
| +++ b/content/renderer/media/media_stream_impl.cc
|
| @@ -9,9 +9,11 @@
|
| #include "base/bind.h"
|
| #include "base/logging.h"
|
| #include "base/metrics/histogram.h"
|
| +#include "base/string_number_conversions.h"
|
| #include "base/synchronization/waitable_event.h"
|
| #include "base/utf_string_conversions.h"
|
| #include "content/renderer/media/capture_video_decoder.h"
|
| +#include "content/renderer/media/media_stream_extra_data.h"
|
| #include "content/renderer/media/media_stream_dependency_factory.h"
|
| #include "content/renderer/media/media_stream_dispatcher.h"
|
| #include "content/renderer/media/peer_connection_handler.h"
|
| @@ -55,51 +57,17 @@ static void UpdateWebRTCMethodCount(JavaScriptAPIName api_name) {
|
|
|
| static int g_next_request_id = 0;
|
|
|
| -// The MediaStreamMananger label for a stream is globally unique. The track
|
| -// session id is globally unique for the set of audio tracks and video tracks
|
| -// respectively. An audio track and a video track can have the same session id
|
| -// (without being related). Hence we create a unique track label from the stream
|
| -// label, track type and track session id:
|
| -// <MediaStreamManager-label>#{audio,video}-<session-ID>.
|
| -static std::string CreateTrackLabel(
|
| - const std::string& manager_label,
|
| - int session_id,
|
| - bool is_video) {
|
| - std::string track_label = manager_label;
|
| - if (is_video) {
|
| - track_label += "#video-";
|
| - } else {
|
| - track_label += "#audio-";
|
| - }
|
| - track_label += session_id;
|
| - return track_label;
|
| -}
|
| -
|
| -// Extracting the MediaStreamManager stream label will only work for track
|
| -// labels created by CreateTrackLabel. If is wasn't, the contents of the
|
| -// returned string is undefined.
|
| -static std::string ExtractManagerStreamLabel(
|
| - const std::string& track_label) {
|
| - std::string manager_label = track_label;
|
| - size_t pos = manager_label.rfind("#");
|
| - // If # isn't found, the string is left intact.
|
| - manager_label = manager_label.substr(0, pos);
|
| - return manager_label;
|
| -}
|
| -
|
| static void CreateWebKitSourceVector(
|
| const std::string& label,
|
| const media_stream::StreamDeviceInfoArray& devices,
|
| WebKit::WebMediaStreamSource::Type type,
|
| WebKit::WebVector<WebKit::WebMediaStreamSource>& webkit_sources) {
|
| ASSERT(devices.size() == webkit_sources.size());
|
| -
|
| for (size_t i = 0; i < devices.size(); ++i) {
|
| - std::string track_label = CreateTrackLabel(
|
| - label, devices[i].session_id,
|
| - type == WebKit::WebMediaStreamSource::TypeVideo);
|
| + std::string source_id = label + base::UintToString(
|
| + static_cast<unsigned int>(i));
|
| webkit_sources[i].initialize(
|
| - UTF8ToUTF16(track_label),
|
| + UTF8ToUTF16(source_id),
|
| type,
|
| UTF8ToUTF16(devices[i].name));
|
| }
|
| @@ -123,7 +91,6 @@ MediaStreamImpl::MediaStreamImpl(
|
| }
|
|
|
| MediaStreamImpl::~MediaStreamImpl() {
|
| - DCHECK(peer_connection_handlers_.empty());
|
| DCHECK(local_media_streams_.empty());
|
| if (dependency_factory_.get())
|
| dependency_factory_->ReleasePeerConnectionFactory();
|
| @@ -156,10 +123,7 @@ WebKit::WebPeerConnectionHandler* MediaStreamImpl::CreatePeerConnectionHandler(
|
|
|
| PeerConnectionHandler* pc_handler = new PeerConnectionHandler(
|
| client,
|
| - this,
|
| dependency_factory_.get());
|
| - peer_connection_handlers_.push_back(pc_handler);
|
| -
|
| return pc_handler;
|
| }
|
|
|
| @@ -176,61 +140,33 @@ MediaStreamImpl::CreatePeerConnectionHandlerJsep(
|
|
|
| PeerConnectionHandlerJsep* pc_handler = new PeerConnectionHandlerJsep(
|
| client,
|
| - this,
|
| dependency_factory_.get());
|
| - peer_connection_handlers_.push_back(pc_handler);
|
| -
|
| return pc_handler;
|
| }
|
|
|
| -void MediaStreamImpl::ClosePeerConnection(
|
| - PeerConnectionHandlerBase* pc_handler) {
|
| - DCHECK(CalledOnValidThread());
|
| - peer_connection_handlers_.remove(pc_handler);
|
| -}
|
| -
|
| -webrtc::LocalMediaStreamInterface* MediaStreamImpl::GetLocalMediaStream(
|
| - const WebKit::WebMediaStreamDescriptor& stream) {
|
| - // TODO(perkj): Change the mapping between a native local media stream and
|
| - // WebMediaStreamDescriptor once there is a common id.
|
| - // For now, we are forced to lookup the sources within a MediaStream.
|
| - WebKit::WebVector<WebKit::WebMediaStreamComponent> video_components;
|
| - stream.videoSources(video_components);
|
| -
|
| - std::string msm_label;
|
| - if (!video_components.isEmpty()) {
|
| - std::string source_id = UTF16ToUTF8(video_components[0].source().id());
|
| - msm_label = ExtractManagerStreamLabel(source_id);
|
| - }
|
| - // If no local video source was found, check if there is an audio source.
|
| - if (msm_label.empty()) {
|
| - WebKit::WebVector<WebKit::WebMediaStreamComponent> audio_components;
|
| - stream.audioSources(audio_components);
|
| - if (!audio_components.isEmpty()) {
|
| - std::string source_id = UTF16ToUTF8(audio_components[0].source().id());
|
| - msm_label = ExtractManagerStreamLabel(source_id);
|
| - }
|
| - }
|
| - LocalNativeStreamMap::iterator it = local_media_streams_.find(msm_label);
|
| - if (it == local_media_streams_.end())
|
| - return NULL;
|
| - return it->second.stream_.get();
|
| -}
|
| -
|
| -bool MediaStreamImpl::StopLocalMediaStream(
|
| +void MediaStreamImpl::StopLocalMediaStream(
|
| const WebKit::WebMediaStreamDescriptor& stream) {
|
| DVLOG(1) << "MediaStreamImpl::StopLocalMediaStream";
|
| - webrtc::LocalMediaStreamInterface* native_stream = GetLocalMediaStream(
|
| - stream);
|
| - if (native_stream) {
|
| - media_stream_dispatcher_->StopStream(native_stream->label());
|
| - local_media_streams_.erase(native_stream->label());
|
| - return true;
|
| +
|
| + MediaStreamExtraData* extra_data =
|
| + static_cast<MediaStreamExtraData*>(stream.extraData());
|
| + if (extra_data && extra_data->local_stream()) {
|
| + media_stream_dispatcher_->StopStream(extra_data->local_stream()->label());
|
| + local_media_streams_.erase(extra_data->local_stream()->label());
|
| } else {
|
| - return false;
|
| + NOTREACHED();
|
| }
|
| }
|
|
|
| +void MediaStreamImpl::CreateMediaStream(
|
| + WebKit::WebFrame* frame,
|
| + WebKit::WebMediaStreamDescriptor* stream) {
|
| + DVLOG(1) << "MediaStreamImpl::CreateMediaStream";
|
| + // TODO(perkj): Need to find the source from all existing local and
|
| + // remote MediaStreams.
|
| + NOTIMPLEMENTED();
|
| +}
|
| +
|
| void MediaStreamImpl::requestUserMedia(
|
| const WebKit::WebUserMediaRequest& user_media_request,
|
| const WebKit::WebVector<WebKit::WebMediaStreamSource>& audio_sources,
|
| @@ -293,28 +229,32 @@ void MediaStreamImpl::cancelUserMediaRequest(
|
| }
|
| }
|
|
|
| +WebKit::WebMediaStreamDescriptor MediaStreamImpl::GetMediaStream(
|
| + const GURL& url) {
|
| + return WebKit::WebMediaStreamRegistry::lookupMediaStreamDescriptor(url);
|
| +}
|
| +
|
| scoped_refptr<media::VideoDecoder> MediaStreamImpl::GetVideoDecoder(
|
| const GURL& url,
|
| media::MessageLoopFactory* message_loop_factory) {
|
| DCHECK(CalledOnValidThread());
|
| - WebKit::WebMediaStreamDescriptor descriptor(
|
| - WebKit::WebMediaStreamRegistry::lookupMediaStreamDescriptor(url));
|
| - if (descriptor.isNull())
|
| + WebKit::WebMediaStreamDescriptor descriptor(GetMediaStream(url));
|
| +
|
| + if (descriptor.isNull() || !descriptor.extraData())
|
| return NULL; // This is not a valid stream.
|
|
|
| - webrtc::LocalMediaStreamInterface* local_stream =
|
| - GetLocalMediaStream(descriptor);
|
| - if (local_stream)
|
| - return CreateLocalVideoDecoder(local_stream, message_loop_factory);
|
| -
|
| - PeerConnectionHandlerBase* pc_handler =
|
| - FindPeerConnectionByStream(descriptor);
|
| - if (pc_handler != NULL) {
|
| - return CreateRemoteVideoDecoder(descriptor,
|
| - pc_handler,
|
| - url,
|
| + DVLOG(1) << "MediaStreamImpl::GetVideoDecoder stream:"
|
| + << UTF16ToUTF8(descriptor.label());
|
| +
|
| + MediaStreamExtraData* extra_data =
|
| + static_cast<MediaStreamExtraData*>(descriptor.extraData());
|
| + if (extra_data->local_stream())
|
| + return CreateLocalVideoDecoder(extra_data->local_stream(),
|
| + message_loop_factory);
|
| + if (extra_data->remote_stream())
|
| + return CreateRemoteVideoDecoder(extra_data->remote_stream(), url,
|
| message_loop_factory);
|
| - }
|
| + NOTREACHED();
|
| return NULL;
|
| }
|
|
|
| @@ -344,17 +284,23 @@ void MediaStreamImpl::OnStreamGenerated(
|
| return;
|
| }
|
|
|
| - CreateNativeLocalMediaStream(label, it->second.frame_,
|
| - audio_source_vector, video_source_vector);
|
| + LocalNativeStreamPtr native_stream(CreateNativeLocalMediaStream(
|
| + label, it->second.frame_, audio_source_vector, video_source_vector));
|
|
|
| - WebKit::WebUserMediaRequest user_media_request(it->second.request_);
|
| + WebKit::WebString webkit_label = UTF8ToUTF16(label);
|
| + WebKit::WebMediaStreamDescriptor description;
|
| + description.initialize(webkit_label, audio_source_vector,
|
| + video_source_vector);
|
| + description.setExtraData(new MediaStreamExtraData(native_stream));
|
| +
|
| + CompleteGetUserMediaRequest(description, &it->second.request_);
|
| user_media_requests_.erase(it);
|
| +}
|
|
|
| - // |user_media_request| can't be mocked. So in order to test at all we check
|
| - // if it isNull.
|
| - if (!user_media_request.isNull())
|
| - user_media_request.requestSucceeded(audio_source_vector,
|
| - video_source_vector);
|
| +void MediaStreamImpl::CompleteGetUserMediaRequest(
|
| + const WebKit::WebMediaStreamDescriptor& stream,
|
| + WebKit::WebUserMediaRequest* request) {
|
| + request->requestSucceeded(stream);
|
| }
|
|
|
| void MediaStreamImpl::OnStreamGenerationFailed(int request_id) {
|
| @@ -422,7 +368,7 @@ void MediaStreamImpl::OnDeviceOpenFailed(int request_id) {
|
| void MediaStreamImpl::FrameWillClose(WebKit::WebFrame* frame) {
|
| LocalNativeStreamMap::iterator it = local_media_streams_.begin();
|
| while (it != local_media_streams_.end()) {
|
| - if (it->second.frame_ == frame) {
|
| + if (it->second == frame) {
|
| DVLOG(1) << "MediaStreamImpl::FrameWillClose: "
|
| << "Stopping stream " << it->first;
|
| media_stream_dispatcher_->StopStream(it->first);
|
| @@ -511,7 +457,7 @@ bool MediaStreamImpl::EnsurePeerConnectionFactory() {
|
| }
|
|
|
| scoped_refptr<media::VideoDecoder> MediaStreamImpl::CreateLocalVideoDecoder(
|
| - webrtc::LocalMediaStreamInterface* stream,
|
| + webrtc::MediaStreamInterface* stream,
|
| media::MessageLoopFactory* message_loop_factory) {
|
| if (!stream->video_tracks() || stream->video_tracks()->count() == 0)
|
| return NULL;
|
| @@ -525,6 +471,10 @@ scoped_refptr<media::VideoDecoder> MediaStreamImpl::CreateLocalVideoDecoder(
|
| capability.color = media::VideoCaptureCapability::kI420;
|
| capability.expected_capture_delay = 0;
|
| capability.interlaced = false;
|
| +
|
| + DVLOG(1) << "MediaStreamImpl::CreateLocalVideoDecoder video_session_id:"
|
| + << video_session_id;
|
| +
|
| return new CaptureVideoDecoder(
|
| message_loop_factory->GetMessageLoopProxy("CaptureVideoDecoderThread"),
|
| video_session_id,
|
| @@ -532,40 +482,27 @@ scoped_refptr<media::VideoDecoder> MediaStreamImpl::CreateLocalVideoDecoder(
|
| capability);
|
| }
|
|
|
| -PeerConnectionHandlerBase* MediaStreamImpl::FindPeerConnectionByStream(
|
| - const WebKit::WebMediaStreamDescriptor& stream) {
|
| - std::list<PeerConnectionHandlerBase*>::iterator it;
|
| - for (it = peer_connection_handlers_.begin();
|
| - it != peer_connection_handlers_.end(); ++it) {
|
| - if ((*it)->GetRemoteMediaStream(stream) != NULL) {
|
| - return *it;
|
| - }
|
| - }
|
| - return NULL;
|
| -}
|
| -
|
| scoped_refptr<media::VideoDecoder> MediaStreamImpl::CreateRemoteVideoDecoder(
|
| - const WebKit::WebMediaStreamDescriptor& stream,
|
| - PeerConnectionHandlerBase* pc_handler,
|
| + webrtc::MediaStreamInterface* stream,
|
| const GURL& url,
|
| media::MessageLoopFactory* message_loop_factory) {
|
| - WebKit::WebVector<WebKit::WebMediaStreamComponent> video_sources;
|
| - stream.videoSources(video_sources);
|
| - if (video_sources.isEmpty())
|
| + if (!stream->video_tracks() || stream->video_tracks()->count() == 0)
|
| return NULL;
|
|
|
| - std::string source_id = UTF16ToUTF8(video_sources[0].source().id());
|
| + DVLOG(1) << "MediaStreamImpl::CreateRemoteVideoDecoder label:"
|
| + << stream->label();
|
| +
|
| RTCVideoDecoder* rtc_video_decoder = new RTCVideoDecoder(
|
| message_loop_factory->GetMessageLoop("RtcVideoDecoderThread"),
|
| url.spec());
|
| talk_base::scoped_refptr<webrtc::VideoRendererWrapperInterface> renderer(
|
| new talk_base::RefCountedObject<VideoRendererWrapper>(rtc_video_decoder));
|
| -
|
| - pc_handler->SetRemoteVideoRenderer(source_id, renderer);
|
| + stream->video_tracks()->at(0)->SetRenderer(renderer);
|
| return rtc_video_decoder;
|
| }
|
|
|
| -void MediaStreamImpl::CreateNativeLocalMediaStream(
|
| +talk_base::scoped_refptr<webrtc::LocalMediaStreamInterface>
|
| +MediaStreamImpl::CreateNativeLocalMediaStream(
|
| const std::string& label,
|
| WebKit::WebFrame* frame,
|
| const WebKit::WebVector<WebKit::WebMediaStreamSource>& audio_sources,
|
| @@ -577,35 +514,34 @@ void MediaStreamImpl::CreateNativeLocalMediaStream(
|
| // track objects however, so we'll just have to skip that. Furthermore,
|
| // creating a peer connection later on will fail if we don't have a factory.
|
| if (!EnsurePeerConnectionFactory()) {
|
| - return;
|
| + return NULL;
|
| }
|
|
|
| - LocalMediaStreamPtr native_stream =
|
| + LocalNativeStreamPtr native_stream =
|
| dependency_factory_->CreateLocalMediaStream(label);
|
|
|
| // Add audio tracks.
|
| for (size_t i = 0; i < audio_sources.size(); ++i) {
|
| talk_base::scoped_refptr<webrtc::LocalAudioTrackInterface> audio_track(
|
| dependency_factory_->CreateLocalAudioTrack(
|
| - UTF16ToUTF8(audio_sources[i].name()), NULL));
|
| + UTF16ToUTF8(audio_sources[i].id()), NULL));
|
| native_stream->AddTrack(audio_track);
|
| }
|
|
|
| // Add video tracks.
|
| for (size_t i = 0; i < video_sources.size(); ++i) {
|
| - std::string msm_label = ExtractManagerStreamLabel(
|
| - UTF16ToUTF8(video_sources[i].id()));
|
| - if (!media_stream_dispatcher_->IsStream(msm_label)) {
|
| + if (!media_stream_dispatcher_->IsStream(label)) {
|
| continue;
|
| }
|
| int video_session_id =
|
| - media_stream_dispatcher_->video_session_id(msm_label, 0);
|
| + media_stream_dispatcher_->video_session_id(label, 0);
|
| talk_base::scoped_refptr<webrtc::LocalVideoTrackInterface> video_track(
|
| dependency_factory_->CreateLocalVideoTrack(
|
| - UTF16ToUTF8(video_sources[i].name()), video_session_id));
|
| + UTF16ToUTF8(video_sources[i].id()), video_session_id));
|
| native_stream->AddTrack(video_track);
|
| }
|
| - local_media_streams_[label] = LocalMediaStreamInfo(frame, native_stream);
|
| + local_media_streams_[label] = frame;
|
| + return native_stream;
|
| }
|
|
|
| MediaStreamImpl::VideoRendererWrapper::VideoRendererWrapper(
|
| @@ -616,5 +552,13 @@ MediaStreamImpl::VideoRendererWrapper::VideoRendererWrapper(
|
| MediaStreamImpl::VideoRendererWrapper::~VideoRendererWrapper() {
|
| }
|
|
|
| -MediaStreamImpl::LocalMediaStreamInfo::~LocalMediaStreamInfo() {
|
| +MediaStreamExtraData::MediaStreamExtraData(
|
| + webrtc::MediaStreamInterface* remote_stream)
|
| + : remote_stream_(remote_stream) {
|
| +}
|
| +MediaStreamExtraData::MediaStreamExtraData(
|
| + webrtc::LocalMediaStreamInterface* local_stream)
|
| + : local_stream_(local_stream) {
|
| +}
|
| +MediaStreamExtraData::~MediaStreamExtraData() {
|
| }
|
|
|