Bug 1232082 - fix removal of remote tracks to update receivers. r=bwc

This commit is contained in:
Jan-Ivar Bruaroey 2016-01-05 19:51:52 -05:00
parent 224b82d51f
commit 9e0d4a3712
3 changed files with 44 additions and 38 deletions

View File

@ -1366,15 +1366,16 @@ PeerConnectionObserver.prototype = {
// STUN requests.
handleIceConnectionStateChange: function(iceConnectionState) {
if (this._dompc.iceConnectionState === 'new') {
let pc = this._dompc;
if (pc.iceConnectionState === 'new') {
var checking_histogram = Services.telemetry.getHistogramById("WEBRTC_ICE_CHECKING_RATE");
if (iceConnectionState === 'checking') {
checking_histogram.add(true);
} else if (iceConnectionState === 'failed') {
checking_histogram.add(false);
}
} else if (this._dompc.iceConnectionState === 'checking') {
var success_histogram = Services.telemetry.getHistogramById(this._dompc._isLoop ?
} else if (pc.iceConnectionState === 'checking') {
var success_histogram = Services.telemetry.getHistogramById(pc._isLoop ?
"LOOP_ICE_SUCCESS_RATE" : "WEBRTC_ICE_SUCCESS_RATE");
if (iceConnectionState === 'completed' ||
iceConnectionState === 'connected') {
@ -1385,10 +1386,10 @@ PeerConnectionObserver.prototype = {
}
if (iceConnectionState === 'failed') {
this._dompc.logError("ICE failed, see about:webrtc for more details", null, 0);
pc.logError("ICE failed, see about:webrtc for more details", null, 0);
}
this._dompc.changeIceConnectionState(iceConnectionState);
pc.changeIceConnectionState(iceConnectionState);
},
// This method is responsible for updating iceGatheringState. This
@ -1443,11 +1444,11 @@ PeerConnectionObserver.prototype = {
},
onGetStatsSuccess: function(dict) {
let chromeobj = new RTCStatsReport(this._dompc._win, dict);
let webidlobj = this._dompc._win.RTCStatsReport._create(this._dompc._win,
chromeobj);
let pc = this._dompc;
let chromeobj = new RTCStatsReport(pc._win, dict);
let webidlobj = pc._win.RTCStatsReport._create(pc._win, chromeobj);
chromeobj.makeStatsPublic();
this._dompc._onGetStatsSuccess(webidlobj);
pc._onGetStatsSuccess(webidlobj);
},
onGetStatsError: function(code, message) {
@ -1460,7 +1461,7 @@ PeerConnectionObserver.prototype = {
this.dispatchEvent(ev);
},
onRemoveStream: function(stream, type) {
onRemoveStream: function(stream) {
this.dispatchEvent(new this._dompc._win.MediaStreamEvent("removestream",
{ stream: stream }));
},
@ -1471,24 +1472,23 @@ PeerConnectionObserver.prototype = {
new RTCRtpReceiver(this,
track));
pc._receivers.push(receiver);
let ev = new this._dompc._win.RTCTrackEvent("track",
{ receiver: receiver,
track: track,
streams: streams });
let ev = new pc._win.RTCTrackEvent("track",
{ receiver: receiver,
track: track,
streams: streams });
this.dispatchEvent(ev);
// Fire legacy event as well for a little bit.
ev = new this._dompc._win.MediaStreamTrackEvent("addtrack", { track: track });
ev = new pc._win.MediaStreamTrackEvent("addtrack", { track: track });
this.dispatchEvent(ev);
},
onRemoveTrack: function(track, type) {
let i = this._dompc._receivers.findIndex(receiver => receiver.track == track);
onRemoveTrack: function(track) {
let pc = this._dompc;
let i = pc._receivers.findIndex(receiver => receiver.track == track);
if (i >= 0) {
this._receivers.splice(i, 1);
pc._receivers.splice(i, 1);
}
this.dispatchEvent(new this._dompc._win.MediaStreamTrackEvent("removetrack",
{ track: track }));
},
onReplaceTrackSuccess: function() {

View File

@ -1393,6 +1393,9 @@ PeerConnectionWrapper.prototype = {
var rtpStatsKey = Object.keys(stats)
.find(key => !stats[key].isRemote && stats[key].type.endsWith("boundrtp"));
ok(rtpStatsKey, "Should have RTP stats for track " + track.id);
if (!rtpStatsKey) {
return false;
}
var rtp = stats[rtpStatsKey];
var nrPackets = rtp[rtp.type == "outboundrtp" ? "packetsSent"
: "packetsReceived"];
@ -1401,21 +1404,12 @@ PeerConnectionWrapper.prototype = {
return nrPackets > 0;
};
return new Promise(resolve => {
info("Checking RTP packet flow for track " + track.id);
info("Checking RTP packet flow for track " + track.id);
var waitForFlow = () => {
this._pc.getStats(track).then(stats => {
if (hasFlow(stats)) {
ok(true, "RTP flowing for track " + track.id);
resolve();
} else {
wait(200).then(waitForFlow);
}
});
};
waitForFlow();
});
var retry = () => this._pc.getStats(track)
.then(stats => hasFlow(stats)? ok(true, "RTP flowing for track " + track.id) :
wait(200).then(retry));
return retry();
},
/**

View File

@ -1868,19 +1868,31 @@ PeerConnectionImpl::SetRemoteDescription(int32_t action, const char* aSDP)
mJsepSession->GetRemoteTracksRemoved();
for (auto i = removedTracks.begin(); i != removedTracks.end(); ++i) {
RefPtr<RemoteSourceStreamInfo> info =
mMedia->GetRemoteStreamById((*i)->GetStreamId());
const std::string& streamId = (*i)->GetStreamId();
const std::string& trackId = (*i)->GetTrackId();
RefPtr<RemoteSourceStreamInfo> info = mMedia->GetRemoteStreamById(streamId);
if (!info) {
MOZ_ASSERT(false, "A stream/track was removed that wasn't in PCMedia. "
"This is a bug.");
continue;
}
mMedia->RemoveRemoteTrack((*i)->GetStreamId(), (*i)->GetTrackId());
mMedia->RemoveRemoteTrack(streamId, trackId);
DOMMediaStream* stream = info->GetMediaStream();
nsTArray<RefPtr<MediaStreamTrack>> tracks;
stream->GetTracks(tracks);
for (auto& track : tracks) {
if (PeerConnectionImpl::GetTrackId(*track) == trackId) {
pco->OnRemoveTrack(*track, jrv);
break;
}
}
// We might be holding the last ref, but that's ok.
if (!info->GetTrackCount()) {
pco->OnRemoveStream(*info->GetMediaStream(), jrv);
pco->OnRemoveStream(*stream, jrv);
}
}