-
Notifications
You must be signed in to change notification settings - Fork 3.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add test that "maintain-framerate" does what it says.
Adds a test that measures the bandwidth, cuts the bandwidth in half, and then measures that framerate is maintained, but resolution is not. Also adds more entropy to the "getNoiseStream()" video signal; the old version generated a video stream of 8 Kbits/second in 640x480. Bug: none Change-Id: Iefe0a44b9686f1bb4bdd13ab63922c3d460c775e
- Loading branch information
1 parent
a8eddd3
commit 4258493
Showing
2 changed files
with
128 additions
and
0 deletions.
There are no files selected for viewing
119 changes: 119 additions & 0 deletions
119
mst-content-hint/RTCRtpSendParameters-degradationEffect-slow.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
<!doctype html> | ||
<meta charset=utf-8> | ||
<meta name="timeout" content="long"> | ||
<title>RTCRtpSendParameters degradationPreference effect</title> | ||
<script src="/resources/testharness.js"></script> | ||
<script src="/resources/testharnessreport.js"></script> | ||
<script src="../webrtc/RTCPeerConnection-helper.js"></script> | ||
<script> | ||
'use strict'; | ||
|
||
// This file contains tests that check that degradation preference | ||
// actually has the desired effect. These tests take a long time to run. | ||
|
||
// Returns incoming bandwidth usage between stats1 and stats2 | ||
// in bits per second. | ||
function bandwidth(stats1, stats2) { | ||
const transport1 = [...stats1.values()].filter(({type}) => type === 'transport')[0]; | ||
const transport2 = [...stats2.values()].filter(({type}) => type === 'transport')[0]; | ||
const bytes = transport2.bytesReceived - transport1.bytesReceived; | ||
// Multiply by 1000 to get per second, divide by 8 to get bits. | ||
const bandwidth = 1000 * 8 * bytes / | ||
(transport2.timestamp - transport1.timestamp); | ||
return bandwidth; | ||
} | ||
|
||
// Returns tuple of { bandwidth, fps, x-res, y-res } | ||
async function measureStuff(t, pc, intervalMs) { | ||
const stats1 = await pc.getStats(); | ||
await new Promise(r => t.step_timeout(r, intervalMs)); | ||
const stats2 = await pc.getStats(); | ||
// RTCInboundStreamStats | ||
const inboundRtp1List = [...stats1.values()].filter(({type}) => type === 'inbound-rtp'); | ||
const inboundRtp2List = [...stats2.values()].filter(({type}) => type === 'inbound-rtp'); | ||
const inboundRtp1 = inboundRtp1List[0]; | ||
const inboundRtp2 = inboundRtp2List[0]; | ||
const fps = 1000 * (inboundRtp2.framesReceived - inboundRtp1.framesReceived) / | ||
(inboundRtp2.timestamp - inboundRtp1.timestamp); | ||
const result = { | ||
bandwidth: bandwidth(stats1, stats2), | ||
fps: fps, | ||
width: inboundRtp2.frameWidth, | ||
height: inboundRtp2.frameHeight | ||
}; | ||
// Unbreak for debugging. | ||
// con sole.log('Measure: ', performance.now(), " ", JSON.stringify(result)); | ||
return result; | ||
} | ||
|
||
// Wait for a certain condition to be true on the traffic measures | ||
// on the PC. Will typically be conditions on resolution, framerate | ||
// or bandwidth. | ||
async function waitForCondition(t, pc, condition, maxWait, stepName) { | ||
let counter = 1; | ||
let measure = await measureStuff(t, pc, 1000); | ||
while (counter < maxWait && !condition(measure)) { | ||
measure = await measureStuff(t, pc, 1000); | ||
counter += 1; | ||
} | ||
assert_true(condition(measure), | ||
`failure in ${stepName}, measure is ${JSON.stringify(measure)}`); | ||
return condition(measure); | ||
} | ||
|
||
promise_test(async t => { | ||
const pc1 = new RTCPeerConnection(); | ||
t.add_cleanup(() => pc1.close()); | ||
const stream = await getNoiseStream({video: true}); | ||
t.add_cleanup(() => stream.getTracks().forEach(track => track.stop())); | ||
const track = stream.getTracks()[0]; | ||
const { sender } = pc1.addTransceiver(track); | ||
|
||
let param = sender.getParameters(); | ||
|
||
assert_equals(param.degradationPreference, undefined, | ||
'Expect initial param.degradationPreference to be undefined'); | ||
|
||
param.degradationPreference = 'maintain-framerate'; | ||
await sender.setParameters(param); | ||
|
||
const pc2 = new RTCPeerConnection(); | ||
t.add_cleanup(() => pc2.close()); | ||
|
||
exchangeIceCandidates(pc1, pc2); | ||
await exchangeOfferAnswer(pc1, pc2); | ||
await listenToConnected(pc1); | ||
// Wait a few seconds to allow things to settle (rampup) | ||
// We know that the generator is supposed to produce 640x480 | ||
// at 10 fps with a bandwidth exceeding 30 kbits/second. | ||
assert_true(await waitForCondition(t, pc2, (measure) => { | ||
return (measure.bandwidth > 30000 && | ||
measure.width == 640 && | ||
measure.fps > 9); | ||
}, 5, 'preconditions')); | ||
|
||
// Measure BW, resolution and frame rate over one second | ||
const stats1 = await measureStuff(t, pc2, 1000); | ||
|
||
// Constrain BW to 1/2 of measured value | ||
const newBandwidth = stats1.bandwidth / 2; | ||
|
||
const parameters = sender.getParameters(); | ||
parameters.encodings[0].maxBitrate = newBandwidth; | ||
await sender.setParameters(parameters); | ||
// Wait until the expected result happens. | ||
let stats2 = await measureStuff(t, pc2, 1000); | ||
let counter = 1; | ||
const maxWaitCount = 20; | ||
const kBandwidthMargin = 1.3; | ||
// It takes time to adapt to a new bandwidth, time to scale down, | ||
// and time to acknowledge that framerate should not be reduced. | ||
assert_true(await waitForCondition(t, pc2, (measure) => { | ||
return (measure.bandwidth < newBandwidth * kBandwidthMargin && | ||
measure.width < stats1.width && | ||
measure.fps > stats1.fps * 0.9); | ||
}, 20, 'adaptation'), | ||
`Target bandwidth ${newBandwidth * kBandwidthMargin}, target min FPS ${stats1.fps * 0.9}`); | ||
}, 'Maintain-framerate reduces resolution on bandwidth cut', { timeout: 35000 }); | ||
|
||
</script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters