Changeset 139611 in webkit


Ignore:
Timestamp:
Jan 14, 2013 5:31:01 AM (11 years ago)
Author:
tommyw@google.com
Message:

MediaStream API: Update the track accessors on MediaStream to match the latest specification
https://bugs.webkit.org/show_bug.cgi?id=106660

Reviewed by Adam Barth.

Source/WebCore:

The spec has significantly changed how tracks are accessed from a MediaStream:
http://dev.w3.org/2011/webrtc/editor/getusermedia.html

In short: the attributes audioTrack/videoTrack that returned special MediaStreamTrackLists have been
replaced by the functions getAudioTracks()/getVideoTracks that return standard sequences of
MediaStreamTracks.

Existing tests updated and expanded to cover patch.

  • CMakeLists.txt:
  • GNUmakefile.list.am:
  • Modules/mediastream/MediaStream.cpp:

(WebCore::MediaStream::create):
(WebCore::MediaStream::MediaStream):
(WebCore::MediaStream::~MediaStream):
(WebCore::MediaStream::readyState):
(WebCore):
(WebCore::MediaStream::addTrack):
(WebCore::MediaStream::removeTrack):
(WebCore::MediaStream::getTrackById):
(WebCore::MediaStream::streamEnded):
(WebCore::MediaStream::contextDestroyed):
(WebCore::MediaStream::scheduleDispatchEvent):
(WebCore::MediaStream::scheduledEventTimerFired):

  • Modules/mediastream/MediaStream.h:

(MediaStream):
(WebCore::MediaStream::getAudioTracks):
(WebCore::MediaStream::getVideoTracks):

  • Modules/mediastream/MediaStream.idl:
  • Modules/mediastream/MediaStreamTrackList.cpp: Removed.
  • Modules/mediastream/MediaStreamTrackList.h: Removed.
  • Modules/mediastream/MediaStreamTrackList.idl: Removed.
  • Modules/webaudio/AudioContext.cpp:

(WebCore::AudioContext::createMediaStreamSource):

  • WebCore.gypi:
  • dom/EventTargetFactory.in:
  • platform/mediastream/MediaStreamDescriptor.h:

(WebCore::MediaStreamDescriptor::addAudioComponent):
(WebCore::MediaStreamDescriptor::removeAudioComponent):
(WebCore::MediaStreamDescriptor::addVideoComponent):
(WebCore::MediaStreamDescriptor::removeVideoComponent):

LayoutTests:

Updating and expanding tests for the new getAudioTracks()/getVideoTracks().

  • fast/mediastream/MediaStreamConstructor-expected.txt:
  • fast/mediastream/MediaStreamConstructor.html:
  • fast/mediastream/MediaStreamTrack.html:
  • fast/mediastream/MediaStreamTrackList-expected.txt:
  • fast/mediastream/MediaStreamTrackList.html:
  • fast/mediastream/RTCPeerConnection-statsSelector-expected.txt:
  • fast/mediastream/RTCPeerConnection-statsSelector.html:
  • fast/mediastream/getusermedia-expected.txt:
  • fast/mediastream/getusermedia.html:
  • webaudio/mediastreamaudiosourcenode-expected.txt:
  • webaudio/mediastreamaudiosourcenode.html:
