Changeset 186081 in webkit


Ignore:
Timestamp:
Jun 29, 2015 12:52:21 PM (9 years ago)
Author:
adam.bergkvist@ericsson.com
Message:

WebRTC: Update the MediaStream API
https://bugs.webkit.org/show_bug.cgi?id=146313

Reviewed by Eric Carlson.

Source/WebCore:

Update the MediaStream API (MediaStream, MediaStreamTrack and
RealtimeMediaSource) to match the Media Capture and Stream
specification [1]. Notable changes:

Updated event handling to synchronously update corresponding
state/attributes as events are dispatched.

Removed 'new' state from MediaStreamTrack. A track is either 'live' or
'ended'. As a consequence 'started' event is also removed.

MediaStreamTrack always has a source (disconnected source concept was
removed from the spec). Therefore, more state can be kept at the source
without going away.

Calculate MediaStream.active internally, from the track set, instead of
setting it externally.

Updated RealtimeMediaSource Observer interface.

Replaced MediaStream's separate audio and video track lists with a
single track set (more aligned with spec).

Updated MediaStream constructor to adopt instead of clone track
arguments (or tracks from MediaStream argument).

Removed MediaStreamTrack.getSources() and corresponding test (removed
from spec).

Test status: 3 added, 8 existing enabled (some updated) and 1 removed.

[1] http://w3c.github.io/mediacapture-main/archives/20150523/getusermedia.html

Tests: fast/mediastream/MediaStreamTrack-clone.html

fast/mediastream/MediaStreamTrack-kind.html
fast/mediastream/MediaStreamTrack-stop.html

  • Modules/mediastream/MediaStream.cpp:

(WebCore::MediaStream::create):
(WebCore::MediaStream::MediaStream):
(WebCore::MediaStream::clone):
(WebCore::MediaStream::addTrack):
(WebCore::MediaStream::removeTrack):
(WebCore::MediaStream::getTrackById):
(WebCore::MediaStream::getAudioTracks):
(WebCore::MediaStream::getVideoTracks):
(WebCore::MediaStream::getTracks):
(WebCore::MediaStream::contextDestroyed):
(WebCore::MediaStream::trackDidEnd):
(WebCore::MediaStream::activeStatusChanged):
(WebCore::MediaStream::didAddTrackToPrivate):
(WebCore::MediaStream::didRemoveTrackFromPrivate):
(WebCore::MediaStream::internalAddTrack):
(WebCore::MediaStream::internalRemoveTrack):
(WebCore::MediaStream::scheduleActiveStateChange):
(WebCore::MediaStream::activityEventTimerFired):
(WebCore::MediaStream::trackVectorForType):
(WebCore::MediaStream::~MediaStream): Deleted.
(WebCore::MediaStream::registry): Deleted.
(WebCore::MediaStream::addObserver): Deleted.
(WebCore::MediaStream::removeObserver): Deleted.

  • Modules/mediastream/MediaStream.h:
  • Modules/mediastream/MediaStream.idl:
  • Modules/mediastream/MediaStreamTrack.cpp:

(WebCore::MediaStreamTrack::MediaStreamTrack):
(WebCore::MediaStreamTrack::~MediaStreamTrack):
(WebCore::MediaStreamTrack::kind):
(WebCore::MediaStreamTrack::id):
(WebCore::MediaStreamTrack::label):
(WebCore::MediaStreamTrack::enabled):
(WebCore::MediaStreamTrack::setEnabled):
(WebCore::MediaStreamTrack::muted):
(WebCore::MediaStreamTrack::readonly):
(WebCore::MediaStreamTrack::remote):
(WebCore::MediaStreamTrack::readyState):
(WebCore::MediaStreamTrack::ended):
(WebCore::MediaStreamTrack::clone):
(WebCore::MediaStreamTrack::stopProducingData):
(WebCore::MediaStreamTrack::states):
(WebCore::MediaStreamTrack::getCapabilities):
(WebCore::MediaStreamTrack::applyConstraints):
(WebCore::MediaStreamTrack::trackEnded):
(WebCore::MediaStreamTrack::trackMutedChanged):
(WebCore::MediaStreamTrack::stop):
(WebCore::MediaStreamTrack::getConstraints): Deleted.
(WebCore::MediaStreamTrack::addObserver): Deleted.
(WebCore::MediaStreamTrack::removeObserver): Deleted.
(WebCore::MediaStreamTrack::configureTrackRendering): Deleted.
(WebCore::MediaStreamTrack::activeDOMObjectName): Deleted.
(WebCore::MediaStreamTrack::canSuspendForPageCache): Deleted.

  • Modules/mediastream/MediaStreamTrack.h:
  • Modules/mediastream/MediaStreamTrack.idl:
  • Modules/mediastream/RTCPeerConnection.cpp:

(WebCore::RTCPeerConnection::didRemoveRemoteStream): Deleted.

  • Modules/mediastream/UserMediaRequest.cpp:

(WebCore::UserMediaRequest::didCreateStream):

  • platform/mediastream/MediaStreamPrivate.cpp:

(WebCore::MediaStreamPrivate::create):
(WebCore::MediaStreamPrivate::MediaStreamPrivate):
(WebCore::MediaStreamPrivate::tracks):
(WebCore::MediaStreamPrivate::updateActiveState):
(WebCore::MediaStreamPrivate::addTrack):
(WebCore::MediaStreamPrivate::removeTrack):

  • platform/mediastream/MediaStreamPrivate.h:

(WebCore::MediaStreamPrivate::active): Deleted.

  • platform/mediastream/MediaStreamTrackPrivate.cpp:

(WebCore::MediaStreamTrackPrivate::create):
(WebCore::MediaStreamTrackPrivate::MediaStreamTrackPrivate):
(WebCore::MediaStreamTrackPrivate::~MediaStreamTrackPrivate):
(WebCore::MediaStreamTrackPrivate::label):
(WebCore::MediaStreamTrackPrivate::setEnabled):
(WebCore::MediaStreamTrackPrivate::endTrack):
(WebCore::MediaStreamTrackPrivate::clone):
(WebCore::MediaStreamTrackPrivate::type):
(WebCore::MediaStreamTrackPrivate::applyConstraints):
(WebCore::MediaStreamTrackPrivate::sourceStopped):
(WebCore::MediaStreamTrackPrivate::sourceMutedChanged):
(WebCore::MediaStreamTrackPrivate::preventSourceFromStopping):
(WebCore::MediaStreamTrackPrivate::muted): Deleted.
(WebCore::MediaStreamTrackPrivate::readonly): Deleted.
(WebCore::MediaStreamTrackPrivate::remote): Deleted.
(WebCore::MediaStreamTrackPrivate::constraints): Deleted.
(WebCore::MediaStreamTrackPrivate::states): Deleted.
(WebCore::MediaStreamTrackPrivate::capabilities): Deleted.

  • platform/mediastream/MediaStreamTrackPrivate.h:

(WebCore::MediaStreamTrackPrivate::id):
(WebCore::MediaStreamTrackPrivate::ended):
(WebCore::MediaStreamTrackPrivate::enabled):
(WebCore::MediaStreamTrackPrivate::setClient):
(WebCore::MediaStreamTrackPrivate::source): Deleted.
(WebCore::MediaStreamTrackPrivate::client): Deleted.

  • platform/mediastream/RealtimeMediaSource.cpp:

(WebCore::RealtimeMediaSource::RealtimeMediaSource):
(WebCore::RealtimeMediaSource::reset):
(WebCore::RealtimeMediaSource::setMuted):
(WebCore::RealtimeMediaSource::readonly):
(WebCore::RealtimeMediaSource::stop):
(WebCore::RealtimeMediaSource::requestStop):
(WebCore::RealtimeMediaSource::addObserver): Deleted.
(WebCore::RealtimeMediaSource::removeObserver): Deleted.

  • platform/mediastream/RealtimeMediaSource.h:

(WebCore::RealtimeMediaSource::stopped):
(WebCore::RealtimeMediaSource::id): Deleted.
(WebCore::RealtimeMediaSource::muted): Deleted.
(WebCore::RealtimeMediaSource::setReadonly): Deleted.

  • platform/mediastream/openwebrtc/RealtimeMediaSourceCenterOwr.cpp:

(WebCore::RealtimeMediaSourceCenterOwr::createMediaStream): Deleted.

  • platform/mock/MockRealtimeMediaSourceCenter.cpp:

(WebCore::MockRealtimeMediaSourceCenter::createMediaStream): Deleted.

LayoutTests:

Test status: 3 added, 8 existing enabled (some updated) and 1 removed.

  • TestExpectations:
  • fast/mediastream/MediaStream-add-ended-tracks-expected.txt:
  • fast/mediastream/MediaStream-add-ended-tracks.html:
  • fast/mediastream/MediaStream-add-remove-tracks-expected.txt:
  • fast/mediastream/MediaStream-add-remove-tracks.html:
  • fast/mediastream/MediaStream-add-tracks-to-inactive-stream.html:
  • fast/mediastream/MediaStream-clone-expected.txt: Added.
  • fast/mediastream/MediaStream-clone.html:
  • fast/mediastream/MediaStream-construct-with-ended-tracks-expected.txt: Added.
  • fast/mediastream/MediaStream-construct-with-ended-tracks.html:
  • fast/mediastream/MediaStream-getTracks-expected.txt:
  • fast/mediastream/MediaStream-getTracks.html:
  • fast/mediastream/MediaStreamConstructor.html:
  • fast/mediastream/MediaStreamTrack-clone-expected.txt: Added.
  • fast/mediastream/MediaStreamTrack-clone.html: Added.
  • fast/mediastream/MediaStreamTrack-getSources-expected.txt: Removed.
  • fast/mediastream/MediaStreamTrack-getSources.html: Removed. Tested method removed from spec.
  • fast/mediastream/MediaStreamTrack-kind-expected.txt: Added.
  • fast/mediastream/MediaStreamTrack-kind.html: Added.
  • fast/mediastream/MediaStreamTrack-stop-expected.txt: Added.
  • fast/mediastream/MediaStreamTrack-stop.html: Added.
  • fast/mediastream/MediaStreamTrackEvent-constructor-expected.txt:
  • fast/mediastream/MediaStreamTrackEvent-constructor.html:
  • fast/mediastream/resources/getUserMedia-helper.js: Added.

(.reject):
(getUserMedia):
(defaultRejectOrCatch):

  • platform/gtk/TestExpectations:
