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

Side by Side Diff: Source/modules/mediastream/MediaStream.cpp

Issue 650063002: Move MediaStream and MediaStreamTrack implementation from modules/mediastream to core/mediastream. Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Rebased. Created 6 years, 2 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
« no previous file with comments | « Source/modules/mediastream/MediaStream.h ('k') | Source/modules/mediastream/MediaStream.idl » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * Copyright (C) 2011 Google Inc. All rights reserved.
3 * Copyright (C) 2011, 2012 Ericsson AB. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND AN Y
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17 * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR AN Y
18 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND O N
21 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26 #include "config.h"
27 #include "modules/mediastream/MediaStream.h"
28
29 #include "bindings/core/v8/ExceptionState.h"
30 #include "core/dom/ExceptionCode.h"
31 #include "modules/mediastream/MediaStreamRegistry.h"
32 #include "modules/mediastream/MediaStreamTrackEvent.h"
33 #include "platform/mediastream/MediaStreamCenter.h"
34 #include "platform/mediastream/MediaStreamSource.h"
35
36 namespace blink {
37
38 static bool containsSource(MediaStreamTrackVector& trackVector, MediaStreamSourc e* source)
39 {
40 for (size_t i = 0; i < trackVector.size(); ++i) {
41 if (source->id() == trackVector[i]->component()->source()->id())
42 return true;
43 }
44 return false;
45 }
46
47 static void processTrack(MediaStreamTrack* track, MediaStreamTrackVector& trackV ector)
48 {
49 if (track->ended())
50 return;
51
52 MediaStreamSource* source = track->component()->source();
53 if (!containsSource(trackVector, source))
54 trackVector.append(track);
55 }
56
57 MediaStream* MediaStream::create(ExecutionContext* context)
58 {
59 MediaStreamTrackVector audioTracks;
60 MediaStreamTrackVector videoTracks;
61
62 return new MediaStream(context, audioTracks, videoTracks);
63 }
64
65 MediaStream* MediaStream::create(ExecutionContext* context, MediaStream* stream)
66 {
67 ASSERT(stream);
68
69 MediaStreamTrackVector audioTracks;
70 MediaStreamTrackVector videoTracks;
71
72 for (size_t i = 0; i < stream->m_audioTracks.size(); ++i)
73 processTrack(stream->m_audioTracks[i].get(), audioTracks);
74
75 for (size_t i = 0; i < stream->m_videoTracks.size(); ++i)
76 processTrack(stream->m_videoTracks[i].get(), videoTracks);
77
78 return new MediaStream(context, audioTracks, videoTracks);
79 }
80
81 MediaStream* MediaStream::create(ExecutionContext* context, const MediaStreamTra ckVector& tracks)
82 {
83 MediaStreamTrackVector audioTracks;
84 MediaStreamTrackVector videoTracks;
85
86 for (size_t i = 0; i < tracks.size(); ++i)
87 processTrack(tracks[i].get(), tracks[i]->kind() == "audio" ? audioTracks : videoTracks);
88
89 return new MediaStream(context, audioTracks, videoTracks);
90 }
91
92 MediaStream* MediaStream::create(ExecutionContext* context, MediaStreamDescripto r* streamDescriptor)
93 {
94 return new MediaStream(context, streamDescriptor);
95 }
96
97 MediaStream::MediaStream(ExecutionContext* context, MediaStreamDescriptor* strea mDescriptor)
98 : ContextLifecycleObserver(context)
99 , m_stopped(false)
100 , m_descriptor(streamDescriptor)
101 , m_scheduledEventTimer(this, &MediaStream::scheduledEventTimerFired)
102 {
103 m_descriptor->setClient(this);
104
105 size_t numberOfAudioTracks = m_descriptor->numberOfAudioComponents();
106 m_audioTracks.reserveCapacity(numberOfAudioTracks);
107 for (size_t i = 0; i < numberOfAudioTracks; i++) {
108 MediaStreamTrack* newTrack = MediaStreamTrack::create(context, m_descrip tor->audioComponent(i));
109 newTrack->registerMediaStream(this);
110 m_audioTracks.append(newTrack);
111 }
112
113 size_t numberOfVideoTracks = m_descriptor->numberOfVideoComponents();
114 m_videoTracks.reserveCapacity(numberOfVideoTracks);
115 for (size_t i = 0; i < numberOfVideoTracks; i++) {
116 MediaStreamTrack* newTrack = MediaStreamTrack::create(context, m_descrip tor->videoComponent(i));
117 newTrack->registerMediaStream(this);
118 m_videoTracks.append(newTrack);
119 }
120 }
121
122 MediaStream::MediaStream(ExecutionContext* context, const MediaStreamTrackVector & audioTracks, const MediaStreamTrackVector& videoTracks)
123 : ContextLifecycleObserver(context)
124 , m_stopped(false)
125 , m_scheduledEventTimer(this, &MediaStream::scheduledEventTimerFired)
126 {
127 MediaStreamComponentVector audioComponents;
128 MediaStreamComponentVector videoComponents;
129
130 MediaStreamTrackVector::const_iterator iter;
131 for (iter = audioTracks.begin(); iter != audioTracks.end(); ++iter) {
132 (*iter)->registerMediaStream(this);
133 audioComponents.append((*iter)->component());
134 }
135 for (iter = videoTracks.begin(); iter != videoTracks.end(); ++iter) {
136 (*iter)->registerMediaStream(this);
137 videoComponents.append((*iter)->component());
138 }
139
140 m_descriptor = MediaStreamDescriptor::create(audioComponents, videoComponent s);
141 m_descriptor->setClient(this);
142 MediaStreamCenter::instance().didCreateMediaStream(m_descriptor.get());
143
144 m_audioTracks = audioTracks;
145 m_videoTracks = videoTracks;
146 }
147
148 MediaStream::~MediaStream()
149 {
150 }
151
152 bool MediaStream::ended() const
153 {
154 return m_stopped || m_descriptor->ended();
155 }
156
157 MediaStreamTrackVector MediaStream::getTracks()
158 {
159 MediaStreamTrackVector tracks;
160 for (MediaStreamTrackVector::iterator iter = m_audioTracks.begin(); iter != m_audioTracks.end(); ++iter)
161 tracks.append(iter->get());
162 for (MediaStreamTrackVector::iterator iter = m_videoTracks.begin(); iter != m_videoTracks.end(); ++iter)
163 tracks.append(iter->get());
164 return tracks;
165 }
166
167 void MediaStream::addTrack(MediaStreamTrack* track, ExceptionState& exceptionSta te)
168 {
169 if (ended()) {
170 exceptionState.throwDOMException(InvalidStateError, "The MediaStream is finished.");
171 return;
172 }
173
174 if (!track) {
175 exceptionState.throwDOMException(TypeMismatchError, "The MediaStreamTrac k provided is invalid.");
176 return;
177 }
178
179 if (getTrackById(track->id()))
180 return;
181
182 switch (track->component()->source()->type()) {
183 case MediaStreamSource::TypeAudio:
184 m_audioTracks.append(track);
185 break;
186 case MediaStreamSource::TypeVideo:
187 m_videoTracks.append(track);
188 break;
189 }
190 track->registerMediaStream(this);
191 m_descriptor->addComponent(track->component());
192 MediaStreamCenter::instance().didAddMediaStreamTrack(m_descriptor.get(), tra ck->component());
193 }
194
195 void MediaStream::removeTrack(MediaStreamTrack* track, ExceptionState& exception State)
196 {
197 if (ended()) {
198 exceptionState.throwDOMException(InvalidStateError, "The MediaStream is finished.");
199 return;
200 }
201
202 if (!track) {
203 exceptionState.throwDOMException(TypeMismatchError, "The MediaStreamTrac k provided is invalid.");
204 return;
205 }
206
207 size_t pos = kNotFound;
208 switch (track->component()->source()->type()) {
209 case MediaStreamSource::TypeAudio:
210 pos = m_audioTracks.find(track);
211 if (pos != kNotFound)
212 m_audioTracks.remove(pos);
213 break;
214 case MediaStreamSource::TypeVideo:
215 pos = m_videoTracks.find(track);
216 if (pos != kNotFound)
217 m_videoTracks.remove(pos);
218 break;
219 }
220
221 if (pos == kNotFound)
222 return;
223 track->unregisterMediaStream(this);
224 m_descriptor->removeComponent(track->component());
225
226 if (!m_audioTracks.size() && !m_videoTracks.size())
227 m_descriptor->setEnded();
228
229 MediaStreamCenter::instance().didRemoveMediaStreamTrack(m_descriptor.get(), track->component());
230 }
231
232 MediaStreamTrack* MediaStream::getTrackById(String id)
233 {
234 for (MediaStreamTrackVector::iterator iter = m_audioTracks.begin(); iter != m_audioTracks.end(); ++iter) {
235 if ((*iter)->id() == id)
236 return iter->get();
237 }
238
239 for (MediaStreamTrackVector::iterator iter = m_videoTracks.begin(); iter != m_videoTracks.end(); ++iter) {
240 if ((*iter)->id() == id)
241 return iter->get();
242 }
243
244 return 0;
245 }
246
247 MediaStream* MediaStream::clone(ExecutionContext* context)
248 {
249 MediaStreamTrackVector tracks;
250 for (MediaStreamTrackVector::iterator iter = m_audioTracks.begin(); iter != m_audioTracks.end(); ++iter)
251 tracks.append((*iter)->clone(context));
252 for (MediaStreamTrackVector::iterator iter = m_videoTracks.begin(); iter != m_videoTracks.end(); ++iter)
253 tracks.append((*iter)->clone(context));
254 return MediaStream::create(context, tracks);
255 }
256
257 void MediaStream::stop()
258 {
259 if (ended())
260 return;
261
262 MediaStreamCenter::instance().didStopLocalMediaStream(descriptor());
263
264 streamEnded();
265 }
266
267 void MediaStream::trackEnded()
268 {
269 for (MediaStreamTrackVector::iterator iter = m_audioTracks.begin(); iter != m_audioTracks.end(); ++iter) {
270 if (!(*iter)->ended())
271 return;
272 }
273
274 for (MediaStreamTrackVector::iterator iter = m_videoTracks.begin(); iter != m_videoTracks.end(); ++iter) {
275 if (!(*iter)->ended())
276 return;
277 }
278
279 streamEnded();
280 }
281
282 void MediaStream::streamEnded()
283 {
284 if (ended())
285 return;
286
287 m_descriptor->setEnded();
288 scheduleDispatchEvent(Event::create(EventTypeNames::ended));
289 }
290
291 void MediaStream::contextDestroyed()
292 {
293 ContextLifecycleObserver::contextDestroyed();
294 m_stopped = true;
295 }
296
297 const AtomicString& MediaStream::interfaceName() const
298 {
299 return EventTargetNames::MediaStream;
300 }
301
302 ExecutionContext* MediaStream::executionContext() const
303 {
304 return ContextLifecycleObserver::executionContext();
305 }
306
307 void MediaStream::addRemoteTrack(MediaStreamComponent* component)
308 {
309 ASSERT(component);
310 if (ended())
311 return;
312
313 MediaStreamTrack* track = MediaStreamTrack::create(executionContext(), compo nent);
314 switch (component->source()->type()) {
315 case MediaStreamSource::TypeAudio:
316 m_audioTracks.append(track);
317 break;
318 case MediaStreamSource::TypeVideo:
319 m_videoTracks.append(track);
320 break;
321 }
322 track->registerMediaStream(this);
323 m_descriptor->addComponent(component);
324
325 scheduleDispatchEvent(MediaStreamTrackEvent::create(EventTypeNames::addtrack , false, false, track));
326 }
327
328 void MediaStream::removeRemoteTrack(MediaStreamComponent* component)
329 {
330 if (m_stopped)
331 return;
332
333 MediaStreamTrackVector* tracks = 0;
334 switch (component->source()->type()) {
335 case MediaStreamSource::TypeAudio:
336 tracks = &m_audioTracks;
337 break;
338 case MediaStreamSource::TypeVideo:
339 tracks = &m_videoTracks;
340 break;
341 }
342
343 size_t index = kNotFound;
344 for (size_t i = 0; i < tracks->size(); ++i) {
345 if ((*tracks)[i]->component() == component) {
346 index = i;
347 break;
348 }
349 }
350 if (index == kNotFound)
351 return;
352
353 m_descriptor->removeComponent(component);
354
355 MediaStreamTrack* track = (*tracks)[index];
356 track->unregisterMediaStream(this);
357 tracks->remove(index);
358 scheduleDispatchEvent(MediaStreamTrackEvent::create(EventTypeNames::removetr ack, false, false, track));
359 }
360
361 void MediaStream::scheduleDispatchEvent(PassRefPtrWillBeRawPtr<Event> event)
362 {
363 m_scheduledEvents.append(event);
364
365 if (!m_scheduledEventTimer.isActive())
366 m_scheduledEventTimer.startOneShot(0, FROM_HERE);
367 }
368
369 void MediaStream::scheduledEventTimerFired(Timer<MediaStream>*)
370 {
371 if (m_stopped)
372 return;
373
374 WillBeHeapVector<RefPtrWillBeMember<Event> > events;
375 events.swap(m_scheduledEvents);
376
377 WillBeHeapVector<RefPtrWillBeMember<Event> >::iterator it = events.begin();
378 for (; it != events.end(); ++it)
379 dispatchEvent((*it).release());
380
381 events.clear();
382 }
383
384 URLRegistry& MediaStream::registry() const
385 {
386 return MediaStreamRegistry::registry();
387 }
388
389 void MediaStream::trace(Visitor* visitor)
390 {
391 visitor->trace(m_audioTracks);
392 visitor->trace(m_videoTracks);
393 visitor->trace(m_scheduledEvents);
394 visitor->trace(m_descriptor);
395 EventTargetWithInlineData::trace(visitor);
396 MediaStreamDescriptorClient::trace(visitor);
397 }
398
399 } // namespace blink
OLDNEW
« no previous file with comments | « Source/modules/mediastream/MediaStream.h ('k') | Source/modules/mediastream/MediaStream.idl » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698