Backed out changeset 4cc3fae66ffb (bug 1250990) for frequent failure of modified test test_peerConnection_scaleResolution.html. r=frequentorange

This commit is contained in:
Sebastian Hengst 2016-02-28 09:59:16 +01:00
parent d4b0049e46
commit 06d19d0d14
2 changed files with 149 additions and 155 deletions

View File

@ -12,37 +12,33 @@
visible: true visible: true
}); });
var pc1 = new RTCPeerConnection();
var pc2 = new RTCPeerConnection();
var add = (pc, can, failed) => can && pc.addIceCandidate(can).catch(failed);
pc1.onicecandidate = e => add(pc2, e.candidate, generateErrorCallback());
pc2.onicecandidate = e => add(pc1, e.candidate, generateErrorCallback());
pc1.onnegotiationneeded = e =>
pc1.createOffer().then(d => pc1.setLocalDescription(d))
.then(() => pc2.setRemoteDescription(pc1.localDescription))
.then(() => pc2.createAnswer()).then(d => pc2.setLocalDescription(d))
.then(() => pc1.setRemoteDescription(pc2.localDescription))
.catch(generateErrorCallback());
var mustRejectWith = (msg, reason, f) => var mustRejectWith = (msg, reason, f) =>
f().then(() => ok(false, msg), f().then(() => ok(false, msg),
e => is(e.name, reason, msg)); e => is(e.name, reason, msg));
var v1, v2;
var removeVP8 = d => (d.sdp = d.sdp.replace("a=rtpmap:120 VP8/90000\r\n", ""), d); runNetworkTest(function() {
v1 = createMediaElement('video', 'v1');
v2 = createMediaElement('video', 'v2');
function testScale(codec) { is(v2.currentTime, 0, "v2.currentTime is zero at outset");
var pc1 = new RTCPeerConnection();
var pc2 = new RTCPeerConnection();
var add = (pc, can, failed) => can && pc.addIceCandidate(can).catch(failed); navigator.mediaDevices.getUserMedia({ video: true })
pc1.onicecandidate = e => add(pc2, e.candidate, generateErrorCallback());
pc2.onicecandidate = e => add(pc1, e.candidate, generateErrorCallback());
info("testing scaling with " + codec);
pc1.onnegotiationneeded = e =>
pc1.createOffer()
.then(d => pc1.setLocalDescription(codec == "VP8" ? d : removeVP8(d)))
.then(() => pc2.setRemoteDescription(pc1.localDescription))
.then(() => pc2.createAnswer()).then(d => pc2.setLocalDescription(d))
.then(() => pc1.setRemoteDescription(pc2.localDescription))
.catch(generateErrorCallback());
return navigator.mediaDevices.getUserMedia({ video: true })
.then(stream => { .then(stream => {
var v1 = createMediaElement('video', 'v1');
var v2 = createMediaElement('video', 'v2');
is(v2.currentTime, 0, "v2.currentTime is zero at outset");
v1.srcObject = stream; v1.srcObject = stream;
var sender = pc1.addTrack(stream.getVideoTracks()[0], stream); var sender = pc1.addTrack(stream.getVideoTracks()[0], stream);
@ -50,29 +46,23 @@
() => sender.setParameters({ encodings: () => sender.setParameters({ encodings:
[{ scaleResolutionDownBy: 0.5 } ] })) [{ scaleResolutionDownBy: 0.5 } ] }))
.then(() => sender.setParameters({ encodings: [{ maxBitrate: 60000, .then(() => sender.setParameters({ encodings: [{ maxBitrate: 60000,
scaleResolutionDownBy: 2 }] })) scaleResolutionDownBy: 2 }] }))
.then(() => new Promise(resolve => pc2.ontrack = e => resolve(e)))
.then(e => v2.srcObject = e.streams[0])
.then(() => new Promise(resolve => v2.onloadedmetadata = resolve))
.then(() => waitUntil(() => v2.currentTime > 0 && v2.srcObject.currentTime > 0))
.then(() => ok(v2.currentTime > 0, "v2.currentTime is moving (" + v2.currentTime + ")"))
.then(() => wait(1000)) // TODO: Bug 1248154
.then(() => {
ok(v1.videoWidth > 0, "source width is positive");
ok(v1.videoHeight > 0, "source height is positive");
is(v2.videoWidth, v1.videoWidth / 2, "sink is half the width of source");
is(v2.videoHeight, v1.videoHeight / 2, "sink is half the height of source");
})
.then(() => {
stream.getTracks().forEach(track => track.stop());
v1.srcObject = v2.srcObject = null;
})
}) })
.catch(generateErrorCallback()); .then(() => new Promise(resolve => pc2.ontrack = e => resolve(e)))
} .then(e => v2.srcObject = e.streams[0])
.then(() => new Promise(resolve => v2.onloadedmetadata = resolve))
runNetworkTest(() => testScale("VP8").then(() => testScale("H264")) .then(() => waitUntil(() => v2.currentTime > 0 && v2.srcObject.currentTime > 0))
.then(networkTestFinished)); .then(() => ok(v2.currentTime > 0, "v2.currentTime is moving (" + v2.currentTime + ")"))
.then(() => wait(1000)) // TODO: Bug 1248154
.then(() => {
ok(v1.videoWidth > 0, "source width is positive");
ok(v1.videoHeight > 0, "source height is positive");
is(v2.videoWidth, v1.videoWidth / 2, "sink is half the width of source");
is(v2.videoHeight, v1.videoHeight / 2, "sink is half the height of source");
})
.catch(generateErrorCallback())
.then(networkTestFinished);
});
</script> </script>
</pre> </pre>
</body> </body>

