Commit fd01ce17 authored by tommyw@google.com's avatar tommyw@google.com

MediaStream API: Update the track accessors on MediaStream to match the latest specification

https://bugs.webkit.org/show_bug.cgi?id=106660

Reviewed by Adam Barth.

Source/WebCore:

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

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

Existing tests updated and expanded to cover patch.

* CMakeLists.txt:
* GNUmakefile.list.am:
* Modules/mediastream/MediaStream.cpp:
(WebCore::MediaStream::create):
(WebCore::MediaStream::MediaStream):
(WebCore::MediaStream::~MediaStream):
(WebCore::MediaStream::readyState):
(WebCore):
(WebCore::MediaStream::addTrack):
(WebCore::MediaStream::removeTrack):
(WebCore::MediaStream::getTrackById):
(WebCore::MediaStream::streamEnded):
(WebCore::MediaStream::contextDestroyed):
(WebCore::MediaStream::scheduleDispatchEvent):
(WebCore::MediaStream::scheduledEventTimerFired):
* Modules/mediastream/MediaStream.h:
(MediaStream):
(WebCore::MediaStream::getAudioTracks):
(WebCore::MediaStream::getVideoTracks):
* Modules/mediastream/MediaStream.idl:
* Modules/mediastream/MediaStreamTrackList.cpp: Removed.
* Modules/mediastream/MediaStreamTrackList.h: Removed.
* Modules/mediastream/MediaStreamTrackList.idl: Removed.
* Modules/webaudio/AudioContext.cpp:
(WebCore::AudioContext::createMediaStreamSource):
* WebCore.gypi:
* dom/EventTargetFactory.in:
* platform/mediastream/MediaStreamDescriptor.h:
(WebCore::MediaStreamDescriptor::addAudioComponent):
(WebCore::MediaStreamDescriptor::removeAudioComponent):
(WebCore::MediaStreamDescriptor::addVideoComponent):
(WebCore::MediaStreamDescriptor::removeVideoComponent):

LayoutTests:

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

