Title: [157958] trunk/Source/WebCore
Revision
157958
Author
[email protected]
Date
2013-10-24 15:22:21 -0700 (Thu, 24 Oct 2013)

Log Message

[MediaStream API] allow a stream source to be shared
https://bugs.webkit.org/show_bug.cgi?id=121954

Patch by Thiago de Barros Lacerda <[email protected]> on 2013-10-24
Reviewed by Eric Carlson.

Now, the MediaStreamSource don't know about the MediaStream that owns it,
since there can be more than one MediaStream that has it as source for some track.
MediaStreamTrack classes now have observers registered, in case there are more than
one MediaStream owning that track

No new tests, no change in functionality.

* Modules/mediastream/MediaStream.cpp:
(WebCore::MediaStream::MediaStream): Adding the MediaStream as an observer for each track it owns.

(WebCore::MediaStream::addTrack): Now adding the MediaStream as an observer the new added track
and adding the source to the MediaStreamDescriptor.

(WebCore::MediaStream::removeTrack): Instead of removing the source right away, we first check if
there isn't any other track using that source, if not we remove the source.

(WebCore::MediaStream::haveTrackWithSource):
(WebCore::MediaStream::addRemoteSource): MediaStreamSource has no information about the MediaStream
that uses it, so now we don't set the stream in the source anymore.

(WebCore::MediaStream::removeRemoteSource): There can be more than on track using the source. So we
get each track that is using the source and then remove it and fire the ended event.

* Modules/mediastream/MediaStream.h:
* Modules/mediastream/MediaStreamTrack.cpp:
(WebCore::MediaStreamTrack::addObserver):
(WebCore::MediaStreamTrack::removeObserver):
(WebCore::MediaStreamTrack::trackDidEnd): Does not get the client from the MediaStreamDescriptor, it now
notify each of its observers that the track ended.

* Modules/mediastream/MediaStreamTrack.h: Adding Observer class.

* platform/mediastream/MediaStreamDescriptor.cpp: Destructor now does nothing. Previously it was setting
each MediaStreamSource's descriptor to null.

(WebCore::MediaStreamDescriptor::removeSource): Not setting the stream in source anymore.

(WebCore::MediaStreamDescriptor::MediaStreamDescriptor): Ditto.

(WebCore::MediaStreamDescriptor::setEnded): Not setting the state of the source to Ended

* platform/mediastream/MediaStreamDescriptor.h:
(WebCore::MediaStreamDescriptor::~MediaStreamDescriptor):
* platform/mediastream/MediaStreamSource.cpp: Removing references to MediaStream object
(WebCore::MediaStreamSource::MediaStreamSource):
(WebCore::MediaStreamSource::reset):
* platform/mediastream/MediaStreamSource.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (157957 => 157958)


