Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(226)

Side by Side Diff: content/renderer/media/remote_media_stream_impl.cc

Issue 2902733003: RemoteMediaStreamImpl using WebRtcMediaStreamTrackMap. (Closed)
Patch Set: Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 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/remote_media_stream_impl.h" 5 #include "content/renderer/media/remote_media_stream_impl.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <string> 8 #include <string>
9 #include <utility> 9 #include <utility>
10 #include <vector> 10 #include <vector>
11 11
12 #include "base/bind.h" 12 #include "base/bind.h"
13 #include "base/location.h" 13 #include "base/location.h"
14 #include "base/logging.h" 14 #include "base/logging.h"
15 #include "base/macros.h" 15 #include "base/macros.h"
16 #include "base/threading/thread_task_runner_handle.h" 16 #include "base/threading/thread_task_runner_handle.h"
17 #include "content/renderer/media/media_stream.h" 17 #include "content/renderer/media/media_stream.h"
18 #include "content/renderer/media/media_stream_track.h" 18 #include "content/renderer/media/media_stream_track.h"
19 #include "content/renderer/media/media_stream_video_track.h" 19 #include "content/renderer/media/media_stream_video_track.h"
20 #include "content/renderer/media/remote_media_stream_track_adapter.h" 20 #include "content/renderer/media/remote_media_stream_track_adapter.h"
21 #include "content/renderer/media/webrtc/media_stream_remote_video_source.h" 21 #include "content/renderer/media/webrtc/media_stream_remote_video_source.h"
22 #include "third_party/WebKit/public/platform/WebMediaStreamTrack.h" 22 #include "third_party/WebKit/public/platform/WebMediaStreamTrack.h"
23 #include "third_party/WebKit/public/platform/WebString.h" 23 #include "third_party/WebKit/public/platform/WebString.h"
24 24
25 namespace content { 25 namespace content {
26
26 namespace { 27 namespace {
27 28
28 template <typename WebRtcTrackVector, typename AdapterType> 29 // Gets the adapters for the tracks that are members of the webrtc stream.
29 void CreateAdaptersForTracks( 30 // Invoke on webrtc signaling thread. New adapters are initialized in a post
30 const WebRtcTrackVector& tracks, 31 // to the main thread after which their |web_track| becomes available.
31 std::vector<scoped_refptr<AdapterType>>* observers, 32 RemoteMediaStreamImpl::AdapterRefMap GetAdapterRefMapFromWebRtcStream(
32 const scoped_refptr<base::SingleThreadTaskRunner>& main_thread) { 33 const scoped_refptr<WebRtcMediaStreamTrackAdapterMap>& track_adapter_map,
33 for (auto& track : tracks) 34 webrtc::MediaStreamInterface* webrtc_stream) {
34 observers->push_back(new AdapterType(main_thread, track)); 35 RemoteMediaStreamImpl::AdapterRefMap adapter_refs;
36 for (auto& webrtc_audio_track : webrtc_stream->GetAudioTracks()) {
37 adapter_refs.insert(
38 std::make_pair(webrtc_audio_track->id(),
39 track_adapter_map->GetOrCreateRemoteTrackAdapter(
40 webrtc_audio_track.get())));
41 }
42 for (auto& webrtc_video_track : webrtc_stream->GetVideoTracks()) {
43 adapter_refs.insert(
44 std::make_pair(webrtc_video_track->id(),
45 track_adapter_map->GetOrCreateRemoteTrackAdapter(
46 webrtc_video_track.get())));
47 }
48 return adapter_refs;
35 } 49 }
36 50
37 template<typename VectorType>
38 bool IsTrackInVector(const VectorType& v, const std::string& id) {
39 for (const auto& t : v) {
40 if (t->id() == id)
41 return true;
42 }
43 return false;
44 }
45 } // namespace 51 } // namespace
46 52
47 RemoteMediaStreamImpl::Observer::Observer( 53 RemoteMediaStreamImpl::Observer::Observer(
48 const base::WeakPtr<RemoteMediaStreamImpl>& media_stream, 54 const base::WeakPtr<RemoteMediaStreamImpl>& media_stream,
49 const scoped_refptr<base::SingleThreadTaskRunner>& main_thread, 55 const scoped_refptr<base::SingleThreadTaskRunner>& main_thread,
56 const scoped_refptr<WebRtcMediaStreamTrackAdapterMap>& track_adapter_map,
50 webrtc::MediaStreamInterface* webrtc_stream) 57 webrtc::MediaStreamInterface* webrtc_stream)
51 : media_stream_(media_stream), 58 : media_stream_(media_stream),
52 main_thread_(main_thread), 59 main_thread_(main_thread),
60 track_adapter_map_(track_adapter_map),
53 webrtc_stream_(webrtc_stream) { 61 webrtc_stream_(webrtc_stream) {
54 webrtc_stream_->RegisterObserver(this); 62 webrtc_stream_->RegisterObserver(this);
55 } 63 }
56 64
57 RemoteMediaStreamImpl::Observer::~Observer() { 65 RemoteMediaStreamImpl::Observer::~Observer() {
58 DCHECK(!webrtc_stream_.get()) << "Unregister hasn't been called"; 66 DCHECK(!webrtc_stream_.get()) << "Unregister hasn't been called";
59 } 67 }
60 68
61 void RemoteMediaStreamImpl::Observer::InitializeOnMainThread( 69 void RemoteMediaStreamImpl::Observer::InitializeOnMainThread(
62 const std::string& label) { 70 const std::string& label,
71 AdapterRefMap adapter_refs,
72 size_t audio_track_count,
73 size_t video_track_count) {
63 DCHECK(main_thread_->BelongsToCurrentThread()); 74 DCHECK(main_thread_->BelongsToCurrentThread());
64 if (media_stream_) 75 if (media_stream_) {
65 media_stream_->InitializeOnMainThread(label); 76 media_stream_->InitializeOnMainThread(label, std::move(adapter_refs),
77 audio_track_count, video_track_count);
78 }
66 } 79 }
67 80
68 void RemoteMediaStreamImpl::Observer::Unregister() { 81 void RemoteMediaStreamImpl::Observer::Unregister() {
69 DCHECK(main_thread_->BelongsToCurrentThread()); 82 DCHECK(main_thread_->BelongsToCurrentThread());
70 webrtc_stream_->UnregisterObserver(this); 83 webrtc_stream_->UnregisterObserver(this);
71 // Since we're guaranteed to not get further notifications, it's safe to 84 // Since we're guaranteed to not get further notifications, it's safe to
72 // release the webrtc_stream_ here. 85 // release the webrtc_stream_ here.
73 webrtc_stream_ = nullptr; 86 webrtc_stream_ = nullptr;
74 } 87 }
75 88
76 void RemoteMediaStreamImpl::Observer::OnChanged() { 89 void RemoteMediaStreamImpl::Observer::OnChanged() {
77 std::unique_ptr<RemoteAudioTrackAdapters> audio( 90 AdapterRefMap new_adapter_refs = GetAdapterRefMapFromWebRtcStream(
Guido Urdaneta 2017/06/12 14:25:28 Is there a race if you access track_adapter_map_ f
hbos_chromium 2017/06/12 15:05:20 No, track_adapter_map_ is thread-safe.
Guido Urdaneta 2017/06/12 15:18:34 Acknowledged.
78 new RemoteAudioTrackAdapters()); 91 track_adapter_map_, webrtc_stream_.get());
79 std::unique_ptr<RemoteVideoTrackAdapters> video( 92 main_thread_->PostTask(
80 new RemoteVideoTrackAdapters()); 93 FROM_HERE,
81 94 base::Bind(&RemoteMediaStreamImpl::Observer::OnChangedOnMainThread, this,
82 CreateAdaptersForTracks( 95 base::Passed(&new_adapter_refs)));
83 webrtc_stream_->GetAudioTracks(), audio.get(), main_thread_);
84 CreateAdaptersForTracks(
85 webrtc_stream_->GetVideoTracks(), video.get(), main_thread_);
86
87 main_thread_->PostTask(FROM_HERE,
88 base::Bind(&RemoteMediaStreamImpl::Observer::OnChangedOnMainThread,
89 this, base::Passed(&audio), base::Passed(&video)));
90 } 96 }
91 97
92 void RemoteMediaStreamImpl::Observer::OnChangedOnMainThread( 98 void RemoteMediaStreamImpl::Observer::OnChangedOnMainThread(
93 std::unique_ptr<RemoteAudioTrackAdapters> audio_tracks, 99 AdapterRefMap new_adapter_refs) {
94 std::unique_ptr<RemoteVideoTrackAdapters> video_tracks) {
95 DCHECK(main_thread_->BelongsToCurrentThread()); 100 DCHECK(main_thread_->BelongsToCurrentThread());
96 if (media_stream_) 101 if (media_stream_)
97 media_stream_->OnChanged(std::move(audio_tracks), std::move(video_tracks)); 102 media_stream_->OnChanged(std::move(new_adapter_refs));
98 } 103 }
99 104
100 // Called on the signaling thread. 105 // Called on the signaling thread.
101 RemoteMediaStreamImpl::RemoteMediaStreamImpl( 106 RemoteMediaStreamImpl::RemoteMediaStreamImpl(
102 const scoped_refptr<base::SingleThreadTaskRunner>& main_thread, 107 const scoped_refptr<base::SingleThreadTaskRunner>& main_thread,
108 const scoped_refptr<WebRtcMediaStreamTrackAdapterMap>& track_adapter_map,
103 webrtc::MediaStreamInterface* webrtc_stream) 109 webrtc::MediaStreamInterface* webrtc_stream)
104 : signaling_thread_(base::ThreadTaskRunnerHandle::Get()), 110 : signaling_thread_(base::ThreadTaskRunnerHandle::Get()),
111 track_adapter_map_(track_adapter_map),
105 weak_factory_(this) { 112 weak_factory_(this) {
Guido Urdaneta 2017/06/12 14:25:28 If necessary, can you add a check to ensure this r
hbos_chromium 2017/06/12 15:05:20 Added a DCHECK that we are not on the main thread,
Guido Urdaneta 2017/06/12 15:18:34 Acknowledged.
113 DCHECK(track_adapter_map_);
106 observer_ = new RemoteMediaStreamImpl::Observer( 114 observer_ = new RemoteMediaStreamImpl::Observer(
107 weak_factory_.GetWeakPtr(), main_thread, webrtc_stream); 115 weak_factory_.GetWeakPtr(), main_thread, track_adapter_map_,
108 CreateAdaptersForTracks(webrtc_stream->GetAudioTracks(), 116 webrtc_stream);
109 &audio_track_observers_, main_thread);
110 CreateAdaptersForTracks(webrtc_stream->GetVideoTracks(),
111 &video_track_observers_, main_thread);
112 117
113 main_thread->PostTask(FROM_HERE, 118 AdapterRefMap adapter_refs =
119 GetAdapterRefMapFromWebRtcStream(track_adapter_map_, webrtc_stream);
120 main_thread->PostTask(
121 FROM_HERE,
114 base::Bind(&RemoteMediaStreamImpl::Observer::InitializeOnMainThread, 122 base::Bind(&RemoteMediaStreamImpl::Observer::InitializeOnMainThread,
115 observer_, webrtc_stream->label())); 123 observer_, webrtc_stream->label(), base::Passed(&adapter_refs),
124 webrtc_stream->GetAudioTracks().size(),
125 webrtc_stream->GetVideoTracks().size()));
116 } 126 }
117 127
118 RemoteMediaStreamImpl::~RemoteMediaStreamImpl() { 128 RemoteMediaStreamImpl::~RemoteMediaStreamImpl() {
119 DCHECK(observer_->main_thread()->BelongsToCurrentThread()); 129 DCHECK(observer_->main_thread()->BelongsToCurrentThread());
120 for (auto& track : audio_track_observers_)
121 track->Unregister();
122 observer_->Unregister(); 130 observer_->Unregister();
131 OnChanged(AdapterRefMap());
123 } 132 }
124 133
125 void RemoteMediaStreamImpl::InitializeOnMainThread(const std::string& label) { 134 void RemoteMediaStreamImpl::InitializeOnMainThread(const std::string& label,
135 AdapterRefMap adapter_refs,
136 size_t audio_track_count,
137 size_t video_track_count) {
126 DCHECK(observer_->main_thread()->BelongsToCurrentThread()); 138 DCHECK(observer_->main_thread()->BelongsToCurrentThread());
127 blink::WebVector<blink::WebMediaStreamTrack> webkit_audio_tracks( 139 DCHECK_EQ(audio_track_count + video_track_count, adapter_refs.size());
128 audio_track_observers_.size()); 140
129 for (size_t i = 0; i < audio_track_observers_.size(); ++i) { 141 adapter_refs_ = std::move(adapter_refs);
130 audio_track_observers_[i]->Initialize(); 142 blink::WebVector<blink::WebMediaStreamTrack> web_audio_tracks(
131 webkit_audio_tracks[i] = *audio_track_observers_[i]->web_track(); 143 audio_track_count);
144 blink::WebVector<blink::WebMediaStreamTrack> web_video_tracks(
145 video_track_count);
146 size_t audio_i = 0;
147 size_t video_i = 0;
148 for (const auto& it : adapter_refs_) {
149 const blink::WebMediaStreamTrack& web_track = it.second->web_track();
150 if (web_track.Source().GetType() == blink::WebMediaStreamSource::kTypeAudio)
151 web_audio_tracks[audio_i++] = web_track;
152 else
153 web_video_tracks[video_i++] = web_track;
132 } 154 }
133 155
134 blink::WebVector<blink::WebMediaStreamTrack> webkit_video_tracks( 156 webkit_stream_.Initialize(blink::WebString::FromUTF8(label), web_audio_tracks,
135 video_track_observers_.size()); 157 web_video_tracks);
136 for (size_t i = 0; i < video_track_observers_.size(); ++i) {
137 video_track_observers_[i]->Initialize();
138 webkit_video_tracks[i] = *video_track_observers_[i]->web_track();
139 }
140
141 webkit_stream_.Initialize(blink::WebString::FromUTF8(label),
142 webkit_audio_tracks, webkit_video_tracks);
143 webkit_stream_.SetExtraData(new MediaStream()); 158 webkit_stream_.SetExtraData(new MediaStream());
144 } 159 }
145 160
146 void RemoteMediaStreamImpl::OnChanged( 161 void RemoteMediaStreamImpl::OnChanged(AdapterRefMap new_adapter_refs) {
147 std::unique_ptr<RemoteAudioTrackAdapters> audio_tracks, 162 DCHECK(observer_->main_thread()->BelongsToCurrentThread());
148 std::unique_ptr<RemoteVideoTrackAdapters> video_tracks) { 163
149 // Find removed tracks. 164 // Find removed tracks.
150 auto audio_it = audio_track_observers_.begin(); 165 for (auto it = adapter_refs_.begin(); it != adapter_refs_.end();) {
151 while (audio_it != audio_track_observers_.end()) { 166 if (new_adapter_refs.find(it->first) == new_adapter_refs.end()) {
152 if (!IsTrackInVector(*audio_tracks.get(), (*audio_it)->id())) { 167 webkit_stream_.RemoveTrack(it->second->web_track());
153 (*audio_it)->Unregister(); 168 it = adapter_refs_.erase(it);
154 webkit_stream_.RemoveTrack(*(*audio_it)->web_track());
155 audio_it = audio_track_observers_.erase(audio_it);
156 } else { 169 } else {
157 ++audio_it; 170 ++it;
158 } 171 }
159 } 172 }
160 173 // Find added tracks.
161 auto video_it = video_track_observers_.begin(); 174 for (auto& it : new_adapter_refs) {
162 while (video_it != video_track_observers_.end()) { 175 if (adapter_refs_.find(it.first) == adapter_refs_.end()) {
163 if (!IsTrackInVector(*video_tracks.get(), (*video_it)->id())) { 176 webkit_stream_.AddTrack(it.second->web_track());
164 webkit_stream_.RemoveTrack(*(*video_it)->web_track()); 177 adapter_refs_.insert(std::make_pair(it.first, std::move(it.second)));
165 video_it = video_track_observers_.erase(video_it);
166 } else {
167 ++video_it;
168 } 178 }
169 } 179 }
170
171 // Find added tracks.
172 for (auto& track : *audio_tracks.get()) {
173 if (!IsTrackInVector(audio_track_observers_, track->id())) {
174 track->Initialize();
175 audio_track_observers_.push_back(track);
176 webkit_stream_.AddTrack(*track->web_track());
177 // Set the track to null to avoid unregistering it below now that it's
178 // been associated with a media stream.
179 track = nullptr;
180 }
181 }
182
183 // Find added video tracks.
184 for (const auto& track : *video_tracks.get()) {
185 if (!IsTrackInVector(video_track_observers_, track->id())) {
186 track->Initialize();
187 video_track_observers_.push_back(track);
188 webkit_stream_.AddTrack(*track->web_track());
189 }
190 }
191
192 // Unregister all the audio track observers that were not used.
193 // We need to do this before destruction since the observers can't unregister
194 // from within the dtor due to a race.
195 for (auto& track : *audio_tracks.get()) {
196 if (track.get())
197 track->Unregister();
198 }
199 } 180 }
200 181
201 } // namespace content 182 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698