Changeset 157958 in webkit


Ignore:
Timestamp:
Oct 24, 2013 3:22:21 PM (10 years ago)
Author:
commit-queue@webkit.org
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 <thiago.lacerda@openbossa.org> 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:
Location:
trunk/Source/WebCore
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r157957 r157958  
     12013-10-24  Thiago de Barros Lacerda  <thiago.lacerda@openbossa.org>
     2
     3        [MediaStream API] allow a stream source to be shared
     4        https://bugs.webkit.org/show_bug.cgi?id=121954
     5
     6        Reviewed by Eric Carlson.
     7
     8        Now, the MediaStreamSource don't know about the MediaStream that owns it,
     9        since there can be more than one MediaStream that has it as source for some track.
     10        MediaStreamTrack classes now have observers registered, in case there are more than
     11        one MediaStream owning that track
     12
     13        No new tests, no change in functionality.
     14
     15        * Modules/mediastream/MediaStream.cpp:
     16        (WebCore::MediaStream::MediaStream): Adding the MediaStream as an observer for each track it owns.
     17
     18        (WebCore::MediaStream::addTrack): Now adding the MediaStream as an observer the new added track
     19        and adding the source to the MediaStreamDescriptor.
     20
     21        (WebCore::MediaStream::removeTrack): Instead of removing the source right away, we first check if
     22        there isn't any other track using that source, if not we remove the source.
     23
     24        (WebCore::MediaStream::haveTrackWithSource):
     25        (WebCore::MediaStream::addRemoteSource): MediaStreamSource has no information about the MediaStream
     26        that uses it, so now we don't set the stream in the source anymore.
     27
     28        (WebCore::MediaStream::removeRemoteSource): There can be more than on track using the source. So we
     29        get each track that is using the source and then remove it and fire the ended event.
     30
     31        * Modules/mediastream/MediaStream.h:
     32        * Modules/mediastream/MediaStreamTrack.cpp:
     33        (WebCore::MediaStreamTrack::addObserver):
     34        (WebCore::MediaStreamTrack::removeObserver):
     35        (WebCore::MediaStreamTrack::trackDidEnd): Does not get the client from the MediaStreamDescriptor, it now
     36        notify each of its observers that the track ended.
     37
     38        * Modules/mediastream/MediaStreamTrack.h: Adding Observer class.
     39
     40        * platform/mediastream/MediaStreamDescriptor.cpp: Destructor now does nothing. Previously it was setting
     41        each MediaStreamSource's descriptor to null.
     42
     43        (WebCore::MediaStreamDescriptor::removeSource): Not setting the stream in source anymore.
     44
     45        (WebCore::MediaStreamDescriptor::MediaStreamDescriptor): Ditto.
     46
     47        (WebCore::MediaStreamDescriptor::setEnded): Not setting the state of the source to Ended
     48
     49        * platform/mediastream/MediaStreamDescriptor.h:
     50        (WebCore::MediaStreamDescriptor::~MediaStreamDescriptor):
     51        * platform/mediastream/MediaStreamSource.cpp: Removing references to MediaStream object
     52        (WebCore::MediaStreamSource::MediaStreamSource):
     53        (WebCore::MediaStreamSource::reset):
     54        * platform/mediastream/MediaStreamSource.h:
     55
    1562013-10-24  Daniel Bates  <dabates@apple.com>
    257
  • trunk/Source/WebCore/Modules/mediastream/MediaStream.cpp

    r157653 r157958  
    119119    m_descriptor->setClient(this);
    120120
     121    RefPtr<MediaStreamTrack> track;
    121122    size_t numberOfAudioTracks = m_descriptor->numberOfAudioStreams();
    122123    m_audioTracks.reserveCapacity(numberOfAudioTracks);
    123     for (size_t i = 0; i < numberOfAudioTracks; i++)
    124         m_audioTracks.append(AudioStreamTrack::create(context, m_descriptor->audioStreams(i)));
     124    for (size_t i = 0; i < numberOfAudioTracks; i++) {
     125        track = AudioStreamTrack::create(context, m_descriptor->audioStreams(i));
     126        track->addObserver(this);
     127        m_audioTracks.append(track.release());
     128    }
    125129
    126130    size_t numberOfVideoTracks = m_descriptor->numberOfVideoStreams();
    127131    m_videoTracks.reserveCapacity(numberOfVideoTracks);
    128     for (size_t i = 0; i < numberOfVideoTracks; i++)
    129         m_videoTracks.append(VideoStreamTrack::create(context, m_descriptor->videoStreams(i)));
     132    for (size_t i = 0; i < numberOfVideoTracks; i++) {
     133        track = VideoStreamTrack::create(context, m_descriptor->videoStreams(i));
     134        track->addObserver(this);
     135        m_videoTracks.append(track.release());
     136    }
    130137}
    131138
     
    186193        break;
    187194    }
     195
     196    track->addObserver(this);
     197    m_descriptor->addSource(track->source());
    188198}
    189199
     
    219229        return;
    220230
    221     m_descriptor->removeSource(track->source());
    222 
     231    // There can be other tracks using the same source in the same MediaStream,
     232    // like when MediaStreamTrack::clone() is called, for instance.
     233    // Spec says that a source can be shared, so we must assure that there is no
     234    // other track using it.
     235    if (!haveTrackWithSource(track->source()))
     236        m_descriptor->removeSource(track->source());
     237
     238    track->removeObserver(this);
    223239    if (!m_audioTracks.size() && !m_videoTracks.size())
    224240        setEnded();
     241}
     242
     243bool MediaStream::haveTrackWithSource(PassRefPtr<MediaStreamSource> source)
     244{
     245    if (source->type() == MediaStreamSource::Audio) {
     246        for (MediaStreamTrackVector::iterator iter = m_audioTracks.begin(); iter != m_audioTracks.end(); ++iter) {
     247            if ((*iter)->source() == source.get())
     248                return true;
     249        }
     250        return false;
     251    }
     252
     253    for (MediaStreamTrackVector::iterator iter = m_videoTracks.begin(); iter != m_videoTracks.end(); ++iter) {
     254        if ((*iter)->source() == source.get())
     255            return true;
     256    }
     257
     258    return false;
    225259}
    226260
     
    272306        return;
    273307
    274     source->setStream(descriptor());
    275 
    276308    RefPtr<MediaStreamTrack> track;
    277309    switch (source->type()) {
     
    285317        break;
    286318    }
     319    track->addObserver(this);
    287320    m_descriptor->addSource(source);
    288321
     
    305338    }
    306339
    307     size_t index = notFound;
     340    Vector<int> tracksToRemove;
    308341    for (size_t i = 0; i < tracks->size(); ++i) {
    309         if ((*tracks)[i]->source() == source) {
    310             index = i;
    311             break;
    312         }
    313     }
    314     if (index == notFound)
    315         return;
     342        if ((*tracks)[i]->source() == source)
     343            tracksToRemove.append(i);
     344    }
    316345
    317346    m_descriptor->removeSource(source);
    318347
    319     RefPtr<MediaStreamTrack> track = (*tracks)[index];
    320     tracks->remove(index);
    321     scheduleDispatchEvent(MediaStreamTrackEvent::create(eventNames().removetrackEvent, false, false, track));
     348    for (int i = tracksToRemove.size() - 1; i >= 0; i--) {
     349        RefPtr<MediaStreamTrack> track = (*tracks)[tracksToRemove[i]];
     350        track->removeObserver(this);
     351        tracks->remove(tracksToRemove[i]);
     352        scheduleDispatchEvent(MediaStreamTrackEvent::create(eventNames().removetrackEvent, false, false, track.release()));
     353    }
    322354}
    323355
  • trunk/Source/WebCore/Modules/mediastream/MediaStream.h

    r157653 r157958  
    9999    virtual void removeRemoteSource(MediaStreamSource*) OVERRIDE FINAL;
    100100
     101    bool haveTrackWithSource(PassRefPtr<MediaStreamSource>);
     102
    101103    void scheduleDispatchEvent(PassRefPtr<Event>);
    102104    void scheduledEventTimerFired(Timer<MediaStream>*);
  • trunk/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp

    r157733 r157958  
    297297}
    298298
     299void MediaStreamTrack::addObserver(MediaStreamTrack::Observer* observer)
     300{
     301    m_observers.append(observer);
     302}
     303
     304void MediaStreamTrack::removeObserver(MediaStreamTrack::Observer* observer)
     305{
     306    size_t pos = m_observers.find(observer);
     307    if (pos != notFound)
     308        m_observers.remove(pos);
     309}
     310
    299311void MediaStreamTrack::sourceStateChanged()
    300312{
     
    348360void MediaStreamTrack::trackDidEnd()
    349361{
    350     // FIXME: this is wrong, the track shouldn't have to call the descriptor's client!
    351     MediaStreamDescriptorClient* client = m_source ? m_source->stream()->client() : 0;
    352     if (!client)
    353         return;
    354    
    355     client->trackDidEnd();
    356     setState(MediaStreamSource::Ended);
     362    for (Vector<Observer*>::iterator i = m_observers.begin(); i != m_observers.end(); ++i)
     363        (*i)->trackDidEnd();
    357364}
    358365
  • trunk/Source/WebCore/Modules/mediastream/MediaStreamTrack.h

    r157733 r157958  
    5050class MediaStreamTrack : public RefCounted<MediaStreamTrack>, public ScriptWrappable, public ActiveDOMObject, public EventTargetWithInlineData, public MediaStreamSource::Observer {
    5151public:
     52    class Observer {
     53    public:
     54        virtual void trackDidEnd() = 0;
     55    };
     56
    5257    virtual ~MediaStreamTrack();
    5358
     
    8691
    8792    bool ended() const;
     93
     94    void addObserver(Observer*);
     95    void removeObserver(Observer*);
    8896
    8997    // EventTarget
     
    126134    Mutex m_mutex;
    127135
     136    Vector<Observer*> m_observers;
     137
    128138    bool m_stopped;
    129139    bool m_enabled;
  • trunk/Source/WebCore/platform/mediastream/MediaStreamDescriptor.cpp

    r157268 r157958  
    4949}
    5050
    51 MediaStreamDescriptor::~MediaStreamDescriptor()
    52 {
    53     for (size_t i = 0; i < m_audioStreamSources.size(); i++)
    54         m_audioStreamSources[i]->setStream(0);
    55    
    56     for (size_t i = 0; i < m_videoStreamSources.size(); i++)
    57         m_videoStreamSources[i]->setStream(0);
    58 }
    59 
    6051void MediaStreamDescriptor::addSource(PassRefPtr<MediaStreamSource> source)
    6152{
     
    8980        break;
    9081    }
    91 
    92     source->setStream(0);
    9382}
    9483
     
    115104{
    116105    ASSERT(m_id.length());
    117     for (size_t i = 0; i < audioSources.size(); i++) {
    118         audioSources[i]->setStream(this);
     106    for (size_t i = 0; i < audioSources.size(); i++)
    119107        m_audioStreamSources.append(audioSources[i]);
    120     }
    121108
    122     for (size_t i = 0; i < videoSources.size(); i++) {
    123         videoSources[i]->setStream(this);
     109    for (size_t i = 0; i < videoSources.size(); i++)
    124110        m_videoStreamSources.append(videoSources[i]);
    125     }
    126111}
    127112
     
    130115    if (m_client)
    131116        m_client->streamDidEnd();
     117
    132118    m_ended = true;
    133     for (size_t i = 0; i < m_audioStreamSources.size(); i++)
    134         m_audioStreamSources[i]->setReadyState(MediaStreamSource::Ended);
    135     for (size_t i = 0; i < m_videoStreamSources.size(); i++)
    136         m_videoStreamSources[i]->setReadyState(MediaStreamSource::Ended);
    137119}
    138120
  • trunk/Source/WebCore/platform/mediastream/MediaStreamDescriptor.h

    r157653 r157958  
    3636
    3737#include "MediaStreamSource.h"
     38#include "MediaStreamTrack.h"
    3839#include <wtf/RefCounted.h>
    3940#include <wtf/Vector.h>
     
    4142namespace WebCore {
    4243
    43 class MediaStreamDescriptorClient {
     44class MediaStreamDescriptorClient : public MediaStreamTrack::Observer {
    4445public:
    4546    virtual ~MediaStreamDescriptorClient() { }
    4647
    47     virtual void trackDidEnd() = 0;
    4848    virtual void streamDidEnd() = 0;
    4949    virtual void addRemoteSource(MediaStreamSource*) = 0;
     
    5757    static PassRefPtr<MediaStreamDescriptor> create(const MediaStreamSourceVector& audioSources, const MediaStreamSourceVector& videoSources, EndedAtCreationFlag);
    5858
    59     virtual ~MediaStreamDescriptor();
     59    virtual ~MediaStreamDescriptor() { }
    6060
    6161    MediaStreamDescriptorClient* client() const { return m_client; }
  • trunk/Source/WebCore/platform/mediastream/MediaStreamSource.cpp

    r157068 r157958  
    4949    , m_name(name)
    5050    , m_readyState(New)
    51     , m_stream(0)
    5251    , m_enabled(true)
    5352    , m_muted(false)
     
    6463{
    6564    m_readyState = New;
    66     m_stream = 0;
    6765    m_enabled = true;
    6866    m_muted = false;
     
    9189    if (pos != notFound)
    9290        m_observers.remove(pos);
    93 }
    94 
    95 void MediaStreamSource::setStream(MediaStreamDescriptor* stream)
    96 {
    97     // FIXME: A source should not need to know about its stream(s). This will be fixed as a part of
    98     // https://bugs.webkit.org/show_bug.cgi?id=121954
    99     m_stream = stream;
    10091}
    10192
  • trunk/Source/WebCore/platform/mediastream/MediaStreamSource.h

    r157653 r157958  
    101101    void stop();
    102102
    103     MediaStreamDescriptor* stream() const { return m_stream; }
    104     void setStream(MediaStreamDescriptor*);
    105    
    106103protected:
    107104    MediaStreamSource(const String& id, Type, const String& name);
     
    114111    Vector<Observer*> m_observers;
    115112    RefPtr<MediaConstraints> m_constraints;
    116     MediaStreamDescriptor* m_stream;
    117113    MediaStreamSourceStates m_states;
    118114
Note: See TracChangeset for help on using the changeset viewer.