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
3 // found in the LICENSE file.
5 #include "content/renderer/media/remote_media_stream_impl.h"
9 #include "base/logging.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "content/renderer/media/media_stream.h"
12 #include "content/renderer/media/media_stream_video_track.h"
13 #include "content/renderer/media/webrtc/media_stream_remote_video_source.h"
14 #include "content/renderer/media/webrtc/peer_connection_dependency_factory.h"
15 #include "third_party/WebKit/public/platform/WebString.h"
21 void InitializeWebkitTrack(webrtc::MediaStreamTrackInterface
* track
,
22 blink::WebMediaStreamTrack
* webkit_track
,
23 blink::WebMediaStreamSource::Type type
) {
24 blink::WebMediaStreamSource webkit_source
;
25 blink::WebString
webkit_track_id(base::UTF8ToUTF16(track
->id()));
27 webkit_source
.initialize(webkit_track_id
, type
, webkit_track_id
);
28 webkit_track
->initialize(webkit_track_id
, webkit_source
);
30 if (type
== blink::WebMediaStreamSource::TypeVideo
) {
31 MediaStreamRemoteVideoSource
* video_source
=
32 new MediaStreamRemoteVideoSource(
33 static_cast<webrtc::VideoTrackInterface
*>(track
));
34 webkit_source
.setExtraData(video_source
);
35 // Initial constraints must be provided to a MediaStreamVideoTrack. But
36 // no constraints are available initially on a remote video track.
37 blink::WebMediaConstraints constraints
;
38 constraints
.initialize();
39 webkit_track
->setExtraData(
40 new MediaStreamVideoTrack(video_source
, constraints
,
41 MediaStreamVideoSource::ConstraintsCallback(),
44 DCHECK(type
== blink::WebMediaStreamSource::TypeAudio
);
45 content::PeerConnectionDependencyFactory::AddNativeAudioTrackToBlinkTrack(
46 track
, *webkit_track
, false);
52 // Base class used for mapping between webrtc and blink MediaStream tracks.
53 // An instance of a RemoteMediaStreamTrackAdapter is stored in
54 // RemoteMediaStreamImpl per remote audio and video track.
55 class RemoteMediaStreamTrackAdapter
{
57 RemoteMediaStreamTrackAdapter(webrtc::MediaStreamTrackInterface
* webrtc_track
,
58 const blink::WebMediaStreamTrack
& webkit_track
)
59 : webrtc_track_(webrtc_track
),
60 webkit_track_(webkit_track
) {
63 virtual ~RemoteMediaStreamTrackAdapter() {
66 webrtc::MediaStreamTrackInterface
* observed_track() {
67 return webrtc_track_
.get();
70 const blink::WebMediaStreamTrack
& webkit_track() { return webkit_track_
; }
73 scoped_refptr
<webrtc::MediaStreamTrackInterface
> webrtc_track_
;
74 blink::WebMediaStreamTrack webkit_track_
;
76 DISALLOW_COPY_AND_ASSIGN(RemoteMediaStreamTrackAdapter
);
79 static content::RemoteMediaStreamTrackAdapter
* FindTrackObserver(
80 webrtc::MediaStreamTrackInterface
* track
,
81 const ScopedVector
<content::RemoteMediaStreamTrackAdapter
>& observers
) {
82 ScopedVector
<content::RemoteMediaStreamTrackAdapter
>::const_iterator it
=
84 for (; it
!= observers
.end(); ++it
) {
85 if ((*it
)->observed_track() == track
)
91 // RemoteAudioMediaStreamTrackAdapter is responsible for listening on state
92 // change notifications on a remote webrtc audio MediaStreamTracks and notify
94 class RemoteAudioMediaStreamTrackAdapter
95 : public RemoteMediaStreamTrackAdapter
,
96 public webrtc::ObserverInterface
,
97 public base::NonThreadSafe
{
99 RemoteAudioMediaStreamTrackAdapter(
100 webrtc::MediaStreamTrackInterface
* webrtc_track
,
101 const blink::WebMediaStreamTrack
& webkit_track
);
102 virtual ~RemoteAudioMediaStreamTrackAdapter();
105 // webrtc::ObserverInterface implementation.
106 virtual void OnChanged() OVERRIDE
;
108 webrtc::MediaStreamTrackInterface::TrackState state_
;
110 DISALLOW_COPY_AND_ASSIGN(RemoteAudioMediaStreamTrackAdapter
);
113 RemoteAudioMediaStreamTrackAdapter::RemoteAudioMediaStreamTrackAdapter(
114 webrtc::MediaStreamTrackInterface
* webrtc_track
,
115 const blink::WebMediaStreamTrack
& webkit_track
)
116 : RemoteMediaStreamTrackAdapter(webrtc_track
, webkit_track
),
117 state_(observed_track()->state()) {
118 observed_track()->RegisterObserver(this);
121 RemoteAudioMediaStreamTrackAdapter::~RemoteAudioMediaStreamTrackAdapter() {
122 observed_track()->UnregisterObserver(this);
125 void RemoteAudioMediaStreamTrackAdapter::OnChanged() {
126 DCHECK(CalledOnValidThread());
128 webrtc::MediaStreamTrackInterface::TrackState state
=
129 observed_track()->state();
135 case webrtc::MediaStreamTrackInterface::kInitializing
:
136 // Ignore the kInitializing state since there is no match in
137 // WebMediaStreamSource::ReadyState.
139 case webrtc::MediaStreamTrackInterface::kLive
:
140 webkit_track().source().setReadyState(
141 blink::WebMediaStreamSource::ReadyStateLive
);
143 case webrtc::MediaStreamTrackInterface::kEnded
:
144 webkit_track().source().setReadyState(
145 blink::WebMediaStreamSource::ReadyStateEnded
);
153 RemoteMediaStreamImpl::RemoteMediaStreamImpl(
154 webrtc::MediaStreamInterface
* webrtc_stream
)
155 : webrtc_stream_(webrtc_stream
) {
156 webrtc_stream_
->RegisterObserver(this);
158 webrtc::AudioTrackVector webrtc_audio_tracks
=
159 webrtc_stream_
->GetAudioTracks();
160 blink::WebVector
<blink::WebMediaStreamTrack
> webkit_audio_tracks(
161 webrtc_audio_tracks
.size());
163 // Initialize WebKit audio tracks.
165 for (; i
< webrtc_audio_tracks
.size(); ++i
) {
166 webrtc::AudioTrackInterface
* audio_track
= webrtc_audio_tracks
[i
];
168 InitializeWebkitTrack(audio_track
, &webkit_audio_tracks
[i
],
169 blink::WebMediaStreamSource::TypeAudio
);
170 audio_track_observers_
.push_back(
171 new RemoteAudioMediaStreamTrackAdapter(audio_track
,
172 webkit_audio_tracks
[i
]));
175 // Initialize WebKit video tracks.
176 webrtc::VideoTrackVector webrtc_video_tracks
=
177 webrtc_stream_
->GetVideoTracks();
178 blink::WebVector
<blink::WebMediaStreamTrack
> webkit_video_tracks(
179 webrtc_video_tracks
.size());
180 for (i
= 0; i
< webrtc_video_tracks
.size(); ++i
) {
181 webrtc::VideoTrackInterface
* video_track
= webrtc_video_tracks
[i
];
183 InitializeWebkitTrack(video_track
, &webkit_video_tracks
[i
],
184 blink::WebMediaStreamSource::TypeVideo
);
185 video_track_observers_
.push_back(
186 new RemoteMediaStreamTrackAdapter(video_track
,
187 webkit_video_tracks
[i
]));
190 webkit_stream_
.initialize(base::UTF8ToUTF16(webrtc_stream
->label()),
191 webkit_audio_tracks
, webkit_video_tracks
);
192 webkit_stream_
.setExtraData(new MediaStream(webrtc_stream
));
195 RemoteMediaStreamImpl::~RemoteMediaStreamImpl() {
196 webrtc_stream_
->UnregisterObserver(this);
199 void RemoteMediaStreamImpl::OnChanged() {
200 // Find removed audio tracks.
201 ScopedVector
<RemoteMediaStreamTrackAdapter
>::iterator audio_it
=
202 audio_track_observers_
.begin();
203 while (audio_it
!= audio_track_observers_
.end()) {
204 std::string track_id
= (*audio_it
)->observed_track()->id();
205 if (webrtc_stream_
->FindAudioTrack(track_id
) == NULL
) {
206 webkit_stream_
.removeTrack((*audio_it
)->webkit_track());
207 audio_it
= audio_track_observers_
.erase(audio_it
);
213 // Find removed video tracks.
214 ScopedVector
<RemoteMediaStreamTrackAdapter
>::iterator video_it
=
215 video_track_observers_
.begin();
216 while (video_it
!= video_track_observers_
.end()) {
217 std::string track_id
= (*video_it
)->observed_track()->id();
218 if (webrtc_stream_
->FindVideoTrack(track_id
) == NULL
) {
219 webkit_stream_
.removeTrack((*video_it
)->webkit_track());
220 video_it
= video_track_observers_
.erase(video_it
);
226 // Find added audio tracks.
227 webrtc::AudioTrackVector webrtc_audio_tracks
=
228 webrtc_stream_
->GetAudioTracks();
229 for (webrtc::AudioTrackVector::iterator it
= webrtc_audio_tracks
.begin();
230 it
!= webrtc_audio_tracks
.end(); ++it
) {
231 if (!FindTrackObserver(*it
, audio_track_observers_
)) {
232 blink::WebMediaStreamTrack new_track
;
233 InitializeWebkitTrack(*it
, &new_track
,
234 blink::WebMediaStreamSource::TypeAudio
);
235 audio_track_observers_
.push_back(
236 new RemoteAudioMediaStreamTrackAdapter(*it
, new_track
));
237 webkit_stream_
.addTrack(new_track
);
241 // Find added video tracks.
242 webrtc::VideoTrackVector webrtc_video_tracks
=
243 webrtc_stream_
->GetVideoTracks();
244 for (webrtc::VideoTrackVector::iterator it
= webrtc_video_tracks
.begin();
245 it
!= webrtc_video_tracks
.end(); ++it
) {
246 if (!FindTrackObserver(*it
, video_track_observers_
)) {
247 blink::WebMediaStreamTrack new_track
;
248 InitializeWebkitTrack(*it
, &new_track
,
249 blink::WebMediaStreamSource::TypeVideo
);
250 video_track_observers_
.push_back(
251 new RemoteMediaStreamTrackAdapter(*it
, new_track
));
252 webkit_stream_
.addTrack(new_track
);
257 } // namespace content