* fast/mediastream/MediaStreamConstructor-expected.txt:
* fast/mediastream/MediaStreamConstructor.html:
* fast/mediastream/MediaStreamTrack.html:
* fast/mediastream/MediaStreamTrackList-expected.txt:
* fast/mediastream/MediaStreamTrackList.html:
* fast/mediastream/RTCPeerConnection-statsSelector-expected.txt:
* fast/mediastream/RTCPeerConnection-statsSelector.html:
* fast/mediastream/getusermedia-expected.txt:
* fast/mediastream/getusermedia.html:
* webaudio/mediastreamaudiosourcenode-expected.txt:
* webaudio/mediastreamaudiosourcenode.html:


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@139611 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 3f070ca6
2013-01-14 Tommy Widenflycht <tommyw@google.com>
MediaStream API: Update the track accessors on MediaStream to match the latest specification
https://bugs.webkit.org/show_bug.cgi?id=106660
Reviewed by Adam Barth.
Updating and expanding tests for the new getAudioTracks()/getVideoTracks().
* fast/mediastream/MediaStreamConstructor-expected.txt:
* fast/mediastream/MediaStreamConstructor.html:
* fast/mediastream/MediaStreamTrack.html:
* fast/mediastream/MediaStreamTrackList-expected.txt:
* fast/mediastream/MediaStreamTrackList.html:
* fast/mediastream/RTCPeerConnection-statsSelector-expected.txt:
* fast/mediastream/RTCPeerConnection-statsSelector.html:
* fast/mediastream/getusermedia-expected.txt:
* fast/mediastream/getusermedia.html:
* webaudio/mediastreamaudiosourcenode-expected.txt:
* webaudio/mediastreamaudiosourcenode.html:
2013-01-14 Alexander Pavlov <apavlov@chromium.org>
Web Inspector: [Styles] Color names parsed inside "background-image" values
......@@ -4,12 +4,12 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE
PASS Got local stream.
PASS localStream.audioTracks.length is 1
PASS localStream.videoTracks.length is 1
PASS localStream.getAudioTracks().length is 1
PASS localStream.getVideoTracks().length is 1
PASS typeof webkitMediaStream === 'function' is true
PASS new webkitMediaStream(document) threw exception TypeError: Type error.
PASS new webkitMediaStream([document]) threw exception TypeError: Invalid Array element type.
PASS new webkitMediaStream([stream.audioTracks[0], document]) threw exception TypeError: Invalid Array element type.
PASS new webkitMediaStream([stream.getAudioTracks()[0], document]) threw exception TypeError: Invalid Array element type.
PASS new webkitMediaStream([null]) threw exception TypeError: Invalid Array element type.
PASS new webkitMediaStream([undefined]) threw exception TypeError: Invalid Array element type.
PASS new webkitMediaStream(null) threw exception TypeError: Type error.
......@@ -18,44 +18,44 @@ PASS Stream constructed
PASS [object MediaStream] is non-null.
PASS [object MediaStream] is defined.
PASS newStream.constructor.name is 'MediaStream'
PASS newStream.audioTracks.length is nAudio
PASS newStream.videoTracks.length is nVideo
PASS newStream.getAudioTracks().length is nAudio
PASS newStream.getVideoTracks().length is nVideo
PASS Stream constructed
PASS [object MediaStream] is non-null.
PASS [object MediaStream] is defined.
PASS newStream.constructor.name is 'MediaStream'
PASS newStream.audioTracks.length is nAudio
PASS newStream.videoTracks.length is nVideo
PASS newStream.getAudioTracks().length is nAudio
PASS newStream.getVideoTracks().length is nVideo
PASS Stream constructed
PASS [object MediaStream] is non-null.
PASS [object MediaStream] is defined.
PASS newStream.constructor.name is 'MediaStream'
PASS newStream.audioTracks.length is nAudio
PASS newStream.videoTracks.length is nVideo
PASS newStream.getAudioTracks().length is nAudio
PASS newStream.getVideoTracks().length is nVideo
PASS Stream constructed
PASS [object MediaStream] is non-null.
PASS [object MediaStream] is defined.
PASS newStream.constructor.name is 'MediaStream'
PASS newStream.audioTracks.length is nAudio
PASS newStream.videoTracks.length is nVideo
PASS newStream.getAudioTracks().length is nAudio
PASS newStream.getVideoTracks().length is nVideo
PASS Stream constructed
PASS [object MediaStream] is non-null.
PASS [object MediaStream] is defined.
PASS newStream.constructor.name is 'MediaStream'
PASS newStream.audioTracks.length is nAudio
PASS newStream.videoTracks.length is nVideo
PASS newStream.getAudioTracks().length is nAudio
PASS newStream.getVideoTracks().length is nVideo
PASS Stream constructed
PASS [object MediaStream] is non-null.
PASS [object MediaStream] is defined.
PASS newStream.constructor.name is 'MediaStream'
PASS newStream.audioTracks.length is nAudio
PASS newStream.videoTracks.length is nVideo
PASS newStream.getAudioTracks().length is nAudio
PASS newStream.getVideoTracks().length is nVideo
PASS Stream constructed
PASS [object MediaStream] is non-null.
PASS [object MediaStream] is defined.
PASS newStream.constructor.name is 'MediaStream'
PASS newStream.audioTracks.length is nAudio
PASS newStream.videoTracks.length is nVideo
PASS newStream.getAudioTracks().length is nAudio
PASS newStream.getVideoTracks().length is nVideo
PASS successfullyParsed is true
TEST COMPLETE
......
......@@ -33,8 +33,8 @@ function getUserMedia(dictionary, callback) {
function gotStream(s) {
localStream = s;
testPassed('Got local stream.');
shouldBe('localStream.audioTracks.length', '1');
shouldBe('localStream.videoTracks.length', '1');
shouldBe('localStream.getAudioTracks().length', '1');
shouldBe('localStream.getVideoTracks().length', '1');
shouldBeTrue("typeof webkitMediaStream === 'function'");
......@@ -47,7 +47,7 @@ function testConstructor(s) {
stream = s;
shouldThrow('new webkitMediaStream(document)');
shouldThrow('new webkitMediaStream([document])');
shouldThrow('new webkitMediaStream([stream.audioTracks[0], document])');
shouldThrow('new webkitMediaStream([stream.getAudioTracks()[0], document])');
shouldThrow('new webkitMediaStream([null])');
shouldThrow('new webkitMediaStream([undefined])');
shouldThrow('new webkitMediaStream(null)');
......@@ -56,12 +56,12 @@ function testConstructor(s) {
verifyStream(new webkitMediaStream(), 0, 0);
verifyStream(new webkitMediaStream([]), 0, 0);
verifyStream(new webkitMediaStream(s), s.audioTracks.length, s.videoTracks.length);
verifyStream(new webkitMediaStream(s), s.getAudioTracks().length, s.getVideoTracks().length);
verifyStream(new webkitMediaStream([s.audioTracks[0]]), 1, 0);
verifyStream(new webkitMediaStream([s.videoTracks[0]]), 0, 1);
verifyStream(new webkitMediaStream([s.audioTracks[0], s.videoTracks[0]]), 1, 1);
verifyStream(new webkitMediaStream([s.videoTracks[0], s.audioTracks[0], s.videoTracks[0]]), 1, 1);
verifyStream(new webkitMediaStream([s.getAudioTracks()[0]]), 1, 0);
verifyStream(new webkitMediaStream([s.getVideoTracks()[0]]), 0, 1);
verifyStream(new webkitMediaStream([s.getAudioTracks()[0], s.getVideoTracks()[0]]), 1, 1);
verifyStream(new webkitMediaStream([s.getVideoTracks()[0], s.getAudioTracks()[0], s.getVideoTracks()[0]]), 1, 1);
}
function verifyStream(s, numAudioTracks, numVideoTracks) {
......@@ -73,8 +73,8 @@ function verifyStream(s, numAudioTracks, numVideoTracks) {
shouldBeNonNull(newStream);
shouldBeDefined(newStream);
shouldBe("newStream.constructor.name", "'MediaStream'");
shouldBe('newStream.audioTracks.length', 'nAudio');
shouldBe('newStream.videoTracks.length', 'nVideo');
shouldBe('newStream.getAudioTracks().length', 'nAudio');
shouldBe('newStream.getVideoTracks().length', 'nVideo');
}
getUserMedia({video:true, audio:true}, gotStream);
......
......@@ -53,7 +53,7 @@ function gotStream(s) {
testPassed('getUserMedia succeeded.');
stream = s;
track = stream.videoTracks[0];
track = stream.getVideoTracks()[0];
track.onunmute = onTrackUnmute;
track.onmute = onTrackMute;
......
......@@ -3,10 +3,12 @@ Tests MediaStreamTrackList callbacks.
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
PASS stream1.getTrackById(track.id).id is track.id
PASS stream2.getTrackById(track.id) is null
PASS Add track callback succeeded.
PASS Remove track callback succeeded.
PASS stream1.videoTracks.add(stream2.videoTracks[0]) threw exception Error: InvalidStateError: DOM Exception 11.
PASS stream1.videoTracks.remove(stream2.videoTracks[0]) threw exception Error: InvalidStateError: DOM Exception 11.
PASS stream1.addTrack(stream2.getVideoTracks()[0]) threw exception Error: InvalidStateError: DOM Exception 11.
PASS stream1.removeTrack(stream2.getVideoTracks()[0]) threw exception Error: InvalidStateError: DOM Exception 11.
PASS successfullyParsed is true
TEST COMPLETE
......
......@@ -32,18 +32,19 @@ function onRemoveTrack(e) {
// Now test that add failes when the parent stream has been stopped.
stream1.stop();
shouldThrow('stream1.videoTracks.add(stream2.videoTracks[0])');
shouldThrow('stream1.videoTracks.remove(stream2.videoTracks[0])');
shouldThrow('stream1.addTrack(stream2.getVideoTracks()[0])');
shouldThrow('stream1.removeTrack(stream2.getVideoTracks()[0])');
finishJSTest();
}
function onAddTrack(e) {
testPassed('Add track callback succeeded.');
event = e;
stream1.videoTracks.onremovetrack = onRemoveTrack;
stream1.onremovetrack = onRemoveTrack;
try {
stream1.videoTracks.remove(e.track);
stream1.removeTrack(event.track);
} catch (exception) {
testFailed("remove threw an exception.");
finishJSTest();
......@@ -52,11 +53,14 @@ function onAddTrack(e) {
function gotStream2(s) {
stream2 = s;
stream1.onaddtrack = onAddTrack;
stream1.videoTracks.onaddtrack = onAddTrack;
track = stream1.getVideoTracks()[0];
shouldBe('stream1.getTrackById(track.id).id', 'track.id');
shouldBeNull('stream2.getTrackById(track.id)');
try {
stream1.videoTracks.add(stream2.videoTracks[0]);
stream1.addTrack(stream2.getVideoTracks()[0]);
} catch (exception) {
testFailed("add threw an exception.");
finishJSTest();
......@@ -65,6 +69,7 @@ function gotStream2(s) {
function gotStream1(s) {
stream1 = s;
getUserMedia({audio:true, video:true}, gotStream2);
}
......
......@@ -6,7 +6,7 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE
PASS pc = new webkitRTCPeerConnection(null) did not throw exception.
PASS getUserMedia({audio:true, video:true}, gotStream) did not throw exception.
PASS Got a stream.
PASS pc.getStats(statsHandler2, pc.localStreams[0].videoTracks[0]) did not throw exception.
PASS pc.getStats(statsHandler2, pc.localStreams[0].getVideoTracks()[0]) did not throw exception.
PASS statsHandler2 was called
PASS result.length is >= 1
PASS timestamp is >= startTime
......
......@@ -31,7 +31,7 @@ function gotStream(s) {
stream = s;
pc.addStream(stream);
shouldNotThrow('pc.getStats(statsHandler2, pc.localStreams[0].videoTracks[0])');
shouldNotThrow('pc.getStats(statsHandler2, pc.localStreams[0].getVideoTracks()[0])');
}
function statsHandler2(status)
......
......@@ -6,26 +6,26 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE
PASS navigator.webkitGetUserMedia({audio:false, video:false}, error, error); threw exception Error: NotSupportedError: DOM Exception 9.
PASS navigator.webkitGetUserMedia({audio:true}, gotStream1, error); did not throw exception.
PASS Stream generated.
PASS stream.audioTracks.length is 1
PASS stream.videoTracks.length is 0
PASS stream.getAudioTracks().length is 1
PASS stream.getVideoTracks().length is 0
PASS navigator.webkitGetUserMedia({video:true}, gotStream2, error); did not throw exception.
PASS Stream generated.
PASS stream.audioTracks.length is 0
PASS stream.videoTracks.length is 1
PASS stream.getAudioTracks().length is 0
PASS stream.getVideoTracks().length is 1
PASS navigator.webkitGetUserMedia({audio:true, video:true}, gotStream3, error); did not throw exception.
PASS Stream generated.
PASS stream.audioTracks.length is 1
PASS stream.videoTracks.length is 1
PASS stream.getAudioTracks().length is 1
PASS stream.getVideoTracks().length is 1
PASS navigator.webkitGetUserMedia({audio:{mandatory:{}, optional:[]}, video:true}, gotStream4, error); did not throw exception.
PASS Stream generated.
PASS stream.audioTracks.length is 1
PASS stream.videoTracks.length is 1
PASS stream.getAudioTracks().length is 1
PASS stream.getVideoTracks().length is 1
PASS navigator.webkitGetUserMedia({audio:{mandatory:{'valid_but_unsupported_1':0}, optional:[]}, video:true}, gotStreamInError, error1); did not throw exception.
PASS Error callback called.
PASS navigator.webkitGetUserMedia({audio:{mandatory:{'valid_and_supported_1':1}, optional:[{'valid_but_unsupported_1':0}]}, video:true}, gotStream5, error); did not throw exception.
PASS Stream generated.
PASS stream.audioTracks.length is 1
PASS stream.videoTracks.length is 1
PASS stream.getAudioTracks().length is 1
PASS stream.getVideoTracks().length is 1
PASS successfullyParsed is true
TEST COMPLETE
......
......@@ -25,8 +25,8 @@ function gotStreamInError(s) {
function gotStream5(s) {
stream = s;
testPassed('Stream generated.');
shouldBe('stream.audioTracks.length', '1');
shouldBe('stream.videoTracks.length', '1');
shouldBe('stream.getAudioTracks().length', '1');
shouldBe('stream.getVideoTracks().length', '1');
finishJSTest();
}
......@@ -39,8 +39,8 @@ function error1() {
function gotStream4(s) {
stream = s;
testPassed('Stream generated.');
shouldBe('stream.audioTracks.length', '1');
shouldBe('stream.videoTracks.length', '1');
shouldBe('stream.getAudioTracks().length', '1');
shouldBe('stream.getVideoTracks().length', '1');
shouldNotThrow("navigator.webkitGetUserMedia({audio:{mandatory:{'valid_but_unsupported_1':0}, optional:[]}, video:true}, gotStreamInError, error1);");
}
......@@ -48,8 +48,8 @@ function gotStream4(s) {
function gotStream3(s) {
stream = s;
testPassed('Stream generated.');
shouldBe('stream.audioTracks.length', '1');
shouldBe('stream.videoTracks.length', '1');
shouldBe('stream.getAudioTracks().length', '1');
shouldBe('stream.getVideoTracks().length', '1');
shouldNotThrow("navigator.webkitGetUserMedia({audio:{mandatory:{}, optional:[]}, video:true}, gotStream4, error);");
}
......@@ -57,8 +57,8 @@ function gotStream3(s) {
function gotStream2(s) {
stream = s;
testPassed('Stream generated.');
shouldBe('stream.audioTracks.length', '0');
shouldBe('stream.videoTracks.length', '1');
shouldBe('stream.getAudioTracks().length', '0');
shouldBe('stream.getVideoTracks().length', '1');
shouldNotThrow("navigator.webkitGetUserMedia({audio:true, video:true}, gotStream3, error);");
}
......@@ -66,8 +66,8 @@ function gotStream2(s) {
function gotStream1(s) {
stream = s;
testPassed('Stream generated.');
shouldBe('stream.audioTracks.length', '1');
shouldBe('stream.videoTracks.length', '0');
shouldBe('stream.getAudioTracks().length', '1');
shouldBe('stream.getVideoTracks().length', '0');
shouldNotThrow("navigator.webkitGetUserMedia({video:true}, gotStream2, error);")
}
......
......@@ -3,8 +3,8 @@ Basic tests for MediaStreamAudioSourceNode API.
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
PASS {audio:true} generated stream
PASS s.audioTracks.length is 1
PASS s.videoTracks.length is 0
PASS s.getAudioTracks().length is 1
PASS s.getVideoTracks().length is 0
PASS Source AudioNode has no inputs.
PASS Source AudioNode has one output.
PASS connect() exception thrown for illegal destination AudioNode.
......
......@@ -32,8 +32,8 @@ function getUserMedia(dictionary, callback) {
function gotStream(stream) {
s = stream;
testPassed('{audio:true} generated stream');
shouldBe('s.audioTracks.length', '1');
shouldBe('s.videoTracks.length', '0');
shouldBe('s.getAudioTracks().length', '1');
shouldBe('s.getVideoTracks().length', '0');
context = new webkitAudioContext();
......
......@@ -220,7 +220,6 @@ set(WebCore_IDL_FILES
Modules/mediastream/MediaStreamList.idl
Modules/mediastream/MediaStreamTrack.idl
Modules/mediastream/MediaStreamTrackEvent.idl
Modules/mediastream/MediaStreamTrackList.idl
Modules/mediastream/NavigatorMediaStream.idl
Modules/mediastream/NavigatorUserMediaError.idl
Modules/mediastream/NavigatorUserMediaErrorCallback.idl
......@@ -861,7 +860,6 @@ set(WebCore_SOURCES
Modules/mediastream/MediaStreamRegistry.cpp
Modules/mediastream/MediaStreamTrack.cpp
Modules/mediastream/MediaStreamTrackEvent.cpp
Modules/mediastream/MediaStreamTrackList.cpp
Modules/mediastream/NavigatorMediaStream.cpp
Modules/mediastream/RTCDataChannel.cpp
Modules/mediastream/RTCDataChannelEvent.cpp
......
2013-01-14 Tommy Widenflycht <tommyw@google.com>
MediaStream API: Update the track accessors on MediaStream to match the latest specification
https://bugs.webkit.org/show_bug.cgi?id=106660
Reviewed by Adam Barth.
The spec has significantly changed how tracks are accessed from a MediaStream:
http://dev.w3.org/2011/webrtc/editor/getusermedia.html
In short: the attributes audioTrack/videoTrack that returned special MediaStreamTrackLists have been
replaced by the functions getAudioTracks()/getVideoTracks that return standard sequences of
MediaStreamTracks.
Existing tests updated and expanded to cover patch.
* CMakeLists.txt:
* GNUmakefile.list.am:
* Modules/mediastream/MediaStream.cpp:
(WebCore::MediaStream::create):
(WebCore::MediaStream::MediaStream):
(WebCore::MediaStream::~MediaStream):
(WebCore::MediaStream::readyState):
(WebCore):
(WebCore::MediaStream::addTrack):
(WebCore::MediaStream::removeTrack):
(WebCore::MediaStream::getTrackById):
(WebCore::MediaStream::streamEnded):
(WebCore::MediaStream::contextDestroyed):
(WebCore::MediaStream::scheduleDispatchEvent):
(WebCore::MediaStream::scheduledEventTimerFired):
* Modules/mediastream/MediaStream.h:
(MediaStream):
(WebCore::MediaStream::getAudioTracks):
(WebCore::MediaStream::getVideoTracks):
* Modules/mediastream/MediaStream.idl:
* Modules/mediastream/MediaStreamTrackList.cpp: Removed.
* Modules/mediastream/MediaStreamTrackList.h: Removed.
* Modules/mediastream/MediaStreamTrackList.idl: Removed.
* Modules/webaudio/AudioContext.cpp:
(WebCore::AudioContext::createMediaStreamSource):
* WebCore.gypi:
* dom/EventTargetFactory.in:
* platform/mediastream/MediaStreamDescriptor.h:
(WebCore::MediaStreamDescriptor::addAudioComponent):
(WebCore::MediaStreamDescriptor::removeAudioComponent):
(WebCore::MediaStreamDescriptor::addVideoComponent):
(WebCore::MediaStreamDescriptor::removeVideoComponent):
2013-01-14 Kentaro Hara <haraken@chromium.org>
[V8] Add m_isolate to ScriptController, WorkerScriptController and V8DOMWindowShell
......@@ -521,8 +521,6 @@ webcore_built_sources += \
DerivedSources/WebCore/JSMediaStreamTrack.h \
DerivedSources/WebCore/JSMediaStreamTrackEvent.cpp \
DerivedSources/WebCore/JSMediaStreamTrackEvent.h \
DerivedSources/WebCore/JSMediaStreamTrackList.cpp \
DerivedSources/WebCore/JSMediaStreamTrackList.h \
DerivedSources/WebCore/JSMediaQueryList.cpp \
DerivedSources/WebCore/JSMediaQueryList.h \
DerivedSources/WebCore/JSMemoryInfo.cpp \
......@@ -1243,7 +1241,6 @@ dom_binding_idls += \
$(WebCore)/Modules/mediastream/MediaStreamList.idl \
$(WebCore)/Modules/mediastream/MediaStreamTrack.idl \
$(WebCore)/Modules/mediastream/MediaStreamTrackEvent.idl \
$(WebCore)/Modules/mediastream/MediaStreamTrackList.idl \
$(WebCore)/Modules/mediastream/NavigatorMediaStream.idl \
$(WebCore)/Modules/mediastream/NavigatorUserMediaError.idl \
$(WebCore)/Modules/mediastream/NavigatorUserMediaErrorCallback.idl \
......@@ -1939,8 +1936,6 @@ webcore_modules_sources += \
Source/WebCore/Modules/mediastream/MediaStreamTrack.h \
Source/WebCore/Modules/mediastream/MediaStreamTrackEvent.cpp \
Source/WebCore/Modules/mediastream/MediaStreamTrackEvent.h \
Source/WebCore/Modules/mediastream/MediaStreamTrackList.cpp \
Source/WebCore/Modules/mediastream/MediaStreamTrackList.h \
Source/WebCore/Modules/mediastream/NavigatorMediaStream.cpp \
Source/WebCore/Modules/mediastream/NavigatorMediaStream.h \
Source/WebCore/Modules/mediastream/NavigatorUserMediaError.h \
......
......@@ -32,6 +32,7 @@
#include "ExceptionCode.h"
#include "MediaStreamCenter.h"
#include "MediaStreamSource.h"
#include "MediaStreamTrackEvent.h"
#include "UUID.h"
namespace WebCore {
......@@ -78,11 +79,11 @@ PassRefPtr<MediaStream> MediaStream::create(ScriptExecutionContext* context, Pas
MediaStreamSourceVector audioSources;
MediaStreamSourceVector videoSources;
for (size_t i = 0; i < stream->audioTracks()->length(); ++i)
processTrack(stream->audioTracks()->item(i), audioSources);
for (size_t i = 0; i < stream->m_audioTracks.size(); ++i)
processTrack(stream->m_audioTracks[i].get(), audioSources);
for (size_t i = 0; i < stream->videoTracks()->length(); ++i)
processTrack(stream->videoTracks()->item(i), videoSources);
for (size_t i = 0; i < stream->m_videoTracks.size(); ++i)
processTrack(stream->m_videoTracks[i].get(), videoSources);
return createFromSourceVectors(context, audioSources, videoSources);
}
......@@ -105,35 +106,118 @@ PassRefPtr<MediaStream> MediaStream::create(ScriptExecutionContext* context, Pas
MediaStream::MediaStream(ScriptExecutionContext* context, PassRefPtr<MediaStreamDescriptor> streamDescriptor)
: ContextDestructionObserver(context)
, m_stopped(false)
, m_descriptor(streamDescriptor)
, m_scheduledEventTimer(this, &MediaStream::scheduledEventTimerFired)
{
m_descriptor->setClient(this);
MediaStreamTrackVector audioTrackVector;
size_t numberOfAudioTracks = m_descriptor->numberOfAudioComponents();
audioTrackVector.reserveCapacity(numberOfAudioTracks);
m_audioTracks.reserveCapacity(numberOfAudioTracks);
for (size_t i = 0; i < numberOfAudioTracks; i++)
audioTrackVector.append(MediaStreamTrack::create(context, m_descriptor, m_descriptor->audioComponent(i)));
m_audioTracks = MediaStreamTrackList::create(this, audioTrackVector);
m_audioTracks.append(MediaStreamTrack::create(context, m_descriptor, m_descriptor->audioComponent(i)));
MediaStreamTrackVector videoTrackVector;
size_t numberOfVideoTracks = m_descriptor->numberOfVideoComponents();
videoTrackVector.reserveCapacity(numberOfVideoTracks);
m_videoTracks.reserveCapacity(numberOfVideoTracks);
for (size_t i = 0; i < numberOfVideoTracks; i++)
videoTrackVector.append(MediaStreamTrack::create(context, m_descriptor, m_descriptor->videoComponent(i)));
m_videoTracks = MediaStreamTrackList::create(this, videoTrackVector);
m_videoTracks.append(MediaStreamTrack::create(context, m_descriptor, m_descriptor->videoComponent(i)));
}
MediaStream::~MediaStream()
{
m_descriptor->setClient(0);
m_audioTracks->detachOwner();
m_videoTracks->detachOwner();
}
bool MediaStream::ended() const
{
return m_descriptor->ended();
return m_stopped || m_descriptor->ended();
}
void MediaStream::addTrack(PassRefPtr<MediaStreamTrack> prpTrack, ExceptionCode& ec)
{
if (ended()) {
ec = INVALID_STATE_ERR;
return;
}
if (!prpTrack) {
ec = TYPE_MISMATCH_ERR;
return;
}
RefPtr<MediaStreamTrack> track = prpTrack;
if (getTrackById(track->id()))
return;
RefPtr<MediaStreamComponent> component = MediaStreamComponent::create(track->component()->source());
RefPtr<MediaStreamTrack> newTrack = MediaStreamTrack::create(scriptExecutionContext(), m_descriptor, component.get());
switch (component->source()->type()) {
case MediaStreamSource::TypeAudio:
m_descriptor->addAudioComponent(component.release());
m_audioTracks.append(newTrack);
break;
case MediaStreamSource::TypeVideo:
m_descriptor->addVideoComponent(component.release());
m_videoTracks.append(newTrack);
break;
}
MediaStreamCenter::instance().didAddMediaStreamTrack(m_descriptor.get(), newTrack->component());
scheduleDispatchEvent(MediaStreamTrackEvent::create(eventNames().addtrackEvent, false, false, newTrack.release()));
}
void MediaStream::removeTrack(PassRefPtr<MediaStreamTrack> prpTrack , ExceptionCode& ec)
{
if (ended()) {
ec = INVALID_STATE_ERR;
return;
}
if (!prpTrack) {
ec = TYPE_MISMATCH_ERR;
return;
}
RefPtr<MediaStreamTrack> track = prpTrack;
switch (track->component()->source()->type()) {
case MediaStreamSource::TypeAudio: {
size_t pos = m_audioTracks.find(track);
if (pos != notFound) {
m_audioTracks.remove(pos);
m_descriptor->removeAudioComponent(track->component());
}
break;
}
case MediaStreamSource::TypeVideo: {
size_t pos = m_videoTracks.find(track);
if (pos != notFound) {
m_videoTracks.remove(pos);
m_descriptor->removeVideoComponent(track->component());
}
break;
}
}
MediaStreamCenter::instance().didRemoveMediaStreamTrack(m_descriptor.get(), track->component());
scheduleDispatchEvent(MediaStreamTrackEvent::create(eventNames().removetrackEvent, false, false, track.release()));
}
MediaStreamTrack* MediaStream::getTrackById(String id)
{
for (MediaStreamTrackVector::iterator iter = m_audioTracks.begin(); iter != m_audioTracks.end(); ++iter) {
if ((*iter)->id() == id)
return (*iter).get();
}
for (MediaStreamTrackVector::iterator iter = m_videoTracks.begin(); iter != m_videoTracks.end(); ++iter) {
if ((*iter)->id() == id)
return (*iter).get();
}
return 0;
}
void MediaStream::streamEnded()
......@@ -142,10 +226,12 @@ void MediaStream::streamEnded()
return;
m_descriptor->setEnded();
m_audioTracks->detachOwner();
m_videoTracks->detachOwner();
scheduleDispatchEvent(Event::create(eventNames().endedEvent, false, false));
}
dispatchEvent(Event::create(eventNames().endedEvent, false, false));
void MediaStream::contextDestroyed()
{