View File

@ -1277,76 +1277,80 @@ WebrtcVideoConduit::ReconfigureSendCodec(unsigned short width,
CSFLogDebug(logTag, CSFLogDebug(logTag,
"%s: Requesting resolution change to %ux%u (from %ux%u)", "%s: Requesting resolution change to %ux%u (from %ux%u)",
__FUNCTION__, width, height, vie_codec.width, vie_codec.height); __FUNCTION__, width, height, vie_codec.width, vie_codec.height);
// Likely spurious unless there was some error, but rarely checked
if (vie_codec.width != width || vie_codec.height != height ||
vie_codec.maxFramerate != mSendingFramerate)
{
vie_codec.width = width;
vie_codec.height = height;
vie_codec.maxFramerate = mSendingFramerate;
SelectBitrates(vie_codec.width, vie_codec.height, 0,
mLastFramerateTenths,
vie_codec.minBitrate,
vie_codec.startBitrate,
vie_codec.maxBitrate);
vie_codec.width = width; for (size_t i = vie_codec.numberOfSimulcastStreams; i > 0; --i) {
vie_codec.height = height; webrtc::SimulcastStream& stream(vie_codec.simulcastStream[i - 1]);
vie_codec.maxFramerate = mSendingFramerate; stream.width = width;
SelectBitrates(vie_codec.width, vie_codec.height, 0, stream.height = height;
mLastFramerateTenths, MOZ_ASSERT(stream.jsScaleDownBy >= 1.0);
vie_codec.minBitrate, uint32_t new_width = uint32_t(width / stream.jsScaleDownBy);
vie_codec.startBitrate, uint32_t new_height = uint32_t(height / stream.jsScaleDownBy);
vie_codec.maxBitrate); // TODO: If two layers are similar, only alloc bits to one (Bug 1249859)
if (new_width != width || new_height != height) {
if (vie_codec.numberOfSimulcastStreams == 1) {
// Use less strict scaling in unicast. That way 320x240 / 3 = 106x79.
ConstrainPreservingAspectRatio(new_width, new_height,
&stream.width, &stream.height);
} else {
// webrtc.org supposedly won't tolerate simulcast unless every stream
// is exactly the same aspect ratio. 320x240 / 3 = 80x60.
ConstrainPreservingAspectRatioExact(new_width*new_height,
&stream.width, &stream.height);
}
}
// Give each layer default appropriate bandwidth limits based on the
// resolution/framerate of that layer
SelectBitrates(stream.width, stream.height, stream.jsMaxBitrate,
mLastFramerateTenths,
stream.minBitrate,
stream.targetBitrate,
stream.maxBitrate);
for (size_t i = vie_codec.numberOfSimulcastStreams; i > 0; --i) { vie_codec.minBitrate = std::min(stream.minBitrate, vie_codec.minBitrate);
webrtc::SimulcastStream& stream(vie_codec.simulcastStream[i - 1]); vie_codec.startBitrate += stream.targetBitrate;
stream.width = width; vie_codec.maxBitrate = std::max(stream.maxBitrate, vie_codec.maxBitrate);
stream.height = height;
MOZ_ASSERT(stream.jsScaleDownBy >= 1.0); // webrtc.org expects the last, highest fidelity, simulcast stream to
uint32_t new_width = uint32_t(width / stream.jsScaleDownBy); // always have the same resolution as vie_codec
uint32_t new_height = uint32_t(height / stream.jsScaleDownBy); if (i == vie_codec.numberOfSimulcastStreams) {
// TODO: If two layers are similar, only alloc bits to one (Bug 1249859) vie_codec.width = stream.width;
if (new_width != width || new_height != height) { vie_codec.height = stream.height;
if (vie_codec.numberOfSimulcastStreams == 1) {
// Use less strict scaling in unicast. That way 320x240 / 3 = 106x79.
ConstrainPreservingAspectRatio(new_width, new_height,
&stream.width, &stream.height);
} else {
// webrtc.org supposedly won't tolerate simulcast unless every stream
// is exactly the same aspect ratio. 320x240 / 3 = 80x60.
ConstrainPreservingAspectRatioExact(new_width*new_height,
&stream.width, &stream.height);
} }
} }
// Give each layer default appropriate bandwidth limits based on the if (vie_codec.numberOfSimulcastStreams != 0) {
// resolution/framerate of that layer vie_codec.startBitrate /= vie_codec.numberOfSimulcastStreams;
SelectBitrates(stream.width, stream.height, stream.jsMaxBitrate, }
mLastFramerateTenths, if ((err = mPtrViECodec->SetSendCodec(mChannel, vie_codec)) != 0)
stream.minBitrate, {
stream.targetBitrate, CSFLogError(logTag, "%s: SetSendCodec(%ux%u) failed, err %d",
stream.maxBitrate); __FUNCTION__, width, height, err);
return NS_ERROR_FAILURE;
vie_codec.minBitrate = std::min(stream.minBitrate, vie_codec.minBitrate); }
vie_codec.startBitrate += stream.targetBitrate; if (mMinBitrateEstimate != 0) {
vie_codec.maxBitrate = std::max(stream.maxBitrate, vie_codec.maxBitrate); mPtrViENetwork->SetBitrateConfig(mChannel,
mMinBitrateEstimate,
// webrtc.org expects the last, highest fidelity, simulcast stream to std::max(vie_codec.startBitrate,
// always have the same resolution as vie_codec mMinBitrateEstimate),
if (i == vie_codec.numberOfSimulcastStreams) { std::max(vie_codec.maxBitrate,
vie_codec.width = stream.width; mMinBitrateEstimate));
vie_codec.height = stream.height;
} }
}
if (vie_codec.numberOfSimulcastStreams != 0) {
vie_codec.startBitrate /= vie_codec.numberOfSimulcastStreams;
}
if ((err = mPtrViECodec->SetSendCodec(mChannel, vie_codec)) != 0)
{
CSFLogError(logTag, "%s: SetSendCodec(%ux%u) failed, err %d",
__FUNCTION__, width, height, err);
return NS_ERROR_FAILURE;
}
if (mMinBitrateEstimate != 0) {
mPtrViENetwork->SetBitrateConfig(mChannel,
mMinBitrateEstimate,
std::max(vie_codec.startBitrate,
mMinBitrateEstimate),
std::max(vie_codec.maxBitrate,
mMinBitrateEstimate));
}
CSFLogDebug(logTag, "%s: Encoder resolution changed to %ux%u @ %ufps, bitrate %u:%u", CSFLogDebug(logTag, "%s: Encoder resolution changed to %ux%u @ %ufps, bitrate %u:%u",
__FUNCTION__, width, height, mSendingFramerate, __FUNCTION__, width, height, mSendingFramerate,
vie_codec.minBitrate, vie_codec.maxBitrate); vie_codec.minBitrate, vie_codec.maxBitrate);
} // else no change; mSendingWidth likely was 0
if (frame) { if (frame) {
// XXX I really don't like doing this from MainThread... // XXX I really don't like doing this from MainThread...
mPtrExtCapture->IncomingFrame(*frame); mPtrExtCapture->IncomingFrame(*frame);
@ -1860,57 +1864,57 @@ WebrtcVideoConduit::CodecConfigToWebRTCCodec(const VideoCodecConfig* codecInfo,
cinst.codecSpecific.H264.spsLen = 0; cinst.codecSpecific.H264.spsLen = 0;
cinst.codecSpecific.H264.ppsData = nullptr; cinst.codecSpecific.H264.ppsData = nullptr;
cinst.codecSpecific.H264.ppsLen = 0; cinst.codecSpecific.H264.ppsLen = 0;
} } else {
// Init mSimulcastEncodings always since they hold info from setParameters. // TODO(bug 1210175): H264 doesn't support simulcast yet.
// TODO(bug 1210175): H264 doesn't support simulcast yet. for (size_t i = 0; i < codecInfo->mSimulcastEncodings.size(); ++i) {
for (size_t i = 0; i < codecInfo->mSimulcastEncodings.size(); ++i) { const VideoCodecConfig::SimulcastEncoding& encoding =
const VideoCodecConfig::SimulcastEncoding& encoding = codecInfo->mSimulcastEncodings[i];
codecInfo->mSimulcastEncodings[i]; // Make sure the constraints on the whole stream are reflected.
// Make sure the constraints on the whole stream are reflected. webrtc::SimulcastStream stream;
webrtc::SimulcastStream stream; memset(&stream, 0, sizeof(stream));
memset(&stream, 0, sizeof(stream)); stream.width = cinst.width;
stream.width = cinst.width; stream.height = cinst.height;
stream.height = cinst.height; stream.numberOfTemporalLayers = 1;
stream.numberOfTemporalLayers = 1; stream.maxBitrate = cinst.maxBitrate;
stream.maxBitrate = cinst.maxBitrate; stream.targetBitrate = cinst.targetBitrate;
stream.targetBitrate = cinst.targetBitrate; stream.minBitrate = cinst.minBitrate;
stream.minBitrate = cinst.minBitrate; stream.qpMax = cinst.qpMax;
stream.qpMax = cinst.qpMax; strncpy(stream.rid, encoding.rid.c_str(), sizeof(stream.rid)-1);
strncpy(stream.rid, encoding.rid.c_str(), sizeof(stream.rid)-1); stream.rid[sizeof(stream.rid) - 1] = 0;
stream.rid[sizeof(stream.rid) - 1] = 0;
// Apply encoding-specific constraints. // Apply encoding-specific constraints.
stream.width = MinIgnoreZero( stream.width = MinIgnoreZero(
stream.width, stream.width,
(unsigned short)encoding.constraints.maxWidth); (unsigned short)encoding.constraints.maxWidth);
stream.height = MinIgnoreZero( stream.height = MinIgnoreZero(
stream.height, stream.height,
(unsigned short)encoding.constraints.maxHeight); (unsigned short)encoding.constraints.maxHeight);
// webrtc.org uses kbps, we use bps // webrtc.org uses kbps, we use bps
stream.jsMaxBitrate = encoding.constraints.maxBr/1000; stream.jsMaxBitrate = encoding.constraints.maxBr/1000;
stream.jsScaleDownBy = encoding.constraints.scaleDownBy; stream.jsScaleDownBy = encoding.constraints.scaleDownBy;
MOZ_ASSERT(stream.jsScaleDownBy >= 1.0); MOZ_ASSERT(stream.jsScaleDownBy >= 1.0);
uint32_t width = stream.width? stream.width : 640; uint32_t width = stream.width? stream.width : 640;
uint32_t height = stream.height? stream.height : 480; uint32_t height = stream.height? stream.height : 480;
uint32_t new_width = uint32_t(width / stream.jsScaleDownBy); uint32_t new_width = uint32_t(width / stream.jsScaleDownBy);
uint32_t new_height = uint32_t(height / stream.jsScaleDownBy); uint32_t new_height = uint32_t(height / stream.jsScaleDownBy);
if (new_width != width || new_height != height) { if (new_width != width || new_height != height) {
// Estimate. Overridden on first frame. // Estimate. Overridden on first frame.
SelectBitrates(new_width, new_height, stream.jsMaxBitrate, SelectBitrates(new_width, new_height, stream.jsMaxBitrate,
mLastFramerateTenths, mLastFramerateTenths,
stream.minBitrate, stream.minBitrate,
stream.targetBitrate, stream.targetBitrate,
stream.maxBitrate); stream.maxBitrate);
}
// webrtc.org expects simulcast streams to be ordered by increasing
// fidelity, our jsep code does the opposite.
cinst.simulcastStream[codecInfo->mSimulcastEncodings.size()-i-1] = stream;
} }
// webrtc.org expects simulcast streams to be ordered by increasing
// fidelity, our jsep code does the opposite.
cinst.simulcastStream[codecInfo->mSimulcastEncodings.size()-i-1] = stream;
}
cinst.numberOfSimulcastStreams = codecInfo->mSimulcastEncodings.size(); cinst.numberOfSimulcastStreams = codecInfo->mSimulcastEncodings.size();
}
} }
//Copy the codec passed into Conduit's database //Copy the codec passed into Conduit's database