Index: content/renderer/media/webrtc/webrtc_media_stream_track_adapter.cc |
diff --git a/content/renderer/media/webrtc/webrtc_media_stream_track_adapter.cc b/content/renderer/media/webrtc/webrtc_media_stream_track_adapter.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..64129a221d363315b64d558fa6816e4991c50dce |
--- /dev/null |
+++ b/content/renderer/media/webrtc/webrtc_media_stream_track_adapter.cc |
@@ -0,0 +1,287 @@ |
+// Copyright (c) 2017 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_track_adapter.h" |
+ |
+#include "content/renderer/media/media_stream_audio_track.h" |
+#include "content/renderer/media/webrtc/media_stream_video_webrtc_sink.h" |
+#include "content/renderer/media/webrtc/peer_connection_dependency_factory.h" |
+#include "content/renderer/media/webrtc/processed_local_audio_source.h" |
+ |
+namespace content { |
+ |
+// static |
+scoped_refptr<WebRtcMediaStreamTrackAdapter> |
+WebRtcMediaStreamTrackAdapter::CreateLocalTrackAdapter( |
+ PeerConnectionDependencyFactory* factory, |
+ const scoped_refptr<base::SingleThreadTaskRunner>& main_thread, |
+ const blink::WebMediaStreamTrack& web_track) { |
+ DCHECK(main_thread->BelongsToCurrentThread()); |
+ DCHECK(!web_track.Source().Remote()); |
+ scoped_refptr<WebRtcMediaStreamTrackAdapter> local_track_adapter( |
+ new WebRtcMediaStreamTrackAdapter(factory, main_thread)); |
+ if (web_track.Source().GetType() == blink::WebMediaStreamSource::kTypeAudio) { |
+ local_track_adapter->InitializeLocalAudioTrack(web_track); |
+ } else { |
+ DCHECK_EQ(web_track.Source().GetType(), |
+ blink::WebMediaStreamSource::kTypeVideo); |
+ local_track_adapter->InitializeLocalVideoTrack(web_track); |
+ } |
+ return local_track_adapter; |
+} |
+ |
+// static |
+scoped_refptr<WebRtcMediaStreamTrackAdapter> |
+WebRtcMediaStreamTrackAdapter::CreateRemoteTrackAdapter( |
+ PeerConnectionDependencyFactory* factory, |
+ const scoped_refptr<base::SingleThreadTaskRunner>& main_thread, |
+ webrtc::MediaStreamTrackInterface* webrtc_track) { |
+ DCHECK(factory->GetWebRtcSignalingThread()->BelongsToCurrentThread()); |
+ DCHECK(webrtc_track); |
+ scoped_refptr<WebRtcMediaStreamTrackAdapter> remote_track_adapter( |
+ new WebRtcMediaStreamTrackAdapter(factory, main_thread)); |
+ if (webrtc_track->kind() == webrtc::MediaStreamTrackInterface::kAudioKind) { |
+ remote_track_adapter->InitializeRemoteAudioTrack( |
+ static_cast<webrtc::AudioTrackInterface*>(webrtc_track)); |
+ } else { |
+ DCHECK_EQ(webrtc_track->kind(), |
+ webrtc::MediaStreamTrackInterface::kVideoKind); |
+ remote_track_adapter->InitializeRemoteVideoTrack( |
+ static_cast<webrtc::VideoTrackInterface*>(webrtc_track)); |
+ } |
+ return remote_track_adapter; |
+} |
+ |
+WebRtcMediaStreamTrackAdapter::WebRtcMediaStreamTrackAdapter( |
+ PeerConnectionDependencyFactory* factory, |
+ const scoped_refptr<base::SingleThreadTaskRunner>& main_thread) |
+ : factory_(factory), main_thread_(main_thread), is_initialized_(false) { |
+ DCHECK(factory_); |
+ DCHECK(main_thread_); |
+} |
+ |
+WebRtcMediaStreamTrackAdapter::~WebRtcMediaStreamTrackAdapter() { |
+ DCHECK(main_thread_->BelongsToCurrentThread()); |
+ DCHECK(!is_initialized_); |
+} |
+ |
+void WebRtcMediaStreamTrackAdapter::Dispose() { |
+ DCHECK(main_thread_->BelongsToCurrentThread()); |
+ if (!is_initialized_) |
+ return; |
+ is_initialized_ = false; |
+ if (!web_track_.Source().Remote()) { |
+ if (web_track_.Source().GetType() == |
+ blink::WebMediaStreamSource::kTypeAudio) { |
+ DisposeLocalAudioTrack(); |
+ } else { |
+ DCHECK_EQ(web_track_.Source().GetType(), |
+ blink::WebMediaStreamSource::kTypeVideo); |
+ DisposeLocalVideoTrack(); |
+ } |
+ } else { |
+ if (web_track_.Source().GetType() == |
+ blink::WebMediaStreamSource::kTypeAudio) { |
+ DisposeRemoteAudioTrack(); |
+ } else { |
+ DCHECK_EQ(web_track_.Source().GetType(), |
+ blink::WebMediaStreamSource::kTypeVideo); |
+ DisposeRemoteVideoTrack(); |
+ } |
+ } |
+} |
+ |
+bool WebRtcMediaStreamTrackAdapter::is_initialized() const { |
+ return is_initialized_; |
+} |
+ |
+const blink::WebMediaStreamTrack& WebRtcMediaStreamTrackAdapter::web_track() |
+ const { |
+ DCHECK(is_initialized_); |
+ DCHECK(!web_track_.IsNull()); |
+ return web_track_; |
+} |
+ |
+webrtc::MediaStreamTrackInterface* WebRtcMediaStreamTrackAdapter::webrtc_track() |
+ const { |
+ DCHECK(is_initialized_); |
+ DCHECK(webrtc_track_); |
+ return webrtc_track_.get(); |
+} |
+ |
+bool WebRtcMediaStreamTrackAdapter::IsEqual( |
+ const blink::WebMediaStreamTrack& web_track) const { |
+ DCHECK(is_initialized_); |
+ return web_track_.GetTrackData() == web_track.GetTrackData(); |
+} |
+ |
+void WebRtcMediaStreamTrackAdapter::InitializeLocalAudioTrack( |
+ const blink::WebMediaStreamTrack& web_track) { |
+ DCHECK(main_thread_->BelongsToCurrentThread()); |
+ DCHECK(!is_initialized_); |
+ DCHECK(!web_track.IsNull()); |
+ DCHECK(!web_track.Source().Remote()); |
+ DCHECK_EQ(web_track.Source().GetType(), |
+ blink::WebMediaStreamSource::kTypeAudio); |
+ web_track_ = web_track; |
+ MediaStreamAudioTrack* native_track = MediaStreamAudioTrack::From(web_track_); |
+ DCHECK(native_track); |
+ |
+ // Non-WebRtc remote sources and local sources do not provide an instance of |
+ // the webrtc::AudioSourceInterface, and also do not need references to the |
+ // audio level calculator or audio processor passed to the sink. |
+ webrtc::AudioSourceInterface* source_interface = nullptr; |
+ local_track_audio_sink_.reset( |
+ new WebRtcAudioSink(web_track_.Id().Utf8(), source_interface, |
+ factory_->GetWebRtcSignalingThread())); |
+ |
+ if (auto* media_stream_source = ProcessedLocalAudioSource::From( |
+ MediaStreamAudioSource::From(web_track_.Source()))) { |
+ local_track_audio_sink_->SetLevel(media_stream_source->audio_level()); |
+ // The sink only grabs stats from the audio processor. Stats are only |
+ // available if audio processing is turned on. Therefore, only provide the |
+ // sink a reference to the processor if audio processing is turned on. |
+ if (auto processor = media_stream_source->audio_processor()) { |
+ if (processor->has_audio_processing()) |
+ local_track_audio_sink_->SetAudioProcessor(processor); |
+ } |
+ } |
+ native_track->AddSink(local_track_audio_sink_.get()); |
+ webrtc_track_ = local_track_audio_sink_->webrtc_audio_track(); |
+ DCHECK(webrtc_track_); |
+ is_initialized_ = true; |
+} |
+ |
+void WebRtcMediaStreamTrackAdapter::InitializeLocalVideoTrack( |
+ const blink::WebMediaStreamTrack& web_track) { |
+ DCHECK(main_thread_->BelongsToCurrentThread()); |
+ DCHECK(!is_initialized_); |
+ DCHECK(!web_track.IsNull()); |
+ DCHECK(!web_track.Source().Remote()); |
+ DCHECK_EQ(web_track.Source().GetType(), |
+ blink::WebMediaStreamSource::kTypeVideo); |
+ web_track_ = web_track; |
+ local_track_video_sink_.reset( |
+ new MediaStreamVideoWebRtcSink(web_track_, factory_)); |
+ webrtc_track_ = local_track_video_sink_->webrtc_video_track(); |
+ DCHECK(webrtc_track_); |
+ is_initialized_ = true; |
+} |
+ |
+void WebRtcMediaStreamTrackAdapter::InitializeRemoteAudioTrack( |
+ webrtc::AudioTrackInterface* webrtc_audio_track) { |
+ DCHECK(factory_->GetWebRtcSignalingThread()->BelongsToCurrentThread()); |
+ DCHECK(!is_initialized_); |
+ DCHECK(webrtc_audio_track); |
+ DCHECK_EQ(webrtc_audio_track->kind(), |
+ webrtc::MediaStreamTrackInterface::kAudioKind); |
+ remote_audio_track_adapter_ = |
+ new RemoteAudioTrackAdapter(main_thread_, webrtc_audio_track); |
+ webrtc_track_ = webrtc_audio_track; |
+ main_thread_->PostTask( |
+ FROM_HERE, base::Bind(&WebRtcMediaStreamTrackAdapter:: |
+ FinalizeRemoteTrackInitializationOnMainThread, |
+ this)); |
+} |
+ |
+void WebRtcMediaStreamTrackAdapter::InitializeRemoteVideoTrack( |
+ webrtc::VideoTrackInterface* webrtc_video_track) { |
+ DCHECK(factory_->GetWebRtcSignalingThread()->BelongsToCurrentThread()); |
+ DCHECK(!is_initialized_); |
+ DCHECK(webrtc_video_track); |
+ DCHECK_EQ(webrtc_video_track->kind(), |
+ webrtc::MediaStreamTrackInterface::kVideoKind); |
+ remote_video_track_adapter_ = |
+ new RemoteVideoTrackAdapter(main_thread_, webrtc_video_track); |
+ webrtc_track_ = webrtc_video_track; |
+ main_thread_->PostTask( |
+ FROM_HERE, base::Bind(&WebRtcMediaStreamTrackAdapter:: |
+ FinalizeRemoteTrackInitializationOnMainThread, |
+ this)); |
+} |
+ |
+void WebRtcMediaStreamTrackAdapter:: |
+ FinalizeRemoteTrackInitializationOnMainThread() { |
+ DCHECK(main_thread_->BelongsToCurrentThread()); |
+ DCHECK(remote_audio_track_adapter_ || remote_video_track_adapter_); |
+ if (remote_audio_track_adapter_) { |
+ remote_audio_track_adapter_->Initialize(); |
+ web_track_ = *remote_audio_track_adapter_->web_track(); |
+ } else { |
+ remote_video_track_adapter_->Initialize(); |
+ web_track_ = *remote_video_track_adapter_->web_track(); |
+ } |
+ is_initialized_ = true; |
+} |
+ |
+void WebRtcMediaStreamTrackAdapter::DisposeLocalAudioTrack() { |
+ DCHECK(main_thread_->BelongsToCurrentThread()); |
+ DCHECK(!is_initialized_); |
+ DCHECK(!web_track_.Source().Remote()); |
+ DCHECK_EQ(web_track_.Source().GetType(), |
+ blink::WebMediaStreamSource::kTypeAudio); |
+ MediaStreamAudioTrack* audio_track = MediaStreamAudioTrack::From(web_track_); |
+ DCHECK(audio_track); |
+ DCHECK(local_track_audio_sink_); |
+ audio_track->RemoveSink(local_track_audio_sink_.get()); |
+ local_track_audio_sink_.reset(); |
+ webrtc_track_ = nullptr; |
+ web_track_.Reset(); |
+} |
+ |
+void WebRtcMediaStreamTrackAdapter::DisposeLocalVideoTrack() { |
+ DCHECK(main_thread_->BelongsToCurrentThread()); |
+ DCHECK(!is_initialized_); |
+ DCHECK(!web_track_.Source().Remote()); |
+ DCHECK_EQ(web_track_.Source().GetType(), |
+ blink::WebMediaStreamSource::kTypeVideo); |
+ local_track_video_sink_.reset(); |
+ webrtc_track_ = nullptr; |
+ web_track_.Reset(); |
+} |
+ |
+void WebRtcMediaStreamTrackAdapter::DisposeRemoteAudioTrack() { |
+ DCHECK(main_thread_->BelongsToCurrentThread()); |
+ DCHECK(!is_initialized_); |
+ DCHECK(web_track_.Source().Remote()); |
+ DCHECK_EQ(web_track_.Source().GetType(), |
+ blink::WebMediaStreamSource::kTypeAudio); |
+ factory_->GetWebRtcSignalingThread()->PostTask( |
+ FROM_HERE, |
+ base::Bind(&WebRtcMediaStreamTrackAdapter:: |
+ UnregisterRemoteAudioTrackAdapterOnSignalingThread, |
+ this)); |
+} |
+ |
+void WebRtcMediaStreamTrackAdapter::DisposeRemoteVideoTrack() { |
+ DCHECK(main_thread_->BelongsToCurrentThread()); |
+ DCHECK(!is_initialized_); |
+ DCHECK(web_track_.Source().Remote()); |
+ DCHECK_EQ(web_track_.Source().GetType(), |
+ blink::WebMediaStreamSource::kTypeVideo); |
+ FinalizeRemoteTrackDisposingOnMainThread(); |
+} |
+ |
+void WebRtcMediaStreamTrackAdapter:: |
+ UnregisterRemoteAudioTrackAdapterOnSignalingThread() { |
+ DCHECK(factory_->GetWebRtcSignalingThread()->BelongsToCurrentThread()); |
+ DCHECK(!is_initialized_); |
+ DCHECK(remote_audio_track_adapter_); |
+ remote_audio_track_adapter_->Unregister(); |
+ main_thread_->PostTask( |
+ FROM_HERE, base::Bind(&WebRtcMediaStreamTrackAdapter:: |
+ FinalizeRemoteTrackDisposingOnMainThread, |
+ this)); |
+} |
+ |
+void WebRtcMediaStreamTrackAdapter::FinalizeRemoteTrackDisposingOnMainThread() { |
+ DCHECK(main_thread_->BelongsToCurrentThread()); |
+ DCHECK(!is_initialized_); |
+ remote_audio_track_adapter_ = nullptr; |
+ remote_video_track_adapter_ = nullptr; |
+ webrtc_track_ = nullptr; |
+ web_track_.Reset(); |
+} |
+ |
+} // namespace content |