--- trunk/Source/WebCore/ChangeLog	2013-10-24 21:40:55 UTC (rev 157957)
+++ trunk/Source/WebCore/ChangeLog	2013-10-24 22:22:21 UTC (rev 157958)
@@ -1,3 +1,58 @@
+2013-10-24  Thiago de Barros Lacerda  <[email protected]>
+
+        [MediaStream API] allow a stream source to be shared
+        https://bugs.webkit.org/show_bug.cgi?id=121954
+
+        Reviewed by Eric Carlson.
+
+        Now, the MediaStreamSource don't know about the MediaStream that owns it,
+        since there can be more than one MediaStream that has it as source for some track.
+        MediaStreamTrack classes now have observers registered, in case there are more than
+        one MediaStream owning that track
+
+        No new tests, no change in functionality.
+
+        * Modules/mediastream/MediaStream.cpp:
+        (WebCore::MediaStream::MediaStream): Adding the MediaStream as an observer for each track it owns.
+
+        (WebCore::MediaStream::addTrack): Now adding the MediaStream as an observer the new added track
+        and adding the source to the MediaStreamDescriptor.
+
+        (WebCore::MediaStream::removeTrack): Instead of removing the source right away, we first check if
+        there isn't any other track using that source, if not we remove the source.
+
+        (WebCore::MediaStream::haveTrackWithSource):
+        (WebCore::MediaStream::addRemoteSource): MediaStreamSource has no information about the MediaStream
+        that uses it, so now we don't set the stream in the source anymore.
+
+        (WebCore::MediaStream::removeRemoteSource): There can be more than on track using the source. So we
+        get each track that is using the source and then remove it and fire the ended event.
+
+        * Modules/mediastream/MediaStream.h:
+        * Modules/mediastream/MediaStreamTrack.cpp:
+        (WebCore::MediaStreamTrack::addObserver):
+        (WebCore::MediaStreamTrack::removeObserver):
+        (WebCore::MediaStreamTrack::trackDidEnd): Does not get the client from the MediaStreamDescriptor, it now
+        notify each of its observers that the track ended.
+
+        * Modules/mediastream/MediaStreamTrack.h: Adding Observer class.
+
+        * platform/mediastream/MediaStreamDescriptor.cpp: Destructor now does nothing. Previously it was setting
+        each MediaStreamSource's descriptor to null.
+
+        (WebCore::MediaStreamDescriptor::removeSource): Not setting the stream in source anymore.
+
+        (WebCore::MediaStreamDescriptor::MediaStreamDescriptor): Ditto.
+
+        (WebCore::MediaStreamDescriptor::setEnded): Not setting the state of the source to Ended
+
+        * platform/mediastream/MediaStreamDescriptor.h:
+        (WebCore::MediaStreamDescriptor::~MediaStreamDescriptor):
+        * platform/mediastream/MediaStreamSource.cpp: Removing references to MediaStream object
+        (WebCore::MediaStreamSource::MediaStreamSource):
+        (WebCore::MediaStreamSource::reset):
+        * platform/mediastream/MediaStreamSource.h:
+
 2013-10-24  Daniel Bates  <[email protected]>
 
         Crash in WebCore::NavigationScheduler::startTimer()

Modified: trunk/Source/WebCore/Modules/mediastream/MediaStream.cpp (157957 => 157958)


--- trunk/Source/WebCore/Modules/mediastream/MediaStream.cpp	2013-10-24 21:40:55 UTC (rev 157957)
+++ trunk/Source/WebCore/Modules/mediastream/MediaStream.cpp	2013-10-24 22:22:21 UTC (rev 157958)
@@ -118,15 +118,22 @@
     ASSERT(m_descriptor);
     m_descriptor->setClient(this);
 
+    RefPtr<MediaStreamTrack> track;
     size_t numberOfAudioTracks = m_descriptor->numberOfAudioStreams();
     m_audioTracks.reserveCapacity(numberOfAudioTracks);
-    for (size_t i = 0; i < numberOfAudioTracks; i++)
-        m_audioTracks.append(AudioStreamTrack::create(context, m_descriptor->audioStreams(i)));
+    for (size_t i = 0; i < numberOfAudioTracks; i++) {
+        track = AudioStreamTrack::create(context, m_descriptor->audioStreams(i));
+        track->addObserver(this);
+        m_audioTracks.append(track.release());
+    }
 
     size_t numberOfVideoTracks = m_descriptor->numberOfVideoStreams();
     m_videoTracks.reserveCapacity(numberOfVideoTracks);
-    for (size_t i = 0; i < numberOfVideoTracks; i++)
-        m_videoTracks.append(VideoStreamTrack::create(context, m_descriptor->videoStreams(i)));
+    for (size_t i = 0; i < numberOfVideoTracks; i++) {
+        track = VideoStreamTrack::create(context, m_descriptor->videoStreams(i));
+        track->addObserver(this);
+        m_videoTracks.append(track.release());
+    }
 }
 
 MediaStream::~MediaStream()
@@ -185,6 +192,9 @@
         m_videoTracks.append(track);
         break;
     }
+
+    track->addObserver(this);
+    m_descriptor->addSource(track->source());
 }
 
 void MediaStream::removeTrack(PassRefPtr<MediaStreamTrack> prpTrack, ExceptionCode& ec)
@@ -218,12 +228,36 @@
     if (pos == notFound)
         return;
 
-    m_descriptor->removeSource(track->source());
+    // There can be other tracks using the same source in the same MediaStream,
+    // like when MediaStreamTrack::clone() is called, for instance.
+    // Spec says that a source can be shared, so we must assure that there is no
+    // other track using it.
+    if (!haveTrackWithSource(track->source()))
+        m_descriptor->removeSource(track->source());
 
