| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 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/renderer/media/webrtc/webrtc_media_stream_adapter.h" | 5 #include "content/renderer/media/webrtc/webrtc_media_stream_adapter.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "content/renderer/media/media_stream_audio_source.h" |
| 8 #include "content/renderer/media/media_stream_audio_track.h" | 9 #include "content/renderer/media/media_stream_audio_track.h" |
| 9 #include "content/renderer/media/media_stream_track.h" | 10 #include "content/renderer/media/media_stream_track.h" |
| 10 #include "content/renderer/media/webrtc/media_stream_video_webrtc_sink.h" | 11 #include "content/renderer/media/webrtc/media_stream_video_webrtc_sink.h" |
| 11 #include "content/renderer/media/webrtc/peer_connection_dependency_factory.h" | 12 #include "content/renderer/media/webrtc/peer_connection_dependency_factory.h" |
| 12 #include "content/renderer/media/webrtc/processed_local_audio_source.h" | |
| 13 #include "content/renderer/media/webrtc/webrtc_audio_sink.h" | |
| 14 #include "third_party/WebKit/public/platform/WebMediaStreamSource.h" | 13 #include "third_party/WebKit/public/platform/WebMediaStreamSource.h" |
| 15 #include "third_party/WebKit/public/platform/WebMediaStreamTrack.h" | 14 #include "third_party/WebKit/public/platform/WebMediaStreamTrack.h" |
| 16 #include "third_party/WebKit/public/platform/WebString.h" | 15 #include "third_party/WebKit/public/platform/WebString.h" |
| 17 | 16 |
| 18 namespace content { | 17 namespace content { |
| 19 | 18 |
| 20 WebRtcMediaStreamAdapter::WebRtcMediaStreamAdapter( | 19 WebRtcMediaStreamAdapter::WebRtcMediaStreamAdapter( |
| 21 const blink::WebMediaStream& web_stream, | 20 const blink::WebMediaStream& web_stream, |
| 22 PeerConnectionDependencyFactory* factory) | 21 PeerConnectionDependencyFactory* factory) |
| 23 : web_stream_(web_stream), | 22 : web_stream_(web_stream), |
| 24 factory_(factory) { | 23 factory_(factory) { |
| 25 webrtc_media_stream_ = | 24 webrtc_media_stream_ = |
| 26 factory_->CreateLocalMediaStream(web_stream.id().utf8()); | 25 factory_->CreateLocalMediaStream(web_stream.id().utf8()); |
| 27 | 26 |
| 28 blink::WebVector<blink::WebMediaStreamTrack> audio_tracks; | 27 blink::WebVector<blink::WebMediaStreamTrack> audio_tracks; |
| 29 web_stream_.audioTracks(audio_tracks); | 28 web_stream_.audioTracks(audio_tracks); |
| 30 for (blink::WebMediaStreamTrack& audio_track : audio_tracks) | 29 for (blink::WebMediaStreamTrack& audio_track : audio_tracks) |
| 31 AddAudioSinkToTrack(audio_track); | 30 CreateAudioTrack(audio_track); |
| 32 | 31 |
| 33 blink::WebVector<blink::WebMediaStreamTrack> video_tracks; | 32 blink::WebVector<blink::WebMediaStreamTrack> video_tracks; |
| 34 web_stream_.videoTracks(video_tracks); | 33 web_stream_.videoTracks(video_tracks); |
| 35 for (blink::WebMediaStreamTrack& video_track : video_tracks) | 34 for (blink::WebMediaStreamTrack& video_track : video_tracks) |
| 36 AddVideoSinkToTrack(video_track); | 35 CreateVideoTrack(video_track); |
| 37 | 36 |
| 38 MediaStream* const native_stream = MediaStream::GetMediaStream(web_stream_); | 37 MediaStream* const native_stream = MediaStream::GetMediaStream(web_stream_); |
| 39 native_stream->AddObserver(this); | 38 native_stream->AddObserver(this); |
| 40 } | 39 } |
| 41 | 40 |
| 42 WebRtcMediaStreamAdapter::~WebRtcMediaStreamAdapter() { | 41 WebRtcMediaStreamAdapter::~WebRtcMediaStreamAdapter() { |
| 43 MediaStream* const native_stream = MediaStream::GetMediaStream(web_stream_); | 42 MediaStream* const native_stream = MediaStream::GetMediaStream(web_stream_); |
| 44 native_stream->RemoveObserver(this); | 43 native_stream->RemoveObserver(this); |
| 45 | |
| 46 blink::WebVector<blink::WebMediaStreamTrack> audio_tracks; | |
| 47 web_stream_.audioTracks(audio_tracks); | |
| 48 for (blink::WebMediaStreamTrack& audio_track : audio_tracks) | |
| 49 TrackRemoved(audio_track); | |
| 50 DCHECK(audio_sinks_.empty()); | |
| 51 blink::WebVector<blink::WebMediaStreamTrack> video_tracks; | |
| 52 web_stream_.videoTracks(video_tracks); | |
| 53 for (blink::WebMediaStreamTrack& video_track : video_tracks) | |
| 54 TrackRemoved(video_track); | |
| 55 DCHECK(video_sinks_.empty()); | |
| 56 } | 44 } |
| 57 | 45 |
| 58 void WebRtcMediaStreamAdapter::TrackAdded( | 46 void WebRtcMediaStreamAdapter::TrackAdded( |
| 59 const blink::WebMediaStreamTrack& track) { | 47 const blink::WebMediaStreamTrack& track) { |
| 60 if (track.source().getType() == blink::WebMediaStreamSource::TypeAudio) | 48 if (track.source().getType() == blink::WebMediaStreamSource::TypeAudio) |
| 61 AddAudioSinkToTrack(track); | 49 CreateAudioTrack(track); |
| 62 else | 50 else |
| 63 AddVideoSinkToTrack(track); | 51 CreateVideoTrack(track); |
| 64 } | 52 } |
| 65 | 53 |
| 66 void WebRtcMediaStreamAdapter::TrackRemoved( | 54 void WebRtcMediaStreamAdapter::TrackRemoved( |
| 67 const blink::WebMediaStreamTrack& track) { | 55 const blink::WebMediaStreamTrack& track) { |
| 68 const std::string track_id = track.id().utf8(); | 56 const std::string track_id = track.id().utf8(); |
| 69 if (track.source().getType() == blink::WebMediaStreamSource::TypeAudio) { | 57 if (track.source().getType() == blink::WebMediaStreamSource::TypeAudio) { |
| 70 scoped_refptr<webrtc::AudioTrackInterface> webrtc_track = | 58 webrtc_media_stream_->RemoveTrack( |
| 71 make_scoped_refptr( | 59 webrtc_media_stream_->FindAudioTrack(track_id)); |
| 72 webrtc_media_stream_->FindAudioTrack(track_id).get()); | |
| 73 if (!webrtc_track) | |
| 74 return; | |
| 75 webrtc_media_stream_->RemoveTrack(webrtc_track.get()); | |
| 76 | |
| 77 for (auto it = audio_sinks_.begin(); it != audio_sinks_.end(); ++it) { | |
| 78 if ((*it)->webrtc_audio_track() == webrtc_track.get()) { | |
| 79 if (auto* media_stream_track = MediaStreamAudioTrack::From(track)) | |
| 80 media_stream_track->RemoveSink(it->get()); | |
| 81 audio_sinks_.erase(it); | |
| 82 break; | |
| 83 } | |
| 84 } | |
| 85 } else { | 60 } else { |
| 86 DCHECK_EQ(track.source().getType(), blink::WebMediaStreamSource::TypeVideo); | 61 DCHECK_EQ(track.source().getType(), blink::WebMediaStreamSource::TypeVideo); |
| 87 scoped_refptr<webrtc::VideoTrackInterface> webrtc_track = | 62 scoped_refptr<webrtc::VideoTrackInterface> webrtc_track = |
| 88 make_scoped_refptr( | 63 webrtc_media_stream_->FindVideoTrack(track_id).get(); |
| 89 webrtc_media_stream_->FindVideoTrack(track_id).get()); | |
| 90 if (!webrtc_track) | |
| 91 return; | |
| 92 webrtc_media_stream_->RemoveTrack(webrtc_track.get()); | 64 webrtc_media_stream_->RemoveTrack(webrtc_track.get()); |
| 93 | 65 |
| 94 for (auto it = video_sinks_.begin(); it != video_sinks_.end(); ++it) { | 66 for (ScopedVector<MediaStreamVideoWebRtcSink>::iterator it = |
| 67 video_adapters_.begin(); it != video_adapters_.end(); ++it) { |
| 95 if ((*it)->webrtc_video_track() == webrtc_track.get()) { | 68 if ((*it)->webrtc_video_track() == webrtc_track.get()) { |
| 96 video_sinks_.erase(it); | 69 video_adapters_.erase(it); |
| 97 break; | 70 break; |
| 98 } | 71 } |
| 99 } | 72 } |
| 100 } | 73 } |
| 101 } | 74 } |
| 102 | 75 |
| 103 void WebRtcMediaStreamAdapter::AddAudioSinkToTrack( | 76 void WebRtcMediaStreamAdapter::CreateAudioTrack( |
| 104 const blink::WebMediaStreamTrack& track) { | 77 const blink::WebMediaStreamTrack& track) { |
| 78 DCHECK_EQ(track.source().getType(), blink::WebMediaStreamSource::TypeAudio); |
| 79 // A media stream is connected to a peer connection, enable the |
| 80 // peer connection mode for the sources. |
| 105 MediaStreamAudioTrack* native_track = MediaStreamAudioTrack::From(track); | 81 MediaStreamAudioTrack* native_track = MediaStreamAudioTrack::From(track); |
| 106 if (!native_track) { | 82 if (!native_track) { |
| 107 DLOG(ERROR) << "No native track for blink audio track."; | 83 DLOG(ERROR) << "No native track for blink audio track."; |
| 108 return; | 84 return; |
| 109 } | 85 } |
| 110 | 86 |
| 111 WebRtcAudioSink* audio_sink; | 87 webrtc::AudioTrackInterface* audio_track = native_track->GetAudioAdapter(); |
| 112 if (auto* media_stream_source = ProcessedLocalAudioSource::From( | 88 if (!audio_track) { |
| 113 MediaStreamAudioSource::From(track.source()))) { | 89 DLOG(ERROR) << "Audio track doesn't support webrtc."; |
| 114 audio_sink = new WebRtcAudioSink( | 90 return; |
| 115 track.id().utf8(), media_stream_source->rtc_source(), | |
| 116 factory_->GetWebRtcSignalingThread()); | |
| 117 audio_sink->SetLevel(media_stream_source->audio_level()); | |
| 118 // The sink only grabs stats from the audio processor. Stats are only | |
| 119 // available if audio processing is turned on. Therefore, only provide the | |
| 120 // sink a reference to the processor if audio processing is turned on. | |
| 121 if (auto processor = media_stream_source->audio_processor()) { | |
| 122 if (processor && processor->has_audio_processing()) | |
| 123 audio_sink->SetAudioProcessor(processor); | |
| 124 } | |
| 125 } else { | |
| 126 // Remote sources and other non-WebRtc local sources do not provide an | |
| 127 // instance of the webrtc::AudioSourceInterface, and also do not need | |
| 128 // references to the audio level calculator or audio processor passed to the | |
| 129 // sink. | |
| 130 webrtc::AudioSourceInterface* source_interface = nullptr; | |
| 131 audio_sink = new WebRtcAudioSink( | |
| 132 track.id().utf8(), source_interface, | |
| 133 factory_->GetWebRtcSignalingThread()); | |
| 134 } | 91 } |
| 135 | 92 |
| 136 audio_sinks_.push_back(std::unique_ptr<WebRtcAudioSink>(audio_sink)); | 93 if (native_track->is_local_track()) { |
| 137 native_track->AddSink(audio_sink); | 94 const blink::WebMediaStreamSource& source = track.source(); |
| 138 webrtc_media_stream_->AddTrack(audio_sink->webrtc_audio_track()); | 95 MediaStreamAudioSource* audio_source = MediaStreamAudioSource::From(source); |
| 96 if (audio_source && audio_source->audio_capturer()) |
| 97 audio_source->audio_capturer()->EnablePeerConnectionMode(); |
| 98 } |
| 99 |
| 100 webrtc_media_stream_->AddTrack(audio_track); |
| 139 } | 101 } |
| 140 | 102 |
| 141 void WebRtcMediaStreamAdapter::AddVideoSinkToTrack( | 103 void WebRtcMediaStreamAdapter::CreateVideoTrack( |
| 142 const blink::WebMediaStreamTrack& track) { | 104 const blink::WebMediaStreamTrack& track) { |
| 143 DCHECK_EQ(track.source().getType(), blink::WebMediaStreamSource::TypeVideo); | 105 DCHECK_EQ(track.source().getType(), blink::WebMediaStreamSource::TypeVideo); |
| 144 MediaStreamVideoWebRtcSink* video_sink = | 106 MediaStreamVideoWebRtcSink* adapter = |
| 145 new MediaStreamVideoWebRtcSink(track, factory_); | 107 new MediaStreamVideoWebRtcSink(track, factory_); |
| 146 video_sinks_.push_back( | 108 video_adapters_.push_back(adapter); |
| 147 std::unique_ptr<MediaStreamVideoWebRtcSink>(video_sink)); | 109 webrtc_media_stream_->AddTrack(adapter->webrtc_video_track()); |
| 148 webrtc_media_stream_->AddTrack(video_sink->webrtc_video_track()); | |
| 149 } | 110 } |
| 150 | 111 |
| 151 } // namespace content | 112 } // namespace content |
| OLD | NEW |