Index: content/renderer/media/remote_media_stream_impl.cc |
diff --git a/content/renderer/media/remote_media_stream_impl.cc b/content/renderer/media/remote_media_stream_impl.cc |
index b52625358466d9953bd57a098934964eb5df311f..6f94d1898268ef6c6b2d5f5c8dcb6cff2e1a455d 100644 |
--- a/content/renderer/media/remote_media_stream_impl.cc |
+++ b/content/renderer/media/remote_media_stream_impl.cc |
@@ -6,142 +6,280 @@ |
#include <string> |
+#include "base/bind.h" |
+#include "base/location.h" |
#include "base/logging.h" |
#include "base/strings/utf_string_conversions.h" |
+#include "base/thread_task_runner_handle.h" |
#include "content/renderer/media/media_stream.h" |
+#include "content/renderer/media/media_stream_track.h" |
#include "content/renderer/media/media_stream_video_track.h" |
#include "content/renderer/media/webrtc/media_stream_remote_video_source.h" |
#include "content/renderer/media/webrtc/peer_connection_dependency_factory.h" |
#include "third_party/WebKit/public/platform/WebString.h" |
namespace content { |
- |
namespace { |
-void InitializeWebkitTrack(webrtc::MediaStreamTrackInterface* track, |
- blink::WebMediaStreamTrack* webkit_track, |
- blink::WebMediaStreamSource::Type type) { |
- blink::WebMediaStreamSource webkit_source; |
- blink::WebString webkit_track_id(base::UTF8ToUTF16(track->id())); |
- |
- webkit_source.initialize(webkit_track_id, type, webkit_track_id); |
- webkit_track->initialize(webkit_track_id, webkit_source); |
+template <typename WebRtcTrackVector, typename AdapterType> |
+void CreateAdaptersForTracks( |
+ const WebRtcTrackVector& tracks, |
+ std::vector<scoped_refptr<AdapterType>>* observers, |
+ const scoped_refptr<base::SingleThreadTaskRunner>& main_thread) { |
+ for (auto& track : tracks) |
+ observers->push_back(new AdapterType(main_thread, track)); |
+} |
- if (type == blink::WebMediaStreamSource::TypeVideo) { |
- MediaStreamRemoteVideoSource* video_source = |
- new MediaStreamRemoteVideoSource( |
- static_cast<webrtc::VideoTrackInterface*>(track)); |
- webkit_source.setExtraData(video_source); |
- // Initial constraints must be provided to a MediaStreamVideoTrack. But |
- // no constraints are available initially on a remote video track. |
- blink::WebMediaConstraints constraints; |
- constraints.initialize(); |
- webkit_track->setExtraData( |
- new MediaStreamVideoTrack(video_source, constraints, |
- MediaStreamVideoSource::ConstraintsCallback(), |
- track->enabled())); |
- } else { |
- DCHECK(type == blink::WebMediaStreamSource::TypeAudio); |
- content::PeerConnectionDependencyFactory::AddNativeAudioTrackToBlinkTrack( |
- track, *webkit_track, false); |
+template<typename VectorType> |
+bool IsTrackInVector(const VectorType& v, const std::string& id) { |
+ for (const auto& t : v) { |
+ if (t->id() == id) |
+ return true; |
} |
+ return false; |
} |
- |
} // namespace |
+class RemoteMediaStreamTrack : public MediaStreamTrack { |
perkj_chrome
2014/10/30 12:42:35
This is only used by Remote Audio tracks it looks
tommi (sloooow) - chröme
2014/10/30 20:37:36
Renamed to RemoteMediaStreamAudioTrack.
Are you OK
|
+ public: |
+ RemoteMediaStreamTrack( |
+ const scoped_refptr<webrtc::MediaStreamTrackInterface>& track, |
+ const scoped_refptr<base::SingleThreadTaskRunner>& signaling_thread) |
+ : MediaStreamTrack(track, false), signaling_thread_(signaling_thread) { |
+ } |
+ |
+ ~RemoteMediaStreamTrack() override { |
+ } |
+ |
+ private: |
+ void SetEnabled(bool enabled) override { |
+ if (!track_.get()) |
+ return; |
+ |
+ // Due to a discrepancy in libjingle, we have to post to the signaling |
+ // thread. Usually we get a proxy object, but in the case of audio tracks, |
+ // we get a direct pointer to the object. |
+ signaling_thread_->PostTask(FROM_HERE, base::Bind( |
+ base::IgnoreResult(&webrtc::MediaStreamTrackInterface::set_enabled), |
+ track_, enabled)); |
+ } |
+ |
+ void Stop() override { |
+ // Stop means that a track should be stopped permanently. But |
+ // since there is no proper way of doing that on a remote track, we can |
+ // at least disable the track. Blink will not call down to the content layer |
+ // after a track has been stopped. |
+ SetEnabled(false); |
+ } |
+ |
+ webrtc::AudioTrackInterface* GetAudioAdapter() override { |
+ // Since the object pointed to by |track_| is not a proxy object but |
+ // actually a pointer to a single threaded object that lives on the |
+ // signaling thread, we need to make sure we're on the right thread. |
+ // However, today (Oct 2014), I'm not aware of any callers to this method |
+ // for remote audio tracks. |
+ DCHECK(signaling_thread_->BelongsToCurrentThread()); |
+ DCHECK_EQ(track_->kind(), "audio"); |
+ return static_cast<webrtc::AudioTrackInterface*>(track_.get()); |
+ } |
+ |
+ private: |
+ const scoped_refptr<base::SingleThreadTaskRunner> signaling_thread_; |
+}; |
+ |
// Base class used for mapping between webrtc and blink MediaStream tracks. |
// An instance of a RemoteMediaStreamTrackAdapter is stored in |
// RemoteMediaStreamImpl per remote audio and video track. |
-class RemoteMediaStreamTrackAdapter { |
+template<typename WebRtcMediaStreamTrackType> |
+class RemoteMediaStreamTrackAdapter |
+ : public base::RefCountedThreadSafe< |
+ RemoteMediaStreamTrackAdapter<WebRtcMediaStreamTrackType>> { |
public: |
- RemoteMediaStreamTrackAdapter(webrtc::MediaStreamTrackInterface* webrtc_track, |
- const blink::WebMediaStreamTrack& webkit_track) |
- : webrtc_track_(webrtc_track), |
- webkit_track_(webkit_track) { |
+ RemoteMediaStreamTrackAdapter( |
+ const scoped_refptr<base::SingleThreadTaskRunner>& main_thread, |
+ WebRtcMediaStreamTrackType* webrtc_track) |
+ : main_thread_(main_thread), webrtc_track_(webrtc_track), |
+ id_(webrtc_track->id()) { |
+ } |
+ |
+ const scoped_refptr<WebRtcMediaStreamTrackType>& observed_track() { |
+ return webrtc_track_; |
+ } |
+ |
+ blink::WebMediaStreamTrack* webkit_track() { |
+ DCHECK(main_thread_->BelongsToCurrentThread()); |
+ DCHECK(!webkit_track_.isNull()); |
+ return &webkit_track_; |
+ } |
+ |
+ const std::string& id() const { return id_; } |
+ |
+ bool initialized() const { |
+ DCHECK(main_thread_->BelongsToCurrentThread()); |
+ return !webkit_track_.isNull(); |
+ } |
+ |
+ void Initialize() { |
+ DCHECK(main_thread_->BelongsToCurrentThread()); |
+ DCHECK(!initialized()); |
+ webkit_initialize_.Run(); |
+ webkit_initialize_.Reset(); |
+ DCHECK(initialized()); |
} |
+ protected: |
+ friend class base::RefCountedThreadSafe< |
+ RemoteMediaStreamTrackAdapter<WebRtcMediaStreamTrackType>>; |
+ |
virtual ~RemoteMediaStreamTrackAdapter() { |
+ DCHECK(main_thread_->BelongsToCurrentThread()); |
} |
- webrtc::MediaStreamTrackInterface* observed_track() { |
- return webrtc_track_.get(); |
+ void InitializeWebkitTrack(blink::WebMediaStreamSource::Type type) { |
+ DCHECK(main_thread_->BelongsToCurrentThread()); |
+ DCHECK(webkit_track_.isNull()); |
+ |
+ blink::WebString webkit_track_id(base::UTF8ToUTF16(id_)); |
+ blink::WebMediaStreamSource webkit_source; |
+ webkit_source.initialize(webkit_track_id, type, webkit_track_id); |
+ webkit_track_.initialize(webkit_track_id, webkit_source); |
+ DCHECK(!webkit_track_.isNull()); |
} |
- const blink::WebMediaStreamTrack& webkit_track() { return webkit_track_; } |
+ const scoped_refptr<base::SingleThreadTaskRunner> main_thread_; |
+ // This callback will be run when Initialize() is called and then freed. |
+ // The callback is used by derived classes to bind objects that need to be |
+ // instantiated and initialized on the signaling thread but then moved to |
+ // and used on the main thread when initializing the webkit object(s). |
+ base::Callback<void()> webkit_initialize_; |
private: |
- scoped_refptr<webrtc::MediaStreamTrackInterface> webrtc_track_; |
+ const scoped_refptr<WebRtcMediaStreamTrackType> webrtc_track_; |
blink::WebMediaStreamTrack webkit_track_; |
+ // const copy of the webrtc track id that allows us to check it from both the |
+ // main and signaling threads without incurring a synchronous thread hop. |
+ const std::string id_; |
DISALLOW_COPY_AND_ASSIGN(RemoteMediaStreamTrackAdapter); |
}; |
-static content::RemoteMediaStreamTrackAdapter* FindTrackObserver( |
- webrtc::MediaStreamTrackInterface* track, |
- const ScopedVector<content::RemoteMediaStreamTrackAdapter>& observers) { |
- ScopedVector<content::RemoteMediaStreamTrackAdapter>::const_iterator it = |
- observers.begin(); |
- for (; it != observers.end(); ++it) { |
- if ((*it)->observed_track() == track) |
- return *it; |
+class RemoteVideoTrackAdapter |
+ : public RemoteMediaStreamTrackAdapter<webrtc::VideoTrackInterface> { |
+ public: |
+ RemoteVideoTrackAdapter( |
perkj_chrome
2014/10/30 12:42:35
Add comment here to about // Called on the signal
tommi (sloooow) - chröme
2014/10/30 20:37:35
Done.
|
+ const scoped_refptr<base::SingleThreadTaskRunner>& main_thread, |
+ webrtc::VideoTrackInterface* webrtc_track) |
+ : RemoteMediaStreamTrackAdapter(main_thread, webrtc_track) { |
+ scoped_refptr<MediaStreamRemoteVideoSource::Observer> source_observer( |
+ new MediaStreamRemoteVideoSource::Observer(main_thread, |
+ observed_track().get())); |
+ webkit_initialize_ = base::Bind( |
+ &RemoteVideoTrackAdapter::InitializeWebkitVideoTrack, |
+ this, source_observer, observed_track()->enabled()); |
} |
- return NULL; |
-} |
-// RemoteAudioMediaStreamTrackAdapter is responsible for listening on state |
+ protected: |
+ ~RemoteVideoTrackAdapter() override {} |
+ |
+ private: |
+ void InitializeWebkitVideoTrack( |
+ const scoped_refptr<MediaStreamRemoteVideoSource::Observer>& observer, |
+ bool enabled) { |
+ scoped_ptr<MediaStreamRemoteVideoSource> video_source( |
perkj_chrome
2014/10/30 12:42:35
thread check please.
This is done on the main ren
tommi (sloooow) - chröme
2014/10/30 20:37:35
Done. Yes, this is on the main render thread (we c
|
+ new MediaStreamRemoteVideoSource(observer)); |
+ InitializeWebkitTrack(blink::WebMediaStreamSource::TypeVideo); |
+ webkit_track()->source().setExtraData(video_source.get()); |
+ // Initial constraints must be provided to a MediaStreamVideoTrack. But |
+ // no constraints are available initially on a remote video track. |
+ blink::WebMediaConstraints constraints; |
+ constraints.initialize(); |
+ MediaStreamVideoTrack* media_stream_track = |
+ new MediaStreamVideoTrack(video_source.release(), constraints, |
+ MediaStreamVideoSource::ConstraintsCallback(), enabled); |
+ webkit_track()->setExtraData(media_stream_track); |
+ } |
+}; |
+ |
+// RemoteAudioTrackAdapter is responsible for listening on state |
// change notifications on a remote webrtc audio MediaStreamTracks and notify |
// WebKit. |
-class RemoteAudioMediaStreamTrackAdapter |
- : public RemoteMediaStreamTrackAdapter, |
- public webrtc::ObserverInterface, |
- public base::NonThreadSafe { |
+class RemoteAudioTrackAdapter |
+ : public RemoteMediaStreamTrackAdapter<webrtc::AudioTrackInterface>, |
+ public webrtc::ObserverInterface { |
public: |
- RemoteAudioMediaStreamTrackAdapter( |
- webrtc::MediaStreamTrackInterface* webrtc_track, |
- const blink::WebMediaStreamTrack& webkit_track); |
- ~RemoteAudioMediaStreamTrackAdapter() override; |
+ RemoteAudioTrackAdapter( |
+ const scoped_refptr<base::SingleThreadTaskRunner>& main_thread, |
+ webrtc::AudioTrackInterface* webrtc_track); |
+ |
+ protected: |
+ ~RemoteAudioTrackAdapter() override; |
private: |
+ void InitializeWebkitAudioTrack( |
+ scoped_ptr<RemoteMediaStreamTrack> media_stream_track); |
+ |
// webrtc::ObserverInterface implementation. |
void OnChanged() override; |
+ void OnChangedOnMainThread( |
+ webrtc::MediaStreamTrackInterface::TrackState state); |
+ |
webrtc::MediaStreamTrackInterface::TrackState state_; |
- DISALLOW_COPY_AND_ASSIGN(RemoteAudioMediaStreamTrackAdapter); |
+ DISALLOW_COPY_AND_ASSIGN(RemoteAudioTrackAdapter); |
}; |
-RemoteAudioMediaStreamTrackAdapter::RemoteAudioMediaStreamTrackAdapter( |
- webrtc::MediaStreamTrackInterface* webrtc_track, |
- const blink::WebMediaStreamTrack& webkit_track) |
- : RemoteMediaStreamTrackAdapter(webrtc_track, webkit_track), |
+// Called on the signaling thread. |
+RemoteAudioTrackAdapter::RemoteAudioTrackAdapter( |
+ const scoped_refptr<base::SingleThreadTaskRunner>& main_thread, |
+ webrtc::AudioTrackInterface* webrtc_track) |
+ : RemoteMediaStreamTrackAdapter(main_thread, webrtc_track), |
state_(observed_track()->state()) { |
observed_track()->RegisterObserver(this); |
+ scoped_ptr<RemoteMediaStreamTrack> media_stream_track( |
+ new RemoteMediaStreamTrack(observed_track().get(), |
+ base::ThreadTaskRunnerHandle::Get())); |
+ webkit_initialize_ = base::Bind( |
+ &RemoteAudioTrackAdapter::InitializeWebkitAudioTrack, |
+ this, base::Passed(&media_stream_track)); |
} |
-RemoteAudioMediaStreamTrackAdapter::~RemoteAudioMediaStreamTrackAdapter() { |
+RemoteAudioTrackAdapter::~RemoteAudioTrackAdapter() { |
observed_track()->UnregisterObserver(this); |
} |
-void RemoteAudioMediaStreamTrackAdapter::OnChanged() { |
- DCHECK(CalledOnValidThread()); |
+void RemoteAudioTrackAdapter::InitializeWebkitAudioTrack( |
+ scoped_ptr<RemoteMediaStreamTrack> media_stream_track) { |
+ InitializeWebkitTrack(blink::WebMediaStreamSource::TypeAudio); |
+ webkit_track()->setExtraData(media_stream_track.release()); |
+} |
+ |
+void RemoteAudioTrackAdapter::OnChanged() { |
+ main_thread_->PostTask(FROM_HERE, |
+ base::Bind(&RemoteAudioTrackAdapter::OnChangedOnMainThread, |
+ this, observed_track()->state())); |
+} |
+ |
+void RemoteAudioTrackAdapter::OnChangedOnMainThread( |
+ webrtc::MediaStreamTrackInterface::TrackState state) { |
+ DCHECK(main_thread_->BelongsToCurrentThread()); |
- webrtc::MediaStreamTrackInterface::TrackState state = |
- observed_track()->state(); |
- if (state == state_) |
+ if (state == state_ || !initialized()) |
return; |
state_ = state; |
+ |
switch (state) { |
case webrtc::MediaStreamTrackInterface::kInitializing: |
// Ignore the kInitializing state since there is no match in |
// WebMediaStreamSource::ReadyState. |
break; |
case webrtc::MediaStreamTrackInterface::kLive: |
- webkit_track().source().setReadyState( |
+ webkit_track()->source().setReadyState( |
blink::WebMediaStreamSource::ReadyStateLive); |
break; |
case webrtc::MediaStreamTrackInterface::kEnded: |
- webkit_track().source().setReadyState( |
+ webkit_track()->source().setReadyState( |
blink::WebMediaStreamSource::ReadyStateEnded); |
break; |
default: |
@@ -150,106 +288,105 @@ void RemoteAudioMediaStreamTrackAdapter::OnChanged() { |
} |
} |
+// Called on the signaling thread. |
RemoteMediaStreamImpl::RemoteMediaStreamImpl( |
+ const scoped_refptr<base::SingleThreadTaskRunner>& main_thread, |
webrtc::MediaStreamInterface* webrtc_stream) |
- : webrtc_stream_(webrtc_stream) { |
+ : main_thread_(main_thread), |
+ signaling_thread_(base::ThreadTaskRunnerHandle::Get()), |
+ webrtc_stream_(webrtc_stream) { |
webrtc_stream_->RegisterObserver(this); |
- webrtc::AudioTrackVector webrtc_audio_tracks = |
- webrtc_stream_->GetAudioTracks(); |
+ CreateAdaptersForTracks(webrtc_stream_->GetAudioTracks(), |
perkj_chrome
2014/10/30 12:42:35
I would much prefer if this and the trackadapters
tommi (sloooow) - chröme
2014/10/30 20:37:36
I think we discussed this offline and agreed to st
|
+ &audio_track_observers_, main_thread); |
+ CreateAdaptersForTracks(webrtc_stream_->GetVideoTracks(), |
+ &video_track_observers_, main_thread); |
+ |
+ main_thread_->PostTask(FROM_HERE, |
+ base::Bind(&RemoteMediaStreamImpl::InitializeOnWebKitThread, |
+ base::Unretained(this), webrtc_stream_->label())); |
+} |
+ |
+RemoteMediaStreamImpl::~RemoteMediaStreamImpl() { |
+ DCHECK(main_thread_->BelongsToCurrentThread()); |
+ webrtc_stream_->UnregisterObserver(this); |
+} |
+ |
+void RemoteMediaStreamImpl::InitializeOnWebKitThread(const std::string& label) { |
+ DCHECK(main_thread_->BelongsToCurrentThread()); |
blink::WebVector<blink::WebMediaStreamTrack> webkit_audio_tracks( |
- webrtc_audio_tracks.size()); |
- |
- // Initialize WebKit audio tracks. |
- size_t i = 0; |
- for (; i < webrtc_audio_tracks.size(); ++i) { |
- webrtc::AudioTrackInterface* audio_track = webrtc_audio_tracks[i]; |
- DCHECK(audio_track); |
- InitializeWebkitTrack(audio_track, &webkit_audio_tracks[i], |
- blink::WebMediaStreamSource::TypeAudio); |
- audio_track_observers_.push_back( |
- new RemoteAudioMediaStreamTrackAdapter(audio_track, |
- webkit_audio_tracks[i])); |
+ audio_track_observers_.size()); |
+ for (size_t i = 0; i < audio_track_observers_.size(); ++i) { |
+ audio_track_observers_[i]->Initialize(); |
+ webkit_audio_tracks[i] = *audio_track_observers_[i]->webkit_track(); |
} |
- // Initialize WebKit video tracks. |
- webrtc::VideoTrackVector webrtc_video_tracks = |
- webrtc_stream_->GetVideoTracks(); |
blink::WebVector<blink::WebMediaStreamTrack> webkit_video_tracks( |
- webrtc_video_tracks.size()); |
- for (i = 0; i < webrtc_video_tracks.size(); ++i) { |
- webrtc::VideoTrackInterface* video_track = webrtc_video_tracks[i]; |
- DCHECK(video_track); |
- InitializeWebkitTrack(video_track, &webkit_video_tracks[i], |
- blink::WebMediaStreamSource::TypeVideo); |
- video_track_observers_.push_back( |
- new RemoteMediaStreamTrackAdapter(video_track, |
- webkit_video_tracks[i])); |
+ video_track_observers_.size()); |
+ for (size_t i = 0; i < video_track_observers_.size(); ++i) { |
+ video_track_observers_[i]->Initialize(); |
+ webkit_video_tracks[i] = *video_track_observers_[i]->webkit_track(); |
} |
- webkit_stream_.initialize(base::UTF8ToUTF16(webrtc_stream->label()), |
+ webkit_stream_.initialize(base::UTF8ToUTF16(label), |
webkit_audio_tracks, webkit_video_tracks); |
- webkit_stream_.setExtraData(new MediaStream(webrtc_stream)); |
+ webkit_stream_.setExtraData(new MediaStream(webrtc_stream_.get())); |
} |
-RemoteMediaStreamImpl::~RemoteMediaStreamImpl() { |
- webrtc_stream_->UnregisterObserver(this); |
+void RemoteMediaStreamImpl::OnChanged() { |
+ scoped_ptr<RemoteAudioTrackAdapters> audio(new RemoteAudioTrackAdapters()); |
+ scoped_ptr<RemoteVideoTrackAdapters> video(new RemoteVideoTrackAdapters()); |
+ |
+ CreateAdaptersForTracks( |
+ webrtc_stream_->GetAudioTracks(), audio.get(), main_thread_); |
+ CreateAdaptersForTracks( |
+ webrtc_stream_->GetVideoTracks(), video.get(), main_thread_); |
+ |
+ // TODO(tommi): Unretained safe? |
+ main_thread_->PostTask(FROM_HERE, |
+ base::Bind(&RemoteMediaStreamImpl::OnChangedOnMainThread, |
+ base::Unretained(this), base::Passed(&audio), base::Passed(&video))); |
} |
-void RemoteMediaStreamImpl::OnChanged() { |
- // Find removed audio tracks. |
- ScopedVector<RemoteMediaStreamTrackAdapter>::iterator audio_it = |
- audio_track_observers_.begin(); |
+void RemoteMediaStreamImpl::OnChangedOnMainThread( |
+ scoped_ptr<RemoteAudioTrackAdapters> audio_tracks, |
+ scoped_ptr<RemoteVideoTrackAdapters> video_tracks) { |
+ // Find removed tracks. |
+ auto audio_it = audio_track_observers_.begin(); |
while (audio_it != audio_track_observers_.end()) { |
- std::string track_id = (*audio_it)->observed_track()->id(); |
- if (webrtc_stream_->FindAudioTrack(track_id) == NULL) { |
- webkit_stream_.removeTrack((*audio_it)->webkit_track()); |
+ if (!IsTrackInVector(*audio_tracks.get(), (*audio_it)->id())) { |
+ webkit_stream_.removeTrack(*(*audio_it)->webkit_track()); |
audio_it = audio_track_observers_.erase(audio_it); |
} else { |
++audio_it; |
} |
} |
- // Find removed video tracks. |
- ScopedVector<RemoteMediaStreamTrackAdapter>::iterator video_it = |
- video_track_observers_.begin(); |
+ auto video_it = video_track_observers_.begin(); |
while (video_it != video_track_observers_.end()) { |
- std::string track_id = (*video_it)->observed_track()->id(); |
- if (webrtc_stream_->FindVideoTrack(track_id) == NULL) { |
- webkit_stream_.removeTrack((*video_it)->webkit_track()); |
+ if (!IsTrackInVector(*video_tracks.get(), (*video_it)->id())) { |
+ webkit_stream_.removeTrack(*(*video_it)->webkit_track()); |
video_it = video_track_observers_.erase(video_it); |
} else { |
++video_it; |
} |
} |
- // Find added audio tracks. |
- webrtc::AudioTrackVector webrtc_audio_tracks = |
- webrtc_stream_->GetAudioTracks(); |
- for (webrtc::AudioTrackVector::iterator it = webrtc_audio_tracks.begin(); |
- it != webrtc_audio_tracks.end(); ++it) { |
- if (!FindTrackObserver(*it, audio_track_observers_)) { |
- blink::WebMediaStreamTrack new_track; |
- InitializeWebkitTrack(*it, &new_track, |
- blink::WebMediaStreamSource::TypeAudio); |
- audio_track_observers_.push_back( |
- new RemoteAudioMediaStreamTrackAdapter(*it, new_track)); |
- webkit_stream_.addTrack(new_track); |
+ // Find added tracks. |
+ for (const auto& track : *audio_tracks.get()) { |
+ if (!IsTrackInVector(audio_track_observers_, track->id())) { |
+ track->Initialize(); |
+ audio_track_observers_.push_back(track); |
+ webkit_stream_.addTrack(*track->webkit_track()); |
} |
} |
// Find added video tracks. |
- webrtc::VideoTrackVector webrtc_video_tracks = |
- webrtc_stream_->GetVideoTracks(); |
- for (webrtc::VideoTrackVector::iterator it = webrtc_video_tracks.begin(); |
- it != webrtc_video_tracks.end(); ++it) { |
- if (!FindTrackObserver(*it, video_track_observers_)) { |
- blink::WebMediaStreamTrack new_track; |
- InitializeWebkitTrack(*it, &new_track, |
- blink::WebMediaStreamSource::TypeVideo); |
- video_track_observers_.push_back( |
- new RemoteMediaStreamTrackAdapter(*it, new_track)); |
- webkit_stream_.addTrack(new_track); |
+ for (const auto& track : *video_tracks.get()) { |
+ if (!IsTrackInVector(video_track_observers_, track->id())) { |
+ track->Initialize(); |
+ video_track_observers_.push_back(track); |
+ webkit_stream_.addTrack(*track->webkit_track()); |
} |
} |
} |