+    track->removeObserver(this);
     if (!m_audioTracks.size() && !m_videoTracks.size())
         setEnded();
 }
 
+bool MediaStream::haveTrackWithSource(PassRefPtr<MediaStreamSource> source)
+{
+    if (source->type() == MediaStreamSource::Audio) {
+        for (MediaStreamTrackVector::iterator iter = m_audioTracks.begin(); iter != m_audioTracks.end(); ++iter) {
+            if ((*iter)->source() == source.get())
+                return true;
+        }
+        return false;
+    }
+
+    for (MediaStreamTrackVector::iterator iter = m_videoTracks.begin(); iter != m_videoTracks.end(); ++iter) {
+        if ((*iter)->source() == source.get())
+            return true;
+    }
+
+    return false;
+}
+
 MediaStreamTrack* MediaStream::getTrackById(String id)
 {
     for (MediaStreamTrackVector::iterator iter = m_audioTracks.begin(); iter != m_audioTracks.end(); ++iter) {
@@ -271,8 +305,6 @@
     if (ended())
         return;
 
-    source->setStream(descriptor());
-
     RefPtr<MediaStreamTrack> track;
     switch (source->type()) {
     case MediaStreamSource::Audio:
@@ -284,6 +316,7 @@
         m_videoTracks.append(track);
         break;
     }
+    track->addObserver(this);
     m_descriptor->addSource(source);
 
     scheduleDispatchEvent(MediaStreamTrackEvent::create(eventNames().addtrackEvent, false, false, track));
@@ -304,21 +337,20 @@
         break;
     }
 
-    size_t index = notFound;
+    Vector<int> tracksToRemove;
     for (size_t i = 0; i < tracks->size(); ++i) {
-        if ((*tracks)[i]->source() == source) {
-            index = i;
-            break;
-        }
+        if ((*tracks)[i]->source() == source)
+            tracksToRemove.append(i);
     }
-    if (index == notFound)
-        return;
 
     m_descriptor->removeSource(source);
 
-    RefPtr<MediaStreamTrack> track = (*tracks)[index];
-    tracks->remove(index);
-    scheduleDispatchEvent(MediaStreamTrackEvent::create(eventNames().removetrackEvent, false, false, track));
+    for (int i = tracksToRemove.size() - 1; i >= 0; i--) {
+        RefPtr<MediaStreamTrack> track = (*tracks)[tracksToRemove[i]];
+        track->removeObserver(this);
+        tracks->remove(tracksToRemove[i]);
+        scheduleDispatchEvent(MediaStreamTrackEvent::create(eventNames().removetrackEvent, false, false, track.release()));
+    }
 }
 
 void MediaStream::scheduleDispatchEvent(PassRefPtr<Event> event)

Modified: trunk/Source/WebCore/Modules/mediastream/MediaStream.h (157957 => 157958)


--- trunk/Source/WebCore/Modules/mediastream/MediaStream.h	2013-10-24 21:40:55 UTC (rev 157957)
+++ trunk/Source/WebCore/Modules/mediastream/MediaStream.h	2013-10-24 22:22:21 UTC (rev 157958)
@@ -98,6 +98,8 @@
     virtual void addRemoteSource(MediaStreamSource*) OVERRIDE FINAL;
     virtual void removeRemoteSource(MediaStreamSource*) OVERRIDE FINAL;
 
+    bool haveTrackWithSource(PassRefPtr<MediaStreamSource>);
+
     void scheduleDispatchEvent(PassRefPtr<Event>);
     void scheduledEventTimerFired(Timer<MediaStream>*);
 

Modified: trunk/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp (157957 => 157958)


--- trunk/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp	2013-10-24 21:40:55 UTC (rev 157957)
+++ trunk/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp	2013-10-24 22:22:21 UTC (rev 157958)
@@ -296,6 +296,18 @@
     return m_stopped || m_readyState == MediaStreamSource::Ended;
 }
 