Location:
trunk
Files:
3 deleted
22 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r139607 r139611  
     12013-01-14  Tommy Widenflycht  <tommyw@google.com>
     2
     3        MediaStream API: Update the track accessors on MediaStream to match the latest specification
     4        https://bugs.webkit.org/show_bug.cgi?id=106660
     5
     6        Reviewed by Adam Barth.
     7
     8        Updating and expanding tests for the new getAudioTracks()/getVideoTracks().
     9
     10        * fast/mediastream/MediaStreamConstructor-expected.txt:
     11        * fast/mediastream/MediaStreamConstructor.html:
     12        * fast/mediastream/MediaStreamTrack.html:
     13        * fast/mediastream/MediaStreamTrackList-expected.txt:
     14        * fast/mediastream/MediaStreamTrackList.html:
     15        * fast/mediastream/RTCPeerConnection-statsSelector-expected.txt:
     16        * fast/mediastream/RTCPeerConnection-statsSelector.html:
     17        * fast/mediastream/getusermedia-expected.txt:
     18        * fast/mediastream/getusermedia.html:
     19        * webaudio/mediastreamaudiosourcenode-expected.txt:
     20        * webaudio/mediastreamaudiosourcenode.html:
     21
    1222013-01-14  Alexander Pavlov  <apavlov@chromium.org>
    223
  • trunk/LayoutTests/fast/mediastream/MediaStreamConstructor-expected.txt

    r138354 r139611  
    55
    66PASS Got local stream.
    7 PASS localStream.audioTracks.length is 1
    8 PASS localStream.videoTracks.length is 1
     7PASS localStream.getAudioTracks().length is 1
     8PASS localStream.getVideoTracks().length is 1
    99PASS typeof webkitMediaStream === 'function' is true
    1010PASS new webkitMediaStream(document) threw exception TypeError: Type error.
    1111PASS new webkitMediaStream([document]) threw exception TypeError: Invalid Array element type.
    12 PASS new webkitMediaStream([stream.audioTracks[0], document]) threw exception TypeError: Invalid Array element type.
     12PASS new webkitMediaStream([stream.getAudioTracks()[0], document]) threw exception TypeError: Invalid Array element type.
    1313PASS new webkitMediaStream([null]) threw exception TypeError: Invalid Array element type.
    1414PASS new webkitMediaStream([undefined]) threw exception TypeError: Invalid Array element type.
     
    1919PASS [object MediaStream] is defined.
    2020PASS newStream.constructor.name is 'MediaStream'
    21 PASS newStream.audioTracks.length is nAudio
    22 PASS newStream.videoTracks.length is nVideo
     21PASS newStream.getAudioTracks().length is nAudio
     22PASS newStream.getVideoTracks().length is nVideo
    2323PASS Stream constructed
    2424PASS [object MediaStream] is non-null.
    2525PASS [object MediaStream] is defined.
    2626PASS newStream.constructor.name is 'MediaStream'
    27 PASS newStream.audioTracks.length is nAudio
    28 PASS newStream.videoTracks.length is nVideo
     27PASS newStream.getAudioTracks().length is nAudio
     28PASS newStream.getVideoTracks().length is nVideo
    2929PASS Stream constructed
    3030PASS [object MediaStream] is non-null.
    3131PASS [object MediaStream] is defined.
    3232PASS newStream.constructor.name is 'MediaStream'
    33 PASS newStream.audioTracks.length is nAudio
    34 PASS newStream.videoTracks.length is nVideo
     33PASS newStream.getAudioTracks().length is nAudio
     34PASS newStream.getVideoTracks().length is nVideo
    3535PASS Stream constructed
    3636PASS [object MediaStream] is non-null.
    3737PASS [object MediaStream] is defined.
    3838PASS newStream.constructor.name is 'MediaStream'
    39 PASS newStream.audioTracks.length is nAudio
    40 PASS newStream.videoTracks.length is nVideo
     39PASS newStream.getAudioTracks().length is nAudio
     40PASS newStream.getVideoTracks().length is nVideo
    4141PASS Stream constructed
    4242PASS [object MediaStream] is non-null.
    4343PASS [object MediaStream] is defined.
    4444PASS newStream.constructor.name is 'MediaStream'
    45 PASS newStream.audioTracks.length is nAudio
    46 PASS newStream.videoTracks.length is nVideo
     45PASS newStream.getAudioTracks().length is nAudio
     46PASS newStream.getVideoTracks().length is nVideo
    4747PASS Stream constructed
    4848PASS [object MediaStream] is non-null.
    4949PASS [object MediaStream] is defined.
    5050PASS newStream.constructor.name is 'MediaStream'
    51 PASS newStream.audioTracks.length is nAudio
    52 PASS newStream.videoTracks.length is nVideo
     51PASS newStream.getAudioTracks().length is nAudio
     52PASS newStream.getVideoTracks().length is nVideo
    5353PASS Stream constructed
    5454PASS [object MediaStream] is non-null.
    5555PASS [object MediaStream] is defined.
    5656PASS newStream.constructor.name is 'MediaStream'
    57 PASS newStream.audioTracks.length is nAudio
    58 PASS newStream.videoTracks.length is nVideo
     57PASS newStream.getAudioTracks().length is nAudio
     58PASS newStream.getVideoTracks().length is nVideo
    5959PASS successfullyParsed is true
    6060
  • trunk/LayoutTests/fast/mediastream/MediaStreamConstructor.html

    r138354 r139611  
    3434    localStream = s;
    3535    testPassed('Got local stream.');
    36     shouldBe('localStream.audioTracks.length', '1');
    37     shouldBe('localStream.videoTracks.length', '1');
     36    shouldBe('localStream.getAudioTracks().length', '1');
     37    shouldBe('localStream.getVideoTracks().length', '1');
    3838
    3939    shouldBeTrue("typeof webkitMediaStream === 'function'");
     
    4848    shouldThrow('new webkitMediaStream(document)');
    4949    shouldThrow('new webkitMediaStream([document])');
    50     shouldThrow('new webkitMediaStream([stream.audioTracks[0], document])');
     50    shouldThrow('new webkitMediaStream([stream.getAudioTracks()[0], document])');
    5151    shouldThrow('new webkitMediaStream([null])');
    5252    shouldThrow('new webkitMediaStream([undefined])');
     
    5757    verifyStream(new webkitMediaStream([]), 0, 0);
    5858
    59     verifyStream(new webkitMediaStream(s), s.audioTracks.length, s.videoTracks.length);
     59    verifyStream(new webkitMediaStream(s), s.getAudioTracks().length, s.getVideoTracks().length);
    6060
    61     verifyStream(new webkitMediaStream([s.audioTracks[0]]), 1, 0);
    62     verifyStream(new webkitMediaStream([s.videoTracks[0]]), 0, 1);
    63     verifyStream(new webkitMediaStream([s.audioTracks[0], s.videoTracks[0]]), 1, 1);
    64     verifyStream(new webkitMediaStream([s.videoTracks[0], s.audioTracks[0], s.videoTracks[0]]), 1, 1);
     61    verifyStream(new webkitMediaStream([s.getAudioTracks()[0]]), 1, 0);
     62    verifyStream(new webkitMediaStream([s.getVideoTracks()[0]]), 0, 1);
     63    verifyStream(new webkitMediaStream([s.getAudioTracks()[0], s.getVideoTracks()[0]]), 1, 1);
     64    verifyStream(new webkitMediaStream([s.getVideoTracks()[0], s.getAudioTracks()[0], s.getVideoTracks()[0]]), 1, 1);
    6565}
    6666
     
    7474    shouldBeDefined(newStream);
    7575    shouldBe("newStream.constructor.name", "'MediaStream'");
    76     shouldBe('newStream.audioTracks.length', 'nAudio');
    77     shouldBe('newStream.videoTracks.length', 'nVideo');
     76    shouldBe('newStream.getAudioTracks().length', 'nAudio');
     77    shouldBe('newStream.getVideoTracks().length', 'nVideo');
    7878}
    7979
  • trunk/LayoutTests/fast/mediastream/MediaStreamTrack.html

    r123627 r139611  
    5454
    5555    stream = s;
    56     track = stream.videoTracks[0];
     56    track = stream.getVideoTracks()[0];
    5757
    5858    track.onunmute = onTrackUnmute;
  • trunk/LayoutTests/fast/mediastream/MediaStreamTrackList-expected.txt

    r134648 r139611  
    44
    55
     6PASS stream1.getTrackById(track.id).id is track.id
     7PASS stream2.getTrackById(track.id) is null
    68PASS Add track callback succeeded.
    79PASS Remove track callback succeeded.
    8 PASS stream1.videoTracks.add(stream2.videoTracks[0]) threw exception Error: InvalidStateError: DOM Exception 11.
    9 PASS stream1.videoTracks.remove(stream2.videoTracks[0]) threw exception Error: InvalidStateError: DOM Exception 11.
     10PASS stream1.addTrack(stream2.getVideoTracks()[0]) threw exception Error: InvalidStateError: DOM Exception 11.
     11PASS stream1.removeTrack(stream2.getVideoTracks()[0]) threw exception Error: InvalidStateError: DOM Exception 11.
    1012PASS successfullyParsed is true
    1113
  • trunk/LayoutTests/fast/mediastream/MediaStreamTrackList.html

    r127485 r139611  
    3333    // Now test that add failes when the parent stream has been stopped.
    3434    stream1.stop();
    35     shouldThrow('stream1.videoTracks.add(stream2.videoTracks[0])');
    36     shouldThrow('stream1.videoTracks.remove(stream2.videoTracks[0])');
     35    shouldThrow('stream1.addTrack(stream2.getVideoTracks()[0])');
     36    shouldThrow('stream1.removeTrack(stream2.getVideoTracks()[0])');
    3737
    3838    finishJSTest();
     
    4141function onAddTrack(e) {
    4242    testPassed('Add track callback succeeded.');
     43    event = e;
    4344
    44     stream1.videoTracks.onremovetrack = onRemoveTrack;
     45    stream1.onremovetrack = onRemoveTrack;
    4546    try {
    46         stream1.videoTracks.remove(e.track);
     47        stream1.removeTrack(event.track);
    4748    } catch (exception) {
    4849        testFailed("remove threw an exception.");
     
    5354function gotStream2(s) {
    5455    stream2 = s;
     56    stream1.onaddtrack = onAddTrack;
    5557
    56     stream1.videoTracks.onaddtrack = onAddTrack;
     58    track = stream1.getVideoTracks()[0];
     59    shouldBe('stream1.getTrackById(track.id).id', 'track.id');
     60    shouldBeNull('stream2.getTrackById(track.id)');
    5761
    5862    try {
    59         stream1.videoTracks.add(stream2.videoTracks[0]);
     63        stream1.addTrack(stream2.getVideoTracks()[0]);
    6064    } catch (exception) {
    6165        testFailed("add threw an exception.");
     
    6670function gotStream1(s) {
    6771    stream1 = s;
     72
    6873    getUserMedia({audio:true, video:true}, gotStream2);
    6974}
  • trunk/LayoutTests/fast/mediastream/RTCPeerConnection-statsSelector-expected.txt

    r131584 r139611  
    77PASS getUserMedia({audio:true, video:true}, gotStream) did not throw exception.
    88PASS Got a stream.
    9 PASS pc.getStats(statsHandler2, pc.localStreams[0].videoTracks[0]) did not throw exception.
     9PASS pc.getStats(statsHandler2, pc.localStreams[0].getVideoTracks()[0]) did not throw exception.
    1010PASS statsHandler2 was called
    1111PASS result.length is >= 1
  • trunk/LayoutTests/fast/mediastream/RTCPeerConnection-statsSelector.html

    r131584 r139611  
    3232
    3333    pc.addStream(stream);
    34     shouldNotThrow('pc.getStats(statsHandler2, pc.localStreams[0].videoTracks[0])');
     34    shouldNotThrow('pc.getStats(statsHandler2, pc.localStreams[0].getVideoTracks()[0])');
    3535}
    3636
  • trunk/LayoutTests/fast/mediastream/getusermedia-expected.txt

    r134792 r139611  
    77PASS navigator.webkitGetUserMedia({audio:true}, gotStream1, error); did not throw exception.
    88PASS Stream generated.
    9 PASS stream.audioTracks.length is 1
    10 PASS stream.videoTracks.length is 0
     9PASS stream.getAudioTracks().length is 1
     10PASS stream.getVideoTracks().length is 0
    1111PASS navigator.webkitGetUserMedia({video:true}, gotStream2, error); did not throw exception.
    1212PASS Stream generated.
    13 PASS stream.audioTracks.length is 0
    14 PASS stream.videoTracks.length is 1
     13PASS stream.getAudioTracks().length is 0
     14PASS stream.getVideoTracks().length is 1
    1515PASS navigator.webkitGetUserMedia({audio:true, video:true}, gotStream3, error); did not throw exception.
    1616PASS Stream generated.
    17 PASS stream.audioTracks.length is 1
    18 PASS stream.videoTracks.length is 1
     17PASS stream.getAudioTracks().length is 1
     18PASS stream.getVideoTracks().length is 1
    1919PASS navigator.webkitGetUserMedia({audio:{mandatory:{}, optional:[]}, video:true}, gotStream4, error); did not throw exception.
    2020PASS Stream generated.
    21 PASS stream.audioTracks.length is 1
    22 PASS stream.videoTracks.length is 1
     21PASS stream.getAudioTracks().length is 1
     22PASS stream.getVideoTracks().length is 1
    2323PASS navigator.webkitGetUserMedia({audio:{mandatory:{'valid_but_unsupported_1':0}, optional:[]}, video:true}, gotStreamInError, error1); did not throw exception.
    2424PASS Error callback called.
    2525PASS navigator.webkitGetUserMedia({audio:{mandatory:{'valid_and_supported_1':1}, optional:[{'valid_but_unsupported_1':0}]}, video:true}, gotStream5, error); did not throw exception.
    2626PASS Stream generated.
    27 PASS stream.audioTracks.length is 1
    28 PASS stream.videoTracks.length is 1
     27PASS stream.getAudioTracks().length is 1
     28PASS stream.getVideoTracks().length is 1
    2929PASS successfullyParsed is true
    3030
  • trunk/LayoutTests/fast/mediastream/getusermedia.html

    r129749 r139611  
    2626    stream = s;
    2727    testPassed('Stream generated.');
    28     shouldBe('stream.audioTracks.length', '1');
    29     shouldBe('stream.videoTracks.length', '1');
     28    shouldBe('stream.getAudioTracks().length', '1');
     29    shouldBe('stream.getVideoTracks().length', '1');
    3030    finishJSTest();
    3131}
     
    4040    stream = s;
    4141    testPassed('Stream generated.');
    42     shouldBe('stream.audioTracks.length', '1');
    43     shouldBe('stream.videoTracks.length', '1');
     42    shouldBe('stream.getAudioTracks().length', '1');
     43    shouldBe('stream.getVideoTracks().length', '1');
    4444
    4545    shouldNotThrow("navigator.webkitGetUserMedia({audio:{mandatory:{'valid_but_unsupported_1':0}, optional:[]}, video:true}, gotStreamInError, error1);");
     
    4949    stream = s;
    5050    testPassed('Stream generated.');
    51     shouldBe('stream.audioTracks.length', '1');
    52     shouldBe('stream.videoTracks.length', '1');
     51    shouldBe('stream.getAudioTracks().length', '1');
     52    shouldBe('stream.getVideoTracks().length', '1');
    5353
    5454    shouldNotThrow("navigator.webkitGetUserMedia({audio:{mandatory:{}, optional:[]}, video:true}, gotStream4, error);");
     
    5858    stream = s;
    5959    testPassed('Stream generated.');
    60     shouldBe('stream.audioTracks.length', '0');
    61     shouldBe('stream.videoTracks.length', '1');
     60    shouldBe('stream.getAudioTracks().length', '0');
     61    shouldBe('stream.getVideoTracks().length', '1');
    6262
    6363    shouldNotThrow("navigator.webkitGetUserMedia({audio:true, video:true}, gotStream3, error);");
     
    6767    stream = s;
    6868    testPassed('Stream generated.');
    69     shouldBe('stream.audioTracks.length', '1');
    70     shouldBe('stream.videoTracks.length', '0');
     69    shouldBe('stream.getAudioTracks().length', '1');
     70    shouldBe('stream.getVideoTracks().length', '0');
    7171
    7272    shouldNotThrow("navigator.webkitGetUserMedia({video:true}, gotStream2, error);")
  • trunk/LayoutTests/webaudio/mediastreamaudiosourcenode-expected.txt

    r124255 r139611  
    44
    55PASS {audio:true} generated stream
    6 PASS s.audioTracks.length is 1
    7 PASS s.videoTracks.length is 0
     6PASS s.getAudioTracks().length is 1
     7PASS s.getVideoTracks().length is 0
    88PASS Source AudioNode has no inputs.
    99PASS Source AudioNode has one output.
  • trunk/LayoutTests/webaudio/mediastreamaudiosourcenode.html

    r124255 r139611  
    3333    s = stream;
    3434    testPassed('{audio:true} generated stream');
    35     shouldBe('s.audioTracks.length', '1');
    36     shouldBe('s.videoTracks.length', '0');
     35    shouldBe('s.getAudioTracks().length', '1');
     36    shouldBe('s.getVideoTracks().length', '0');
    3737
    3838    context = new webkitAudioContext();
  • trunk/Source/WebCore/CMakeLists.txt

    r139409 r139611  
    221221    Modules/mediastream/MediaStreamTrack.idl
    222222    Modules/mediastream/MediaStreamTrackEvent.idl
    223     Modules/mediastream/MediaStreamTrackList.idl
    224223    Modules/mediastream/NavigatorMediaStream.idl
    225224    Modules/mediastream/NavigatorUserMediaError.idl
     
    862861    Modules/mediastream/MediaStreamTrack.cpp
    863862    Modules/mediastream/MediaStreamTrackEvent.cpp
    864     Modules/mediastream/MediaStreamTrackList.cpp
    865863    Modules/mediastream/NavigatorMediaStream.cpp
    866864    Modules/mediastream/RTCDataChannel.cpp
  • trunk/Source/WebCore/ChangeLog

    r139610 r139611  
     12013-01-14  Tommy Widenflycht  <tommyw@google.com>
     2
     3        MediaStream API: Update the track accessors on MediaStream to match the latest specification
     4        https://bugs.webkit.org/show_bug.cgi?id=106660
     5
     6        Reviewed by Adam Barth.
     7
     8        The spec has significantly changed how tracks are accessed from a MediaStream:
     9        http://dev.w3.org/2011/webrtc/editor/getusermedia.html
     10
     11        In short: the attributes audioTrack/videoTrack that returned special MediaStreamTrackLists have been
     12        replaced by the functions getAudioTracks()/getVideoTracks that return standard sequences of
     13        MediaStreamTracks.
     14
     15        Existing tests updated and expanded to cover patch.
     16
     17        * CMakeLists.txt:
     18        * GNUmakefile.list.am:
     19        * Modules/mediastream/MediaStream.cpp:
     20        (WebCore::MediaStream::create):
     21        (WebCore::MediaStream::MediaStream):
     22        (WebCore::MediaStream::~MediaStream):
     23        (WebCore::MediaStream::readyState):
     24        (WebCore):
     25        (WebCore::MediaStream::addTrack):
     26        (WebCore::MediaStream::removeTrack):
     27        (WebCore::MediaStream::getTrackById):
     28        (WebCore::MediaStream::streamEnded):
     29        (WebCore::MediaStream::contextDestroyed):
     30        (WebCore::MediaStream::scheduleDispatchEvent):
     31        (WebCore::MediaStream::scheduledEventTimerFired):
     32        * Modules/mediastream/MediaStream.h:
     33        (MediaStream):
     34        (WebCore::MediaStream::getAudioTracks):
     35        (WebCore::MediaStream::getVideoTracks):
     36        * Modules/mediastream/MediaStream.idl:
     37        * Modules/mediastream/MediaStreamTrackList.cpp: Removed.
     38        * Modules/mediastream/MediaStreamTrackList.h: Removed.
     39        * Modules/mediastream/MediaStreamTrackList.idl: Removed.
     40        * Modules/webaudio/AudioContext.cpp:
     41        (WebCore::AudioContext::createMediaStreamSource):
     42        * WebCore.gypi:
     43        * dom/EventTargetFactory.in:
     44        * platform/mediastream/MediaStreamDescriptor.h:
     45        (WebCore::MediaStreamDescriptor::addAudioComponent):
     46        (WebCore::MediaStreamDescriptor::removeAudioComponent):
     47        (WebCore::MediaStreamDescriptor::addVideoComponent):
     48        (WebCore::MediaStreamDescriptor::removeVideoComponent):
     49
    1502013-01-14  Kentaro Hara  <haraken@chromium.org>
    251
  • trunk/Source/WebCore/GNUmakefile.list.am

    r139533 r139611  
    522522        DerivedSources/WebCore/JSMediaStreamTrackEvent.cpp \
    523523        DerivedSources/WebCore/JSMediaStreamTrackEvent.h \
    524         DerivedSources/WebCore/JSMediaStreamTrackList.cpp \
    525         DerivedSources/WebCore/JSMediaStreamTrackList.h \
    526524        DerivedSources/WebCore/JSMediaQueryList.cpp \
    527525        DerivedSources/WebCore/JSMediaQueryList.h \
     
    12441242        $(WebCore)/Modules/mediastream/MediaStreamTrack.idl \
    12451243        $(WebCore)/Modules/mediastream/MediaStreamTrackEvent.idl \
    1246         $(WebCore)/Modules/mediastream/MediaStreamTrackList.idl \
    12471244        $(WebCore)/Modules/mediastream/NavigatorMediaStream.idl \
    12481245        $(WebCore)/Modules/mediastream/NavigatorUserMediaError.idl \
     
    19401937        Source/WebCore/Modules/mediastream/MediaStreamTrackEvent.cpp \
    19411938        Source/WebCore/Modules/mediastream/MediaStreamTrackEvent.h \
    1942         Source/WebCore/Modules/mediastream/MediaStreamTrackList.cpp \
    1943         Source/WebCore/Modules/mediastream/MediaStreamTrackList.h \
    19441939        Source/WebCore/Modules/mediastream/NavigatorMediaStream.cpp \
    19451940        Source/WebCore/Modules/mediastream/NavigatorMediaStream.h \
  • trunk/Source/WebCore/Modules/mediastream/MediaStream.cpp

    r139598 r139611  
    3333#include "MediaStreamCenter.h"
    3434#include "MediaStreamSource.h"
     35#include "MediaStreamTrackEvent.h"
    3536#include "UUID.h"
    3637
     
    7980    MediaStreamSourceVector videoSources;
    8081
    81     for (size_t i = 0; i < stream->audioTracks()->length(); ++i)
    82         processTrack(stream->audioTracks()->item(i), audioSources);
    83 
    84     for (size_t i = 0; i < stream->videoTracks()->length(); ++i)
    85         processTrack(stream->videoTracks()->item(i), videoSources);
     82    for (size_t i = 0; i < stream->m_audioTracks.size(); ++i)
     83        processTrack(stream->m_audioTracks[i].get(), audioSources);
     84
     85    for (size_t i = 0; i < stream->m_videoTracks.size(); ++i)
     86        processTrack(stream->m_videoTracks[i].get(), videoSources);
    8687
    8788    return createFromSourceVectors(context, audioSources, videoSources);
     
    106107MediaStream::MediaStream(ScriptExecutionContext* context, PassRefPtr<MediaStreamDescriptor> streamDescriptor)
    107108    : ContextDestructionObserver(context)
     109    , m_stopped(false)
    108110    , m_descriptor(streamDescriptor)
     111    , m_scheduledEventTimer(this, &MediaStream::scheduledEventTimerFired)
    109112{
    110113    m_descriptor->setClient(this);
    111114
    112     MediaStreamTrackVector audioTrackVector;
    113115    size_t numberOfAudioTracks = m_descriptor->numberOfAudioComponents();
    114     audioTrackVector.reserveCapacity(numberOfAudioTracks);
     116    m_audioTracks.reserveCapacity(numberOfAudioTracks);
    115117    for (size_t i = 0; i < numberOfAudioTracks; i++)
    116         audioTrackVector.append(MediaStreamTrack::create(context, m_descriptor, m_descriptor->audioComponent(i)));
    117     m_audioTracks = MediaStreamTrackList::create(this, audioTrackVector);
    118 
    119     MediaStreamTrackVector videoTrackVector;
     118        m_audioTracks.append(MediaStreamTrack::create(context, m_descriptor, m_descriptor->audioComponent(i)));
     119
    120120    size_t numberOfVideoTracks = m_descriptor->numberOfVideoComponents();
    121     videoTrackVector.reserveCapacity(numberOfVideoTracks);
     121    m_videoTracks.reserveCapacity(numberOfVideoTracks);
    122122    for (size_t i = 0; i < numberOfVideoTracks; i++)
    123         videoTrackVector.append(MediaStreamTrack::create(context, m_descriptor, m_descriptor->videoComponent(i)));
    124     m_videoTracks = MediaStreamTrackList::create(this, videoTrackVector);
     123        m_videoTracks.append(MediaStreamTrack::create(context, m_descriptor, m_descriptor->videoComponent(i)));
    125124}
    126125
     
    128127{
    129128    m_descriptor->setClient(0);
    130     m_audioTracks->detachOwner();
    131     m_videoTracks->detachOwner();
    132129}
    133130
    134131bool MediaStream::ended() const
    135132{
    136     return m_descriptor->ended();
    137 }
    138 
    139 void MediaStream::streamEnded()
    140 {
    141     if (ended())
    142         return;
    143 
    144     m_descriptor->setEnded();
    145     m_audioTracks->detachOwner();
    146     m_videoTracks->detachOwner();
    147 
    148     dispatchEvent(Event::create(eventNames().endedEvent, false, false));
    149 }
    150 
    151 const AtomicString& MediaStream::interfaceName() const
    152 {
    153     return eventNames().interfaceForMediaStream;
    154 }
    155 
    156 ScriptExecutionContext* MediaStream::scriptExecutionContext() const
    157 {
    158     return ContextDestructionObserver::scriptExecutionContext();
    159 }
    160 
    161 EventTargetData* MediaStream::eventTargetData()
    162 {
    163     return &m_eventTargetData;
    164 }
    165 
    166 EventTargetData* MediaStream::ensureEventTargetData()
    167 {
    168     return &m_eventTargetData;
    169 }
    170 
    171 void MediaStream::addTrack(MediaStreamComponent* component)
    172 {
    173     RefPtr<MediaStreamTrack> track = MediaStreamTrack::create(scriptExecutionContext(), m_descriptor, component);
    174     ExceptionCode ec = 0;
     133    return m_stopped || m_descriptor->ended();
     134}
     135
     136void MediaStream::addTrack(PassRefPtr<MediaStreamTrack> prpTrack, ExceptionCode& ec)
     137{
     138    if (ended()) {
     139        ec = INVALID_STATE_ERR;
     140        return;
     141    }
     142
     143    if (!prpTrack) {
     144        ec = TYPE_MISMATCH_ERR;
     145        return;
     146    }
     147
     148    RefPtr<MediaStreamTrack> track = prpTrack;
     149
     150    if (getTrackById(track->id()))
     151        return;
     152
     153    RefPtr<MediaStreamComponent> component = MediaStreamComponent::create(track->component()->source());
     154    RefPtr<MediaStreamTrack> newTrack = MediaStreamTrack::create(scriptExecutionContext(), m_descriptor, component.get());
     155
    175156    switch (component->source()->type()) {
    176157    case MediaStreamSource::TypeAudio:
    177         m_audioTracks->add(track, ec);
     158        m_descriptor->addAudioComponent(component.release());
     159        m_audioTracks.append(newTrack);
    178160        break;
    179161    case MediaStreamSource::TypeVideo:
    180         m_videoTracks->add(track, ec);
    181         break;
    182     }
    183     ASSERT(!ec);
    184 }
    185 
    186 void MediaStream::removeTrack(MediaStreamComponent* component)
    187 {
     162        m_descriptor->addVideoComponent(component.release());
     163        m_videoTracks.append(newTrack);
     164        break;
     165    }
     166
     167    MediaStreamCenter::instance().didAddMediaStreamTrack(m_descriptor.get(), newTrack->component());
     168    scheduleDispatchEvent(MediaStreamTrackEvent::create(eventNames().addtrackEvent, false, false, newTrack.release()));
     169}
     170
     171void MediaStream::removeTrack(PassRefPtr<MediaStreamTrack> prpTrack , ExceptionCode& ec)
     172{
     173    if (ended()) {
     174        ec = INVALID_STATE_ERR;
     175        return;
     176    }
     177
     178    if (!prpTrack) {
     179        ec = TYPE_MISMATCH_ERR;
     180        return;
     181    }
     182
     183    RefPtr<MediaStreamTrack> track = prpTrack;
     184
     185    switch (track->component()->source()->type()) {
     186    case MediaStreamSource::TypeAudio: {
     187        size_t pos = m_audioTracks.find(track);
     188        if (pos != notFound) {
     189            m_audioTracks.remove(pos);
     190            m_descriptor->removeAudioComponent(track->component());
     191        }
     192        break;
     193    }
     194    case MediaStreamSource::TypeVideo: {
     195        size_t pos = m_videoTracks.find(track);
     196        if (pos != notFound) {
     197            m_videoTracks.remove(pos);
     198            m_descriptor->removeVideoComponent(track->component());
     199        }
     200        break;
     201    }
     202    }
     203
     204    MediaStreamCenter::instance().didRemoveMediaStreamTrack(m_descriptor.get(), track->component());
     205    scheduleDispatchEvent(MediaStreamTrackEvent::create(eventNames().removetrackEvent, false, false, track.release()));
     206}
     207
     208MediaStreamTrack* MediaStream::getTrackById(String id)
     209{
     210    for (MediaStreamTrackVector::iterator iter = m_audioTracks.begin(); iter != m_audioTracks.end(); ++iter) {
     211        if ((*iter)->id() == id)
     212            return (*iter).get();
     213    }
     214
     215    for (MediaStreamTrackVector::iterator iter = m_videoTracks.begin(); iter != m_videoTracks.end(); ++iter) {
     216        if ((*iter)->id() == id)
     217            return (*iter).get();
     218    }
     219
     220    return 0;
     221}
     222
     223void MediaStream::streamEnded()
     224{
     225    if (ended())
     226        return;
     227
     228    m_descriptor->setEnded();
     229    scheduleDispatchEvent(Event::create(eventNames().endedEvent, false, false));
     230}
     231
     232void MediaStream::contextDestroyed()
     233{
     234    m_stopped = true;
     235}
     236
     237const AtomicString& MediaStream::interfaceName() const
     238{
     239    return eventNames().interfaceForMediaStream;
     240}
     241
     242ScriptExecutionContext* MediaStream::scriptExecutionContext() const
     243{
     244    return ContextDestructionObserver::scriptExecutionContext();
     245}
     246
     247EventTargetData* MediaStream::eventTargetData()
     248{
     249    return &m_eventTargetData;
     250}
     251
     252EventTargetData* MediaStream::ensureEventTargetData()
     253{
     254    return &m_eventTargetData;
     255}
     256
     257void MediaStream::addTrack(MediaStreamComponent* component)
     258{
     259    if (ended())
     260        return;
     261
     262    RefPtr<MediaStreamTrack> track = MediaStreamTrack::create(scriptExecutionContext(), m_descriptor, component);
    188263    switch (component->source()->type()) {
    189264    case MediaStreamSource::TypeAudio:
    190         m_audioTracks->remove(component);
     265        m_audioTracks.append(track);
    191266        break;
    192267    case MediaStreamSource::TypeVideo:
    193         m_videoTracks->remove(component);
    194         break;
    195     }
     268        m_videoTracks.append(track);
     269        break;
     270    }
     271
     272    scheduleDispatchEvent(MediaStreamTrackEvent::create(eventNames().addtrackEvent, false, false, track));
     273}
     274
     275void MediaStream::removeTrack(MediaStreamComponent* component)
     276{
     277    if (ended())
     278        return;
     279
     280    MediaStreamTrackVector* tracks = 0;
     281    switch (component->source()->type()) {
     282    case MediaStreamSource::TypeAudio:
     283        tracks = &m_audioTracks;
     284        break;
     285    case MediaStreamSource::TypeVideo:
     286        tracks = &m_videoTracks;
     287        break;
     288    }
     289
     290    size_t index = notFound;
     291    for (size_t i = 0; i < tracks->size(); ++i) {
     292        if ((*tracks)[i]->component() == component) {
     293            index = i;
     294            break;
     295        }
     296    }
     297    if (index == notFound)
     298        return;
     299
     300    RefPtr<MediaStreamTrack> track = (*tracks)[index];
     301    tracks->remove(index);
     302    scheduleDispatchEvent(MediaStreamTrackEvent::create(eventNames().removetrackEvent, false, false, track));
     303}
     304
     305void MediaStream::scheduleDispatchEvent(PassRefPtr<Event> event)
     306{
     307    m_scheduledEvents.append(event);
     308
     309    if (!m_scheduledEventTimer.isActive())
     310        m_scheduledEventTimer.startOneShot(0);
     311}
     312
     313void MediaStream::scheduledEventTimerFired(Timer<MediaStream>*)
     314{
     315    if (m_stopped)
     316        return;
     317
     318    Vector<RefPtr<Event> > events;
     319    events.swap(m_scheduledEvents);
     320
     321    Vector<RefPtr<Event> >::iterator it = events.begin();
     322    for (; it != events.end(); ++it)
     323        dispatchEvent((*it).release());
     324
     325    events.clear();
    196326}
    197327
  • trunk/Source/WebCore/Modules/mediastream/MediaStream.h

    r139598 r139611  
    3131#include "ContextDestructionObserver.h"
    3232#include "EventTarget.h"
     33#include "ExceptionBase.h"
    3334#include "MediaStreamDescriptor.h"
    34 #include "MediaStreamTrackList.h"
     35#include "MediaStreamTrack.h"
     36#include "Timer.h"
    3537#include <wtf/RefCounted.h>
    3638#include <wtf/RefPtr.h>
     
    5153    String id() const { return m_descriptor->id(); }
    5254
    53     MediaStreamTrackList* audioTracks() { return m_audioTracks.get(); }
    54     MediaStreamTrackList* videoTracks() { return m_videoTracks.get(); }
     55    void addTrack(PassRefPtr<MediaStreamTrack>, ExceptionCode&);
     56    void removeTrack(PassRefPtr<MediaStreamTrack>, ExceptionCode&);
     57    MediaStreamTrack* getTrackById(String);
     58
     59    MediaStreamTrackVector getAudioTracks() const { return m_audioTracks; }
     60    MediaStreamTrackVector getVideoTracks() const { return m_videoTracks; }
    5561
    5662    bool ended() const;
    5763
    5864    DEFINE_ATTRIBUTE_EVENT_LISTENER(ended);
     65    DEFINE_ATTRIBUTE_EVENT_LISTENER(addtrack);
     66    DEFINE_ATTRIBUTE_EVENT_LISTENER(removetrack);
    5967
    6068    // MediaStreamDescriptorClient
     
    7987    virtual EventTargetData* ensureEventTargetData() OVERRIDE;
    8088
     89    // ContextDestructionObserver
     90    virtual void contextDestroyed();
     91
    8192private:
    8293    // EventTarget
     
    8899    virtual void removeTrack(MediaStreamComponent*) OVERRIDE;
    89100
     101    void scheduleDispatchEvent(PassRefPtr<Event>);
     102    void scheduledEventTimerFired(Timer<MediaStream>*);
     103
     104    bool m_stopped;
     105
    90106    EventTargetData m_eventTargetData;
    91107
    92     RefPtr<MediaStreamTrackList> m_audioTracks;
    93     RefPtr<MediaStreamTrackList> m_videoTracks;
     108    MediaStreamTrackVector m_audioTracks;
     109    MediaStreamTrackVector m_videoTracks;
    94110    RefPtr<MediaStreamDescriptor> m_descriptor;
     111
     112    Timer<MediaStream> m_scheduledEventTimer;
     113    Vector<RefPtr<Event> > m_scheduledEvents;
    95114};
    96115
  • trunk/Source/WebCore/Modules/mediastream/MediaStream.idl

    r139598 r139611  
    3737    readonly attribute DOMString id;
    3838
    39     readonly attribute MediaStreamTrackList audioTracks;
    40     readonly attribute MediaStreamTrackList videoTracks;
     39    sequence<MediaStreamTrack> getAudioTracks();
     40    sequence<MediaStreamTrack> getVideoTracks();
     41
     42    void addTrack(MediaStreamTrack track)
     43        raises(DOMException);
     44    void removeTrack(MediaStreamTrack track)
     45        raises(DOMException);
     46    MediaStreamTrack getTrackById(DOMString trackId);
    4147
    4248    readonly attribute boolean ended;
    4349
    4450    attribute EventListener onended;
     51    attribute EventListener onaddtrack;
     52    attribute EventListener onremovetrack;
    4553
    4654    // EventTarget interface
  • trunk/Source/WebCore/Modules/webaudio/AudioContext.cpp

    r139262 r139611  
    396396    AudioSourceProvider* provider = 0;
    397397
    398     if (mediaStream->isLocal() && mediaStream->audioTracks()->length()) {
     398    if (mediaStream->isLocal() && mediaStream->getAudioTracks().size()) {
    399399        provider = destination()->localAudioInputProvider();
    400400        destination()->enableInput();
  • trunk/Source/WebCore/WebCore.gypi

    r139533 r139611  
    7272            'Modules/mediastream/MediaStreamTrack.idl',
    7373            'Modules/mediastream/MediaStreamTrackEvent.idl',
    74             'Modules/mediastream/MediaStreamTrackList.idl',
    7574            'Modules/mediastream/NavigatorMediaStream.idl',
    7675            'Modules/mediastream/NavigatorUserMediaError.idl',
     
    815814            'Modules/mediastream/MediaStreamTrackEvent.cpp',
    816815            'Modules/mediastream/MediaStreamTrackEvent.h',
    817             'Modules/mediastream/MediaStreamTrackList.cpp',
    818             'Modules/mediastream/MediaStreamTrackList.h',
    819816            'Modules/mediastream/NavigatorMediaStream.cpp',
    820817            'Modules/mediastream/NavigatorMediaStream.h',
  • trunk/Source/WebCore/dom/EventTargetFactory.in

    r134084 r139611  
    2020MediaStream conditional=MEDIA_STREAM
    2121MediaStreamTrack conditional=MEDIA_STREAM
    22 MediaStreamTrackList conditional=MEDIA_STREAM
    2322MessagePort
    2423NetworkInfoConnection conditional=NETWORK_INFO
  • trunk/Source/WebCore/platform/mediastream/MediaStreamDescriptor.h

    r139352 r139611  
    6969    unsigned numberOfAudioComponents() const { return m_audioComponents.size(); }
    7070    MediaStreamComponent* audioComponent(unsigned index) const { return m_audioComponents[index].get(); }
     71    void addAudioComponent(PassRefPtr<MediaStreamComponent> component) { m_audioComponents.append(component); }
     72    void removeAudioComponent(MediaStreamComponent* component)
     73    {
     74        size_t pos = m_audioComponents.find(component);
     75        if (pos != notFound)
     76            m_audioComponents.remove(pos);
     77    }
    7178
    7279    unsigned numberOfVideoComponents() const { return m_videoComponents.size(); }
    7380    MediaStreamComponent* videoComponent(unsigned index) const { return m_videoComponents[index].get(); }
     81    void addVideoComponent(PassRefPtr<MediaStreamComponent> component) { m_videoComponents.append(component); }
     82    void removeVideoComponent(MediaStreamComponent* component)
     83    {
     84        size_t pos = m_audioComponents.find(component);
     85        if (pos != notFound)
     86            m_audioComponents.remove(pos);
     87    }
    7488
    7589    bool ended() const { return m_ended; }
Note: See TracChangeset for help on using the changeset viewer.