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

Side by Side Diff: Source/WebCore/Modules/mediastream/MediaStream.cpp

Issue 13776002: MediaStream should fire ended event when all tracks are ended (Closed) Base URL: https://chromium.googlesource.com/chromium/blink@master
Patch Set: MediaStream should fire ended event when all tracks are ended Created 7 years, 8 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 /* 1 /*
2 * Copyright (C) 2011 Google Inc. All rights reserved. 2 * Copyright (C) 2011 Google Inc. All rights reserved.
3 * Copyright (C) 2011, 2012 Ericsson AB. All rights reserved. 3 * Copyright (C) 2011, 2012 Ericsson AB. All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
7 * are met: 7 * are met:
8 * 1. Redistributions of source code must retain the above copyright 8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
108 : ContextDestructionObserver(context) 108 : ContextDestructionObserver(context)
109 , m_stopped(false) 109 , m_stopped(false)
110 , m_descriptor(streamDescriptor) 110 , m_descriptor(streamDescriptor)
111 , m_scheduledEventTimer(this, &MediaStream::scheduledEventTimerFired) 111 , m_scheduledEventTimer(this, &MediaStream::scheduledEventTimerFired)
112 { 112 {
113 m_descriptor->setClient(this); 113 m_descriptor->setClient(this);
114 114
115 size_t numberOfAudioTracks = m_descriptor->numberOfAudioComponents(); 115 size_t numberOfAudioTracks = m_descriptor->numberOfAudioComponents();
116 m_audioTracks.reserveCapacity(numberOfAudioTracks); 116 m_audioTracks.reserveCapacity(numberOfAudioTracks);
117 for (size_t i = 0; i < numberOfAudioTracks; i++) 117 for (size_t i = 0; i < numberOfAudioTracks; i++)
118 m_audioTracks.append(MediaStreamTrack::create(context, m_descriptor->aud ioComponent(i))); 118 m_audioTracks.append(MediaStreamTrack::create(context, m_descriptor->aud ioComponent(i), this));
119 119
120 size_t numberOfVideoTracks = m_descriptor->numberOfVideoComponents(); 120 size_t numberOfVideoTracks = m_descriptor->numberOfVideoComponents();
121 m_videoTracks.reserveCapacity(numberOfVideoTracks); 121 m_videoTracks.reserveCapacity(numberOfVideoTracks);
122 for (size_t i = 0; i < numberOfVideoTracks; i++) 122 for (size_t i = 0; i < numberOfVideoTracks; i++)
123 m_videoTracks.append(MediaStreamTrack::create(context, m_descriptor->vid eoComponent(i))); 123 m_videoTracks.append(MediaStreamTrack::create(context, m_descriptor->vid eoComponent(i), this));
124 } 124 }
125 125
126 MediaStream::~MediaStream() 126 MediaStream::~MediaStream()
127 { 127 {
128 m_descriptor->setClient(0); 128 m_descriptor->setClient(0);
129
130 for (size_t i = 0; i < m_audioTracks.size(); ++i)
131 m_audioTracks[i]->setStream(0);
132
133 for (size_t i = 0; i < m_videoTracks.size(); ++i)
134 m_videoTracks[i]->setStream(0);
129 } 135 }
130 136
131 bool MediaStream::ended() const 137 bool MediaStream::ended() const
132 { 138 {
133 return m_stopped || m_descriptor->ended(); 139 return m_stopped || m_descriptor->ended();
134 } 140 }
135 141
136 void MediaStream::addTrack(PassRefPtr<MediaStreamTrack> prpTrack, ExceptionCode& ec) 142 void MediaStream::addTrack(PassRefPtr<MediaStreamTrack> prpTrack, ExceptionCode& ec)
137 { 143 {
138 if (ended()) { 144 if (ended()) {
139 ec = INVALID_STATE_ERR; 145 ec = INVALID_STATE_ERR;
140 return; 146 return;
141 } 147 }
142 148
143 if (!prpTrack) { 149 if (!prpTrack) {
144 ec = TYPE_MISMATCH_ERR; 150 ec = TYPE_MISMATCH_ERR;
145 return; 151 return;
146 } 152 }
147 153
148 RefPtr<MediaStreamTrack> track = prpTrack; 154 RefPtr<MediaStreamTrack> track = prpTrack;
149 155
150 if (getTrackById(track->id())) 156 if (getTrackById(track->id()))
151 return; 157 return;
152 158
153 RefPtr<MediaStreamComponent> component = MediaStreamComponent::create(m_desc riptor.get(), track->component()->source()); 159 RefPtr<MediaStreamComponent> component = MediaStreamComponent::create(m_desc riptor.get(), track->component()->source());
154 RefPtr<MediaStreamTrack> newTrack = MediaStreamTrack::create(scriptExecution Context(), component.get()); 160 RefPtr<MediaStreamTrack> newTrack = MediaStreamTrack::create(scriptExecution Context(), component.get(), this);
155 161
156 switch (component->source()->type()) { 162 switch (component->source()->type()) {
157 case MediaStreamSource::TypeAudio: 163 case MediaStreamSource::TypeAudio:
158 m_descriptor->addAudioComponent(component.release()); 164 m_descriptor->addAudioComponent(component.release());
159 m_audioTracks.append(newTrack); 165 m_audioTracks.append(newTrack);
160 break; 166 break;
161 case MediaStreamSource::TypeVideo: 167 case MediaStreamSource::TypeVideo:
162 m_descriptor->addVideoComponent(component.release()); 168 m_descriptor->addVideoComponent(component.release());
163 m_videoTracks.append(newTrack); 169 m_videoTracks.append(newTrack);
164 break; 170 break;
(...skipping 13 matching lines...) Expand all
178 ec = TYPE_MISMATCH_ERR; 184 ec = TYPE_MISMATCH_ERR;
179 return; 185 return;
180 } 186 }
181 187
182 RefPtr<MediaStreamTrack> track = prpTrack; 188 RefPtr<MediaStreamTrack> track = prpTrack;
183 189
184 switch (track->component()->source()->type()) { 190 switch (track->component()->source()->type()) {
185 case MediaStreamSource::TypeAudio: { 191 case MediaStreamSource::TypeAudio: {
186 size_t pos = m_audioTracks.find(track); 192 size_t pos = m_audioTracks.find(track);
187 if (pos != notFound) { 193 if (pos != notFound) {
188 m_audioTracks.remove(pos); 194 m_audioTracks.remove(pos);
abarth-chromium 2013/04/08 16:58:41 Will |track| have a dangling reference to this Med
Li Yin 2013/04/09 03:11:54 Thanks for your reminder. If we implement a wrap o
189 m_descriptor->removeAudioComponent(track->component()); 195 m_descriptor->removeAudioComponent(track->component());
190 } 196 }
191 break; 197 break;
192 } 198 }
193 case MediaStreamSource::TypeVideo: { 199 case MediaStreamSource::TypeVideo: {
194 size_t pos = m_videoTracks.find(track); 200 size_t pos = m_videoTracks.find(track);
195 if (pos != notFound) { 201 if (pos != notFound) {
196 m_videoTracks.remove(pos); 202 m_videoTracks.remove(pos);
197 m_descriptor->removeVideoComponent(track->component()); 203 m_descriptor->removeVideoComponent(track->component());
198 } 204 }
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
257 } 263 }
258 264
259 void MediaStream::addRemoteTrack(MediaStreamComponent* component) 265 void MediaStream::addRemoteTrack(MediaStreamComponent* component)
260 { 266 {
261 ASSERT(component && !component->stream()); 267 ASSERT(component && !component->stream());
262 if (ended()) 268 if (ended())
263 return; 269 return;
264 270
265 component->setStream(descriptor()); 271 component->setStream(descriptor());
266 272
267 RefPtr<MediaStreamTrack> track = MediaStreamTrack::create(scriptExecutionCon text(), component); 273 RefPtr<MediaStreamTrack> track = MediaStreamTrack::create(scriptExecutionCon text(), component, this);
268 switch (component->source()->type()) { 274 switch (component->source()->type()) {
269 case MediaStreamSource::TypeAudio: 275 case MediaStreamSource::TypeAudio:
270 m_audioTracks.append(track); 276 m_audioTracks.append(track);
271 break; 277 break;
272 case MediaStreamSource::TypeVideo: 278 case MediaStreamSource::TypeVideo:
273 m_videoTracks.append(track); 279 m_videoTracks.append(track);
274 break; 280 break;
275 } 281 }
276 282
277 scheduleDispatchEvent(MediaStreamTrackEvent::create(eventNames().addtrackEve nt, false, false, track)); 283 scheduleDispatchEvent(MediaStreamTrackEvent::create(eventNames().addtrackEve nt, false, false, track));
(...skipping 18 matching lines...) Expand all
296 for (size_t i = 0; i < tracks->size(); ++i) { 302 for (size_t i = 0; i < tracks->size(); ++i) {
297 if ((*tracks)[i]->component() == component) { 303 if ((*tracks)[i]->component() == component) {
298 index = i; 304 index = i;
299 break; 305 break;
300 } 306 }
301 } 307 }
302 if (index == notFound) 308 if (index == notFound)
303 return; 309 return;
304 310
305 RefPtr<MediaStreamTrack> track = (*tracks)[index]; 311 RefPtr<MediaStreamTrack> track = (*tracks)[index];
306 tracks->remove(index); 312 tracks->remove(index);
abarth-chromium 2013/04/08 16:58:41 Here's another remove that might leave a dangling
307 scheduleDispatchEvent(MediaStreamTrackEvent::create(eventNames().removetrack Event, false, false, track)); 313 scheduleDispatchEvent(MediaStreamTrackEvent::create(eventNames().removetrack Event, false, false, track));
308 } 314 }
309 315
310 void MediaStream::scheduleDispatchEvent(PassRefPtr<Event> event) 316 void MediaStream::scheduleDispatchEvent(PassRefPtr<Event> event)
311 { 317 {
312 m_scheduledEvents.append(event); 318 m_scheduledEvents.append(event);
313 319
314 if (!m_scheduledEventTimer.isActive()) 320 if (!m_scheduledEventTimer.isActive())
315 m_scheduledEventTimer.startOneShot(0); 321 m_scheduledEventTimer.startOneShot(0);
316 } 322 }
317 323
318 void MediaStream::scheduledEventTimerFired(Timer<MediaStream>*) 324 void MediaStream::scheduledEventTimerFired(Timer<MediaStream>*)
319 { 325 {
320 if (m_stopped) 326 if (m_stopped)
321 return; 327 return;
322 328
323 Vector<RefPtr<Event> > events; 329 Vector<RefPtr<Event> > events;
324 events.swap(m_scheduledEvents); 330 events.swap(m_scheduledEvents);
325 331
326 Vector<RefPtr<Event> >::iterator it = events.begin(); 332 Vector<RefPtr<Event> >::iterator it = events.begin();
327 for (; it != events.end(); ++it) 333 for (; it != events.end(); ++it)
328 dispatchEvent((*it).release()); 334 dispatchEvent((*it).release());
329 335
330 events.clear(); 336 events.clear();
331 } 337 }
332 338
339 void MediaStream::trackEndedNotification()
340 {
341 for (size_t i = 0; i < m_audioTracks.size(); ++i)
342 if (!m_audioTracks[i]->ended())
343 return;
344
345 for (size_t i = 0; i < m_videoTracks.size(); ++i)
346 if (!m_videoTracks[i]->ended())
347 return;
348
349 streamEnded();
350 }
333 } // namespace WebCore 351 } // namespace WebCore
334 352
335 #endif // ENABLE(MEDIA_STREAM) 353 #endif // ENABLE(MEDIA_STREAM)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698