+void MediaStreamTrack::addObserver(MediaStreamTrack::Observer* observer)
+{
+    m_observers.append(observer);
+}
+
+void MediaStreamTrack::removeObserver(MediaStreamTrack::Observer* observer)
+{
+    size_t pos = m_observers.find(observer);
+    if (pos != notFound)
+        m_observers.remove(pos);
+}
+
 void MediaStreamTrack::sourceStateChanged()
 {
     if (m_stopped)
@@ -347,13 +359,8 @@
 
 void MediaStreamTrack::trackDidEnd()
 {
-    // FIXME: this is wrong, the track shouldn't have to call the descriptor's client!
-    MediaStreamDescriptorClient* client = m_source ? m_source->stream()->client() : 0;
-    if (!client)
-        return;
-    
-    client->trackDidEnd();
-    setState(MediaStreamSource::Ended);
+    for (Vector<Observer*>::iterator i = m_observers.begin(); i != m_observers.end(); ++i)
+        (*i)->trackDidEnd();
 }
 
 void MediaStreamTrack::stop()

Modified: trunk/Source/WebCore/Modules/mediastream/MediaStreamTrack.h (157957 => 157958)


--- trunk/Source/WebCore/Modules/mediastream/MediaStreamTrack.h	2013-10-24 21:40:55 UTC (rev 157957)
+++ trunk/Source/WebCore/Modules/mediastream/MediaStreamTrack.h	2013-10-24 22:22:21 UTC (rev 157958)
@@ -49,6 +49,11 @@
 
 class MediaStreamTrack : public RefCounted<MediaStreamTrack>, public ScriptWrappable, public ActiveDOMObject, public EventTargetWithInlineData, public MediaStreamSource::Observer {
 public:
+    class Observer {
+    public:
+        virtual void trackDidEnd() = 0;
+    };
+
     virtual ~MediaStreamTrack();
 
     virtual const AtomicString& kind() const = 0;
@@ -86,6 +91,9 @@
 
     bool ended() const;
 
+    void addObserver(Observer*);
+    void removeObserver(Observer*);
+
     // EventTarget
     virtual EventTargetInterface eventTargetInterface() const OVERRIDE FINAL { return MediaStreamTrackEventTargetInterfaceType; }
     virtual ScriptExecutionContext* scriptExecutionContext() const OVERRIDE FINAL { return ActiveDOMObject::scriptExecutionContext(); }
@@ -125,6 +133,8 @@
     mutable String m_id;
     Mutex m_mutex;
 
+    Vector<Observer*> m_observers;
+
     bool m_stopped;
     bool m_enabled;
     bool m_muted;

Modified: trunk/Source/WebCore/platform/mediastream/MediaStreamDescriptor.cpp (157957 => 157958)


--- trunk/Source/WebCore/platform/mediastream/MediaStreamDescriptor.cpp	2013-10-24 21:40:55 UTC (rev 157957)
+++ trunk/Source/WebCore/platform/mediastream/MediaStreamDescriptor.cpp	2013-10-24 22:22:21 UTC (rev 157958)
@@ -48,15 +48,6 @@
     return adoptRef(new MediaStreamDescriptor(createCanonicalUUIDString(), audioSources, videoSources, flag == IsEnded));
 }
 
-MediaStreamDescriptor::~MediaStreamDescriptor()
-{
-    for (size_t i = 0; i < m_audioStreamSources.size(); i++)
-        m_audioStreamSources[i]->setStream(0);
-    
-    for (size_t i = 0; i < m_videoStreamSources.size(); i++)
-        m_videoStreamSources[i]->setStream(0);
-}
-
 void MediaStreamDescriptor::addSource(PassRefPtr<MediaStreamSource> source)
 {
     switch (source->type()) {
@@ -88,8 +79,6 @@
         m_videoStreamSources.remove(pos);
         break;
     }
-
-    source->setStream(0);
 }
 
 void MediaStreamDescriptor::addRemoteSource(MediaStreamSource* source)
@@ -114,26 +103,19 @@
     , m_ended(ended)
 {
     ASSERT(m_id.length());
-    for (size_t i = 0; i < audioSources.size(); i++) {
-        audioSources[i]->setStream(this);
+    for (size_t i = 0; i < audioSources.size(); i++)
         m_audioStreamSources.append(audioSources[i]);
-    }
 
-    for (size_t i = 0; i < videoSources.size(); i++) {
-        videoSources[i]->setStream(this);
+    for (size_t i = 0; i < videoSources.size(); i++)
         m_videoStreamSources.append(videoSources[i]);
-    }
 }
 
 void MediaStreamDescriptor::setEnded()
 {
     if (m_client)
         m_client->streamDidEnd();
+
     m_ended = true;
-    for (size_t i = 0; i < m_audioStreamSources.size(); i++)
-        m_audioStreamSources[i]->setReadyState(MediaStreamSource::Ended);
-    for (size_t i = 0; i < m_videoStreamSources.size(); i++)
-        m_videoStreamSources[i]->setReadyState(MediaStreamSource::Ended);
 }
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/platform/mediastream/MediaStreamDescriptor.h (157957 => 157958)


--- trunk/Source/WebCore/platform/mediastream/MediaStreamDescriptor.h	2013-10-24 21:40:55 UTC (rev 157957)
+++ trunk/Source/WebCore/platform/mediastream/MediaStreamDescriptor.h	2013-10-24 22:22:21 UTC (rev 157958)
@@ -35,16 +35,16 @@
 #if ENABLE(MEDIA_STREAM)
 
 #include "MediaStreamSource.h"
+#include "MediaStreamTrack.h"
 #include <wtf/RefCounted.h>
 #include <wtf/Vector.h>
 
 namespace WebCore {
 
-class MediaStreamDescriptorClient {
+class MediaStreamDescriptorClient : public MediaStreamTrack::Observer {
 public:
     virtual ~MediaStreamDescriptorClient() { }
 
-    virtual void trackDidEnd() = 0;
     virtual void streamDidEnd() = 0;
     virtual void addRemoteSource(MediaStreamSource*) = 0;
     virtual void removeRemoteSource(MediaStreamSource*) = 0;
@@ -56,7 +56,7 @@
 
     static PassRefPtr<MediaStreamDescriptor> create(const MediaStreamSourceVector& audioSources, const MediaStreamSourceVector& videoSources, EndedAtCreationFlag);
 
-    virtual ~MediaStreamDescriptor();
+    virtual ~MediaStreamDescriptor() { }
 
     MediaStreamDescriptorClient* client() const { return m_client; }
     void setClient(MediaStreamDescriptorClient* client) { m_client = client; }

Modified: trunk/Source/WebCore/platform/mediastream/MediaStreamSource.cpp (157957 => 157958)


--- trunk/Source/WebCore/platform/mediastream/MediaStreamSource.cpp	2013-10-24 21:40:55 UTC (rev 157957)
+++ trunk/Source/WebCore/platform/mediastream/MediaStreamSource.cpp	2013-10-24 22:22:21 UTC (rev 157958)
@@ -48,7 +48,6 @@
     , m_type(type)
     , m_name(name)
     , m_readyState(New)
-    , m_stream(0)
     , m_enabled(true)
     , m_muted(false)
     , m_readonly(false)
@@ -63,7 +62,6 @@
 void MediaStreamSource::reset()
 {
     m_readyState = New;
-    m_stream = 0;
     m_enabled = true;
     m_muted = false;
     m_readonly = false;
@@ -92,13 +90,6 @@
         m_observers.remove(pos);
 }
 
-void MediaStreamSource::setStream(MediaStreamDescriptor* stream)
-{
-    // FIXME: A source should not need to know about its stream(s). This will be fixed as a part of
-    // https://bugs.webkit.org/show_bug.cgi?id=121954
-    m_stream = stream;
-}
-
 MediaConstraints* MediaStreamSource::constraints() const
 {
     // FIXME: While this returns 

Modified: trunk/Source/WebCore/platform/mediastream/MediaStreamSource.h (157957 => 157958)


--- trunk/Source/WebCore/platform/mediastream/MediaStreamSource.h	2013-10-24 21:40:55 UTC (rev 157957)
+++ trunk/Source/WebCore/platform/mediastream/MediaStreamSource.h	2013-10-24 22:22:21 UTC (rev 157958)
@@ -100,9 +100,6 @@
 
     void stop();
 
-    MediaStreamDescriptor* stream() const { return m_stream; }
-    void setStream(MediaStreamDescriptor*);
-    
 protected:
     MediaStreamSource(const String& id, Type, const String& name);
 
@@ -113,7 +110,6 @@
     ReadyState m_readyState;
     Vector<Observer*> m_observers;
     RefPtr<MediaConstraints> m_constraints;
-    MediaStreamDescriptor* m_stream;
     MediaStreamSourceStates m_states;
 
     bool m_enabled;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to