mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1032835 - addTrack/removeTrack on-top of existing implementation. r=smaug, r=jesup
This commit is contained in:
parent
39849d0595
commit
185c7d4bdd
@ -196,6 +196,18 @@ DOMMediaStream::GetVideoTracks(nsTArray<nsRefPtr<VideoStreamTrack> >& aTracks)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DOMMediaStream::GetTracks(nsTArray<nsRefPtr<MediaStreamTrack> >& aTracks)
|
||||
{
|
||||
aTracks.AppendElements(mTracks);
|
||||
}
|
||||
|
||||
bool
|
||||
DOMMediaStream::HasTrack(const MediaStreamTrack& aTrack) const
|
||||
{
|
||||
return mTracks.Contains(&aTrack);
|
||||
}
|
||||
|
||||
bool
|
||||
DOMMediaStream::IsFinished()
|
||||
{
|
||||
|
@ -81,6 +81,8 @@ public:
|
||||
|
||||
void GetAudioTracks(nsTArray<nsRefPtr<AudioStreamTrack> >& aTracks);
|
||||
void GetVideoTracks(nsTArray<nsRefPtr<VideoStreamTrack> >& aTracks);
|
||||
void GetTracks(nsTArray<nsRefPtr<MediaStreamTrack> >& aTracks);
|
||||
bool HasTrack(const MediaStreamTrack& aTrack) const;
|
||||
|
||||
MediaStream* GetStream() const { return mStream; }
|
||||
|
||||
|
@ -210,12 +210,6 @@ RTCSessionDescription.prototype = {
|
||||
};
|
||||
|
||||
function RTCStatsReport(win, dict) {
|
||||
function appendStats(stats, report) {
|
||||
stats.forEach(function(stat) {
|
||||
report[stat.id] = stat;
|
||||
});
|
||||
}
|
||||
|
||||
this._win = win;
|
||||
this._pcid = dict.pcid;
|
||||
this._report = convertToRTCStatsReport(dict);
|
||||
@ -287,6 +281,8 @@ RTCIdentityAssertion.prototype = {
|
||||
|
||||
function RTCPeerConnection() {
|
||||
this._queue = [];
|
||||
this._senders = [];
|
||||
this._receivers = [];
|
||||
|
||||
this._pc = null;
|
||||
this._observer = null;
|
||||
@ -341,6 +337,7 @@ RTCPeerConnection.prototype = {
|
||||
}
|
||||
|
||||
this.makeGetterSetterEH("onaddstream");
|
||||
this.makeGetterSetterEH("onaddtrack");
|
||||
this.makeGetterSetterEH("onicecandidate");
|
||||
this.makeGetterSetterEH("onnegotiationneeded");
|
||||
this.makeGetterSetterEH("onsignalingstatechange");
|
||||
@ -805,6 +802,26 @@ RTCPeerConnection.prototype = {
|
||||
throw new this._win.DOMError("", "getStreamById not yet implemented");
|
||||
},
|
||||
|
||||
addTrack: function(track, stream) {
|
||||
if (stream.currentTime === undefined) {
|
||||
throw new this._win.DOMError("", "invalid stream.");
|
||||
}
|
||||
if (stream.getTracks().indexOf(track) == -1) {
|
||||
throw new this._win.DOMError("", "track is not in stream.");
|
||||
}
|
||||
this._checkClosed();
|
||||
this._impl.addTrack(track, stream);
|
||||
let sender = this._win.RTCRtpSender._create(this._win,
|
||||
new RTCRtpSender(this, track));
|
||||
this._senders.push({ sender: sender, stream: stream });
|
||||
return sender;
|
||||
},
|
||||
|
||||
removeTrack: function(sender) {
|
||||
// Bug 844295: Not implementing this functionality.
|
||||
throw new this._win.DOMError("", "removeTrack not yet implemented");
|
||||
},
|
||||
|
||||
close: function() {
|
||||
if (this._closed) {
|
||||
return;
|
||||
@ -830,6 +847,36 @@ RTCPeerConnection.prototype = {
|
||||
return this._impl.getRemoteStreams();
|
||||
},
|
||||
|
||||
getSenders: function() {
|
||||
this._checkClosed();
|
||||
let streams = this._impl.getLocalStreams();
|
||||
let senders = [];
|
||||
// prune senders in case any streams have disappeared down below
|
||||
for (let i = this._senders.length - 1; i >= 0; i--) {
|
||||
if (streams.indexOf(this._senders[i].stream) != -1) {
|
||||
senders.push(this._senders[i].sender);
|
||||
} else {
|
||||
this._senders.splice(i,1);
|
||||
}
|
||||
}
|
||||
return senders;
|
||||
},
|
||||
|
||||
getReceivers: function() {
|
||||
this._checkClosed();
|
||||
let streams = this._impl.getRemoteStreams();
|
||||
let receivers = [];
|
||||
// prune receivers in case any streams have disappeared down below
|
||||
for (let i = this._receivers.length - 1; i >= 0; i--) {
|
||||
if (streams.indexOf(this._receivers[i].stream) != -1) {
|
||||
receivers.push(this._receivers[i].receiver);
|
||||
} else {
|
||||
this._receivers.splice(i,1);
|
||||
}
|
||||
}
|
||||
return receivers;
|
||||
},
|
||||
|
||||
get localDescription() {
|
||||
this._checkClosed();
|
||||
let sdp = this._impl.localDescription;
|
||||
@ -1248,6 +1295,17 @@ PeerConnectionObserver.prototype = {
|
||||
{ stream: stream }));
|
||||
},
|
||||
|
||||
onAddTrack: function(track) {
|
||||
let ev = new this._dompc._win.MediaStreamTrackEvent("addtrack",
|
||||
{ track: track });
|
||||
this._dompc.dispatchEvent(ev);
|
||||
},
|
||||
|
||||
onRemoveTrack: function(track, type) {
|
||||
this.dispatchEvent(new this._dompc._win.MediaStreamTrackEvent("removetrack",
|
||||
{ track: track }));
|
||||
},
|
||||
|
||||
foundIceCandidate: function(cand) {
|
||||
this.dispatchEvent(new this._dompc._win.RTCPeerConnectionIceEvent("icecandidate",
|
||||
{ candidate: cand } ));
|
||||
@ -1279,34 +1337,26 @@ RTCPeerConnectionStatic.prototype = {
|
||||
},
|
||||
};
|
||||
|
||||
function RTCRtpSender() {}
|
||||
function RTCRtpSender(pc, track) {
|
||||
this.pc = pc;
|
||||
this.track = track;
|
||||
}
|
||||
RTCRtpSender.prototype = {
|
||||
classDescription: "RTCRtpSender",
|
||||
classID: PC_SENDER_CID,
|
||||
contractID: PC_SENDER_CONTRACT,
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports,
|
||||
Ci.nsIDOMGlobalPropertyInitializer]),
|
||||
|
||||
init: function(win) { this._win = win; },
|
||||
|
||||
__init: function(track) {
|
||||
this.track = track;
|
||||
}
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports]),
|
||||
};
|
||||
|
||||
function RTCRtpReceiver() {}
|
||||
function RTCRtpReceiver(pc, track) {
|
||||
this.pc = pc;
|
||||
this.track = track;
|
||||
}
|
||||
RTCRtpReceiver.prototype = {
|
||||
classDescription: "RTCRtpReceiver",
|
||||
classID: PC_RECEIVER_CID,
|
||||
contractID: PC_RECEIVER_CONTRACT,
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports,
|
||||
Ci.nsIDOMGlobalPropertyInitializer]),
|
||||
|
||||
init: function(win) { this._win = win; },
|
||||
|
||||
__init: function(track) {
|
||||
this.track = track;
|
||||
}
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports]),
|
||||
};
|
||||
|
||||
this.NSGetFactory = XPCOMUtils.generateNSGetFactory(
|
||||
|
@ -1543,7 +1543,9 @@ PeerConnectionWrapper.prototype = {
|
||||
this.streams.push(stream);
|
||||
|
||||
if (side === 'local') {
|
||||
this._pc.addStream(stream);
|
||||
stream.getTracks().forEach(function(track) {
|
||||
this._pc.addTrack(track, stream);
|
||||
}.bind(this));
|
||||
}
|
||||
|
||||
var element = createMediaElement(type, this.label + '_' + side);
|
||||
|
@ -23,8 +23,9 @@ dictionary MediaStreamConstraints {
|
||||
|
||||
interface MediaStream {
|
||||
// readonly attribute DOMString id;
|
||||
sequence<AudioStreamTrack> getAudioTracks ();
|
||||
sequence<VideoStreamTrack> getVideoTracks ();
|
||||
sequence<AudioStreamTrack> getAudioTracks();
|
||||
sequence<VideoStreamTrack> getVideoTracks();
|
||||
sequence<MediaStreamTrack> getTracks();
|
||||
// MediaStreamTrack getTrackById (DOMString trackId);
|
||||
// void addTrack (MediaStreamTrack track);
|
||||
// void removeTrack (MediaStreamTrack track);
|
||||
|
@ -38,7 +38,11 @@ interface PeerConnectionImpl {
|
||||
[Throws]
|
||||
void getStats(MediaStreamTrack? selector);
|
||||
|
||||
/* Adds the stream created by GetUserMedia */
|
||||
/* Adds the tracks created by GetUserMedia */
|
||||
[Throws]
|
||||
void addTrack(MediaStreamTrack track, MediaStream... streams);
|
||||
[Throws]
|
||||
void removeTrack(MediaStreamTrack track);
|
||||
[Throws]
|
||||
void addStream(MediaStream stream);
|
||||
[Throws]
|
||||
|
@ -34,9 +34,9 @@ interface PeerConnectionObserver
|
||||
/* Notification of one of several types of state changed */
|
||||
void onStateChange(PCObserverStateType state);
|
||||
|
||||
/* Changes to MediaStreams */
|
||||
/* Changes to MediaStreamTracks */
|
||||
void onAddStream(MediaStream stream);
|
||||
void onRemoveStream();
|
||||
void onAddTrack();
|
||||
void onAddTrack(MediaStreamTrack track);
|
||||
void onRemoveTrack();
|
||||
};
|
||||
|
@ -107,10 +107,12 @@ interface mozRTCPeerConnection : EventTarget {
|
||||
void removeStream (MediaStream stream);
|
||||
|
||||
// replaces addStream; fails if already added
|
||||
// because a track can be part of multiple streams, the id parameter
|
||||
// indicates which particular stream should be referenced in signaling
|
||||
// because a track can be part of multiple streams, stream parameters
|
||||
// indicate which particular streams should be referenced in signaling
|
||||
|
||||
RTCRtpSender addTrack(MediaStreamTrack track, DOMString streamId);
|
||||
RTCRtpSender addTrack(MediaStreamTrack track,
|
||||
MediaStream stream,
|
||||
MediaStream... moreStreams);
|
||||
void removeTrack(RTCRtpSender sender);
|
||||
|
||||
sequence<RTCRtpSender> getSenders();
|
||||
|
@ -8,8 +8,7 @@
|
||||
*/
|
||||
|
||||
[Pref="media.peerconnection.enabled",
|
||||
JSImplementation="@mozilla.org/dom/rtpreceiver;1",
|
||||
Constructor (MediaStreamTrack track)]
|
||||
JSImplementation="@mozilla.org/dom/rtpreceiver;1"]
|
||||
interface RTCRtpReceiver {
|
||||
readonly attribute MediaStreamTrack track;
|
||||
};
|
||||
|
@ -8,8 +8,7 @@
|
||||
*/
|
||||
|
||||
[Pref="media.peerconnection.enabled",
|
||||
JSImplementation="@mozilla.org/dom/rtpsender;1",
|
||||
Constructor (MediaStreamTrack track)]
|
||||
JSImplementation="@mozilla.org/dom/rtpsender;1"]
|
||||
interface RTCRtpSender {
|
||||
readonly attribute MediaStreamTrack track;
|
||||
};
|
||||
|
@ -2535,6 +2535,10 @@ static int vcmTxStartICE_m(cc_mcapid_t mcap_id,
|
||||
ENSURE_PC(pc, VCM_ERROR);
|
||||
nsRefPtr<sipcc::LocalSourceStreamInfo> stream =
|
||||
pc.impl()->media()->GetLocalStream(pc_stream_id);
|
||||
if (!stream) {
|
||||
CSFLogError(logTag, "Stream not found");
|
||||
return VCM_ERROR;
|
||||
}
|
||||
|
||||
// Create the transport flows
|
||||
mozilla::RefPtr<TransportFlow> rtp_flow =
|
||||
|
@ -285,6 +285,17 @@ public:
|
||||
CSFLogInfo(logTag, "Returning success for OnAddStream()");
|
||||
// We are running on main thread here so we shouldn't have a race
|
||||
// on this callback
|
||||
|
||||
nsTArray<nsRefPtr<MediaStreamTrack>> tracks;
|
||||
aStream->GetTracks(tracks);
|
||||
for (uint32_t i = 0; i < tracks.Length(); i++) {
|
||||
JSErrorResult rv;
|
||||
mObserver->OnAddTrack(*tracks[i], rv);
|
||||
if (rv.Failed()) {
|
||||
CSFLogError(logTag, ": OnAddTrack(%d) failed! Error: %d", i,
|
||||
rv.ErrorCode());
|
||||
}
|
||||
}
|
||||
JSErrorResult rv;
|
||||
mObserver->OnAddStream(*aStream, rv);
|
||||
if (rv.Failed()) {
|
||||
@ -1465,7 +1476,7 @@ PeerConnectionImpl::AddStream(DOMMediaStream &aMediaStream)
|
||||
}
|
||||
|
||||
uint32_t stream_id;
|
||||
nsresult res = mMedia->AddStream(&aMediaStream, &stream_id);
|
||||
nsresult res = mMedia->AddStream(&aMediaStream, hints, &stream_id);
|
||||
if (NS_FAILED(res)) {
|
||||
return res;
|
||||
}
|
||||
@ -1490,15 +1501,141 @@ NS_IMETHODIMP
|
||||
PeerConnectionImpl::RemoveStream(DOMMediaStream& aMediaStream) {
|
||||
PC_AUTO_ENTER_API_CALL(true);
|
||||
|
||||
uint32_t hints = aMediaStream.GetHintContents();
|
||||
|
||||
uint32_t stream_id;
|
||||
nsresult res = mMedia->RemoveStream(&aMediaStream, &stream_id);
|
||||
nsresult res = mMedia->RemoveStream(&aMediaStream, hints, &stream_id);
|
||||
|
||||
if (NS_FAILED(res))
|
||||
return res;
|
||||
|
||||
aMediaStream.RemovePrincipalChangeObserver(this);
|
||||
|
||||
if (hints & DOMMediaStream::HINT_CONTENTS_AUDIO) {
|
||||
mInternal->mCall->removeStream(stream_id, 0, AUDIO);
|
||||
MOZ_ASSERT(mNumAudioStreams > 0);
|
||||
mNumAudioStreams--;
|
||||
}
|
||||
|
||||
if (hints & DOMMediaStream::HINT_CONTENTS_VIDEO) {
|
||||
mInternal->mCall->removeStream(stream_id, 1, VIDEO);
|
||||
MOZ_ASSERT(mNumVideoStreams > 0);
|
||||
mNumVideoStreams--;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
PeerConnectionImpl::AddTrack(MediaStreamTrack& aTrack,
|
||||
const Sequence<OwningNonNull<DOMMediaStream>>& aStreams)
|
||||
{
|
||||
PC_AUTO_ENTER_API_CALL(true);
|
||||
|
||||
if (!aStreams.Length()) {
|
||||
CSFLogError(logTag, "%s: At least one stream arg required", __FUNCTION__);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
DOMMediaStream& aMediaStream = aStreams[0];
|
||||
#ifdef MOZILLA_INTERNAL_API
|
||||
if (!aMediaStream.HasTrack(aTrack)) {
|
||||
CSFLogError(logTag, "%s: Track is not in stream", __FUNCTION__);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
uint32_t hints = aMediaStream.GetHintContents() &
|
||||
((aTrack.AsAudioStreamTrack()? DOMMediaStream::HINT_CONTENTS_AUDIO : 0) |
|
||||
(aTrack.AsVideoStreamTrack()? DOMMediaStream::HINT_CONTENTS_VIDEO : 0));
|
||||
#else
|
||||
uint32_t hints = aMediaStream.GetHintContents();
|
||||
#endif
|
||||
|
||||
// XXX Remove this check once addStream has an error callback
|
||||
// available and/or we have plumbing to handle multiple
|
||||
// local audio streams.
|
||||
if ((hints & DOMMediaStream::HINT_CONTENTS_AUDIO) &&
|
||||
mNumAudioStreams > 0) {
|
||||
CSFLogError(logTag, "%s: Only one local audio stream is supported for now",
|
||||
__FUNCTION__);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// XXX Remove this check once addStream has an error callback
|
||||
// available and/or we have plumbing to handle multiple
|
||||
// local video streams.
|
||||
if ((hints & DOMMediaStream::HINT_CONTENTS_VIDEO) &&
|
||||
mNumVideoStreams > 0) {
|
||||
CSFLogError(logTag, "%s: Only one local video stream is supported for now",
|
||||
__FUNCTION__);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
uint32_t num = mMedia->LocalStreamsLength();
|
||||
|
||||
uint32_t stream_id;
|
||||
nsresult res = mMedia->AddStream(&aMediaStream, hints, &stream_id);
|
||||
if (NS_FAILED(res)) {
|
||||
return res;
|
||||
}
|
||||
|
||||
if (num != mMedia->LocalStreamsLength()) {
|
||||
aMediaStream.AddPrincipalChangeObserver(this);
|
||||
}
|
||||
|
||||
// TODO(ekr@rtfm.com): these integers should be the track IDs
|
||||
if (hints & DOMMediaStream::HINT_CONTENTS_AUDIO) {
|
||||
mInternal->mCall->addStream(stream_id, 0, AUDIO);
|
||||
mNumAudioStreams++;
|
||||
}
|
||||
|
||||
if (hints & DOMMediaStream::HINT_CONTENTS_VIDEO) {
|
||||
mInternal->mCall->addStream(stream_id, 1, VIDEO);
|
||||
mNumVideoStreams++;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PeerConnectionImpl::RemoveTrack(MediaStreamTrack& aTrack) {
|
||||
PC_AUTO_ENTER_API_CALL(true);
|
||||
|
||||
DOMMediaStream *stream = nullptr;
|
||||
#ifdef MOZILLA_INTERNAL_API
|
||||
for (uint32_t i = 0; i < mMedia->LocalStreamsLength(); ++i) {
|
||||
auto* candidate = mMedia->GetLocalStream(i)->GetMediaStream();
|
||||
if (candidate->HasTrack(aTrack)) {
|
||||
stream = candidate;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (!stream) {
|
||||
CSFLogError(logTag, "%s: Track not found", __FUNCTION__);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
DOMMediaStream& aMediaStream = *stream;
|
||||
|
||||
#ifdef MOZILLA_INTERNAL_API
|
||||
uint32_t hints = aMediaStream.GetHintContents() &
|
||||
((aTrack.AsAudioStreamTrack()? DOMMediaStream::HINT_CONTENTS_AUDIO : 0) |
|
||||
(aTrack.AsVideoStreamTrack()? DOMMediaStream::HINT_CONTENTS_VIDEO : 0));
|
||||
#else
|
||||
uint32_t hints = aMediaStream.GetHintContents();
|
||||
#endif
|
||||
|
||||
uint32_t num = mMedia->LocalStreamsLength();
|
||||
|
||||
uint32_t stream_id;
|
||||
nsresult res = mMedia->RemoveStream(&aMediaStream, hints, &stream_id);
|
||||
|
||||
if (NS_FAILED(res)) {
|
||||
return res;
|
||||
}
|
||||
|
||||
if (num != mMedia->LocalStreamsLength()) {
|
||||
aMediaStream.RemovePrincipalChangeObserver(this);
|
||||
}
|
||||
|
||||
if (hints & DOMMediaStream::HINT_CONTENTS_AUDIO) {
|
||||
mInternal->mCall->removeStream(stream_id, 0, AUDIO);
|
||||
|
@ -375,6 +375,18 @@ public:
|
||||
rv = RemoveStream(aMediaStream);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_TO_ERRORRESULT(AddTrack, ErrorResult &rv,
|
||||
mozilla::dom::MediaStreamTrack& aTrack,
|
||||
const mozilla::dom::Sequence<mozilla::dom::OwningNonNull<DOMMediaStream>>& aStreams)
|
||||
{
|
||||
rv = AddTrack(aTrack, aStreams);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_TO_ERRORRESULT(RemoveTrack, ErrorResult &rv,
|
||||
mozilla::dom::MediaStreamTrack& aTrack)
|
||||
{
|
||||
rv = RemoveTrack(aTrack);
|
||||
}
|
||||
|
||||
nsresult GetPeerIdentity(nsAString& peerIdentity)
|
||||
{
|
||||
|
@ -43,6 +43,12 @@ LocalSourceStreamInfo::ExpectAudio(const mozilla::TrackID aID)
|
||||
mAudioTracks.AppendElement(aID);
|
||||
}
|
||||
|
||||
void
|
||||
LocalSourceStreamInfo::RemoveAudio(const mozilla::TrackID aID)
|
||||
{
|
||||
mAudioTracks.RemoveElement(aID);
|
||||
}
|
||||
|
||||
// If the ExpectVideo hint is on we will add a track at the default first
|
||||
// video track ID (1).
|
||||
void
|
||||
@ -51,6 +57,12 @@ LocalSourceStreamInfo::ExpectVideo(const mozilla::TrackID aID)
|
||||
mVideoTracks.AppendElement(aID);
|
||||
}
|
||||
|
||||
void
|
||||
LocalSourceStreamInfo::RemoveVideo(const mozilla::TrackID aID)
|
||||
{
|
||||
mVideoTracks.RemoveElement(aID);
|
||||
}
|
||||
|
||||
unsigned
|
||||
LocalSourceStreamInfo::AudioTrackCount()
|
||||
{
|
||||
@ -234,7 +246,9 @@ nsresult PeerConnectionMedia::Init(const std::vector<NrIceStunServer>& stun_serv
|
||||
}
|
||||
|
||||
nsresult
|
||||
PeerConnectionMedia::AddStream(nsIDOMMediaStream* aMediaStream, uint32_t *stream_id)
|
||||
PeerConnectionMedia::AddStream(nsIDOMMediaStream* aMediaStream,
|
||||
uint32_t hints,
|
||||
uint32_t *stream_id)
|
||||
{
|
||||
ASSERT_ON_THREAD(mMainThread);
|
||||
|
||||
@ -245,11 +259,9 @@ PeerConnectionMedia::AddStream(nsIDOMMediaStream* aMediaStream, uint32_t *stream
|
||||
|
||||
DOMMediaStream* stream = static_cast<DOMMediaStream*>(aMediaStream);
|
||||
|
||||
CSFLogDebug(logTag, "%s: MediaStream: %p",
|
||||
__FUNCTION__, aMediaStream);
|
||||
CSFLogDebug(logTag, "%s: MediaStream: %p", __FUNCTION__, aMediaStream);
|
||||
|
||||
// Adding tracks here based on nsDOMMediaStream expectation settings
|
||||
uint32_t hints = stream->GetHintContents();
|
||||
#ifdef MOZILLA_INTERNAL_API
|
||||
if (!Preferences::GetBool("media.peerconnection.video.enabled", true)) {
|
||||
hints &= ~(DOMMediaStream::HINT_CONTENTS_VIDEO);
|
||||
@ -262,23 +274,30 @@ PeerConnectionMedia::AddStream(nsIDOMMediaStream* aMediaStream, uint32_t *stream
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Now see if we already have a stream of this type, since we only
|
||||
// allow one of each.
|
||||
// Now see if we already have this stream or another stream with
|
||||
// tracks of the same type, since we only allow one track of each type.
|
||||
// TODO(ekr@rtfm.com): remove this when multiple of each stream
|
||||
// is allowed
|
||||
for (uint32_t u = 0; u < mLocalSourceStreams.Length(); u++) {
|
||||
nsRefPtr<LocalSourceStreamInfo> localSourceStream = mLocalSourceStreams[u];
|
||||
nsRefPtr<LocalSourceStreamInfo> localSourceStream = nullptr;
|
||||
|
||||
if (localSourceStream->GetMediaStream()->GetHintContents() & hints) {
|
||||
for (uint32_t u = 0; u < mLocalSourceStreams.Length(); u++) {
|
||||
auto& lss = mLocalSourceStreams[u];
|
||||
if (((hints & DOMMediaStream::HINT_CONTENTS_AUDIO) && lss->AudioTrackCount()) ||
|
||||
((hints & DOMMediaStream::HINT_CONTENTS_VIDEO) && lss->VideoTrackCount())) {
|
||||
CSFLogError(logTag, "Only one stream of any given type allowed");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
if (stream == lss->GetMediaStream()) {
|
||||
localSourceStream = lss;
|
||||
*stream_id = u;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!localSourceStream) {
|
||||
localSourceStream = new LocalSourceStreamInfo(stream, this);
|
||||
mLocalSourceStreams.AppendElement(localSourceStream);
|
||||
*stream_id = mLocalSourceStreams.Length() - 1;
|
||||
}
|
||||
|
||||
// OK, we're good to add
|
||||
nsRefPtr<LocalSourceStreamInfo> localSourceStream =
|
||||
new LocalSourceStreamInfo(stream, this);
|
||||
*stream_id = mLocalSourceStreams.Length();
|
||||
|
||||
if (hints & DOMMediaStream::HINT_CONTENTS_AUDIO) {
|
||||
localSourceStream->ExpectAudio(TRACK_AUDIO);
|
||||
@ -287,14 +306,13 @@ PeerConnectionMedia::AddStream(nsIDOMMediaStream* aMediaStream, uint32_t *stream
|
||||
if (hints & DOMMediaStream::HINT_CONTENTS_VIDEO) {
|
||||
localSourceStream->ExpectVideo(TRACK_VIDEO);
|
||||
}
|
||||
|
||||
mLocalSourceStreams.AppendElement(localSourceStream);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
PeerConnectionMedia::RemoveStream(nsIDOMMediaStream* aMediaStream, uint32_t *stream_id)
|
||||
PeerConnectionMedia::RemoveStream(nsIDOMMediaStream* aMediaStream,
|
||||
uint32_t hints,
|
||||
uint32_t *stream_id)
|
||||
{
|
||||
MOZ_ASSERT(aMediaStream);
|
||||
ASSERT_ON_THREAD(mMainThread);
|
||||
@ -308,6 +326,17 @@ PeerConnectionMedia::RemoveStream(nsIDOMMediaStream* aMediaStream, uint32_t *str
|
||||
nsRefPtr<LocalSourceStreamInfo> localSourceStream = mLocalSourceStreams[u];
|
||||
if (localSourceStream->GetMediaStream() == stream) {
|
||||
*stream_id = u;
|
||||
|
||||
if (hints & DOMMediaStream::HINT_CONTENTS_AUDIO) {
|
||||
localSourceStream->RemoveAudio(TRACK_AUDIO);
|
||||
}
|
||||
if (hints & DOMMediaStream::HINT_CONTENTS_VIDEO) {
|
||||
localSourceStream->RemoveAudio(TRACK_VIDEO);
|
||||
}
|
||||
if (!(localSourceStream->AudioTrackCount() +
|
||||
localSourceStream->VideoTrackCount())) {
|
||||
mLocalSourceStreams.RemoveElementAt(u);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
@ -226,6 +226,8 @@ public:
|
||||
|
||||
void ExpectAudio(const mozilla::TrackID);
|
||||
void ExpectVideo(const mozilla::TrackID);
|
||||
void RemoveAudio(const mozilla::TrackID);
|
||||
void RemoveVideo(const mozilla::TrackID);
|
||||
unsigned AudioTrackCount();
|
||||
unsigned VideoTrackCount();
|
||||
void DetachTransport_s();
|
||||
@ -301,10 +303,13 @@ class PeerConnectionMedia : public sigslot::has_slots<> {
|
||||
}
|
||||
|
||||
// Add a stream (main thread only)
|
||||
nsresult AddStream(nsIDOMMediaStream* aMediaStream, uint32_t *stream_id);
|
||||
nsresult AddStream(nsIDOMMediaStream* aMediaStream, uint32_t hints,
|
||||
uint32_t *stream_id);
|
||||
|
||||
// Remove a stream (main thread only)
|
||||
nsresult RemoveStream(nsIDOMMediaStream* aMediaStream, uint32_t *stream_id);
|
||||
nsresult RemoveStream(nsIDOMMediaStream* aMediaStream,
|
||||
uint32_t hints,
|
||||
uint32_t *stream_id);
|
||||
|
||||
// Get a specific local stream
|
||||
uint32_t LocalStreamsLength()
|
||||
|
Loading…
Reference in New Issue
Block a user