Changeset 186081 in webkit
- Timestamp:
- Jun 29, 2015 12:52:21 PM (9 years ago)
- Location:
- trunk
- Files:
-
- 10 added
- 2 deleted
- 32 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r186078 r186081 1 2015-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 1 39 2015-06-29 Matt Rajca <mrajca@apple.com> 2 40 -
trunk/LayoutTests/TestExpectations
r186061 r186081 44 44 45 45 webkit.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 ]50 46 51 47 webkit.org/b/126142 css3/calc/transitions-dependent.html [ Pass Failure ] -
trunk/LayoutTests/fast/mediastream/MediaStream-add-ended-tracks-expected.txt
r169611 r186081 5 5 6 6 PASS stream1.getAudioTracks().length is 1 7 PASS stream2.getAudioTracks().length is 1 7 PASS stream1.getVideoTracks().length is 1 8 *** extract audioTrack 9 *** stop audioTrack 8 10 PASS audioTrack.readyState is "ended" 9 PASS stream2.getAudioTracks().length is 2 11 *** construct new 'empty' stream2 12 PASS stream2.getTracks().length is 0 13 PASS stream2.active is false 14 *** add ended audioTrack to stream2 15 *** schedule continuation of test 16 *** extract videoTrack (and verify liveness) 17 PASS videoTrack.readyState is "live" 18 *** add live videoTrack to stream2 19 *** stream2 is active again 20 PASS stream2.active is true 10 21 PASS successfullyParsed is true 11 22 -
trunk/LayoutTests/fast/mediastream/MediaStream-add-ended-tracks.html
r169611 r186081 3 3 <head> 4 4 <script src="../../resources/js-test-pre.js"></script> 5 <script src="./resources/getUserMedia-helper.js"></script> 5 6 <script> 6 7 … … 8 9 var stream2; 9 10 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; 26 12 27 13 function tryAddTrack(stream, track) … … 35 21 } 36 22 37 function createStreamAndAddTracks()23 function shouldNotFireActive() 38 24 { 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 } 45 27 28 function shouldFireActive() 29 { 30 debug("*** stream2 is active again"); 31 shouldBe('stream2.active', 'true'); 46 32 finishJSTest(); 47 33 } 48 34 49 function gotStream2(s)35 function continueTest() 50 36 { 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); 53 44 } 54 45 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) 56 68 { 57 69 stream1 = s; 58 70 shouldBe('stream1.getAudioTracks().length', '1'); 59 getUserMedia({audio:true, video:true}, gotStream2); 71 shouldBe('stream1.getVideoTracks().length', '1'); 72 createStreamAndAddTracks(); 60 73 } 61 74 … … 63 76 { 64 77 description("Test adding tracks to inactive MediaStream."); 65 getUserMedia( {audio:true, video:true}, gotStream1);78 getUserMedia("allow", {audio:true, video:true}, gotStream); 66 79 } 67 80 window.jsTestIsAsync = true; -
trunk/LayoutTests/fast/mediastream/MediaStream-add-remove-tracks-expected.txt
r168679 r186081 45 45 PASS stream1.getVideoTracks().length is 2 46 46 47 *** remove all tracks, stream .ended should return true47 *** remove all tracks, stream will become inactive 48 48 PASS stream2.getAudioTracks().length is 0 49 49 PASS stream2.getVideoTracks().length is 0 50 50 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) 52 PASS stream2.active is true 53 53 54 Stream2 is inactive. 55 PASS stream2.active is false 56 57 *** add non-ended track 58 PASS audioTrack.readyState is not "ended" 59 60 *** active attribute is still false (until event is fired) 61 PASS stream2.active is false 62 63 Stream2 is active. 64 PASS stream2.active is true 54 65 PASS successfullyParsed is true 55 66 -
trunk/LayoutTests/fast/mediastream/MediaStream-add-remove-tracks.html
r168679 r186081 3 3 <head> 4 4 <script src="../../resources/js-test-pre.js"></script> 5 <script src="./resources/getUserMedia-helper.js"></script> 5 6 </head> 6 7 <body> … … 14 15 var audioTrack; 15 16 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 }30 17 31 18 function tryAddTrack(stream, track) { … … 52 39 53 40 function shouldFireActive() { 54 debug("Stream2 is active."); 41 debug("<br>Stream2 is active."); 42 shouldBe('stream2.active', 'true'); 55 43 finishJSTest(); 56 44 } 57 45 58 46 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'); 61 56 } 62 57 … … 125 120 shouldBe('stream1.getVideoTracks().length', '2'); 126 121 127 debug("<br>*** remove all tracks, stream .ended should return true");122 debug("<br>*** remove all tracks, stream will become inactive"); 128 123 tryRemoveTrack(stream2, stream2.getAudioTracks()[0]); 129 124 tryRemoveTrack(stream2, stream2.getVideoTracks()[0]); … … 131 126 shouldBe('stream2.getVideoTracks().length', '0'); 132 127 133 debug("<br>*** it should be impossible to remove a track after the stream has ended");134 should Throw('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'); 135 130 } 136 131 137 132 function gotStream1(s) { 138 133 stream1 = s; 139 getUserMedia( {audio:true, video:true}, gotStream2);134 getUserMedia("allow", {audio:true, video:true}, gotStream2); 140 135 } 141 136 142 getUserMedia( {audio:true, video:true}, gotStream1);137 getUserMedia("allow", {audio:true, video:true}, gotStream1); 143 138 144 139 window.jsTestIsAsync = true; -
trunk/LayoutTests/fast/mediastream/MediaStream-add-tracks-to-inactive-stream.html
r168679 r186081 3 3 <head> 4 4 <script src="../../resources/js-test-pre.js"></script> 5 <script src="./resources/getUserMedia-helper.js"></script> 5 6 <script> 6 7 … … 8 9 var stream1; 9 10 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 }26 11 27 12 function tryAddTrack(stream, track) … … 56 41 { 57 42 description("Test adding tracks to inactive MediaStream."); 58 getUserMedia( {audio:true, video:true}, gotStream1);43 getUserMedia("allow", {audio:true, video:true}, gotStream1); 59 44 } 60 45 window.jsTestIsAsync = true; -
trunk/LayoutTests/fast/mediastream/MediaStream-clone.html
r157273 r186081 3 3 <head> 4 4 <script src="../../resources/js-test-pre.js"></script> 5 <script src="./resources/getUserMedia-helper.js"></script> 5 6 <script> 6 7 var mediaStream; 7 8 var newMediaStream; 8 var audioTracks; 9 var videoTracks; 10 var newAudioTracks; 11 var newVideoTracks; 9 var track; 10 var newTrack; 12 11 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"); 19 23 } 20 24 … … 23 27 debug(""); 24 28 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 25 34 evalAndLog("newMediaStream = mediaStream.clone()"); 26 35 27 36 shouldNotBe('mediaStream.id', 'newMediaStream.id'); 28 37 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]); 33 40 34 checkTracks(audioTracks, newAudioTracks);35 checkTracks(videoTracks, newVideoTracks);36 }37 38 function getUserMediaError() {39 testFailed('Could not get MediaStream');40 41 finishJSTest(); 41 42 } 42 43 43 44 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); 50 46 } 51 47 -
trunk/LayoutTests/fast/mediastream/MediaStream-construct-with-ended-tracks.html
r157268 r186081 3 3 <head> 4 4 <script src="../../resources/js-test-pre.js"></script> 5 <script src="./resources/getUserMedia-helper.js"></script> 5 6 <script> 6 7 var mediaStream; … … 8 9 var audioTrack; 9 10 var newMediaStream; 11 var mediaStreamCopy; 10 12 11 13 function gotStream(stream) { 12 14 mediaStream = stream; 13 15 debug(""); 14 shouldEvaluateTo('mediaStream. ended', false);16 shouldEvaluateTo('mediaStream.active', true); 15 17 16 18 evalAndLog("videoTrack = mediaStream.getVideoTracks()[0]"); … … 30 32 newMediaStream = new webkitMediaStream(tracksArray); 31 33 32 shouldEvaluateTo('newMediaStream. ended', true);33 shouldNotBe EqualToString(mediaStream.id, newMediaStream.id);34 shouldEvaluateTo('newMediaStream.active', false); 35 shouldNotBe('mediaStream.id', 'newMediaStream.id'); 34 36 35 varmediaStreamCopy = new webkitMediaStream(newMediaStream);36 shouldEvaluateTo('mediaStreamCopy. ended', true);37 mediaStreamCopy = new webkitMediaStream(newMediaStream); 38 shouldEvaluateTo('mediaStreamCopy.active', false); 37 39 shouldNotBe('mediaStreamCopy.id', 'newMediaStream.id'); 38 }39 40 40 function getUserMediaError() {41 testFailed('Could not get MediaStream');42 41 finishJSTest(); 43 42 } 44 43 45 44 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); 52 46 } 53 47 -
trunk/LayoutTests/fast/mediastream/MediaStream-getTracks-expected.txt
r169743 r186081 1 Test adding tracks to inactiveMediaStream.1 Test the different methods to get tracks from a MediaStream. 2 2 3 3 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". … … 6 6 PASS stream1.getTracks().length is 2 7 7 PASS stream2.getTracks().length is 2 8 getAudioTracks(), getVideoTracks() and getTracks() must return a new sequence at every invocation 9 PASS stream2.getAudioTracks() != stream2.getAudioTracks() is true 10 PASS stream2.getVideoTracks() != stream2.getVideoTracks() is true 11 PASS stream2.getTracks() != stream2.getTracks() is true 8 12 PASS track added to stream. 9 13 PASS stream2.getAudioTracks().length is 2 … … 13 17 PASS stream2.getAudioTracks().length is 2 14 18 PASS stream2.getVideoTracks().length is 2 15 PASS stream2.getTracks().length is 4 19 PASS allTracks.length is 4 20 PASS stream2.getTrackById(id) is non-null. 21 PASS stream2.getTrackById(id) is non-null. 22 PASS stream2.getTrackById(id) is non-null. 23 PASS stream2.getTrackById(id) is non-null. 24 PASS stream2.getTrackById("foo-id") is null 16 25 PASS successfullyParsed is true 17 26 -
trunk/LayoutTests/fast/mediastream/MediaStream-getTracks.html
r169743 r186081 3 3 <head> 4 4 <script src="../../resources/js-test-pre.js"></script> 5 <script src="./resources/getUserMedia-helper.js"></script> 5 6 <script> 6 7 … … 9 10 var audioTrack; 10 11 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; 27 14 28 15 function tryAddTrack(stream, track) … … 40 27 { 41 28 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 42 35 audioTrack = stream1.getAudioTracks()[0]; 43 36 tryAddTrack(stream2, audioTrack); … … 49 42 shouldBe('stream2.getAudioTracks().length', '2'); 50 43 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")'); 52 51 53 52 finishJSTest(); … … 64 63 stream1 = s; 65 64 shouldBe('stream1.getTracks().length', '2'); 66 getUserMedia( {audio:true, video:true}, gotStream2);65 getUserMedia("allow", {audio:true, video:true}, gotStream2); 67 66 } 68 67 69 68 function startMedia() 70 69 { 71 description("Test adding tracks to inactiveMediaStream.");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); 73 72 } 74 73 window.jsTestIsAsync = true; -
trunk/LayoutTests/fast/mediastream/MediaStreamConstructor.html
r158987 r186081 3 3 <head> 4 4 <script src="../../resources/js-test-pre.js"></script> 5 <script src="./resources/getUserMedia-helper.js"></script> 5 6 </head> 6 7 <body> … … 39 40 40 41 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 }55 42 } 56 43 … … 105 92 } 106 93 107 getUserMedia( {video:true, audio:true}, gotStream);94 getUserMedia("allow", {video:true, audio:true}, gotStream); 108 95 109 96 window.jsTestIsAsync = true; -
trunk/LayoutTests/fast/mediastream/MediaStreamTrackEvent-constructor-expected.txt
r156522 r186081 4 4 5 5 6 PASS getUserMedia({audio:true, video:true}, gotStream) did not throw exception.7 6 8 7 *** getUserMedia() succeeded, test stream *** -
trunk/LayoutTests/fast/mediastream/MediaStreamTrackEvent-constructor.html
r156522 r186081 3 3 <head> 4 4 <script src="../../resources/js-test-pre.js"></script> 5 <script src="./resources/getUserMedia-helper.js"></script> 5 6 </head> 6 7 <script> … … 18 19 clearTimeout(timer); 19 20 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 }36 21 } 37 22 … … 93 78 { 94 79 primeTimeout("Timeout waiting for getUserMedia()"); 95 shouldNotThrow('getUserMedia({audio:true, video:true}, gotStream)');80 getUserMedia("allow", {audio:true, video:true}, gotStream); 96 81 } 97 82 -
trunk/LayoutTests/platform/gtk/TestExpectations
r186021 r186081 316 316 317 317 # 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 ]325 318 webkit.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 ]328 319 webkit.org/b/79203 fast/mediastream/MediaStreamTrack.html [ Skip ] 329 320 webkit.org/b/79203 fast/mediastream/MediaStreamTrack-onended.html [ Skip ] -
trunk/Source/WebCore/ChangeLog
r186079 r186081 1 2015-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 1 157 2015-06-29 Benjamin Poulain <benjamin@webkit.org> 2 158 -
trunk/Source/WebCore/Modules/mediastream/MediaStream.cpp
r185336 r186081 1 1 /* 2 2 * 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. 4 4 * Copyright (C) 2013 Apple Inc. All rights reserved. 5 5 * Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies). … … 42 42 Ref<MediaStream> MediaStream::create(ScriptExecutionContext& context) 43 43 { 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 47 Ref<MediaStream> MediaStream::create(ScriptExecutionContext& context, MediaStream* stream) 48 48 { 49 49 ASSERT(stream); 50 50 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())); 61 52 } 62 53 63 54 Ref<MediaStream> MediaStream::create(ScriptExecutionContext& context, const Vector<RefPtr<MediaStreamTrack>>& tracks) 64 55 { 65 Vector<RefPtr<MediaStreamTrackPrivate>> audioTracks; 66 Vector<RefPtr<MediaStreamTrackPrivate>> videoTracks; 56 return adoptRef(*new MediaStream(context, tracks)); 57 } 58 59 Ref<MediaStream> MediaStream::create(ScriptExecutionContext& context, RefPtr<MediaStreamPrivate>&& streamPrivate) 60 { 61 return adoptRef(*new MediaStream(context, WTF::move(streamPrivate))); 62 } 63 64 MediaStream::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()); 67 72 68 73 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 84 MediaStream::MediaStream(ScriptExecutionContext& context, RefPtr<MediaStreamPrivate>&& streamPrivate) 84 85 : 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) 87 89 { 88 90 ASSERT(m_private); 89 91 m_private->setClient(this); 90 92 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); 96 95 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)); 106 97 } 107 98 } … … 112 103 } 113 104 114 bool MediaStream::active() const 115 { 116 return m_private->active(); 117 } 118 119 void MediaStream::setActive(bool isActive) 120 { 121 if (active() == isActive) 105 RefPtr<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 116 void MediaStream::addTrack(RefPtr<MediaStreamTrack>&& track) 117 { 118 if (!internalAddTrack(WTF::move(track), StreamModifier::DomAPI)) 122 119 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 125 void MediaStream::removeTrack(MediaStreamTrack* track) 126 { 127 if (!internalRemoveTrack(track, StreamModifier::DomAPI)) 145 128 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 134 MediaStreamTrack* 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 143 Vector<RefPtr<MediaStreamTrack>> MediaStream::getAudioTracks() const 144 { 145 return trackVectorForType(RealtimeMediaSource::Audio); 146 } 147 148 Vector<RefPtr<MediaStreamTrack>> MediaStream::getVideoTracks() const 149 { 150 return trackVectorForType(RealtimeMediaSource::Video); 151 } 152 153 Vector<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 162 void MediaStream::contextDestroyed() 163 { 164 ContextDestructionObserver::contextDestroyed(); 165 } 166 167 void MediaStream::trackDidEnd() 168 { 169 m_private->updateActiveState(MediaStreamPrivate::NotifyClientOption::Notify); 170 } 171 172 void 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 179 void 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 188 void MediaStream::didRemoveTrackFromPrivate(MediaStreamTrackPrivate& trackPrivate) 189 { 190 RefPtr<MediaStreamTrack> track = getTrackById(trackPrivate.id()); 191 internalRemoveTrack(WTF::move(track), StreamModifier::Platform); 192 } 193 194 bool MediaStream::internalAddTrack(RefPtr<MediaStreamTrack>&& track, StreamModifier streamModifier) 195 { 159 196 if (getTrackById(track->id())) 160 197 return false; 161 198 162 Vector<RefPtr<MediaStreamTrack>>* tracks = trackVectorForType(track->source()->type()); 163 164 tracks->append(track); 199 m_trackSet.add(track->id(), track); 165 200 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 168 207 return true; 169 208 } 170 209 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) 210 bool MediaStream::internalRemoveTrack(RefPtr<MediaStreamTrack>&& track, StreamModifier streamModifier) 211 { 212 if (!m_trackSet.remove(track->id())) 198 213 return false; 199 214 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 no205 // other track using it.206 if (!haveTrackWithSource(track->source()))207 m_private->removeSource(track->source());208 209 215 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))); 212 221 213 222 return true; 214 223 } 215 224 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() 225 void 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 234 void 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 247 URLRegistry& MediaStream::registry() const 248 { 249 return MediaStreamRegistry::registry(); 250 } 251 252 Vector<RefPtr<MediaStreamTrack>> MediaStream::trackVectorForType(RealtimeMediaSource::Type filterType) const 250 253 { 251 254 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 } 256 259 257 260 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 else280 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() const371 {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;386 261 } 387 262 -
trunk/Source/WebCore/Modules/mediastream/MediaStream.h
r185091 r186081 1 1 /* 2 2 * 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. 4 4 * Copyright (C) 2013 Apple Inc. All rights reserved. 5 5 * Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies). … … 39 39 #include "Timer.h" 40 40 #include "URLRegistry.h" 41 #include <wtf/HashMap.h> 41 42 #include <wtf/RefCounted.h> 42 43 #include <wtf/RefPtr.h> … … 44 45 namespace WebCore { 45 46 46 class MediaStream final : public RefCounted<MediaStream>, public URLRegistrable, public ScriptWrappable, public MediaStreamPrivateClient, public EventTargetWithInlineData, public ContextDestructionObserver {47 class MediaStream final : public RefCounted<MediaStream>, public URLRegistrable, public ScriptWrappable, public MediaStreamPrivateClient, public EventTargetWithInlineData, public ContextDestructionObserver, public MediaStreamTrack::Observer { 47 48 public: 48 49 class Observer { … … 53 54 54 55 static Ref<MediaStream> create(ScriptExecutionContext&); 55 static Ref<MediaStream> create(ScriptExecutionContext&, PassRefPtr<MediaStream>);56 static Ref<MediaStream> create(ScriptExecutionContext&, MediaStream*); 56 57 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>&&); 58 59 virtual ~MediaStream(); 59 60 60 61 String id() const { return m_private->id(); } 61 62 62 void addTrack( PassRefPtr<MediaStreamTrack>, ExceptionCode&);63 void removeTrack( PassRefPtr<MediaStreamTrack>, ExceptionCode&);63 void addTrack(RefPtr<MediaStreamTrack>&&); 64 void removeTrack(MediaStreamTrack*); 64 65 MediaStreamTrack* getTrackById(String); 65 66 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; 69 70 70 PassRefPtr<MediaStream> clone();71 RefPtr<MediaStream> clone(); 71 72 72 bool active() const; 73 void setActive(bool); 73 bool active() const { return m_isActive; } 74 74 75 75 MediaStreamPrivate* privateStream() const { return m_private.get(); } … … 89 89 90 90 protected: 91 MediaStream(ScriptExecutionContext&, PassRefPtr<MediaStreamPrivate>); 91 MediaStream(ScriptExecutionContext&, const Vector<RefPtr<MediaStreamTrack>>&); 92 MediaStream(ScriptExecutionContext&, RefPtr<MediaStreamPrivate>&&); 92 93 93 94 // ContextDestructionObserver … … 95 96 96 97 private: 98 enum class StreamModifier { DomAPI, Platform }; 99 97 100 // EventTarget 98 101 virtual void refEventTarget() override final { ref(); } 99 102 virtual void derefEventTarget() override final { deref(); } 100 103 104 // MediaStreamTrack::Observer 105 virtual void trackDidEnd() override final; 106 101 107 // 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; 108 111 109 bool removeTrack(PassRefPtr<MediaStreamTrack>);110 bool addTrack(PassRefPtr<MediaStreamTrack>);112 bool internalAddTrack(RefPtr<MediaStreamTrack>&&, StreamModifier); 113 bool internalRemoveTrack(RefPtr<MediaStreamTrack>&&, StreamModifier); 111 114 112 bool haveTrackWithSource(PassRefPtr<RealtimeMediaSource>); 115 void scheduleActiveStateChange(); 116 void activityEventTimerFired(); 113 117 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; 120 119 121 120 RefPtr<MediaStreamPrivate> m_private; 122 Vector<RefPtr<MediaStreamTrack>> m_audioTracks;123 Vector<RefPtr<MediaStreamTrack>> m_videoTracks;124 121 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; 127 127 128 128 Vector<Observer*> m_observers; -
trunk/Source/WebCore/Modules/mediastream/MediaStream.idl
r181507 r186081 38 38 sequence<MediaStreamTrack> getVideoTracks(); 39 39 sequence<MediaStreamTrack> getTracks(); 40 MediaStreamTrack getTrackById(DOMString trackId); 40 41 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 44 45 MediaStream clone(); 45 46 -
trunk/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp
r185101 r186081 1 1 /* 2 2 * 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. 4 4 * Copyright (C) 2013 Apple Inc. All rights reserved. 5 5 * Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies). … … 41 41 #include "MediaStream.h" 42 42 #include "MediaStreamPrivate.h" 43 #include "MediaStreamTrackSourcesCallback.h"44 #include "MediaStreamTrackSourcesRequest.h"45 43 #include "MediaTrackConstraints.h" 46 44 #include "NotImplemented.h" 47 #include "RealtimeMediaSourceCenter.h"45 #include <wtf/Functional.h> 48 46 #include <wtf/NeverDestroyed.h> 49 47 … … 53 51 { 54 52 return adoptRef(*new MediaStreamTrack(context, privateTrack)); 55 }56 57 Ref<MediaStreamTrack> MediaStreamTrack::create(MediaStreamTrack& track)58 {59 return adoptRef(*new MediaStreamTrack(track));60 53 } 61 54 … … 63 56 : RefCounted() 64 57 , ActiveDOMObject(&context) 65 , m_privateTrack(privateTrack) 66 , m_eventDispatchScheduled(false) 67 , m_stoppingTrack(false) 58 , m_private(privateTrack) 68 59 { 69 60 suspendIfNeeded(); 70 61 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); 84 63 } 85 64 86 65 MediaStreamTrack::~MediaStreamTrack() 87 66 { 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); 94 68 } 95 69 … … 99 73 static NeverDestroyed<AtomicString> videoKind("video", AtomicString::ConstructFromLiteral); 100 74 101 if (m_private Track->type() == RealtimeMediaSource::Audio)75 if (m_private->type() == RealtimeMediaSource::Audio) 102 76 return audioKind; 103 77 return videoKind; … … 106 80 const String& MediaStreamTrack::id() const 107 81 { 108 return m_private Track->id();82 return m_private->id(); 109 83 } 110 84 111 85 const String& MediaStreamTrack::label() const 112 86 { 113 return m_private Track->label();87 return m_private->label(); 114 88 } 115 89 116 90 bool MediaStreamTrack::enabled() const 117 91 { 118 return m_private Track->enabled();92 return m_private->enabled(); 119 93 } 120 94 121 95 void MediaStreamTrack::setEnabled(bool enabled) 122 96 { 123 m_privateTrack->setEnabled(enabled); 124 } 125 126 bool MediaStreamTrack::stopped() const 127 { 128 return m_privateTrack->stopped(); 97 m_private->setEnabled(enabled); 129 98 } 130 99 131 100 bool MediaStreamTrack::muted() const 132 101 { 133 return m_private Track->muted();102 return m_private->muted(); 134 103 } 135 104 136 105 bool MediaStreamTrack::readonly() const 137 106 { 138 return m_private Track->readonly();107 return m_private->readonly(); 139 108 } 140 109 141 110 bool MediaStreamTrack::remote() const 142 111 { 143 return m_private Track->remote();112 return m_private->remote(); 144 113 } 145 114 146 115 const AtomicString& MediaStreamTrack::readyState() const 147 116 { 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 123 bool MediaStreamTrack::ended() const 124 { 125 return m_private->ended(); 126 } 127 128 RefPtr<MediaStreamTrack> MediaStreamTrack::clone() 129 { 130 return MediaStreamTrack::create(*scriptExecutionContext(), *m_private->clone()); 131 } 132 133 void 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(); 170 143 } 171 144 … … 179 152 RefPtr<MediaSourceStates> MediaStreamTrack::states() const 180 153 { 181 return MediaSourceStates::create(m_private Track->states());154 return MediaSourceStates::create(m_private->states()); 182 155 } 183 156 … … 185 158 { 186 159 // 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 orhas ended always has a source160 // in sync with the track state. A track that has ended always has a source 188 161 // 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()) 192 164 sourceCapabilities->setSourceType(RealtimeMediaSourceStates::None); 193 165 … … 198 170 { 199 171 m_constraints->initialize(constraints); 200 m_private Track->applyConstraints(m_constraints);201 } 202 203 void MediaStreamTrack::applyConstraints( PassRefPtr<MediaConstraints>)172 m_private->applyConstraints(*m_constraints); 173 } 174 175 void MediaStreamTrack::applyConstraints(const MediaConstraints&) 204 176 { 205 177 // FIXME: apply the new constraints to the track 206 178 // 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, using217 // the "ImplementedAs" IDL attribute. This is done because ActiveDOMObject requires218 // a "stop" method.219 220 // The stop method should "Permanently stop the generation of data for track's source", but it221 // 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() const228 {229 return m_privateTrack->ended();230 179 } 231 180 … … 242 191 } 243 192 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)); 193 void MediaStreamTrack::trackEnded() 194 { 195 dispatchEvent(Event::create(eventNames().endedEvent, false, false)); 196 197 for (auto& observer : m_observers) 198 observer->trackDidEnd(); 254 199 255 200 configureTrackRendering(); … … 258 203 void MediaStreamTrack::trackMutedChanged() 259 204 { 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)); 267 207 268 208 configureTrackRendering(); 269 209 } 270 210 271 void MediaStreamTrack::trackEnabledChanged()272 {273 if (stopped())274 return;275 276 setEnabled(m_privateTrack->enabled());277 configureTrackRendering();278 }279 280 211 void MediaStreamTrack::configureTrackRendering() 281 212 { 282 if (stopped())283 return;284 285 213 // 4.3.1 286 214 // ... media from the source only flows when a MediaStreamTrack object is both unmuted and enabled 287 215 } 288 216 289 void MediaStreamTrack::trackDidEnd()290 {291 m_privateTrack->setReadyState(RealtimeMediaSource::Ended);292 293 for (auto& observer : m_observers)294 observer->trackDidEnd();295 }296 297 217 void MediaStreamTrack::stop() 298 218 { 299 m_privateTrack->stop(MediaStreamTrackPrivate::StopTrackOnly);219 stopProducingData(); 300 220 } 301 221 … … 311 231 } 312 232 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 340 233 } // namespace WebCore 341 234 -
trunk/Source/WebCore/Modules/mediastream/MediaStreamTrack.h
r184940 r186081 1 1 /* 2 2 * 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. 4 4 * Copyright (C) 2013 Apple Inc. All rights reserved. 5 5 * Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies). … … 46 46 class MediaConstraintsImpl; 47 47 class MediaSourceStates; 48 class MediaStreamTrackSourcesCallback;49 48 class MediaStreamCapabilities; 50 49 class MediaTrackConstraints; … … 59 58 60 59 static Ref<MediaStreamTrack> create(ScriptExecutionContext&, MediaStreamTrackPrivate&); 61 static Ref<MediaStreamTrack> create(MediaStreamTrack&);62 60 virtual ~MediaStreamTrack(); 63 61 … … 72 70 bool readonly() const; 73 71 bool remote() const; 74 bool stopped() const;75 72 76 73 const AtomicString& readyState() const; 77 74 78 static void getSources(ScriptExecutionContext*, PassRefPtr<MediaStreamTrackSourcesCallback>, ExceptionCode&); 75 bool ended() const; 76 77 RefPtr<MediaStreamTrack> clone(); 78 void stopProducingData(); 79 79 80 80 RefPtr<MediaTrackConstraints> getConstraints() const; … … 82 82 RefPtr<MediaStreamCapabilities> getCapabilities() const; 83 83 void applyConstraints(const Dictionary&); 84 void applyConstraints( PassRefPtr<MediaConstraints>);84 void applyConstraints(const MediaConstraints&); 85 85 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(); } 93 88 94 89 void addObserver(Observer*); … … 106 101 explicit MediaStreamTrack(MediaStreamTrack&); 107 102 108 void setSource(PassRefPtr<RealtimeMediaSource>);109 110 103 void configureTrackRendering(); 111 void trackDidEnd();112 void scheduleEventDispatch(PassRefPtr<Event>);113 104 114 105 // ActiveDOMObject API. … … 122 113 123 114 // MediaStreamTrackPrivateClient 124 void trackReadyStateChanged() override; 125 void trackMutedChanged() override; 126 void trackEnabledChanged() override; 115 void trackEnded(); 116 void trackMutedChanged(); 127 117 128 Vector<RefPtr<Event>> m_scheduledEvents; 118 Vector<Observer*> m_observers; 119 Ref<MediaStreamTrackPrivate> m_private; 129 120 130 121 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;139 122 }; 140 123 -
trunk/Source/WebCore/Modules/mediastream/MediaStreamTrack.idl
r181507 r186081 42 42 readonly attribute boolean remote; 43 43 readonly attribute MediaStreamTrackState readyState; 44 attribute EventHandler onstarted;45 44 attribute EventHandler onended; 46 45 47 [CallWith=ScriptExecutionContext, RaisesException] static void getSources(MediaStreamTrackSourcesCallback callback); 46 MediaStreamTrack clone(); 47 [ImplementedAs=stopProducingData] void stop(); 48 48 49 49 MediaTrackConstraints getConstraints(); 50 51 50 MediaSourceStates states(); 52 53 51 MediaStreamCapabilities getCapabilities(); // returns either AllVideoCapabilities or AllAudioCapabilities 54 55 52 void applyConstraints(Dictionary constraints); 56 53 57 54 attribute EventHandler onoverconstrained; 58 MediaStreamTrack clone();59 [ImplementedAs=stopProducingData] void stop();60 55 61 56 // EventTarget interface -
trunk/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp
r185316 r186081 652 652 // FIXME: this class shouldn't know that the private stream client is a MediaStream! 653 653 RefPtr<MediaStream> stream = static_cast<MediaStream*>(privateStream->client()); 654 stream->setActive(false);655 654 656 655 if (m_signalingState == SignalingStateClosed) -
trunk/Source/WebCore/Modules/mediastream/UserMediaRequest.cpp
r185903 r186081 159 159 RefPtr<MediaStream> stream = MediaStream::create(*m_scriptExecutionContext, privateStream); 160 160 for (auto& track : stream->getAudioTracks()) 161 track->applyConstraints( m_audioConstraints);161 track->applyConstraints(*m_audioConstraints); 162 162 for (auto& track : stream->getVideoTracks()) 163 track->applyConstraints( m_videoConstraints);163 track->applyConstraints(*m_videoConstraints); 164 164 165 165 m_promise.resolve(stream); -
trunk/Source/WebCore/platform/mediastream/MediaStreamPrivate.cpp
r181371 r186081 1 1 /* 2 * Copyright (C) 2011 Ericsson AB. All rights reserved.2 * Copyright (C) 2011, 2015 Ericsson AB. All rights reserved. 3 3 * Copyright (C) 2013 Google Inc. All rights reserved. 4 4 * Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies). … … 43 43 namespace WebCore { 44 44 45 PassRefPtr<MediaStreamPrivate> MediaStreamPrivate::create(const Vector<RefPtr<RealtimeMediaSource>>& audioSources, const Vector<RefPtr<RealtimeMediaSource>>& videoSources)45 RefPtr<MediaStreamPrivate> MediaStreamPrivate::create(const Vector<RefPtr<RealtimeMediaSource>>& audioSources, const Vector<RefPtr<RealtimeMediaSource>>& videoSources) 46 46 { 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); 48 57 } 49 58 50 PassRefPtr<MediaStreamPrivate> MediaStreamPrivate::create(const Vector<RefPtr<MediaStreamTrackPrivate>>& audioPrivateTracks, const Vector<RefPtr<MediaStreamTrackPrivate>>& videoPrivateTracks)59 RefPtr<MediaStreamPrivate> MediaStreamPrivate::create(const Vector<RefPtr<MediaStreamTrackPrivate>>& tracks) 51 60 { 52 return adoptRef(new MediaStreamPrivate(createCanonicalUUIDString(), audioPrivateTracks, videoPrivateTracks));61 return adoptRef(new MediaStreamPrivate(createCanonicalUUIDString(), tracks)); 53 62 } 54 63 55 void MediaStreamPrivate::addSource(PassRefPtr<RealtimeMediaSource> prpSource)64 RefPtr<MediaStreamPrivate> MediaStreamPrivate::create() 56 65 { 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>>()); 71 67 } 72 68 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) 69 MediaStreamPrivate::MediaStreamPrivate(const String& id, const Vector<RefPtr<MediaStreamTrackPrivate>>& tracks) 128 70 : m_client(0) 129 71 , m_id(id) … … 131 73 { 132 74 ASSERT(m_id.length()); 133 for (size_t i = 0; i < audioSources.size(); i++)134 addTrack(MediaStreamTrackPrivate::create(audioSources[i]));135 75 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); 138 78 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); 144 80 } 145 81 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) 82 Vector<RefPtr<MediaStreamTrackPrivate>> MediaStreamPrivate::tracks() const 150 83 { 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); 154 87 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; 163 89 } 164 90 165 void MediaStreamPrivate:: setActive(bool active)91 void MediaStreamPrivate::updateActiveState(NotifyClientOption notifyClientOption) 166 92 { 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 110 void MediaStreamPrivate::addTrack(RefPtr<MediaStreamTrackPrivate>&& track, NotifyClientOption notifyClientOption) 111 { 112 if (m_trackSet.contains(track->id())) 168 113 return; 169 114 170 m_ isActive = active;115 m_trackSet.add(track->id(), track); 171 116 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); 174 121 } 175 122 176 void MediaStreamPrivate:: addTrack(PassRefPtr<MediaStreamTrackPrivate> prpTrack)123 void MediaStreamPrivate::removeTrack(MediaStreamTrackPrivate& track, NotifyClientOption notifyClientOption) 177 124 { 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())) 183 126 return; 184 127 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); 189 130 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); 199 132 } 200 133 -
trunk/Source/WebCore/platform/mediastream/MediaStreamPrivate.h
r181152 r186081 1 1 /* 2 * Copyright (C) 2011 Ericsson AB. All rights reserved.2 * Copyright (C) 2011, 2015 Ericsson AB. All rights reserved. 3 3 * Copyright (C) 2012 Google Inc. All rights reserved. 4 4 * Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies). … … 38 38 #include "MediaStreamTrack.h" 39 39 #include "MediaStreamTrackPrivate.h" 40 #include "RealtimeMediaSource.h"40 #include <wtf/HashMap.h> 41 41 #include <wtf/RefCounted.h> 42 42 #include <wtf/Vector.h> … … 46 46 class MediaStreamTrackPrivate; 47 47 48 class MediaStreamPrivateClient : public MediaStreamTrack::Observer{48 class MediaStreamPrivateClient { 49 49 public: 50 50 virtual ~MediaStreamPrivateClient() { } 51 51 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; 57 55 }; 58 56 59 57 class MediaStreamPrivate : public RefCounted<MediaStreamPrivate> { 60 58 public: 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(); 63 62 64 63 virtual ~MediaStreamPrivate() { } 64 65 enum class NotifyClientOption { Notify, DontNotify }; 65 66 66 67 MediaStreamPrivateClient* client() const { return m_client; } … … 69 70 String id() const { return m_id; } 70 71 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; 88 73 89 74 bool active() const { return m_isActive; } 90 void setActive(bool);75 void updateActiveState(NotifyClientOption); 91 76 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); 97 79 98 80 private: 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>>&); 101 82 102 83 MediaStreamPrivateClient* m_client; 103 84 String m_id; 104 Vector<RefPtr<RealtimeMediaSource>> m_audioStreamSources; 105 Vector<RefPtr<RealtimeMediaSource>> m_videoStreamSources; 85 bool m_isActive; 106 86 107 Vector<RefPtr<MediaStreamTrackPrivate>> m_audioPrivateTracks; 108 Vector<RefPtr<MediaStreamTrackPrivate>> m_videoPrivateTracks; 109 bool m_isActive; 87 HashMap<String, RefPtr<MediaStreamTrackPrivate>> m_trackSet; 110 88 }; 111 89 -
trunk/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp
r181152 r186081 1 1 /* 2 2 * Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies). 3 * Copyright (C) 2015 Ericsson AB. All rights reserved. 3 4 * 4 5 * Redistribution and use in source and binary forms, with or without … … 37 38 namespace WebCore { 38 39 39 PassRefPtr<MediaStreamTrackPrivate> MediaStreamTrackPrivate::create(PassRefPtr<RealtimeMediaSource>source)40 RefPtr<MediaStreamTrackPrivate> MediaStreamTrackPrivate::create(RefPtr<RealtimeMediaSource>&& source) 40 41 { 41 return adoptRef(new MediaStreamTrackPrivate(source)); 42 return adoptRef(new MediaStreamTrackPrivate(WTF::move(source), createCanonicalUUIDString())); 43 } 44 45 RefPtr<MediaStreamTrackPrivate> MediaStreamTrackPrivate::create(RefPtr<RealtimeMediaSource>&& source, const String& id) 46 { 47 return adoptRef(new MediaStreamTrackPrivate(WTF::move(source), id)); 42 48 } 43 49 44 50 MediaStreamTrackPrivate::MediaStreamTrackPrivate(const MediaStreamTrackPrivate& other) 45 51 : RefCounted() 52 , m_source(other.source()) 46 53 , m_client(nullptr) 54 , m_id(createCanonicalUUIDString()) 55 , m_isEnabled(other.enabled()) 56 , m_isEnded(other.ended()) 47 57 { 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); 56 59 } 57 60 58 MediaStreamTrackPrivate::MediaStreamTrackPrivate(PassRefPtr<RealtimeMediaSource> source) 59 : m_source(nullptr) 61 MediaStreamTrackPrivate::MediaStreamTrackPrivate(RefPtr<RealtimeMediaSource>&& source, const String& id) 62 : RefCounted() 63 , m_source(source) 60 64 , 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) 65 68 { 66 m_ignoreMutations = true; 67 setSource(source); 68 m_ignoreMutations = false; 69 m_source->addObserver(this); 69 70 } 70 71 71 72 MediaStreamTrackPrivate::~MediaStreamTrackPrivate() 72 73 { 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); 107 75 } 108 76 109 77 const String& MediaStreamTrackPrivate::label() const 110 78 { 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(); 120 80 } 121 81 122 82 bool MediaStreamTrackPrivate::muted() const 123 83 { 124 if (m_stopped || !m_source)125 return false;126 127 84 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();141 85 } 142 86 143 87 bool MediaStreamTrackPrivate::readonly() const 144 88 { 145 if (m_stopped || !m_source)146 return true;147 148 89 return m_source->readonly(); 149 90 } … … 151 92 bool MediaStreamTrackPrivate::remote() const 152 93 { 153 if (!m_source)154 return false;155 156 94 return m_source->remote(); 157 95 } … … 159 97 void MediaStreamTrackPrivate::setEnabled(bool enabled) 160 98 { 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 103 void MediaStreamTrackPrivate::endTrack() 104 { 105 if (ended()) 162 106 return; 163 107 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); 211 110 } 212 111 … … 216 115 } 217 116 218 117 RealtimeMediaSource::Type MediaStreamTrackPrivate::type() const 118 { 119 return m_source->type(); 120 } 121 219 122 RefPtr<MediaConstraints> MediaStreamTrackPrivate::constraints() const 220 123 { … … 224 127 const RealtimeMediaSourceStates& MediaStreamTrackPrivate::states() const 225 128 { 226 if (!m_source) {227 DEPRECATED_DEFINE_STATIC_LOCAL(const RealtimeMediaSourceStates, noState, ());228 return noState;229 }230 231 129 return m_source->states(); 232 }233 234 RealtimeMediaSource::Type MediaStreamTrackPrivate::type() const235 {236 if (!m_source)237 return RealtimeMediaSource::None;238 239 return m_source->type();240 130 } 241 131 242 132 RefPtr<RealtimeMediaSourceCapabilities> MediaStreamTrackPrivate::capabilities() const 243 133 { 244 if (!m_source)245 return 0;246 247 134 return m_source->capabilities(); 248 135 } 249 136 250 void MediaStreamTrackPrivate::applyConstraints( PassRefPtr<MediaConstraints>)137 void MediaStreamTrackPrivate::applyConstraints(const MediaConstraints&) 251 138 { 252 139 // FIXME: apply the new constraints to the track … … 254 141 } 255 142 256 void MediaStreamTrackPrivate::source ReadyStateChanged()143 void MediaStreamTrackPrivate::sourceStopped() 257 144 { 258 if ( stopped())145 if (ended()) 259 146 return; 260 261 setReadyState(m_source->readyState()); 147 148 m_isEnded = true; 149 150 if (m_client) 151 m_client->trackEnded(); 262 152 } 263 153 264 154 void MediaStreamTrackPrivate::sourceMutedChanged() 265 155 { 266 if (stopped()) 267 return; 268 269 setMuted(m_source->muted()); 156 if (m_client) 157 m_client->trackMutedChanged(); 270 158 } 271 159 272 void MediaStreamTrackPrivate::sourceEnabledChanged()160 bool MediaStreamTrackPrivate::preventSourceFromStopping() 273 161 { 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; 283 163 } 284 164 -
trunk/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h
r181152 r186081 1 1 /* 2 2 * Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies). 3 * Copyright (C) 2015 Ericsson AB. All rights reserved. 3 4 * 4 5 * Redistribution and use in source and binary forms, with or without … … 30 31 31 32 #include "RealtimeMediaSource.h" 32 #include <wtf/PassRefPtr.h>33 33 #include <wtf/RefCounted.h> 34 34 #include <wtf/text/AtomicString.h> … … 43 43 virtual ~MediaStreamTrackPrivateClient() { } 44 44 45 virtual void track ReadyStateChanged() = 0;45 virtual void trackEnded() = 0; 46 46 virtual void trackMutedChanged() = 0; 47 virtual void trackEnabledChanged() = 0;48 47 }; 49 48 50 49 class MediaStreamTrackPrivate : public RefCounted<MediaStreamTrackPrivate>, public RealtimeMediaSource::Observer { 51 50 public: 52 static PassRefPtr<MediaStreamTrackPrivate> create(PassRefPtr<RealtimeMediaSource>); 51 static RefPtr<MediaStreamTrackPrivate> create(RefPtr<RealtimeMediaSource>&&); 52 static RefPtr<MediaStreamTrackPrivate> create(RefPtr<RealtimeMediaSource>&&, const String& id); 53 53 54 54 virtual ~MediaStreamTrackPrivate(); 55 55 56 const String& id() const ;56 const String& id() const { return m_id; } 57 57 const String& label() const; 58 58 59 bool ended() const ;59 bool ended() const { return m_isEnded; } 60 60 61 61 bool muted() const; 62 void setMuted(bool);63 62 64 63 bool readonly() const; 65 64 bool remote() const; 66 65 67 bool enabled() const { return m_ enabled; }66 bool enabled() const { return m_isEnabled; } 68 67 void setEnabled(bool); 69 70 void setReadyState(RealtimeMediaSource::ReadyState);71 RealtimeMediaSource::ReadyState readyState() const;72 68 73 69 RefPtr<MediaStreamTrackPrivate> clone(); 74 70 75 71 RealtimeMediaSource* source() const { return m_source.get(); } 76 void setSource(PassRefPtr<RealtimeMediaSource>);72 RealtimeMediaSource::Type type() const; 77 73 78 enum StopBehavior { StopTrackAndStopSource, StopTrackOnly }; 79 void stop(StopBehavior); 80 bool stopped() const { return m_stopped; } 81 74 void endTrack(); 75 82 76 void setClient(MediaStreamTrackPrivateClient* client) { m_client = client; } 83 84 RealtimeMediaSource::Type type() const;85 77 86 78 const RealtimeMediaSourceStates& states() const; … … 88 80 89 81 RefPtr<MediaConstraints> constraints() const; 90 void applyConstraints( PassRefPtr<MediaConstraints>);82 void applyConstraints(const MediaConstraints&); 91 83 92 84 void configureTrackRendering(); 93 85 94 pr otected:86 private: 95 87 explicit MediaStreamTrackPrivate(const MediaStreamTrackPrivate&); 96 MediaStreamTrackPrivate( PassRefPtr<RealtimeMediaSource>);88 MediaStreamTrackPrivate(RefPtr<RealtimeMediaSource>&&, const String& id); 97 89 98 private:99 90 MediaStreamTrackPrivateClient* client() const { return m_client; } 100 91 101 92 // RealtimeMediaSourceObserver 102 virtual void source ReadyStateChanged() override final;93 virtual void sourceStopped() override final; 103 94 virtual void sourceMutedChanged() override final; 104 virtual void sourceEnabledChanged() override final; 105 virtual bool observerIsEnabled() override final; 95 virtual bool preventSourceFromStopping() override final; 106 96 107 97 RefPtr<RealtimeMediaSource> m_source; 108 98 MediaStreamTrackPrivateClient* m_client; 109 99 RefPtr<MediaConstraints> m_constraints; 110 RealtimeMediaSource::ReadyState m_readyState;111 mutable String m_id;112 100 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; 117 104 }; 118 105 -
trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp
r181371 r186081 3 3 * Copyright (C) 2013 Apple Inc. All rights reserved. 4 4 * Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies). 5 * Copyright (C) 2015 Ericsson AB. All rights reserved. 5 6 * 6 7 * Redistribution and use in source and binary forms, with or without … … 45 46 , m_type(type) 46 47 , m_name(name) 47 , m_readyState(New) 48 , m_enabled(true) 48 , m_stopped(false) 49 49 , m_muted(false) 50 50 , m_readonly(false) … … 55 55 56 56 m_id = createCanonicalUUIDString(); 57 58 startProducingData(); 57 59 } 58 60 59 61 void RealtimeMediaSource::reset() 60 62 { 61 m_readyState = New; 62 m_enabled = true; 63 m_stopped = false; 63 64 m_muted = false; 64 65 m_readonly = false; 65 66 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();85 67 } 86 68 … … 107 89 m_muted = muted; 108 90 109 if ( m_readyState == Ended)91 if (stopped()) 110 92 return; 111 93 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(); 141 96 } 142 97 … … 146 101 } 147 102 148 void RealtimeMediaSource::stop( )103 void RealtimeMediaSource::stop(Observer* callingObserver) 149 104 { 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 118 void 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); 154 128 } 155 129 -
trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.h
r181152 r186081 57 57 58 58 // Source state changes. 59 virtual void source ReadyStateChanged() = 0;59 virtual void sourceStopped() = 0; 60 60 virtual void sourceMutedChanged() = 0; 61 virtual void sourceEnabledChanged() = 0;62 61 63 62 // Observer state queries. 64 virtual bool observerIsEnabled() = 0;63 virtual bool preventSourceFromStopping() = 0; 65 64 }; 66 65 … … 68 67 69 68 bool isAudioStreamSource() const { return type() == Audio; } 70 virtual bool useIDForTrackID() const { return false; }71 69 72 70 const String& id() const { return m_id; } … … 81 79 virtual const RealtimeMediaSourceStates& states() = 0; 82 80 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; } 89 82 90 83 virtual bool muted() const { return m_muted; } … … 103 96 virtual void stopProducingData() { } 104 97 105 void stop(); 98 void stop(Observer* callingObserver = nullptr); 99 void requestStop(Observer* callingObserver = nullptr); 106 100 107 101 void reset(); … … 114 108 Type m_type; 115 109 String m_name; 116 ReadyState m_readyState;110 bool m_stopped; 117 111 Vector<Observer*> m_observers; 118 112 119 bool m_enabled;120 113 bool m_muted; 121 114 bool m_readonly; -
trunk/Source/WebCore/platform/mediastream/openwebrtc/RealtimeMediaSourceCenterOwr.cpp
r185502 r186081 116 116 if (audioSource) { 117 117 audioSource->reset(); 118 audioSource->setReadyState(RealtimeMediaSource::Live);119 118 audioSources.append(audioSource.release()); 120 119 } … … 127 126 if (videoSource) { 128 127 videoSource->reset(); 129 videoSource->setReadyState(RealtimeMediaSource::Live);130 128 videoSources.append(videoSource.release()); 131 129 } -
trunk/Source/WebCore/platform/mock/MockRealtimeMediaSourceCenter.cpp
r181371 r186081 175 175 RefPtr<RealtimeMediaSource> audioSource = it->value; 176 176 audioSource->reset(); 177 audioSource->setReadyState(RealtimeMediaSource::Live);178 177 audioSources.append(audioSource.release()); 179 178 } … … 191 190 RefPtr<RealtimeMediaSource> videoSource = it->value; 192 191 videoSource->reset(); 193 videoSource->setReadyState(RealtimeMediaSource::Live);194 192 videoSources.append(videoSource.release()); 195 193 }
Note: See TracChangeset
for help on using the changeset viewer.