Location:
trunk
Files:
10 added
2 deleted
32 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r186078 r186081  
     12015-06-29  Adam Bergkvist  <adam.bergkvist@ericsson.com>
     2
     3        WebRTC: Update the MediaStream API
     4        https://bugs.webkit.org/show_bug.cgi?id=146313
     5
     6        Reviewed by Eric Carlson.
     7
     8        Test status: 3 added, 8 existing enabled (some updated) and 1 removed.
     9
     10        * TestExpectations:
     11        * fast/mediastream/MediaStream-add-ended-tracks-expected.txt:
     12        * fast/mediastream/MediaStream-add-ended-tracks.html:
     13        * fast/mediastream/MediaStream-add-remove-tracks-expected.txt:
     14        * fast/mediastream/MediaStream-add-remove-tracks.html:
     15        * fast/mediastream/MediaStream-add-tracks-to-inactive-stream.html:
     16        * fast/mediastream/MediaStream-clone-expected.txt: Added.
     17        * fast/mediastream/MediaStream-clone.html:
     18        * fast/mediastream/MediaStream-construct-with-ended-tracks-expected.txt: Added.
     19        * fast/mediastream/MediaStream-construct-with-ended-tracks.html:
     20        * fast/mediastream/MediaStream-getTracks-expected.txt:
     21        * fast/mediastream/MediaStream-getTracks.html:
     22        * fast/mediastream/MediaStreamConstructor.html:
     23        * fast/mediastream/MediaStreamTrack-clone-expected.txt: Added.
     24        * fast/mediastream/MediaStreamTrack-clone.html: Added.
     25        * fast/mediastream/MediaStreamTrack-getSources-expected.txt: Removed.
     26        * fast/mediastream/MediaStreamTrack-getSources.html: Removed. Tested method removed from spec.
     27        * fast/mediastream/MediaStreamTrack-kind-expected.txt: Added.
     28        * fast/mediastream/MediaStreamTrack-kind.html: Added.
     29        * fast/mediastream/MediaStreamTrack-stop-expected.txt: Added.
     30        * fast/mediastream/MediaStreamTrack-stop.html: Added.
     31        * fast/mediastream/MediaStreamTrackEvent-constructor-expected.txt:
     32        * fast/mediastream/MediaStreamTrackEvent-constructor.html:
     33        * fast/mediastream/resources/getUserMedia-helper.js: Added.
     34        (.reject):
     35        (getUserMedia):
     36        (defaultRejectOrCatch):
     37        * platform/gtk/TestExpectations:
     38
    1392015-06-29  Matt Rajca  <mrajca@apple.com>
    240
  • trunk/LayoutTests/TestExpectations

    r186061 r186081  
    4444
    4545webkit.org/b/53990 fast/forms/search-event-delay.html [ Pass Failure ]
    46 
    47 # No port in WebKit already support getMediaStream, so we are skipping those for now.
    48 fast/mediastream/MediaStream-construct-with-ended-tracks.html [ Skip ]
    49 fast/mediastream/MediaStream-clone.html [ Skip ]
    5046
    5147webkit.org/b/126142 css3/calc/transitions-dependent.html [ Pass Failure ]
  • trunk/LayoutTests/fast/mediastream/MediaStream-add-ended-tracks-expected.txt

    r169611 r186081  
    55
    66PASS stream1.getAudioTracks().length is 1
    7 PASS stream2.getAudioTracks().length is 1
     7PASS stream1.getVideoTracks().length is 1
     8*** extract audioTrack
     9*** stop audioTrack
    810PASS audioTrack.readyState is "ended"
    9 PASS stream2.getAudioTracks().length is 2
     11*** construct new 'empty' stream2
     12PASS stream2.getTracks().length is 0
     13PASS stream2.active is false
     14*** add ended audioTrack to stream2
     15*** schedule continuation of test
     16*** extract videoTrack (and verify liveness)
     17PASS videoTrack.readyState is "live"
     18*** add live videoTrack to stream2
     19*** stream2 is active again
     20PASS stream2.active is true
    1021PASS successfullyParsed is true
    1122
  • trunk/LayoutTests/fast/mediastream/MediaStream-add-ended-tracks.html

    r169611 r186081  
    33    <head>
    44        <script src="../../resources/js-test-pre.js"></script>
     5        <script src="./resources/getUserMedia-helper.js"></script>
    56        <script>
    67
     
    89            var stream2;
    910            var audioTrack;
    10 
    11             function error()
    12             {
    13                 testFailed('Stream generation failed.');
    14                 finishJSTest();
    15             }
    16 
    17             function getUserMedia(dictionary, callback)
    18             {
    19                 try {
    20                     navigator.webkitGetUserMedia(dictionary, callback, error);
    21                 } catch (e) {
    22                     testFailed('webkitGetUserMedia threw exception :' + e);
    23                     finishJSTest();
    24                 }
    25             }
     11            var videoTrack;
    2612
    2713            function tryAddTrack(stream, track)
     
    3521            }
    3622
    37             function createStreamAndAddTracks()
     23            function shouldNotFireActive()
    3824            {
    39                 shouldBe('stream2.getAudioTracks().length', '1');
    40                 audioTrack = stream1.getAudioTracks()[0];
    41                 audioTrack.stop();
    42                 shouldBeEqualToString('audioTrack.readyState', 'ended');
    43                 tryAddTrack(stream2, audioTrack);
    44                 shouldBe('stream2.getAudioTracks().length', '2');
     25                testFailed("stream2 should not become active if an ended track is added");
     26            }
    4527
     28            function shouldFireActive()
     29            {
     30                debug("*** stream2 is active again");
     31                shouldBe('stream2.active', 'true');
    4632                finishJSTest();
    4733            }
    4834
    49             function gotStream2(s)
     35            function continueTest()
    5036            {
    51                 stream2 = s;
    52                 createStreamAndAddTracks();
     37                debug("*** extract videoTrack (and verify liveness)");
     38                videoTrack = stream1.getVideoTracks()[0];
     39                shouldBeEqualToString('videoTrack.readyState', 'live');
     40
     41                debug("*** add live videoTrack to stream2");
     42                stream2.onactive = shouldFireActive;
     43                tryAddTrack(stream2, videoTrack);
    5344            }
    5445
    55             function gotStream1(s)
     46            function createStreamAndAddTracks()
     47            {
     48                debug("*** extract audioTrack");
     49                audioTrack = stream1.getAudioTracks()[0];
     50                debug("*** stop audioTrack");
     51                audioTrack.stop();
     52                shouldBeEqualToString('audioTrack.readyState', 'ended');
     53
     54                debug("*** construct new 'empty' stream2")
     55                stream2 = new webkitMediaStream();
     56                shouldBe('stream2.getTracks().length', '0');
     57                shouldBe('stream2.active', 'false');
     58
     59                debug("*** add ended audioTrack to stream2");
     60                stream2.onactive = shouldNotFireActive;
     61                tryAddTrack(stream2, audioTrack);
     62
     63                debug("*** schedule continuation of test");
     64                setTimeout(continueTest);
     65            }
     66
     67            function gotStream(s)
    5668            {
    5769                stream1 = s;
    5870                shouldBe('stream1.getAudioTracks().length', '1');
    59                 getUserMedia({audio:true, video:true}, gotStream2);
     71                shouldBe('stream1.getVideoTracks().length', '1');
     72                createStreamAndAddTracks();
    6073            }
    6174
     
    6376            {
    6477                description("Test adding tracks to inactive MediaStream.");
    65                 getUserMedia({audio:true, video:true}, gotStream1);
     78                getUserMedia("allow", {audio:true, video:true}, gotStream);
    6679            }
    6780            window.jsTestIsAsync = true;
  • trunk/LayoutTests/fast/mediastream/MediaStream-add-remove-tracks-expected.txt

    r168679 r186081  
    4545PASS stream1.getVideoTracks().length is 2
    4646
    47 *** remove all tracks, stream.ended should return true
     47*** remove all tracks, stream will become inactive
    4848PASS stream2.getAudioTracks().length is 0
    4949PASS stream2.getVideoTracks().length is 0
    5050
    51 *** it should be impossible to remove a track after the stream has ended
    52 PASS stream2.removeTrack(audioTrack) threw exception Error: InvalidStateError: DOM Exception 11.
     51*** active attribute is still true (until event is fired)
     52PASS stream2.active is true
     53
    5354Stream2 is inactive.
     55PASS stream2.active is false
     56
     57*** add non-ended track
     58PASS audioTrack.readyState is not "ended"
     59
     60*** active attribute is still false (until event is fired)
     61PASS stream2.active is false
     62
     63Stream2 is active.
     64PASS stream2.active is true
    5465PASS successfullyParsed is true
    5566
  • trunk/LayoutTests/fast/mediastream/MediaStream-add-remove-tracks.html

    r168679 r186081  
    33    <head>
    44        <script src="../../resources/js-test-pre.js"></script>
     5        <script src="./resources/getUserMedia-helper.js"></script>
    56    </head>
    67    <body>
     
    1415            var audioTrack;
    1516            var videoTrack;
    16 
    17             function error() {
    18                 testFailed('Stream generation failed.');
    19                 finishJSTest();
    20             }
    21 
    22             function getUserMedia(dictionary, callback) {
    23                 try {
    24                     navigator.webkitGetUserMedia(dictionary, callback, error);
    25                 } catch (e) {
    26                     testFailed('webkitGetUserMedia threw exception :' + e);
    27                     finishJSTest();
    28                 }
    29             }
    3017
    3118            function tryAddTrack(stream, track) {
     
    5239
    5340            function shouldFireActive() {
    54                 debug("Stream2 is active.");
     41                debug("<br>Stream2 is active.");
     42                shouldBe('stream2.active', 'true');
    5543                finishJSTest();
    5644            }
    5745
    5846            function shouldFireInActive() {
    59                 debug("Stream2 is inactive.");
    60                 finishJSTest();
     47                debug("<br>Stream2 is inactive.");
     48                shouldBe('stream2.active', 'false');
     49
     50                debug("<br>*** add non-ended track");
     51                shouldNotBe('audioTrack.readyState', '"ended"');
     52                tryAddTrack(stream2, audioTrack);
     53
     54                debug("<br>*** active attribute is still false (until event is fired)");
     55                shouldBe('stream2.active', 'false');
    6156            }
    6257
     
    125120                shouldBe('stream1.getVideoTracks().length', '2');
    126121
    127                 debug("<br>*** remove all tracks, stream.ended should return true");
     122                debug("<br>*** remove all tracks, stream will become inactive");
    128123                tryRemoveTrack(stream2, stream2.getAudioTracks()[0]);
    129124                tryRemoveTrack(stream2, stream2.getVideoTracks()[0]);
     
    131126                shouldBe('stream2.getVideoTracks().length', '0');
    132127
    133                 debug("<br>*** it should be impossible to remove a track after the stream has ended");
    134                 shouldThrow('stream2.removeTrack(audioTrack)', '"Error: InvalidStateError: DOM Exception 11"');
     128                debug("<br>*** active attribute is still true (until event is fired)");
     129                shouldBe('stream2.active', 'true');
    135130            }
    136131
    137132            function gotStream1(s) {
    138133                stream1 = s;
    139                 getUserMedia({audio:true, video:true}, gotStream2);
     134                getUserMedia("allow", {audio:true, video:true}, gotStream2);
    140135            }
    141136
    142             getUserMedia({audio:true, video:true}, gotStream1);
     137            getUserMedia("allow", {audio:true, video:true}, gotStream1);
    143138
    144139            window.jsTestIsAsync = true;
  • trunk/LayoutTests/fast/mediastream/MediaStream-add-tracks-to-inactive-stream.html

    r168679 r186081  
    33    <head>
    44        <script src="../../resources/js-test-pre.js"></script>
     5        <script src="./resources/getUserMedia-helper.js"></script>
    56        <script>
    67
     
    89            var stream1;
    910            var audioTrack;
    10 
    11             function error()
    12             {
    13                 testFailed('Stream generation failed.');
    14                 finishJSTest();
    15             }
    16 
    17             function getUserMedia(dictionary, callback)
    18             {
    19                 try {
    20                     navigator.webkitGetUserMedia(dictionary, callback, error);
    21                 } catch (e) {
    22                     testFailed('webkitGetUserMedia threw exception :' + e);
    23                     finishJSTest();
    24                 }
    25             }
    2611
    2712            function tryAddTrack(stream, track)
     
    5641            {
    5742                description("Test adding tracks to inactive MediaStream.");
    58                 getUserMedia({audio:true, video:true}, gotStream1);
     43                getUserMedia("allow", {audio:true, video:true}, gotStream1);
    5944            }
    6045            window.jsTestIsAsync = true;
  • trunk/LayoutTests/fast/mediastream/MediaStream-clone.html

    r157273 r186081  
    33    <head>
    44        <script src="../../resources/js-test-pre.js"></script>
     5        <script src="./resources/getUserMedia-helper.js"></script>
    56        <script>
    67            var mediaStream;
    78            var newMediaStream;
    8             var audioTracks;
    9             var videoTracks;
    10             var newAudioTracks;
    11             var newVideoTracks;
     9            var track;
     10            var newTrack;
    1211
    13             function checkTracks(trackSet1, trackSet2) {
    14                 for (var i = 0; i < trackSet1.length; i++) {
    15                     shouldBe('trackSet1[i].readyState', 'trackSet2[i].readyState');
    16                     shouldBe('trackSet1[i].enabled', 'trackSet2[i].enabled');
    17                     shouldBe('trackSet1[i].muted', 'trackSet2[i].muted');
    18                 }
     12            function checkTracks(track1, track2) {
     13                track = track1;
     14                newTrack = track2;
     15                debug("check tracks");
     16                shouldNotBe('track.id', 'newTrack.id');
     17                shouldBe('track.kind', 'newTrack.kind');
     18                shouldBe('track.label', 'newTrack.label');
     19                shouldBe('track.readyState', 'newTrack.readyState');
     20                shouldBe('track.enabled', 'newTrack.enabled');
     21                shouldBe('track.muted', 'newTrack.muted');
     22                debug("done");
    1923            }
    2024
     
    2327                debug("");
    2428
     29                // Since we don't have any guarantees on the order from getAudio/VideoTracks(), we
     30                // can't have a stream with more than one track of each kind.
     31                shouldBe('mediaStream.getAudioTracks().length', '1');
     32                shouldBe('mediaStream.getVideoTracks().length', '1');
     33
    2534                evalAndLog("newMediaStream = mediaStream.clone()");
    2635
    2736                shouldNotBe('mediaStream.id', 'newMediaStream.id');
    2837
    29                 evalAndLog("audioTracks = mediaStream.getAudioTracks()");
    30                 evalAndLog("videoTracks = mediaStream.getVideoTracks()");
    31                 evalAndLog("newAudioTracks = newMediaStream.getAudioTracks()");
    32                 evalAndLog("newVideoTracks = newMediaStream.getVideoTracks()");
     38                checkTracks(mediaStream.getAudioTracks()[0], newMediaStream.getAudioTracks()[0]);
     39                checkTracks(mediaStream.getVideoTracks()[0], newMediaStream.getVideoTracks()[0]);
    3340
    34                 checkTracks(audioTracks, newAudioTracks);
    35                 checkTracks(videoTracks, newVideoTracks);
    36             }
    37 
    38             function getUserMediaError() {
    39                 testFailed('Could not get MediaStream');
    4041                finishJSTest();
    4142            }
    4243
    4344            function start() {
    44                 try {
    45                     navigator.webkitGetUserMedia({audio:true, video:true}, gotStream, getUserMediaError);
    46                 } catch (e) {
    47                     testFailed('webkitGetUserMedia threw exception :' + e);
    48                     finishJSTest();
    49                 }
     45                getUserMedia("allow", {audio:true, video:true}, gotStream);
    5046            }
    5147
  • trunk/LayoutTests/fast/mediastream/MediaStream-construct-with-ended-tracks.html

    r157268 r186081  
    33    <head>
    44        <script src="../../resources/js-test-pre.js"></script>
     5        <script src="./resources/getUserMedia-helper.js"></script>
    56        <script>
    67            var mediaStream;
     
    89            var audioTrack;
    910            var newMediaStream;
     11            var mediaStreamCopy;
    1012
    1113            function gotStream(stream) {
    1214                mediaStream = stream;
    1315                debug("");
    14                 shouldEvaluateTo('mediaStream.ended', false);
     16                shouldEvaluateTo('mediaStream.active', true);
    1517
    1618                evalAndLog("videoTrack = mediaStream.getVideoTracks()[0]");
     
    3032                newMediaStream = new webkitMediaStream(tracksArray);
    3133
    32                 shouldEvaluateTo('newMediaStream.ended', true);
    33                 shouldNotBeEqualToString(mediaStream.id, newMediaStream.id);
     34                shouldEvaluateTo('newMediaStream.active', false);
     35                shouldNotBe('mediaStream.id', 'newMediaStream.id');
    3436
    35                 var mediaStreamCopy = new webkitMediaStream(newMediaStream);
    36                 shouldEvaluateTo('mediaStreamCopy.ended', true);
     37                mediaStreamCopy = new webkitMediaStream(newMediaStream);
     38                shouldEvaluateTo('mediaStreamCopy.active', false);
    3739                shouldNotBe('mediaStreamCopy.id', 'newMediaStream.id');
    38             }
    3940
    40             function getUserMediaError() {
    41                 testFailed('Could not get MediaStream');
    4241                finishJSTest();
    4342            }
    4443
    4544            function start() {
    46                 try {
    47                     navigator.webkitGetUserMedia({audio:true, video:true}, gotStream, getUserMediaError);
    48                 } catch (e) {
    49                     testFailed('webkitGetUserMedia threw exception :' + e);
    50                     finishJSTest();
    51                 }
     45                getUserMedia("allow", {audio:true, video:true}, gotStream);
    5246            }
    5347
  • trunk/LayoutTests/fast/mediastream/MediaStream-getTracks-expected.txt

    r169743 r186081  
    1 Test adding tracks to inactive MediaStream.
     1Test the different methods to get tracks from a MediaStream.
    22
    33On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
     
    66PASS stream1.getTracks().length is 2
    77PASS stream2.getTracks().length is 2
     8getAudioTracks(), getVideoTracks() and getTracks() must return a new sequence at every invocation
     9PASS stream2.getAudioTracks() != stream2.getAudioTracks() is true
     10PASS stream2.getVideoTracks() != stream2.getVideoTracks() is true
     11PASS stream2.getTracks() != stream2.getTracks() is true
    812PASS track added to stream.
    913PASS stream2.getAudioTracks().length is 2
     
    1317PASS stream2.getAudioTracks().length is 2
    1418PASS stream2.getVideoTracks().length is 2
    15 PASS stream2.getTracks().length is 4
     19PASS allTracks.length is 4
     20PASS stream2.getTrackById(id) is non-null.
     21PASS stream2.getTrackById(id) is non-null.
     22PASS stream2.getTrackById(id) is non-null.
     23PASS stream2.getTrackById(id) is non-null.
     24PASS stream2.getTrackById("foo-id") is null
    1625PASS successfullyParsed is true
    1726
  • trunk/LayoutTests/fast/mediastream/MediaStream-getTracks.html

    r169743 r186081  
    33    <head>
    44        <script src="../../resources/js-test-pre.js"></script>
     5        <script src="./resources/getUserMedia-helper.js"></script>
    56        <script>
    67
     
    910            var audioTrack;
    1011            var videoTrack;
    11 
    12             function error()
    13             {
    14                 testFailed('Stream generation failed.');
    15                 finishJSTest();
    16             }
    17 
    18             function getUserMedia(dictionary, callback)
    19             {
    20                 try {
    21                     navigator.webkitGetUserMedia(dictionary, callback, error);
    22                 } catch (e) {
    23                     testFailed('webkitGetUserMedia threw exception :' + e);
    24                     finishJSTest();
    25                 }
    26             }
     12            var allTracks;
     13            var id;
    2714
    2815            function tryAddTrack(stream, track)
     
    4027            {
    4128                shouldBe('stream2.getTracks().length', '2');
     29
     30                debug('getAudioTracks(), getVideoTracks() and getTracks() must return a new sequence at every invocation');
     31                shouldBeTrue('stream2.getAudioTracks() != stream2.getAudioTracks()');
     32                shouldBeTrue('stream2.getVideoTracks() != stream2.getVideoTracks()');
     33                shouldBeTrue('stream2.getTracks() != stream2.getTracks()');
     34
    4235                audioTrack = stream1.getAudioTracks()[0];
    4336                tryAddTrack(stream2, audioTrack);
     
    4942                shouldBe('stream2.getAudioTracks().length', '2');
    5043                shouldBe('stream2.getVideoTracks().length', '2');
    51                 shouldBe('stream2.getTracks().length', '4');
     44                allTracks = stream2.getTracks();
     45                shouldBe('allTracks.length', '4');
     46                allTracks.forEach(function (track) {
     47                    id = track.id;
     48                    shouldBeNonNull('stream2.getTrackById(id)');
     49                })
     50                shouldBeNull('stream2.getTrackById("foo-id")');
    5251
    5352                finishJSTest();
     
    6463                stream1 = s;
    6564                shouldBe('stream1.getTracks().length', '2');
    66                 getUserMedia({audio:true, video:true}, gotStream2);
     65                getUserMedia("allow", {audio:true, video:true}, gotStream2);
    6766            }
    6867
    6968            function startMedia()
    7069            {
    71                 description("Test adding tracks to inactive MediaStream.");
    72                 getUserMedia({audio:true, video:true}, gotStream1);
     70                description("Test the different methods to get tracks from a MediaStream.");
     71                getUserMedia("allow", {audio:true, video:true}, gotStream1);
    7372            }
    7473            window.jsTestIsAsync = true;
  • trunk/LayoutTests/fast/mediastream/MediaStreamConstructor.html

    r158987 r186081  
    33    <head>
    44        <script src="../../resources/js-test-pre.js"></script>
     5        <script src="./resources/getUserMedia-helper.js"></script>
    56    </head>
    67    <body>
     
    3940
    4041                return true;
    41             }
    42 
    43             function error() {
    44                 testFailed('Stream generation failed.');
    45                 finishJSTest();
    46             }
    47 
    48             function getUserMedia(dictionary, callback) {
    49                 try {
    50                     navigator.webkitGetUserMedia(dictionary, callback, error);
    51                 } catch (e) {
    52                     testFailed('webkitGetUserMedia threw exception :' + e);
    53                     finishJSTest();
    54                 }
    5542            }
    5643
     
    10592            }
    10693
    107             getUserMedia({video:true, audio:true}, gotStream);
     94            getUserMedia("allow", {video:true, audio:true}, gotStream);
    10895
    10996            window.jsTestIsAsync = true;
  • trunk/LayoutTests/fast/mediastream/MediaStreamTrackEvent-constructor-expected.txt

    r156522 r186081  
    44
    55
    6 PASS getUserMedia({audio:true, video:true}, gotStream) did not throw exception.
    76
    87*** getUserMedia() succeeded, test stream ***
  • trunk/LayoutTests/fast/mediastream/MediaStreamTrackEvent-constructor.html

    r156522 r186081  
    33    <head>
    44        <script src="../../resources/js-test-pre.js"></script>
     5        <script src="./resources/getUserMedia-helper.js"></script>
    56    </head>
    67        <script>
     
    1819                clearTimeout(timer);
    1920                finishJSTest();
    20             }
    21 
    22             function error()
    23             {
    24                 testFailed('Stream generation failed.');
    25                 endTest();
    26             }
    27 
    28             function getUserMedia(constraints, callback)
    29             {
    30                 try {
    31                     navigator.webkitGetUserMedia(constraints, callback, error);
    32                 } catch (e) {
    33                     testFailed('webkitGetUserMedia threw exception :' + e);
    34                     endTest();
    35                 }
    3621            }
    3722
     
    9378            {
    9479                primeTimeout("Timeout waiting for getUserMedia()");
    95                 shouldNotThrow('getUserMedia({audio:true, video:true}, gotStream)');
     80                 getUserMedia("allow", {audio:true, video:true}, gotStream);
    9681            }
    9782
  • trunk/LayoutTests/platform/gtk/TestExpectations

    r186021 r186081  
    316316
    317317# Mediastream implementation is not complete yet.
    318 webkit.org/b/79203 fast/mediastream/MediaStream-add-ended-tracks.html [ Skip ]
    319 webkit.org/b/79203 fast/mediastream/MediaStream-add-remove-tracks.html [ Skip ]
    320 webkit.org/b/79203 fast/mediastream/MediaStream-add-tracks-to-inactive-stream.html [ Skip ]
    321 webkit.org/b/79203 fast/mediastream/MediaStream-clone.html [ Skip ]
    322 webkit.org/b/79203 fast/mediastream/MediaStreamConstructor.html [ Skip ]
    323 webkit.org/b/79203 fast/mediastream/MediaStream-construct-with-ended-tracks.html [ Skip ]
    324 webkit.org/b/79203 fast/mediastream/MediaStream-getTracks.html [ Skip ]
    325318webkit.org/b/79203 fast/mediastream/MediaStream-MediaElement-srcObject.html [ Skip ]
    326 webkit.org/b/79203 fast/mediastream/MediaStreamTrackEvent-constructor.html [ Skip ]
    327 webkit.org/b/79203 fast/mediastream/MediaStreamTrack-getSources.html [ Skip ]
    328319webkit.org/b/79203 fast/mediastream/MediaStreamTrack.html [ Skip ]
    329320webkit.org/b/79203 fast/mediastream/MediaStreamTrack-onended.html [ Skip ]
  • trunk/Source/WebCore/ChangeLog

    r186079 r186081  
     12015-06-29  Adam Bergkvist  <adam.bergkvist@ericsson.com>
     2
     3        WebRTC: Update the MediaStream API
     4        https://bugs.webkit.org/show_bug.cgi?id=146313
     5
     6        Reviewed by Eric Carlson.
     7
     8        Update the MediaStream API (MediaStream, MediaStreamTrack and
     9        RealtimeMediaSource) to match the Media Capture and Stream
     10        specification [1]. Notable changes:
     11
     12        Updated event handling to synchronously update corresponding
     13        state/attributes as events are dispatched.
     14
     15        Removed 'new' state from MediaStreamTrack. A track is either 'live' or
     16        'ended'. As a consequence 'started' event is also removed.
     17
     18        MediaStreamTrack always has a source (disconnected source concept was
     19        removed from the spec). Therefore, more state can be kept at the source
     20        without going away.
     21
     22        Calculate MediaStream.active internally, from the track set, instead of
     23        setting it externally.
     24
     25        Updated RealtimeMediaSource Observer interface.
     26
     27        Replaced MediaStream's separate audio and video track lists with a
     28        single track set (more aligned with spec).
     29
     30        Updated MediaStream constructor to adopt instead of clone track
     31        arguments (or tracks from MediaStream argument).
     32
     33        Removed MediaStreamTrack.getSources() and corresponding test (removed
     34        from spec).
     35
     36        Test status: 3 added, 8 existing enabled (some updated) and 1 removed.
     37
     38        [1] http://w3c.github.io/mediacapture-main/archives/20150523/getusermedia.html
     39
     40        Tests: fast/mediastream/MediaStreamTrack-clone.html
     41               fast/mediastream/MediaStreamTrack-kind.html
     42               fast/mediastream/MediaStreamTrack-stop.html
     43
     44        * Modules/mediastream/MediaStream.cpp:
     45        (WebCore::MediaStream::create):
     46        (WebCore::MediaStream::MediaStream):
     47        (WebCore::MediaStream::clone):
     48        (WebCore::MediaStream::addTrack):
     49        (WebCore::MediaStream::removeTrack):
     50        (WebCore::MediaStream::getTrackById):
     51        (WebCore::MediaStream::getAudioTracks):
     52        (WebCore::MediaStream::getVideoTracks):
     53        (WebCore::MediaStream::getTracks):
     54        (WebCore::MediaStream::contextDestroyed):
     55        (WebCore::MediaStream::trackDidEnd):
     56        (WebCore::MediaStream::activeStatusChanged):
     57        (WebCore::MediaStream::didAddTrackToPrivate):
     58        (WebCore::MediaStream::didRemoveTrackFromPrivate):
     59        (WebCore::MediaStream::internalAddTrack):
     60        (WebCore::MediaStream::internalRemoveTrack):
     61        (WebCore::MediaStream::scheduleActiveStateChange):
     62        (WebCore::MediaStream::activityEventTimerFired):
     63        (WebCore::MediaStream::trackVectorForType):
     64        (WebCore::MediaStream::~MediaStream): Deleted.
     65        (WebCore::MediaStream::registry): Deleted.
     66        (WebCore::MediaStream::addObserver): Deleted.
     67        (WebCore::MediaStream::removeObserver): Deleted.
     68        * Modules/mediastream/MediaStream.h:
     69        * Modules/mediastream/MediaStream.idl:
     70        * Modules/mediastream/MediaStreamTrack.cpp:
     71        (WebCore::MediaStreamTrack::MediaStreamTrack):
     72        (WebCore::MediaStreamTrack::~MediaStreamTrack):
     73        (WebCore::MediaStreamTrack::kind):
     74        (WebCore::MediaStreamTrack::id):
     75        (WebCore::MediaStreamTrack::label):
     76        (WebCore::MediaStreamTrack::enabled):
     77        (WebCore::MediaStreamTrack::setEnabled):
     78        (WebCore::MediaStreamTrack::muted):
     79        (WebCore::MediaStreamTrack::readonly):
     80        (WebCore::MediaStreamTrack::remote):
     81        (WebCore::MediaStreamTrack::readyState):
     82        (WebCore::MediaStreamTrack::ended):
     83        (WebCore::MediaStreamTrack::clone):
     84        (WebCore::MediaStreamTrack::stopProducingData):
     85        (WebCore::MediaStreamTrack::states):
     86        (WebCore::MediaStreamTrack::getCapabilities):
     87        (WebCore::MediaStreamTrack::applyConstraints):
     88        (WebCore::MediaStreamTrack::trackEnded):
     89        (WebCore::MediaStreamTrack::trackMutedChanged):
     90        (WebCore::MediaStreamTrack::stop):
     91        (WebCore::MediaStreamTrack::getConstraints): Deleted.
     92        (WebCore::MediaStreamTrack::addObserver): Deleted.
     93        (WebCore::MediaStreamTrack::removeObserver): Deleted.
     94        (WebCore::MediaStreamTrack::configureTrackRendering): Deleted.
     95        (WebCore::MediaStreamTrack::activeDOMObjectName): Deleted.
     96        (WebCore::MediaStreamTrack::canSuspendForPageCache): Deleted.
     97        * Modules/mediastream/MediaStreamTrack.h:
     98        * Modules/mediastream/MediaStreamTrack.idl:
     99        * Modules/mediastream/RTCPeerConnection.cpp:
     100        (WebCore::RTCPeerConnection::didRemoveRemoteStream): Deleted.
     101        * Modules/mediastream/UserMediaRequest.cpp:
     102        (WebCore::UserMediaRequest::didCreateStream):
     103        * platform/mediastream/MediaStreamPrivate.cpp:
     104        (WebCore::MediaStreamPrivate::create):
     105        (WebCore::MediaStreamPrivate::MediaStreamPrivate):
     106        (WebCore::MediaStreamPrivate::tracks):
     107        (WebCore::MediaStreamPrivate::updateActiveState):
     108        (WebCore::MediaStreamPrivate::addTrack):
     109        (WebCore::MediaStreamPrivate::removeTrack):
     110        * platform/mediastream/MediaStreamPrivate.h:
     111        (WebCore::MediaStreamPrivate::active): Deleted.
     112        * platform/mediastream/MediaStreamTrackPrivate.cpp:
     113        (WebCore::MediaStreamTrackPrivate::create):
     114        (WebCore::MediaStreamTrackPrivate::MediaStreamTrackPrivate):
     115        (WebCore::MediaStreamTrackPrivate::~MediaStreamTrackPrivate):
     116        (WebCore::MediaStreamTrackPrivate::label):
     117        (WebCore::MediaStreamTrackPrivate::setEnabled):
     118        (WebCore::MediaStreamTrackPrivate::endTrack):
     119        (WebCore::MediaStreamTrackPrivate::clone):
     120        (WebCore::MediaStreamTrackPrivate::type):
     121        (WebCore::MediaStreamTrackPrivate::applyConstraints):
     122        (WebCore::MediaStreamTrackPrivate::sourceStopped):
     123        (WebCore::MediaStreamTrackPrivate::sourceMutedChanged):
     124        (WebCore::MediaStreamTrackPrivate::preventSourceFromStopping):
     125        (WebCore::MediaStreamTrackPrivate::muted): Deleted.
     126        (WebCore::MediaStreamTrackPrivate::readonly): Deleted.
     127        (WebCore::MediaStreamTrackPrivate::remote): Deleted.
     128        (WebCore::MediaStreamTrackPrivate::constraints): Deleted.
     129        (WebCore::MediaStreamTrackPrivate::states): Deleted.
     130        (WebCore::MediaStreamTrackPrivate::capabilities): Deleted.
     131        * platform/mediastream/MediaStreamTrackPrivate.h:
     132        (WebCore::MediaStreamTrackPrivate::id):
     133        (WebCore::MediaStreamTrackPrivate::ended):
     134        (WebCore::MediaStreamTrackPrivate::enabled):
     135        (WebCore::MediaStreamTrackPrivate::setClient):
     136        (WebCore::MediaStreamTrackPrivate::source): Deleted.
     137        (WebCore::MediaStreamTrackPrivate::client): Deleted.
     138        * platform/mediastream/RealtimeMediaSource.cpp:
     139        (WebCore::RealtimeMediaSource::RealtimeMediaSource):
     140        (WebCore::RealtimeMediaSource::reset):
     141        (WebCore::RealtimeMediaSource::setMuted):
     142        (WebCore::RealtimeMediaSource::readonly):
     143        (WebCore::RealtimeMediaSource::stop):
     144        (WebCore::RealtimeMediaSource::requestStop):
     145        (WebCore::RealtimeMediaSource::addObserver): Deleted.
     146        (WebCore::RealtimeMediaSource::removeObserver): Deleted.
     147        * platform/mediastream/RealtimeMediaSource.h:
     148        (WebCore::RealtimeMediaSource::stopped):
     149        (WebCore::RealtimeMediaSource::id): Deleted.
     150        (WebCore::RealtimeMediaSource::muted): Deleted.
     151        (WebCore::RealtimeMediaSource::setReadonly): Deleted.
     152        * platform/mediastream/openwebrtc/RealtimeMediaSourceCenterOwr.cpp:
     153        (WebCore::RealtimeMediaSourceCenterOwr::createMediaStream): Deleted.
     154        * platform/mock/MockRealtimeMediaSourceCenter.cpp:
     155        (WebCore::MockRealtimeMediaSourceCenter::createMediaStream): Deleted.
     156
    11572015-06-29  Benjamin Poulain  <benjamin@webkit.org>
    2158
  • trunk/Source/WebCore/Modules/mediastream/MediaStream.cpp

    r185336 r186081  
    11/*
    22 * Copyright (C) 2011 Google Inc. All rights reserved.
    3  * Copyright (C) 2011, 2012 Ericsson AB. All rights reserved.
     3 * Copyright (C) 2011, 2012, 2015 Ericsson AB. All rights reserved.
    44 * Copyright (C) 2013 Apple Inc. All rights reserved.
    55 * Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies).
     
    4242Ref<MediaStream> MediaStream::create(ScriptExecutionContext& context)
    4343{
    44     return MediaStream::create(context, MediaStreamPrivate::create(Vector<RefPtr<RealtimeMediaSource>>(), Vector<RefPtr<RealtimeMediaSource>>()));
    45 }
    46 
    47 Ref<MediaStream> MediaStream::create(ScriptExecutionContext& context, PassRefPtr<MediaStream> stream)
     44    return MediaStream::create(context, MediaStreamPrivate::create());
     45}
     46
     47Ref<MediaStream> MediaStream::create(ScriptExecutionContext& context, MediaStream* stream)
    4848{
    4949    ASSERT(stream);
    5050
    51     Vector<RefPtr<MediaStreamTrackPrivate>> audioTracks;
    52     Vector<RefPtr<MediaStreamTrackPrivate>> videoTracks;
    53 
    54     for (auto& track : stream->m_audioTracks)
    55         audioTracks.append(&track->privateTrack());
    56 
    57     for (auto& track : stream->m_videoTracks)
    58         videoTracks.append(&track->privateTrack());
    59 
    60     return MediaStream::create(context, MediaStreamPrivate::create(audioTracks, videoTracks));
     51    return adoptRef(*new MediaStream(context, stream->getTracks()));
    6152}
    6253
    6354Ref<MediaStream> MediaStream::create(ScriptExecutionContext& context, const Vector<RefPtr<MediaStreamTrack>>& tracks)
    6455{
    65     Vector<RefPtr<MediaStreamTrackPrivate>> audioTracks;
    66     Vector<RefPtr<MediaStreamTrackPrivate>> videoTracks;
     56    return adoptRef(*new MediaStream(context, tracks));
     57}
     58
     59Ref<MediaStream> MediaStream::create(ScriptExecutionContext& context, RefPtr<MediaStreamPrivate>&& streamPrivate)
     60{
     61    return adoptRef(*new MediaStream(context, WTF::move(streamPrivate)));
     62}
     63
     64MediaStream::MediaStream(ScriptExecutionContext& context, const Vector<RefPtr<MediaStreamTrack>>& tracks)
     65    : ContextDestructionObserver(&context)
     66    , m_activityEventTimer(*this, &MediaStream::activityEventTimerFired)
     67{
     68    // This constructor preserves MediaStreamTrack instances and must be used by calls originating
     69    // from the JavaScript MediaStream constructor.
     70    Vector<RefPtr<MediaStreamTrackPrivate>> trackPrivates;
     71    trackPrivates.reserveCapacity(tracks.size());
    6772
    6873    for (auto& track : tracks) {
    69         if (track->kind() == "audio")
    70             audioTracks.append(&track->privateTrack());
    71         else
    72             videoTracks.append(&track->privateTrack());
    73     }
    74 
    75     return MediaStream::create(context, MediaStreamPrivate::create(audioTracks, videoTracks));
    76 }
    77 
    78 Ref<MediaStream> MediaStream::create(ScriptExecutionContext& context, PassRefPtr<MediaStreamPrivate> privateStream)
    79 {
    80     return adoptRef(*new MediaStream(context, privateStream));
    81 }
    82 
    83 MediaStream::MediaStream(ScriptExecutionContext& context, PassRefPtr<MediaStreamPrivate> privateStream)
     74        track->addObserver(this);
     75        m_trackSet.add(track->id(), track);
     76        trackPrivates.append(&track->privateTrack());
     77    }
     78
     79    m_private = MediaStreamPrivate::create(trackPrivates);
     80    m_isActive = m_private->active();
     81    m_private->setClient(this);
     82}
     83
     84MediaStream::MediaStream(ScriptExecutionContext& context, RefPtr<MediaStreamPrivate>&& streamPrivate)
    8485    : ContextDestructionObserver(&context)
    85     , m_private(privateStream)
    86     , m_scheduledEventTimer(*this, &MediaStream::scheduledEventTimerFired)
     86    , m_private(streamPrivate)
     87    , m_isActive(m_private->active())
     88    , m_activityEventTimer(*this, &MediaStream::activityEventTimerFired)
    8789{
    8890    ASSERT(m_private);
    8991    m_private->setClient(this);
    9092
    91     RefPtr<MediaStreamTrack> track;
    92     size_t numberOfAudioTracks = m_private->numberOfAudioTracks();
    93     m_audioTracks.reserveCapacity(numberOfAudioTracks);
    94     for (size_t i = 0; i < numberOfAudioTracks; i++) {
    95         track = MediaStreamTrack::create(context, *m_private->audioTracks(i));
     93    for (auto& trackPrivate : m_private->tracks()) {
     94        RefPtr<MediaStreamTrack> track = MediaStreamTrack::create(context, *trackPrivate);
    9695        track->addObserver(this);
    97         m_audioTracks.append(track.release());
    98     }
    99 
    100     size_t numberOfVideoTracks = m_private->numberOfVideoTracks();
    101     m_videoTracks.reserveCapacity(numberOfVideoTracks);
    102     for (size_t i = 0; i < numberOfVideoTracks; i++) {
    103         track = MediaStreamTrack::create(context, *m_private->videoTracks(i));
    104         track->addObserver(this);
    105         m_videoTracks.append(track.release());
     96        m_trackSet.add(track->id(), WTF::move(track));
    10697    }
    10798}
     
    112103}
    113104
    114 bool MediaStream::active() const
    115 {
    116     return m_private->active();
    117 }
    118 
    119 void MediaStream::setActive(bool isActive)
    120 {
    121     if (active() == isActive)
     105RefPtr<MediaStream> MediaStream::clone()
     106{
     107    Vector<RefPtr<MediaStreamTrack>> clonedTracks;
     108    clonedTracks.reserveCapacity(m_trackSet.size());
     109
     110    for (auto& track : m_trackSet.values())
     111        clonedTracks.append(track->clone());
     112
     113    return MediaStream::create(*scriptExecutionContext(), clonedTracks);
     114}
     115
     116void MediaStream::addTrack(RefPtr<MediaStreamTrack>&& track)
     117{
     118    if (!internalAddTrack(WTF::move(track), StreamModifier::DomAPI))
    122119        return;
    123     m_private->setActive(isActive);
    124 }
    125 
    126 PassRefPtr<MediaStream> MediaStream::clone()
    127 {
    128     Vector<RefPtr<MediaStreamTrack>> trackSet;
    129 
    130     cloneMediaStreamTrackVector(trackSet, getAudioTracks());
    131     cloneMediaStreamTrackVector(trackSet, getVideoTracks());
    132     return MediaStream::create(*scriptExecutionContext(), trackSet);
    133 }
    134 
    135 void MediaStream::cloneMediaStreamTrackVector(Vector<RefPtr<MediaStreamTrack>>& destination, const Vector<RefPtr<MediaStreamTrack>>& source)
    136 {
    137     for (auto& track : source)
    138         destination.append(track->clone());
    139 }
    140 
    141 void MediaStream::addTrack(PassRefPtr<MediaStreamTrack> prpTrack, ExceptionCode& ec)
    142 {
    143     if (!prpTrack) {
    144         ec = TYPE_MISMATCH_ERR;
     120
     121    for (auto& observer : m_observers)
     122        observer->didAddOrRemoveTrack();
     123}
     124
     125void MediaStream::removeTrack(MediaStreamTrack* track)
     126{
     127    if (!internalRemoveTrack(track, StreamModifier::DomAPI))
    145128        return;
    146     }
    147 
    148     if (addTrack(prpTrack)) {
    149         for (auto& observer : m_observers)
    150             observer->didAddOrRemoveTrack();
    151     }
    152 }
    153 
    154 bool MediaStream::addTrack(PassRefPtr<MediaStreamTrack> prpTrack)
    155 {
    156     // This is a common part used by addTrack called by JavaScript
    157     // and addRemoteTrack and only addRemoteTrack must fire addtrack event
    158     RefPtr<MediaStreamTrack> track = prpTrack;
     129
     130    for (auto& observer : m_observers)
     131        observer->didAddOrRemoveTrack();
     132}
     133
     134MediaStreamTrack* MediaStream::getTrackById(String id)
     135{
     136    auto it = m_trackSet.find(id);
     137    if (it != m_trackSet.end())
     138        return it->value.get();
     139
     140    return nullptr;
     141}
     142
     143Vector<RefPtr<MediaStreamTrack>> MediaStream::getAudioTracks() const
     144{
     145    return trackVectorForType(RealtimeMediaSource::Audio);
     146}
     147
     148Vector<RefPtr<MediaStreamTrack>> MediaStream::getVideoTracks() const
     149{
     150    return trackVectorForType(RealtimeMediaSource::Video);
     151}
     152
     153Vector<RefPtr<MediaStreamTrack>> MediaStream::getTracks() const
     154{
     155    Vector<RefPtr<MediaStreamTrack>> tracks;
     156    tracks.reserveCapacity(m_trackSet.size());
     157    copyValuesToVector(m_trackSet, tracks);
     158
     159    return tracks;
     160}
     161
     162void MediaStream::contextDestroyed()
     163{
     164    ContextDestructionObserver::contextDestroyed();
     165}
     166
     167void MediaStream::trackDidEnd()
     168{
     169    m_private->updateActiveState(MediaStreamPrivate::NotifyClientOption::Notify);
     170}
     171
     172void MediaStream::activeStatusChanged()
     173{
     174    // Schedule the active state change and event dispatch since this callback may be called
     175    // synchronously from the DOM API (e.g. as a result of addTrack()).
     176    scheduleActiveStateChange();
     177}
     178
     179void MediaStream::didAddTrackToPrivate(MediaStreamTrackPrivate& trackPrivate)
     180{
     181    ScriptExecutionContext* context = scriptExecutionContext();
     182    if (!context)
     183        return;
     184
     185    internalAddTrack(MediaStreamTrack::create(*context, trackPrivate), StreamModifier::Platform);
     186}
     187
     188void MediaStream::didRemoveTrackFromPrivate(MediaStreamTrackPrivate& trackPrivate)
     189{
     190    RefPtr<MediaStreamTrack> track = getTrackById(trackPrivate.id());
     191    internalRemoveTrack(WTF::move(track), StreamModifier::Platform);
     192}
     193
     194bool MediaStream::internalAddTrack(RefPtr<MediaStreamTrack>&& track, StreamModifier streamModifier)
     195{
    159196    if (getTrackById(track->id()))
    160197        return false;
    161198
    162     Vector<RefPtr<MediaStreamTrack>>* tracks = trackVectorForType(track->source()->type());
    163 
    164     tracks->append(track);
     199    m_trackSet.add(track->id(), track);
    165200    track->addObserver(this);
    166     m_private->addTrack(&track->privateTrack());
    167     setActive(true);
     201
     202    if (streamModifier == StreamModifier::DomAPI)
     203        m_private->addTrack(&track->privateTrack(), MediaStreamPrivate::NotifyClientOption::DontNotify);
     204    else
     205        dispatchEvent(MediaStreamTrackEvent::create(eventNames().addtrackEvent, false, false, WTF::move(track)));
     206
    168207    return true;
    169208}
    170209
    171 void MediaStream::removeTrack(PassRefPtr<MediaStreamTrack> prpTrack, ExceptionCode& ec)
    172 {
    173     if (!active()) {
    174         ec = INVALID_STATE_ERR;
    175         return;
    176     }
    177 
    178     if (!prpTrack) {
    179         ec = TYPE_MISMATCH_ERR;
    180         return;
    181     }
    182 
    183     if (removeTrack(prpTrack)) {
    184         for (auto& observer : m_observers)
    185             observer->didAddOrRemoveTrack();
    186     }
    187 }
    188 
    189 bool MediaStream::removeTrack(PassRefPtr<MediaStreamTrack> prpTrack)
    190 {
    191     // This is a common part used by removeTrack called by JavaScript
    192     // and removeRemoteTrack and only removeRemoteTrack must fire removetrack event
    193     RefPtr<MediaStreamTrack> track = prpTrack;
    194     Vector<RefPtr<MediaStreamTrack>>* tracks = trackVectorForType(track->source()->type());
    195 
    196     size_t pos = tracks->find(track);
    197     if (pos == notFound)
     210bool MediaStream::internalRemoveTrack(RefPtr<MediaStreamTrack>&& track, StreamModifier streamModifier)
     211{
     212    if (!m_trackSet.remove(track->id()))
    198213        return false;
    199214
    200     tracks->remove(pos);
    201     m_private->removeTrack(&track->privateTrack());
    202     // There can be other tracks using the same source in the same MediaStream,
    203     // like when MediaStreamTrack::clone() is called, for instance.
    204     // Spec says that a source can be shared, so we must assure that there is no
    205     // other track using it.
    206     if (!haveTrackWithSource(track->source()))
    207         m_private->removeSource(track->source());
    208 
    209215    track->removeObserver(this);
    210     if (!m_audioTracks.size() && !m_videoTracks.size())
    211         setActive(false);
     216
     217    if (streamModifier == StreamModifier::DomAPI)
     218        m_private->removeTrack(track->privateTrack(), MediaStreamPrivate::NotifyClientOption::DontNotify);
     219    else
     220        dispatchEvent(MediaStreamTrackEvent::create(eventNames().removetrackEvent, false, false, WTF::move(track)));
    212221
    213222    return true;
    214223}
    215224
    216 bool MediaStream::haveTrackWithSource(PassRefPtr<RealtimeMediaSource> source)
    217 {
    218     if (source->type() == RealtimeMediaSource::Audio) {
    219         for (auto& track : m_audioTracks) {
    220             if (track->source() == source.get())
    221                 return true;
    222         }
    223         return false;
    224     }
    225 
    226     for (auto& track : m_videoTracks) {
    227         if (track->source() == source.get())
    228             return true;
    229     }
    230 
    231     return false;
    232 }
    233 
    234 MediaStreamTrack* MediaStream::getTrackById(String id)
    235 {
    236     for (auto& track : m_audioTracks) {
    237         if (track->id() == id)
    238             return track.get();
    239     }
    240 
    241     for (auto& track :  m_videoTracks) {
    242         if (track->id() == id)
    243             return track.get();
    244     }
    245 
    246     return nullptr;
    247 }
    248 
    249 Vector<RefPtr<MediaStreamTrack>> MediaStream::getTracks()
     225void MediaStream::scheduleActiveStateChange()
     226{
     227    const AtomicString& eventName = m_isActive ? eventNames().inactiveEvent : eventNames().activeEvent;
     228    m_scheduledActivityEvents.append(Event::create(eventName, false, false));
     229
     230    if (!m_activityEventTimer.isActive())
     231        m_activityEventTimer.startOneShot(0);
     232}
     233
     234void MediaStream::activityEventTimerFired()
     235{
     236    Vector<RefPtr<Event>> events;
     237    events.swap(m_scheduledActivityEvents);
     238
     239    for (auto& event : events) {
     240        m_isActive = event->type() == eventNames().activeEvent;
     241        dispatchEvent(event.release());
     242    }
     243
     244    events.clear();
     245}
     246
     247URLRegistry& MediaStream::registry() const
     248{
     249    return MediaStreamRegistry::registry();
     250}
     251
     252Vector<RefPtr<MediaStreamTrack>> MediaStream::trackVectorForType(RealtimeMediaSource::Type filterType) const
    250253{
    251254    Vector<RefPtr<MediaStreamTrack>> tracks;
    252     for (auto& track : m_audioTracks)
    253         tracks.append(track.get());
    254     for (auto& track : m_videoTracks)
    255         tracks.append(track.get());
     255    for (auto& track : m_trackSet.values()) {
     256        if (track->source()->type() == filterType)
     257            tracks.append(track);
     258    }
    256259
    257260    return tracks;
    258 }
    259 
    260 void MediaStream::trackDidEnd()
    261 {
    262     for (auto& track : m_audioTracks) {
    263         if (!track->ended())
    264             return;
    265     }
    266     for (auto& track : m_videoTracks) {
    267         if (!track->ended())
    268             return;
    269     }
    270 
    271     if (!m_audioTracks.size() && !m_videoTracks.size())
    272         setActive(false);
    273 }
    274 
    275 void MediaStream::setStreamIsActive(bool streamActive)
    276 {
    277     if (streamActive)
    278         scheduleDispatchEvent(Event::create(eventNames().activeEvent, false, false));
    279     else
    280         scheduleDispatchEvent(Event::create(eventNames().inactiveEvent, false, false));
    281 }
    282 
    283 void MediaStream::contextDestroyed()
    284 {
    285     ContextDestructionObserver::contextDestroyed();
    286 }
    287 
    288 void MediaStream::addRemoteSource(RealtimeMediaSource* source)
    289 {
    290     ASSERT(source);
    291     addRemoteTrack(MediaStreamTrackPrivate::create(source).get());
    292 }
    293 
    294 void MediaStream::removeRemoteSource(RealtimeMediaSource* source)
    295 {
    296     ASSERT(source);
    297     if (!active())
    298         return;
    299 
    300     Vector<RefPtr<MediaStreamTrack>>* tracks = trackVectorForType(source->type());
    301 
    302     for (int i = tracks->size() - 1; i >= 0; --i) {
    303         if ((*tracks)[i]->source() != source)
    304             continue;
    305 
    306         RefPtr<MediaStreamTrack> track = (*tracks)[i];
    307         track->removeObserver(this);
    308         tracks->remove(i);
    309         m_private->removeTrack(&track->privateTrack());
    310         scheduleDispatchEvent(MediaStreamTrackEvent::create(eventNames().removetrackEvent, false, false, track.release()));
    311     }
    312 
    313     m_private->removeSource(source);
    314 }
    315 
    316 void MediaStream::addRemoteTrack(MediaStreamTrackPrivate* privateTrack)
    317 {
    318     ASSERT(privateTrack);
    319     if (!active())
    320         return;
    321 
    322     RefPtr<MediaStreamTrack> track;
    323     switch (privateTrack->type()) {
    324     case RealtimeMediaSource::Audio:
    325     case RealtimeMediaSource::Video:
    326         track = MediaStreamTrack::create(*scriptExecutionContext(), *privateTrack);
    327         break;
    328     case RealtimeMediaSource::None:
    329         ASSERT_NOT_REACHED();
    330         break;
    331     }
    332 
    333     if (!track)
    334         return;
    335 
    336     if (addTrack(track))
    337         scheduleDispatchEvent(MediaStreamTrackEvent::create(eventNames().addtrackEvent, false, false, track));
    338 }
    339 
    340 void MediaStream::removeRemoteTrack(MediaStreamTrackPrivate* privateTrack)
    341 {
    342     ASSERT(privateTrack);
    343     if (!active())
    344         return;
    345 
    346     RefPtr<MediaStreamTrack> track = getTrackById(privateTrack->id());
    347     if (removeTrack(track))
    348         scheduleDispatchEvent(MediaStreamTrackEvent::create(eventNames().removetrackEvent, false, false, track.release()));
    349 }
    350 
    351 void MediaStream::scheduleDispatchEvent(PassRefPtr<Event> event)
    352 {
    353     m_scheduledEvents.append(event);
    354 
    355     if (!m_scheduledEventTimer.isActive())
    356         m_scheduledEventTimer.startOneShot(0);
    357 }
    358 
    359 void MediaStream::scheduledEventTimerFired()
    360 {
    361     Vector<RefPtr<Event>> events;
    362     events.swap(m_scheduledEvents);
    363 
    364     for (auto& event : events)
    365         dispatchEvent(event.release());
    366 
    367     events.clear();
    368 }
    369 
    370 URLRegistry& MediaStream::registry() const
    371 {
    372     return MediaStreamRegistry::registry();
    373 }
    374 
    375 Vector<RefPtr<MediaStreamTrack>>* MediaStream::trackVectorForType(RealtimeMediaSource::Type type)
    376 {
    377     switch (type) {
    378     case RealtimeMediaSource::Audio:
    379         return &m_audioTracks;
    380     case RealtimeMediaSource::Video:
    381         return &m_videoTracks;
    382     case RealtimeMediaSource::None:
    383         ASSERT_NOT_REACHED();
    384     }
    385     return nullptr;
    386261}
    387262
  • trunk/Source/WebCore/Modules/mediastream/MediaStream.h

    r185091 r186081  
    11/*
    22 * Copyright (C) 2011 Google Inc. All rights reserved.
    3  * Copyright (C) 2011 Ericsson AB. All rights reserved.
     3 * Copyright (C) 2011, 2015 Ericsson AB. All rights reserved.
    44 * Copyright (C) 2013 Apple Inc. All rights reserved.
    55 * Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies).
     
    3939#include "Timer.h"
    4040#include "URLRegistry.h"
     41#include <wtf/HashMap.h>
    4142#include <wtf/RefCounted.h>
    4243#include <wtf/RefPtr.h>
     
    4445namespace WebCore {
    4546
    46 class MediaStream final : public RefCounted<MediaStream>, public URLRegistrable, public ScriptWrappable, public MediaStreamPrivateClient, public EventTargetWithInlineData, public ContextDestructionObserver {
     47class MediaStream final : public RefCounted<MediaStream>, public URLRegistrable, public ScriptWrappable, public MediaStreamPrivateClient, public EventTargetWithInlineData, public ContextDestructionObserver, public MediaStreamTrack::Observer {
    4748public:
    4849    class Observer {
     
    5354
    5455    static Ref<MediaStream> create(ScriptExecutionContext&);
    55     static Ref<MediaStream> create(ScriptExecutionContext&, PassRefPtr<MediaStream>);
     56    static Ref<MediaStream> create(ScriptExecutionContext&, MediaStream*);
    5657    static Ref<MediaStream> create(ScriptExecutionContext&, const Vector<RefPtr<MediaStreamTrack>>&);
    57     static Ref<MediaStream> create(ScriptExecutionContext&, PassRefPtr<MediaStreamPrivate>);
     58    static Ref<MediaStream> create(ScriptExecutionContext&, RefPtr<MediaStreamPrivate>&&);
    5859    virtual ~MediaStream();
    5960
    6061    String id() const { return m_private->id(); }
    6162
    62     void addTrack(PassRefPtr<MediaStreamTrack>, ExceptionCode&);
    63     void removeTrack(PassRefPtr<MediaStreamTrack>, ExceptionCode&);
     63    void addTrack(RefPtr<MediaStreamTrack>&&);
     64    void removeTrack(MediaStreamTrack*);
    6465    MediaStreamTrack* getTrackById(String);
    6566
    66     const Vector<RefPtr<MediaStreamTrack>>& getAudioTracks() const { return m_audioTracks; }
    67     const Vector<RefPtr<MediaStreamTrack>>& getVideoTracks() const { return m_videoTracks; }
    68     Vector<RefPtr<MediaStreamTrack>> getTracks();
     67    Vector<RefPtr<MediaStreamTrack>> getAudioTracks() const;
     68    Vector<RefPtr<MediaStreamTrack>> getVideoTracks() const;
     69    Vector<RefPtr<MediaStreamTrack>> getTracks() const;
    6970
    70     PassRefPtr<MediaStream> clone();
     71    RefPtr<MediaStream> clone();
    7172
    72     bool active() const;
    73     void setActive(bool);
     73    bool active() const { return m_isActive; }
    7474
    7575    MediaStreamPrivate* privateStream() const { return m_private.get(); }
     
    8989
    9090protected:
    91     MediaStream(ScriptExecutionContext&, PassRefPtr<MediaStreamPrivate>);
     91    MediaStream(ScriptExecutionContext&, const Vector<RefPtr<MediaStreamTrack>>&);
     92    MediaStream(ScriptExecutionContext&, RefPtr<MediaStreamPrivate>&&);
    9293
    9394    // ContextDestructionObserver
     
    9596
    9697private:
     98    enum class StreamModifier { DomAPI, Platform };
     99
    97100    // EventTarget
    98101    virtual void refEventTarget() override final { ref(); }
    99102    virtual void derefEventTarget() override final { deref(); }
    100103
     104    // MediaStreamTrack::Observer
     105    virtual void trackDidEnd() override final;
     106
    101107    // MediaStreamPrivateClient
    102     virtual void trackDidEnd() override final;
    103     virtual void setStreamIsActive(bool) override final;
    104     virtual void addRemoteSource(RealtimeMediaSource*) override final;
    105     virtual void removeRemoteSource(RealtimeMediaSource*) override final;
    106     virtual void addRemoteTrack(MediaStreamTrackPrivate*) override final;
    107     virtual void removeRemoteTrack(MediaStreamTrackPrivate*) override final;
     108    virtual void activeStatusChanged() override final;
     109    virtual void didAddTrackToPrivate(MediaStreamTrackPrivate&) override final;
     110    virtual void didRemoveTrackFromPrivate(MediaStreamTrackPrivate&) override final;
    108111
    109     bool removeTrack(PassRefPtr<MediaStreamTrack>);
    110     bool addTrack(PassRefPtr<MediaStreamTrack>);
     112    bool internalAddTrack(RefPtr<MediaStreamTrack>&&, StreamModifier);
     113    bool internalRemoveTrack(RefPtr<MediaStreamTrack>&&, StreamModifier);
    111114
    112     bool haveTrackWithSource(PassRefPtr<RealtimeMediaSource>);
     115    void scheduleActiveStateChange();
     116    void activityEventTimerFired();
    113117
    114     void scheduleDispatchEvent(PassRefPtr<Event>);
    115     void scheduledEventTimerFired();
    116 
    117     void cloneMediaStreamTrackVector(Vector<RefPtr<MediaStreamTrack>>&, const Vector<RefPtr<MediaStreamTrack>>&);
    118 
    119     Vector<RefPtr<MediaStreamTrack>>* trackVectorForType(RealtimeMediaSource::Type);
     118    Vector<RefPtr<MediaStreamTrack>> trackVectorForType(RealtimeMediaSource::Type) const;
    120119
    121120    RefPtr<MediaStreamPrivate> m_private;
    122     Vector<RefPtr<MediaStreamTrack>> m_audioTracks;
    123     Vector<RefPtr<MediaStreamTrack>> m_videoTracks;
    124121
    125     Timer m_scheduledEventTimer;
    126     Vector<RefPtr<Event>> m_scheduledEvents;
     122    bool m_isActive;
     123    HashMap<String, RefPtr<MediaStreamTrack>> m_trackSet;
     124
     125    Timer m_activityEventTimer;
     126    Vector<RefPtr<Event>> m_scheduledActivityEvents;
    127127
    128128    Vector<Observer*> m_observers;
  • trunk/Source/WebCore/Modules/mediastream/MediaStream.idl

    r181507 r186081  
    3838    sequence<MediaStreamTrack> getVideoTracks();
    3939    sequence<MediaStreamTrack> getTracks();
     40    MediaStreamTrack getTrackById(DOMString trackId);
    4041
    41     [RaisesException] void addTrack(MediaStreamTrack track);
    42     [RaisesException] void removeTrack(MediaStreamTrack track);
    43     MediaStreamTrack getTrackById(DOMString trackId);
     42    void addTrack(MediaStreamTrack track);
     43    void removeTrack(MediaStreamTrack track);
     44
    4445    MediaStream clone();
    4546
  • trunk/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp

    r185101 r186081  
    11/*
    22 * Copyright (C) 2011 Google Inc. All rights reserved.
    3  * Copyright (C) 2011 Ericsson AB. All rights reserved.
     3 * Copyright (C) 2011, 2015 Ericsson AB. All rights reserved.
    44 * Copyright (C) 2013 Apple Inc. All rights reserved.
    55 * Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies).
     
    4141#include "MediaStream.h"
    4242#include "MediaStreamPrivate.h"
    43 #include "MediaStreamTrackSourcesCallback.h"
    44 #include "MediaStreamTrackSourcesRequest.h"
    4543#include "MediaTrackConstraints.h"
    4644#include "NotImplemented.h"
    47 #include "RealtimeMediaSourceCenter.h"
     45#include <wtf/Functional.h>
    4846#include <wtf/NeverDestroyed.h>
    4947
     
    5351{
    5452    return adoptRef(*new MediaStreamTrack(context, privateTrack));
    55 }
    56 
    57 Ref<MediaStreamTrack> MediaStreamTrack::create(MediaStreamTrack& track)
    58 {
    59     return adoptRef(*new MediaStreamTrack(track));
    6053}
    6154
     
    6356    : RefCounted()
    6457    , ActiveDOMObject(&context)
    65     , m_privateTrack(privateTrack)
    66     , m_eventDispatchScheduled(false)
    67     , m_stoppingTrack(false)
     58    , m_private(privateTrack)
    6859{
    6960    suspendIfNeeded();
    7061
    71     m_privateTrack->setClient(this);
    72 }
    73 
    74 MediaStreamTrack::MediaStreamTrack(MediaStreamTrack& other)
    75     : RefCounted()
    76     , ActiveDOMObject(other.scriptExecutionContext())
    77     , m_privateTrack(*other.privateTrack().clone())
    78     , m_eventDispatchScheduled(false)
    79     , m_stoppingTrack(false)
    80 {
    81     suspendIfNeeded();
    82 
    83     m_privateTrack->setClient(this);
     62    m_private->setClient(this);
    8463}
    8564
    8665MediaStreamTrack::~MediaStreamTrack()
    8766{
    88     m_privateTrack->setClient(nullptr);
    89 }
    90 
    91 void MediaStreamTrack::setSource(PassRefPtr<RealtimeMediaSource> newSource)
    92 {
    93     m_privateTrack->setSource(newSource);
     67    m_private->setClient(nullptr);
    9468}
    9569
     
    9973    static NeverDestroyed<AtomicString> videoKind("video", AtomicString::ConstructFromLiteral);
    10074
    101     if (m_privateTrack->type() == RealtimeMediaSource::Audio)
     75    if (m_private->type() == RealtimeMediaSource::Audio)
    10276        return audioKind;
    10377    return videoKind;
     
    10680const String& MediaStreamTrack::id() const
    10781{
    108     return m_privateTrack->id();
     82    return m_private->id();
    10983}
    11084
    11185const String& MediaStreamTrack::label() const
    11286{
    113     return m_privateTrack->label();
     87    return m_private->label();
    11488}
    11589
    11690bool MediaStreamTrack::enabled() const
    11791{
    118     return m_privateTrack->enabled();
     92    return m_private->enabled();
    11993}
    12094
    12195void MediaStreamTrack::setEnabled(bool enabled)
    12296{
    123     m_privateTrack->setEnabled(enabled);
    124 }
    125 
    126 bool MediaStreamTrack::stopped() const
    127 {
    128     return m_privateTrack->stopped();
     97    m_private->setEnabled(enabled);
    12998}
    13099
    131100bool MediaStreamTrack::muted() const
    132101{
    133     return m_privateTrack->muted();
     102    return m_private->muted();
    134103}
    135104
    136105bool MediaStreamTrack::readonly() const
    137106{
    138     return m_privateTrack->readonly();
     107    return m_private->readonly();
    139108}
    140109
    141110bool MediaStreamTrack::remote() const
    142111{
    143     return m_privateTrack->remote();
     112    return m_private->remote();
    144113}
    145114
    146115const AtomicString& MediaStreamTrack::readyState() const
    147116{
    148     static NeverDestroyed<AtomicString> ended("ended", AtomicString::ConstructFromLiteral);
    149     static NeverDestroyed<AtomicString> live("live", AtomicString::ConstructFromLiteral);
    150     static NeverDestroyed<AtomicString> newState("new", AtomicString::ConstructFromLiteral);
    151 
    152     switch (m_privateTrack->readyState()) {
    153     case RealtimeMediaSource::Live:
    154         return live;
    155     case RealtimeMediaSource::New:
    156         return newState;
    157     case RealtimeMediaSource::Ended:
    158         return ended;
    159     }
    160 
    161     ASSERT_NOT_REACHED();
    162     return emptyAtom;
    163 }
    164 
    165 void MediaStreamTrack::getSources(ScriptExecutionContext* context, PassRefPtr<MediaStreamTrackSourcesCallback> callback, ExceptionCode& ec)
    166 {
    167     RefPtr<MediaStreamTrackSourcesRequest> request = MediaStreamTrackSourcesRequest::create(context, callback);
    168     if (!RealtimeMediaSourceCenter::singleton().getMediaStreamTrackSources(request.release()))
    169         ec = NOT_SUPPORTED_ERR;
     117    static NeverDestroyed<AtomicString> endedState("ended", AtomicString::ConstructFromLiteral);
     118    static NeverDestroyed<AtomicString> liveState("live", AtomicString::ConstructFromLiteral);
     119
     120    return ended() ? endedState : liveState;
     121}
     122
     123bool MediaStreamTrack::ended() const
     124{
     125    return m_private->ended();
     126}
     127
     128RefPtr<MediaStreamTrack> MediaStreamTrack::clone()
     129{
     130    return MediaStreamTrack::create(*scriptExecutionContext(), *m_private->clone());
     131}
     132
     133void MediaStreamTrack::stopProducingData()
     134{
     135    // NOTE: this method is called when the "stop" method is called from JS, using
     136    // the "ImplementedAs" IDL attribute. This is done because ActiveDOMObject requires
     137    // a "stop" method.
     138
     139    if (remote() || ended())
     140        return;
     141
     142    m_private->endTrack();
    170143}
    171144
     
    179152RefPtr<MediaSourceStates> MediaStreamTrack::states() const
    180153{
    181     return MediaSourceStates::create(m_privateTrack->states());
     154    return MediaSourceStates::create(m_private->states());
    182155}
    183156
     
    185158{
    186159    // The source may be shared by multiple tracks, so its states is not necessarily
    187     // in sync with the track state. A track that is new or has ended always has a source
     160    // in sync with the track state. A track that has ended always has a source
    188161    // type of "none".
    189     RefPtr<RealtimeMediaSourceCapabilities> sourceCapabilities = m_privateTrack->capabilities();
    190     RealtimeMediaSource::ReadyState readyState = m_privateTrack->readyState();
    191     if (readyState == RealtimeMediaSource::New || readyState == RealtimeMediaSource::Ended)
     162    RefPtr<RealtimeMediaSourceCapabilities> sourceCapabilities = m_private->capabilities();
     163    if (ended())
    192164        sourceCapabilities->setSourceType(RealtimeMediaSourceStates::None);
    193165   
     
    198170{
    199171    m_constraints->initialize(constraints);
    200     m_privateTrack->applyConstraints(m_constraints);
    201 }
    202 
    203 void MediaStreamTrack::applyConstraints(PassRefPtr<MediaConstraints>)
     172    m_private->applyConstraints(*m_constraints);
     173}
     174
     175void MediaStreamTrack::applyConstraints(const MediaConstraints&)
    204176{
    205177    // FIXME: apply the new constraints to the track
    206178    // https://bugs.webkit.org/show_bug.cgi?id=122428
    207 }
    208 
    209 RefPtr<MediaStreamTrack> MediaStreamTrack::clone()
    210 {
    211     return MediaStreamTrack::create(*this);
    212 }
    213 
    214 void MediaStreamTrack::stopProducingData()
    215 {
    216     // NOTE: this method is called when the "stop" method is called from JS, using
    217     // the "ImplementedAs" IDL attribute. This is done because ActiveDOMObject requires
    218     // a "stop" method.
    219    
    220     // The stop method should "Permanently stop the generation of data for track's source", but it
    221     // should not post an 'ended' event.
    222     m_stoppingTrack = true;
    223     m_privateTrack->stop(MediaStreamTrackPrivate::StopTrackAndStopSource);
    224     m_stoppingTrack = false;
    225 }
    226 
    227 bool MediaStreamTrack::ended() const
    228 {
    229     return m_privateTrack->ended();
    230179}
    231180
     
    242191}
    243192
    244 void MediaStreamTrack::trackReadyStateChanged()
    245 {
    246     if (stopped())
    247         return;
    248 
    249     RealtimeMediaSource::ReadyState readyState = m_privateTrack->readyState();
    250     if (readyState == RealtimeMediaSource::Live)
    251         scheduleEventDispatch(Event::create(eventNames().startedEvent, false, false));
    252     else if (readyState == RealtimeMediaSource::Ended && !m_stoppingTrack)
    253         scheduleEventDispatch(Event::create(eventNames().endedEvent, false, false));
     193void MediaStreamTrack::trackEnded()
     194{
     195    dispatchEvent(Event::create(eventNames().endedEvent, false, false));
     196
     197    for (auto& observer : m_observers)
     198        observer->trackDidEnd();
    254199
    255200    configureTrackRendering();
     
    258203void MediaStreamTrack::trackMutedChanged()
    259204{
    260     if (stopped())
    261         return;
    262 
    263     if (muted())
    264         scheduleEventDispatch(Event::create(eventNames().muteEvent, false, false));
    265     else
    266         scheduleEventDispatch(Event::create(eventNames().unmuteEvent, false, false));
     205    AtomicString eventType = muted() ? eventNames().muteEvent : eventNames().unmuteEvent;
     206    dispatchEvent(Event::create(eventType, false, false));
    267207
    268208    configureTrackRendering();
    269209}
    270210
    271 void MediaStreamTrack::trackEnabledChanged()
    272 {
    273     if (stopped())
    274         return;
    275 
    276     setEnabled(m_privateTrack->enabled());
    277     configureTrackRendering();
    278 }
    279 
    280211void MediaStreamTrack::configureTrackRendering()
    281212{
    282     if (stopped())
    283         return;
    284 
    285213    // 4.3.1
    286214    // ... media from the source only flows when a MediaStreamTrack object is both unmuted and enabled
    287215}
    288216
    289 void MediaStreamTrack::trackDidEnd()
    290 {
    291     m_privateTrack->setReadyState(RealtimeMediaSource::Ended);
    292 
    293     for (auto& observer : m_observers)
    294         observer->trackDidEnd();
    295 }
    296 
    297217void MediaStreamTrack::stop()
    298218{
    299     m_privateTrack->stop(MediaStreamTrackPrivate::StopTrackOnly);
     219    stopProducingData();
    300220}
    301221
     
    311231}
    312232
    313 void MediaStreamTrack::scheduleEventDispatch(PassRefPtr<Event> event)
    314 {
    315     {
    316         MutexLocker locker(m_mutex);
    317         m_scheduledEvents.append(event);
    318         if (m_eventDispatchScheduled)
    319             return;
    320         m_eventDispatchScheduled = true;
    321     }
    322 
    323     RefPtr<MediaStreamTrack> protectedThis(this);
    324     callOnMainThread([protectedThis] {
    325         Vector<RefPtr<Event>> events;
    326         {
    327             MutexLocker locker(protectedThis->m_mutex);
    328             protectedThis->m_eventDispatchScheduled = false;
    329             events = WTF::move(protectedThis->m_scheduledEvents);
    330         }
    331 
    332         if (!protectedThis->scriptExecutionContext())
    333             return;
    334 
    335         for (auto& event : events)
    336             protectedThis->dispatchEvent(event.release());
    337     });
    338 }
    339 
    340233} // namespace WebCore
    341234
  • trunk/Source/WebCore/Modules/mediastream/MediaStreamTrack.h

    r184940 r186081  
    11/*
    22 * Copyright (C) 2011 Google Inc. All rights reserved.
    3  * Copyright (C) 2011 Ericsson AB. All rights reserved.
     3 * Copyright (C) 2011, 2015 Ericsson AB. All rights reserved.
    44 * Copyright (C) 2013 Apple Inc. All rights reserved.
    55 * Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies).
     
    4646class MediaConstraintsImpl;
    4747class MediaSourceStates;
    48 class MediaStreamTrackSourcesCallback;
    4948class MediaStreamCapabilities;
    5049class MediaTrackConstraints;
     
    5958
    6059    static Ref<MediaStreamTrack> create(ScriptExecutionContext&, MediaStreamTrackPrivate&);
    61     static Ref<MediaStreamTrack> create(MediaStreamTrack&);
    6260    virtual ~MediaStreamTrack();
    6361
     
    7270    bool readonly() const;
    7371    bool remote() const;
    74     bool stopped() const;
    7572
    7673    const AtomicString& readyState() const;
    7774
    78     static void getSources(ScriptExecutionContext*, PassRefPtr<MediaStreamTrackSourcesCallback>, ExceptionCode&);
     75    bool ended() const;
     76
     77    RefPtr<MediaStreamTrack> clone();
     78    void stopProducingData();
    7979
    8080    RefPtr<MediaTrackConstraints> getConstraints() const;
     
    8282    RefPtr<MediaStreamCapabilities> getCapabilities() const;
    8383    void applyConstraints(const Dictionary&);
    84     void applyConstraints(PassRefPtr<MediaConstraints>);
     84    void applyConstraints(const MediaConstraints&);
    8585
    86     RefPtr<MediaStreamTrack> clone();
    87     void stopProducingData();
    88 
    89     RealtimeMediaSource* source() const { return m_privateTrack->source(); }
    90     MediaStreamTrackPrivate& privateTrack() { return m_privateTrack.get(); }
    91 
    92     bool ended() const;
     86    RealtimeMediaSource* source() const { return m_private->source(); }
     87    MediaStreamTrackPrivate& privateTrack() { return m_private.get(); }
    9388
    9489    void addObserver(Observer*);
     
    106101    explicit MediaStreamTrack(MediaStreamTrack&);
    107102
    108     void setSource(PassRefPtr<RealtimeMediaSource>);
    109 
    110103    void configureTrackRendering();
    111     void trackDidEnd();
    112     void scheduleEventDispatch(PassRefPtr<Event>);
    113104
    114105    // ActiveDOMObject API.
     
    122113
    123114    // MediaStreamTrackPrivateClient
    124     void trackReadyStateChanged() override;
    125     void trackMutedChanged() override;
    126     void trackEnabledChanged() override;
     115    void trackEnded();
     116    void trackMutedChanged();
    127117
    128     Vector<RefPtr<Event>> m_scheduledEvents;
     118    Vector<Observer*> m_observers;
     119    Ref<MediaStreamTrackPrivate> m_private;
    129120
    130121    RefPtr<MediaConstraintsImpl> m_constraints;
    131     Mutex m_mutex;
    132 
    133     Vector<Observer*> m_observers;
    134 
    135     Ref<MediaStreamTrackPrivate> m_privateTrack;
    136     bool m_eventDispatchScheduled;
    137 
    138     bool m_stoppingTrack;
    139122};
    140123
  • trunk/Source/WebCore/Modules/mediastream/MediaStreamTrack.idl

    r181507 r186081  
    4242    readonly attribute boolean remote;
    4343    readonly attribute MediaStreamTrackState readyState;
    44     attribute EventHandler onstarted;
    4544    attribute EventHandler onended;
    4645
    47     [CallWith=ScriptExecutionContext, RaisesException] static void getSources(MediaStreamTrackSourcesCallback callback);
     46    MediaStreamTrack clone();
     47    [ImplementedAs=stopProducingData] void stop();
    4848
    4949    MediaTrackConstraints getConstraints();
    50 
    5150    MediaSourceStates states();
    52 
    5351    MediaStreamCapabilities getCapabilities(); // returns either AllVideoCapabilities or AllAudioCapabilities
    54 
    5552    void applyConstraints(Dictionary constraints);
    5653
    5754    attribute EventHandler onoverconstrained;
    58     MediaStreamTrack clone();
    59     [ImplementedAs=stopProducingData] void stop();
    6055
    6156    // EventTarget interface
  • trunk/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp

    r185316 r186081  
    652652    // FIXME: this class shouldn't know that the private stream client is a MediaStream!
    653653    RefPtr<MediaStream> stream = static_cast<MediaStream*>(privateStream->client());
    654     stream->setActive(false);
    655654
    656655    if (m_signalingState == SignalingStateClosed)
  • trunk/Source/WebCore/Modules/mediastream/UserMediaRequest.cpp

    r185903 r186081  
    159159    RefPtr<MediaStream> stream = MediaStream::create(*m_scriptExecutionContext, privateStream);
    160160    for (auto& track : stream->getAudioTracks())
    161         track->applyConstraints(m_audioConstraints);
     161        track->applyConstraints(*m_audioConstraints);
    162162    for (auto& track : stream->getVideoTracks())
    163         track->applyConstraints(m_videoConstraints);
     163        track->applyConstraints(*m_videoConstraints);
    164164
    165165    m_promise.resolve(stream);
  • trunk/Source/WebCore/platform/mediastream/MediaStreamPrivate.cpp

    r181371 r186081  
    11/*
    2  * Copyright (C) 2011 Ericsson AB. All rights reserved.
     2 * Copyright (C) 2011, 2015 Ericsson AB. All rights reserved.
    33 * Copyright (C) 2013 Google Inc. All rights reserved.
    44 * Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies).
     
    4343namespace WebCore {
    4444
    45 PassRefPtr<MediaStreamPrivate> MediaStreamPrivate::create(const Vector<RefPtr<RealtimeMediaSource>>& audioSources, const Vector<RefPtr<RealtimeMediaSource>>& videoSources)
     45RefPtr<MediaStreamPrivate> MediaStreamPrivate::create(const Vector<RefPtr<RealtimeMediaSource>>& audioSources, const Vector<RefPtr<RealtimeMediaSource>>& videoSources)
    4646{
    47     return adoptRef(new MediaStreamPrivate(createCanonicalUUIDString(), audioSources, videoSources));
     47    Vector<RefPtr<MediaStreamTrackPrivate>> tracks;
     48    tracks.reserveCapacity(audioSources.size() + videoSources.size());
     49
     50    for (auto source : audioSources)
     51        tracks.append(MediaStreamTrackPrivate::create(WTF::move(source)));
     52
     53    for (auto source : videoSources)
     54        tracks.append(MediaStreamTrackPrivate::create(WTF::move(source)));
     55
     56    return MediaStreamPrivate::create(tracks);
    4857}
    4958
    50 PassRefPtr<MediaStreamPrivate> MediaStreamPrivate::create(const Vector<RefPtr<MediaStreamTrackPrivate>>& audioPrivateTracks, const Vector<RefPtr<MediaStreamTrackPrivate>>& videoPrivateTracks)
     59RefPtr<MediaStreamPrivate> MediaStreamPrivate::create(const Vector<RefPtr<MediaStreamTrackPrivate>>& tracks)
    5160{
    52     return adoptRef(new MediaStreamPrivate(createCanonicalUUIDString(), audioPrivateTracks, videoPrivateTracks));
     61    return adoptRef(new MediaStreamPrivate(createCanonicalUUIDString(), tracks));
    5362}
    5463
    55 void MediaStreamPrivate::addSource(PassRefPtr<RealtimeMediaSource> prpSource)
     64RefPtr<MediaStreamPrivate> MediaStreamPrivate::create()
    5665{
    57     RefPtr<RealtimeMediaSource> source = prpSource;
    58     switch (source->type()) {
    59     case RealtimeMediaSource::Audio:
    60         if (m_audioStreamSources.find(source) == notFound)
    61             m_audioStreamSources.append(source);
    62         break;
    63     case RealtimeMediaSource::Video:
    64         if (m_videoStreamSources.find(source) == notFound)
    65             m_videoStreamSources.append(source);
    66         break;
    67     case RealtimeMediaSource::None:
    68         ASSERT_NOT_REACHED();
    69         break;
    70     }
     66    return MediaStreamPrivate::create(Vector<RefPtr<MediaStreamTrackPrivate>>());
    7167}
    7268
    73 void MediaStreamPrivate::removeSource(PassRefPtr<RealtimeMediaSource> source)
    74 {
    75     size_t pos = notFound;
    76     switch (source->type()) {
    77     case RealtimeMediaSource::Audio:
    78         pos = m_audioStreamSources.find(source);
    79         if (pos == notFound)
    80             return;
    81         m_audioStreamSources.remove(pos);
    82         break;
    83     case RealtimeMediaSource::Video:
    84         pos = m_videoStreamSources.find(source);
    85         if (pos == notFound)
    86             return;
    87         m_videoStreamSources.remove(pos);
    88         break;
    89     case RealtimeMediaSource::None:
    90         ASSERT_NOT_REACHED();
    91         break;
    92     }
    93 }
    94 
    95 void MediaStreamPrivate::addRemoteSource(RealtimeMediaSource* source)
    96 {
    97     if (m_client)
    98         m_client->addRemoteSource(source);
    99     else
    100         addSource(source);
    101 }
    102 
    103 void MediaStreamPrivate::removeRemoteSource(RealtimeMediaSource* source)
    104 {
    105     if (m_client)
    106         m_client->removeRemoteSource(source);
    107     else
    108         removeSource(source);
    109 }
    110 
    111 void MediaStreamPrivate::addRemoteTrack(MediaStreamTrackPrivate* track)
    112 {
    113     if (m_client)
    114         m_client->addRemoteTrack(track);
    115     else
    116         addTrack(track);
    117 }
    118 
    119 void MediaStreamPrivate::removeRemoteTrack(MediaStreamTrackPrivate* track)
    120 {
    121     if (m_client)
    122         m_client->removeRemoteTrack(track);
    123     else
    124         removeTrack(track);
    125 }
    126 
    127 MediaStreamPrivate::MediaStreamPrivate(const String& id, const Vector<RefPtr<RealtimeMediaSource>>& audioSources, const Vector<RefPtr<RealtimeMediaSource>>& videoSources)
     69MediaStreamPrivate::MediaStreamPrivate(const String& id, const Vector<RefPtr<MediaStreamTrackPrivate>>& tracks)
    12870    : m_client(0)
    12971    , m_id(id)
     
    13173{
    13274    ASSERT(m_id.length());
    133     for (size_t i = 0; i < audioSources.size(); i++)
    134         addTrack(MediaStreamTrackPrivate::create(audioSources[i]));
    13575
    136     for (size_t i = 0; i < videoSources.size(); i++)
    137         addTrack(MediaStreamTrackPrivate::create(videoSources[i]));
     76    for (auto& track : tracks)
     77        m_trackSet.add(track->id(), track);
    13878
    139     unsigned providedSourcesSize = audioSources.size() + videoSources.size();
    140     unsigned tracksSize = m_audioPrivateTracks.size() + m_videoPrivateTracks.size();
    141 
    142     if (providedSourcesSize > 0 && tracksSize > 0)
    143         m_isActive = true;
     79    updateActiveState(NotifyClientOption::DontNotify);
    14480}
    14581
    146 MediaStreamPrivate::MediaStreamPrivate(const String& id, const Vector<RefPtr<MediaStreamTrackPrivate>>& audioPrivateTracks, const Vector<RefPtr<MediaStreamTrackPrivate>>& videoPrivateTracks)
    147     : m_client(0)
    148     , m_id(id)
    149     , m_isActive(false)
     82Vector<RefPtr<MediaStreamTrackPrivate>> MediaStreamPrivate::tracks() const
    15083{
    151     ASSERT(m_id.length());
    152     for (size_t i = 0; i < audioPrivateTracks.size(); i++)
    153         addTrack(audioPrivateTracks[i]);
     84    Vector<RefPtr<MediaStreamTrackPrivate>> tracks;
     85    tracks.reserveCapacity(m_trackSet.size());
     86    copyValuesToVector(m_trackSet, tracks);
    15487
    155     for (size_t i = 0; i < videoPrivateTracks.size(); i++)
    156         addTrack(videoPrivateTracks[i]);
    157 
    158     unsigned providedTracksSize = audioPrivateTracks.size() + videoPrivateTracks.size();
    159     unsigned tracksSize = m_audioPrivateTracks.size() + m_videoPrivateTracks.size();
    160 
    161     if (providedTracksSize > 0 && tracksSize > 0)
    162         m_isActive = true;
     88    return tracks;
    16389}
    16490
    165 void MediaStreamPrivate::setActive(bool active)
     91void MediaStreamPrivate::updateActiveState(NotifyClientOption notifyClientOption)
    16692{
    167     if (m_isActive == active)
     93    // A stream is active if it has at least one un-ended track.
     94    bool newActiveState = false;
     95    for (auto& track : m_trackSet.values()) {
     96        if (!track->ended()) {
     97            newActiveState = true;
     98            break;
     99        }
     100    }
     101
     102    if (newActiveState == m_isActive)
     103        return;
     104    m_isActive = newActiveState;
     105
     106    if (m_client && notifyClientOption == NotifyClientOption::Notify)
     107        m_client->activeStatusChanged();
     108}
     109
     110void MediaStreamPrivate::addTrack(RefPtr<MediaStreamTrackPrivate>&& track, NotifyClientOption notifyClientOption)
     111{
     112    if (m_trackSet.contains(track->id()))
    168113        return;
    169114
    170     m_isActive = active;
     115    m_trackSet.add(track->id(), track);
    171116
    172     if (m_client)
    173         m_client->setStreamIsActive(active);
     117    if (m_client && notifyClientOption == NotifyClientOption::Notify)
     118        m_client->didAddTrackToPrivate(*track.get());
     119
     120    updateActiveState(NotifyClientOption::Notify);
    174121}
    175122
    176 void MediaStreamPrivate::addTrack(PassRefPtr<MediaStreamTrackPrivate> prpTrack)
     123void MediaStreamPrivate::removeTrack(MediaStreamTrackPrivate& track, NotifyClientOption notifyClientOption)
    177124{
    178     RefPtr<MediaStreamTrackPrivate> track = prpTrack;
    179     Vector<RefPtr<MediaStreamTrackPrivate>>& tracks = track->type() == RealtimeMediaSource::Audio ? m_audioPrivateTracks : m_videoPrivateTracks;
    180 
    181     size_t pos = tracks.find(track);
    182     if (pos != notFound)
     125    if (!m_trackSet.remove(track.id()))
    183126        return;
    184127
    185     tracks.append(track);
    186     if (track->source())
    187         addSource(track->source());
    188 }
     128    if (m_client && notifyClientOption == NotifyClientOption::Notify)
     129        m_client->didRemoveTrackFromPrivate(track);
    189130
    190 void MediaStreamPrivate::removeTrack(PassRefPtr<MediaStreamTrackPrivate> track)
    191 {
    192     Vector<RefPtr<MediaStreamTrackPrivate>>& tracks = track->type() == RealtimeMediaSource::Audio ? m_audioPrivateTracks : m_videoPrivateTracks;
    193 
    194     size_t pos = tracks.find(track);
    195     if (pos == notFound)
    196         return;
    197 
    198     tracks.remove(pos);
     131    updateActiveState(NotifyClientOption::Notify);
    199132}
    200133
  • trunk/Source/WebCore/platform/mediastream/MediaStreamPrivate.h

    r181152 r186081  
    11/*
    2  * Copyright (C) 2011 Ericsson AB. All rights reserved.
     2 * Copyright (C) 2011, 2015 Ericsson AB. All rights reserved.
    33 * Copyright (C) 2012 Google Inc. All rights reserved.
    44 * Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies).
     
    3838#include "MediaStreamTrack.h"
    3939#include "MediaStreamTrackPrivate.h"
    40 #include "RealtimeMediaSource.h"
     40#include <wtf/HashMap.h>
    4141#include <wtf/RefCounted.h>
    4242#include <wtf/Vector.h>
     
    4646class MediaStreamTrackPrivate;
    4747
    48 class MediaStreamPrivateClient : public MediaStreamTrack::Observer {
     48class MediaStreamPrivateClient {
    4949public:
    5050    virtual ~MediaStreamPrivateClient() { }
    5151
    52     virtual void setStreamIsActive(bool) = 0;
    53     virtual void addRemoteSource(RealtimeMediaSource*) = 0;
    54     virtual void removeRemoteSource(RealtimeMediaSource*) = 0;
    55     virtual void addRemoteTrack(MediaStreamTrackPrivate*) = 0;
    56     virtual void removeRemoteTrack(MediaStreamTrackPrivate*) = 0;
     52    virtual void activeStatusChanged() = 0;
     53    virtual void didAddTrackToPrivate(MediaStreamTrackPrivate&) = 0;
     54    virtual void didRemoveTrackFromPrivate(MediaStreamTrackPrivate&) = 0;
    5755};
    5856
    5957class MediaStreamPrivate : public RefCounted<MediaStreamPrivate> {
    6058public:
    61     static PassRefPtr<MediaStreamPrivate> create(const Vector<RefPtr<RealtimeMediaSource>>& audioSources, const Vector<RefPtr<RealtimeMediaSource>>& videoSources);
    62     static PassRefPtr<MediaStreamPrivate> create(const Vector<RefPtr<MediaStreamTrackPrivate>>& audioPrivateTracks, const Vector<RefPtr<MediaStreamTrackPrivate>>& videoPrivateTracks);
     59    static RefPtr<MediaStreamPrivate> create(const Vector<RefPtr<RealtimeMediaSource>>& audioSources, const Vector<RefPtr<RealtimeMediaSource>>& videoSources);
     60    static RefPtr<MediaStreamPrivate> create(const Vector<RefPtr<MediaStreamTrackPrivate>>&);
     61    static RefPtr<MediaStreamPrivate> create();
    6362
    6463    virtual ~MediaStreamPrivate() { }
     64
     65    enum class NotifyClientOption { Notify, DontNotify };
    6566
    6667    MediaStreamPrivateClient* client() const { return m_client; }
     
    6970    String id() const { return m_id; }
    7071
    71     unsigned numberOfAudioSources() const { return m_audioStreamSources.size(); }
    72     RealtimeMediaSource* audioSources(unsigned index) const { return m_audioStreamSources[index].get(); }
    73 
    74     unsigned numberOfVideoSources() const { return m_videoStreamSources.size(); }
    75     RealtimeMediaSource* videoSources(unsigned index) const { return m_videoStreamSources[index].get(); }
    76 
    77     unsigned numberOfAudioTracks() const { return m_audioPrivateTracks.size(); }
    78     MediaStreamTrackPrivate* audioTracks(unsigned index) const { return m_audioPrivateTracks[index].get(); }
    79 
    80     unsigned numberOfVideoTracks() const { return m_videoPrivateTracks.size(); }
    81     MediaStreamTrackPrivate* videoTracks(unsigned index) const { return m_videoPrivateTracks[index].get(); }
    82 
    83     void addSource(PassRefPtr<RealtimeMediaSource>);
    84     void removeSource(PassRefPtr<RealtimeMediaSource>);
    85 
    86     void addRemoteSource(RealtimeMediaSource*);
    87     void removeRemoteSource(RealtimeMediaSource*);
     72    Vector<RefPtr<MediaStreamTrackPrivate>> tracks() const;
    8873
    8974    bool active() const { return m_isActive; }
    90     void setActive(bool);
     75    void updateActiveState(NotifyClientOption);
    9176
    92     void addTrack(PassRefPtr<MediaStreamTrackPrivate>);
    93     void removeTrack(PassRefPtr<MediaStreamTrackPrivate>);
    94 
    95     void addRemoteTrack(MediaStreamTrackPrivate*);
    96     void removeRemoteTrack(MediaStreamTrackPrivate*);
     77    void addTrack(RefPtr<MediaStreamTrackPrivate>&&, NotifyClientOption);
     78    void removeTrack(MediaStreamTrackPrivate&, NotifyClientOption);
    9779
    9880private:
    99     MediaStreamPrivate(const String& id, const Vector<RefPtr<RealtimeMediaSource>>& audioSources, const Vector<RefPtr<RealtimeMediaSource>>& videoSources);
    100     MediaStreamPrivate(const String& id, const Vector<RefPtr<MediaStreamTrackPrivate>>& audioPrivateTracks, const Vector<RefPtr<MediaStreamTrackPrivate>>& videoPrivateTracks);
     81    MediaStreamPrivate(const String& id, const Vector<RefPtr<MediaStreamTrackPrivate>>&);
    10182
    10283    MediaStreamPrivateClient* m_client;
    10384    String m_id;
    104     Vector<RefPtr<RealtimeMediaSource>> m_audioStreamSources;
    105     Vector<RefPtr<RealtimeMediaSource>> m_videoStreamSources;
     85    bool m_isActive;
    10686
    107     Vector<RefPtr<MediaStreamTrackPrivate>> m_audioPrivateTracks;
    108     Vector<RefPtr<MediaStreamTrackPrivate>> m_videoPrivateTracks;
    109     bool m_isActive;
     87    HashMap<String, RefPtr<MediaStreamTrackPrivate>> m_trackSet;
    11088};
    11189
  • trunk/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp

    r181152 r186081  
    11/*
    22 *  Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies).
     3 *  Copyright (C) 2015 Ericsson AB. All rights reserved.
    34 *
    45 * Redistribution and use in source and binary forms, with or without
     
    3738namespace WebCore {
    3839
    39 PassRefPtr<MediaStreamTrackPrivate> MediaStreamTrackPrivate::create(PassRefPtr<RealtimeMediaSource> source)
     40RefPtr<MediaStreamTrackPrivate> MediaStreamTrackPrivate::create(RefPtr<RealtimeMediaSource>&& source)
    4041{
    41     return adoptRef(new MediaStreamTrackPrivate(source));
     42    return adoptRef(new MediaStreamTrackPrivate(WTF::move(source), createCanonicalUUIDString()));
     43}
     44
     45RefPtr<MediaStreamTrackPrivate> MediaStreamTrackPrivate::create(RefPtr<RealtimeMediaSource>&& source, const String& id)
     46{
     47    return adoptRef(new MediaStreamTrackPrivate(WTF::move(source), id));
    4248}
    4349
    4450MediaStreamTrackPrivate::MediaStreamTrackPrivate(const MediaStreamTrackPrivate& other)
    4551    : RefCounted()
     52    , m_source(other.source())
    4653    , m_client(nullptr)
     54    , m_id(createCanonicalUUIDString())
     55    , m_isEnabled(other.enabled())
     56    , m_isEnded(other.ended())
    4757{
    48     m_ignoreMutations = true;
    49     m_id = createCanonicalUUIDString();
    50     setSource(other.source());
    51     m_readyState = other.readyState();
    52     m_muted = other.muted();
    53     m_enabled = other.enabled();
    54     m_stopped = other.stopped();
    55     m_ignoreMutations = false;
     58    m_source->addObserver(this);
    5659}
    5760
    58 MediaStreamTrackPrivate::MediaStreamTrackPrivate(PassRefPtr<RealtimeMediaSource> source)
    59     : m_source(nullptr)
     61MediaStreamTrackPrivate::MediaStreamTrackPrivate(RefPtr<RealtimeMediaSource>&& source, const String& id)
     62    : RefCounted()
     63    , m_source(source)
    6064    , m_client(nullptr)
    61     , m_readyState(RealtimeMediaSource::New)
    62     , m_muted(false)
    63     , m_enabled(true)
    64     , m_stopped(false)
     65    , m_id(id)
     66    , m_isEnabled(true)
     67    , m_isEnded(false)
    6568{
    66     m_ignoreMutations = true;
    67     setSource(source);
    68     m_ignoreMutations = false;
     69    m_source->addObserver(this);
    6970}
    7071
    7172MediaStreamTrackPrivate::~MediaStreamTrackPrivate()
    7273{
    73     if (m_source)
    74         m_source->removeObserver(this);
    75 }
    76 
    77 void MediaStreamTrackPrivate::setSource(PassRefPtr<RealtimeMediaSource> source)
    78 {
    79     if (m_source)
    80         m_source->removeObserver(this);
    81 
    82     m_source = source;
    83 
    84     if (!m_source)
    85         return;
    86 
    87     setMuted(m_source->muted());
    88     setReadyState(m_source->readyState());
    89     if (m_source)
    90         m_source->addObserver(this);
    91 }
    92 
    93 const String& MediaStreamTrackPrivate::id() const
    94 {
    95     if (!m_id.isEmpty())
    96         return m_id;
    97 
    98     // The spec says:
    99     //   Unless a MediaStreamTrack object is created as a part a of special purpose algorithm that
    100     //   specifies how the track id must be initialized, the user agent must generate a globally
    101     //   unique identifier string and initialize the object's id attribute to that string.
    102     if (m_source && m_source->useIDForTrackID())
    103         return m_source->id();
    104 
    105     m_id = createCanonicalUUIDString();
    106     return m_id;
     74    m_source->removeObserver(this);
    10775}
    10876
    10977const String& MediaStreamTrackPrivate::label() const
    11078{
    111     if (m_source)
    112         return m_source->name();
    113 
    114     return emptyString();
    115 }
    116 
    117 bool MediaStreamTrackPrivate::ended() const
    118 {
    119     return m_stopped || (m_source && m_source->readyState() == RealtimeMediaSource::Ended);
     79    return m_source->name();
    12080}
    12181
    12282bool MediaStreamTrackPrivate::muted() const
    12383{
    124     if (m_stopped || !m_source)
    125         return false;
    126 
    12784    return m_source->muted();
    128 }
    129 
    130 void MediaStreamTrackPrivate::setMuted(bool muted)
    131 {
    132     if (m_muted == muted)
    133         return;
    134 
    135     m_muted = muted;
    136 
    137     if (!m_client || m_ignoreMutations)
    138         return;
    139 
    140     m_client->trackMutedChanged();
    14185}
    14286
    14387bool MediaStreamTrackPrivate::readonly() const
    14488{
    145     if (m_stopped || !m_source)
    146         return true;
    147 
    14889    return m_source->readonly();
    14990}
     
    15192bool MediaStreamTrackPrivate::remote() const
    15293{
    153     if (!m_source)
    154         return false;
    155 
    15694    return m_source->remote();
    15795}
     
    15997void MediaStreamTrackPrivate::setEnabled(bool enabled)
    16098{
    161     if (m_stopped || m_enabled == enabled)
     99    // Always update the enabled state regardless of the track being ended.
     100    m_isEnabled = enabled;
     101}
     102
     103void MediaStreamTrackPrivate::endTrack()
     104{
     105    if (ended())
    162106        return;
    163107
    164     // 4.3.3.1
    165     // ... after a MediaStreamTrack is disassociated from its track, its enabled attribute still
    166     // changes value when set; it just doesn't do anything with that new value.
    167     m_enabled = enabled;
    168 
    169     if (m_source)
    170         m_source->setEnabled(enabled);
    171 
    172     if (!m_client || m_ignoreMutations)
    173         return;
    174 
    175     m_client->trackEnabledChanged();
    176 }
    177 
    178 void MediaStreamTrackPrivate::stop(StopBehavior stopSource)
    179 {
    180     if (m_stopped)
    181         return;
    182 
    183     if (stopSource == StopTrackAndStopSource && m_source)
    184         m_source->stop();
    185 
    186     setReadyState(RealtimeMediaSource::Ended);
    187     m_stopped = true;
    188 }
    189 
    190 RealtimeMediaSource::ReadyState MediaStreamTrackPrivate::readyState() const
    191 {
    192     if (m_stopped)
    193         return RealtimeMediaSource::Ended;
    194 
    195     return m_readyState;
    196 }
    197 
    198 void MediaStreamTrackPrivate::setReadyState(RealtimeMediaSource::ReadyState state)
    199 {
    200     if (m_readyState == RealtimeMediaSource::Ended || m_readyState == state)
    201         return;
    202 
    203     RealtimeMediaSource::ReadyState oldState = m_readyState;
    204     m_readyState = state;
    205 
    206     if (!m_client || m_ignoreMutations)
    207         return;
    208 
    209     if ((m_readyState == RealtimeMediaSource::Live && oldState == RealtimeMediaSource::New) || m_readyState == RealtimeMediaSource::Ended)
    210         m_client->trackReadyStateChanged();
     108    m_isEnded = true;
     109    m_source->requestStop(this);
    211110}
    212111
     
    216115}
    217116
    218    
     117RealtimeMediaSource::Type MediaStreamTrackPrivate::type() const
     118{
     119    return m_source->type();
     120}
     121
    219122RefPtr<MediaConstraints> MediaStreamTrackPrivate::constraints() const
    220123{
     
    224127const RealtimeMediaSourceStates& MediaStreamTrackPrivate::states() const
    225128{
    226     if (!m_source) {
    227         DEPRECATED_DEFINE_STATIC_LOCAL(const RealtimeMediaSourceStates, noState, ());
    228         return noState;
    229     }
    230    
    231129    return m_source->states();
    232 }
    233 
    234 RealtimeMediaSource::Type MediaStreamTrackPrivate::type() const
    235 {
    236     if (!m_source)
    237         return RealtimeMediaSource::None;
    238 
    239     return m_source->type();
    240130}
    241131
    242132RefPtr<RealtimeMediaSourceCapabilities> MediaStreamTrackPrivate::capabilities() const
    243133{
    244     if (!m_source)
    245         return 0;
    246 
    247134    return m_source->capabilities();
    248135}
    249136
    250 void MediaStreamTrackPrivate::applyConstraints(PassRefPtr<MediaConstraints>)
     137void MediaStreamTrackPrivate::applyConstraints(const MediaConstraints&)
    251138{
    252139    // FIXME: apply the new constraints to the track
     
    254141}
    255142
    256 void MediaStreamTrackPrivate::sourceReadyStateChanged()
     143void MediaStreamTrackPrivate::sourceStopped()
    257144{
    258     if (stopped())
     145    if (ended())
    259146        return;
    260    
    261     setReadyState(m_source->readyState());
     147
     148    m_isEnded = true;
     149
     150    if (m_client)
     151        m_client->trackEnded();
    262152}
    263153
    264154void MediaStreamTrackPrivate::sourceMutedChanged()
    265155{
    266     if (stopped())
    267         return;
    268    
    269     setMuted(m_source->muted());
     156    if (m_client)
     157        m_client->trackMutedChanged();
    270158}
    271159
    272 void MediaStreamTrackPrivate::sourceEnabledChanged()
     160bool MediaStreamTrackPrivate::preventSourceFromStopping()
    273161{
    274     if (stopped())
    275         return;
    276    
    277     setEnabled(m_source->enabled());
    278 }
    279 
    280 bool MediaStreamTrackPrivate::observerIsEnabled()
    281 {
    282     return enabled();
     162    return !m_isEnded;
    283163}
    284164
  • trunk/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h

    r181152 r186081  
    11/*
    22 *  Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies).
     3 *  Copyright (C) 2015 Ericsson AB. All rights reserved.
    34 *
    45 * Redistribution and use in source and binary forms, with or without
     
    3031
    3132#include "RealtimeMediaSource.h"
    32 #include <wtf/PassRefPtr.h>
    3333#include <wtf/RefCounted.h>
    3434#include <wtf/text/AtomicString.h>
     
    4343    virtual ~MediaStreamTrackPrivateClient() { }
    4444
    45     virtual void trackReadyStateChanged() = 0;
     45    virtual void trackEnded() = 0;
    4646    virtual void trackMutedChanged() = 0;
    47     virtual void trackEnabledChanged() = 0;
    4847};
    4948
    5049class MediaStreamTrackPrivate : public RefCounted<MediaStreamTrackPrivate>, public RealtimeMediaSource::Observer {
    5150public:
    52     static PassRefPtr<MediaStreamTrackPrivate> create(PassRefPtr<RealtimeMediaSource>);
     51    static RefPtr<MediaStreamTrackPrivate> create(RefPtr<RealtimeMediaSource>&&);
     52    static RefPtr<MediaStreamTrackPrivate> create(RefPtr<RealtimeMediaSource>&&, const String& id);
    5353
    5454    virtual ~MediaStreamTrackPrivate();
    5555
    56     const String& id() const;
     56    const String& id() const { return m_id; }
    5757    const String& label() const;
    5858
    59     bool ended() const;
     59    bool ended() const { return m_isEnded; }
    6060
    6161    bool muted() const;
    62     void setMuted(bool);
    6362
    6463    bool readonly() const;
    6564    bool remote() const;
    6665
    67     bool enabled() const { return m_enabled; }
     66    bool enabled() const { return m_isEnabled; }
    6867    void setEnabled(bool);
    69 
    70     void setReadyState(RealtimeMediaSource::ReadyState);
    71     RealtimeMediaSource::ReadyState readyState() const;
    7268
    7369    RefPtr<MediaStreamTrackPrivate> clone();
    7470
    7571    RealtimeMediaSource* source() const { return m_source.get(); }
    76     void setSource(PassRefPtr<RealtimeMediaSource>);
     72    RealtimeMediaSource::Type type() const;
    7773
    78     enum StopBehavior { StopTrackAndStopSource, StopTrackOnly };
    79     void stop(StopBehavior);
    80     bool stopped() const { return m_stopped; }
    81    
     74    void endTrack();
     75
    8276    void setClient(MediaStreamTrackPrivateClient* client) { m_client = client; }
    83 
    84     RealtimeMediaSource::Type type() const;
    8577
    8678    const RealtimeMediaSourceStates& states() const;
     
    8880
    8981    RefPtr<MediaConstraints> constraints() const;
    90     void applyConstraints(PassRefPtr<MediaConstraints>);
     82    void applyConstraints(const MediaConstraints&);
    9183
    9284    void configureTrackRendering();
    9385
    94 protected:
     86private:
    9587    explicit MediaStreamTrackPrivate(const MediaStreamTrackPrivate&);
    96     MediaStreamTrackPrivate(PassRefPtr<RealtimeMediaSource>);
     88    MediaStreamTrackPrivate(RefPtr<RealtimeMediaSource>&&, const String& id);
    9789
    98 private:
    9990    MediaStreamTrackPrivateClient* client() const { return m_client; }
    10091
    10192    // RealtimeMediaSourceObserver
    102     virtual void sourceReadyStateChanged() override final;
     93    virtual void sourceStopped() override final;
    10394    virtual void sourceMutedChanged() override final;
    104     virtual void sourceEnabledChanged() override final;
    105     virtual bool observerIsEnabled() override final;
     95    virtual bool preventSourceFromStopping() override final;
    10696   
    10797    RefPtr<RealtimeMediaSource> m_source;
    10898    MediaStreamTrackPrivateClient* m_client;
    10999    RefPtr<MediaConstraints> m_constraints;
    110     RealtimeMediaSource::ReadyState m_readyState;
    111     mutable String m_id;
    112100
    113     bool m_muted;
    114     bool m_enabled;
    115     bool m_stopped;
    116     bool m_ignoreMutations;
     101    String m_id;
     102    bool m_isEnabled;
     103    bool m_isEnded;
    117104};
    118105
  • trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp

    r181371 r186081  
    33 * Copyright (C) 2013 Apple Inc. All rights reserved.
    44 * Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies).
     5 * Copyright (C) 2015 Ericsson AB. All rights reserved.
    56 *
    67 * Redistribution and use in source and binary forms, with or without
     
    4546    , m_type(type)
    4647    , m_name(name)
    47     , m_readyState(New)
    48     , m_enabled(true)
     48    , m_stopped(false)
    4949    , m_muted(false)
    5050    , m_readonly(false)
     
    5555   
    5656    m_id = createCanonicalUUIDString();
     57
     58    startProducingData();
    5759}
    5860
    5961void RealtimeMediaSource::reset()
    6062{
    61     m_readyState = New;
    62     m_enabled = true;
     63    m_stopped = false;
    6364    m_muted = false;
    6465    m_readonly = false;
    6566    m_remote = false;
    66 }
    67 
    68 void RealtimeMediaSource::setReadyState(ReadyState readyState)
    69 {
    70     if (m_readyState == Ended || m_readyState == readyState)
    71         return;
    72 
    73     m_readyState = readyState;
    74     for (auto observer = m_observers.begin(); observer != m_observers.end(); ++observer)
    75         (*observer)->sourceReadyStateChanged();
    76 
    77     if (m_readyState == Live) {
    78         startProducingData();
    79         return;
    80     }
    81    
    82     // There are no more consumers of this source's data, shut it down as appropriate.
    83     if (m_readyState == Ended)
    84         stopProducingData();
    8567}
    8668
     
    10789    m_muted = muted;
    10890
    109     if (m_readyState == Ended)
     91    if (stopped())
    11092        return;
    11193
    112     for (auto observer = m_observers.begin(); observer != m_observers.end(); ++observer)
    113         (*observer)->sourceMutedChanged();
    114 }
    115 
    116 void RealtimeMediaSource::setEnabled(bool enabled)
    117 {
    118     if (!enabled) {
    119         // Don't disable the source unless all observers are disabled.
    120         for (auto observer = m_observers.begin(); observer != m_observers.end(); ++observer) {
    121             if ((*observer)->observerIsEnabled())
    122                 return;
    123         }
    124     }
    125 
    126     if (m_enabled == enabled)
    127         return;
    128 
    129     m_enabled = enabled;
    130 
    131     if (m_readyState == Ended)
    132         return;
    133 
    134     if (!enabled)
    135         stopProducingData();
    136     else
    137         startProducingData();
    138 
    139     for (auto observer = m_observers.begin(); observer != m_observers.end(); ++observer)
    140         (*observer)->sourceEnabledChanged();
     94    for (auto& observer : m_observers)
     95        observer->sourceMutedChanged();
    14196}
    14297
     
    146101}
    147102
    148 void RealtimeMediaSource::stop()
     103void RealtimeMediaSource::stop(Observer* callingObserver)
    149104{
    150     // This is called from the track.stop() method, which should "Permanently stop the generation of data
    151     // for track's source", so go straight to ended. This will notify any other tracks using this source
    152     // that it is no longer available.
    153     setReadyState(Ended);
     105    if (stopped())
     106        return;
     107
     108    m_stopped = true;
     109
     110    for (auto observer : m_observers) {
     111        if (observer != callingObserver)
     112            observer->sourceStopped();
     113    }
     114
     115    stopProducingData();
     116}
     117
     118void RealtimeMediaSource::requestStop(Observer* callingObserver)
     119{
     120    if (stopped())
     121        return;
     122
     123    for (auto observer : m_observers) {
     124        if (observer->preventSourceFromStopping())
     125            return;
     126    }
     127    stop(callingObserver);
    154128}
    155129
  • trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.h

    r181152 r186081  
    5757       
    5858        // Source state changes.
    59         virtual void sourceReadyStateChanged() = 0;
     59        virtual void sourceStopped() = 0;
    6060        virtual void sourceMutedChanged() = 0;
    61         virtual void sourceEnabledChanged() = 0;
    6261
    6362        // Observer state queries.
    64         virtual bool observerIsEnabled() = 0;
     63        virtual bool preventSourceFromStopping() = 0;
    6564    };
    6665
     
    6867
    6968    bool isAudioStreamSource() const { return type() == Audio; }
    70     virtual bool useIDForTrackID() const { return false; }
    7169
    7270    const String& id() const { return m_id; }
     
    8179    virtual const RealtimeMediaSourceStates& states() = 0;
    8280   
    83     enum ReadyState { New = 0, Live = 1, Ended = 2 };
    84     virtual ReadyState readyState() const { return m_readyState; }
    85     virtual void setReadyState(ReadyState);
    86 
    87     virtual bool enabled() const { return m_enabled; }
    88     virtual void setEnabled(bool);
     81    bool stopped() const { return m_stopped; }
    8982
    9083    virtual bool muted() const { return m_muted; }
     
    10396    virtual void stopProducingData() { }
    10497
    105     void stop();
     98    void stop(Observer* callingObserver = nullptr);
     99    void requestStop(Observer* callingObserver = nullptr);
    106100
    107101    void reset();
     
    114108    Type m_type;
    115109    String m_name;
    116     ReadyState m_readyState;
     110    bool m_stopped;
    117111    Vector<Observer*> m_observers;
    118112
    119     bool m_enabled;
    120113    bool m_muted;
    121114    bool m_readonly;
  • trunk/Source/WebCore/platform/mediastream/openwebrtc/RealtimeMediaSourceCenterOwr.cpp

    r185502 r186081  
    116116        if (audioSource) {
    117117            audioSource->reset();
    118             audioSource->setReadyState(RealtimeMediaSource::Live);
    119118            audioSources.append(audioSource.release());
    120119        }
     
    127126        if (videoSource) {
    128127            videoSource->reset();
    129             videoSource->setReadyState(RealtimeMediaSource::Live);
    130128            videoSources.append(videoSource.release());
    131129        }
  • trunk/Source/WebCore/platform/mock/MockRealtimeMediaSourceCenter.cpp

    r181371 r186081  
    175175        RefPtr<RealtimeMediaSource> audioSource = it->value;
    176176        audioSource->reset();
    177         audioSource->setReadyState(RealtimeMediaSource::Live);
    178177        audioSources.append(audioSource.release());
    179178    }
     
    191190        RefPtr<RealtimeMediaSource> videoSource = it->value;
    192191        videoSource->reset();
    193         videoSource->setReadyState(RealtimeMediaSource::Live);
    194192        videoSources.append(videoSource.release());
    195193    }
Note: See TracChangeset for help on using the changeset viewer.