|
1 | 1 | <!doctype html> |
2 | 2 | <meta charset=utf-8> |
| 3 | +<meta name="timeout" content="long"> |
3 | 4 | <title>RTCRtpParameters encodings</title> |
4 | 5 | <script src="/resources/testharness.js"></script> |
5 | 6 | <script src="/resources/testharnessreport.js"></script> |
|
12 | 13 | // Test is based on the following editor draft: |
13 | 14 | // https://w3c.github.io/webrtc-svc/ |
14 | 15 |
|
15 | | - // Get the first encoding in param.encodings. |
16 | | - // Asserts that param.encodings has at least one element. |
17 | | - function getFirstEncoding(param) { |
18 | | - const { encodings } = param; |
19 | | - assert_equals(encodings.length, 1); |
20 | | - return encodings[0]; |
21 | | - } |
22 | | - |
23 | | - const capabilities = RTCRtpSender.getCapabilities('video'); |
24 | | - let index = 0; |
25 | | - for (const codec of capabilities.codecs) { |
26 | | - if ('scalabilityModes' in codec && codec.scalabilityModes.length > 0) { |
27 | | - for (const scalabilityMode of codec.scalabilityModes) { |
28 | | - promise_test(async t => { |
29 | | - const v = document.createElement('video'); |
30 | | - v.autoplay = true; |
31 | | - const pc1 = new RTCPeerConnection(); |
32 | | - const pc2 = new RTCPeerConnection(); |
33 | | - t.add_cleanup(() => pc1.close()); |
34 | | - t.add_cleanup(() => pc2.close()); |
35 | | - const stream1 = await getNoiseStream({ video: { signal: 100 , width: 60, height: 60} }); |
36 | | - const [track1] = stream1.getTracks(); |
37 | | - t.add_cleanup(() => track1.stop()); |
38 | | - const transceiver = pc1.addTransceiver(track1, { |
39 | | - sendEncodings: [{ scalabilityMode: scalabilityMode }], |
40 | | - }); |
41 | | - transceiver.setCodecPreferences([codec]); |
42 | | - const haveTrackEvent = new Promise(r => pc2.ontrack = r); |
43 | | - exchangeIceCandidates(pc1, pc2); |
44 | | - await exchangeOfferAnswer(pc1, pc2); |
45 | | - v.srcObject = new MediaStream([(await haveTrackEvent).track]); |
46 | | - await new Promise(r => v.onloadedmetadata = r); |
47 | | - await detectSignal(t, v, 100); |
48 | | - const sendParams = pc1.getSenders()[0].getParameters(); |
49 | | - assert_equals(sendParams.encodings[0].scalabilityMode, scalabilityMode); |
50 | | - }, `[${index++}] ${codec.mimeType} - ${scalabilityMode} should produce valid video content`); |
51 | | - } |
52 | | - } |
53 | | - } |
54 | | - |
55 | 16 | promise_test(async t => { |
56 | 17 | const pc = new RTCPeerConnection(); |
57 | 18 | t.add_cleanup(() => pc.close()); |
|
84 | 45 | assert_true(svcSupported); |
85 | 46 | }, `Sender capabilities should include at least some scalability modes`); |
86 | 47 |
|
87 | | -promise_test(async t => { |
88 | | - const pc = new RTCPeerConnection(); |
89 | | - t.add_cleanup(() => pc.close()); |
90 | | - const { sender } = pc.addTransceiver('video'); |
91 | | - const param = sender.getParameters(); |
92 | | - assert_equals(param.encodings.length, 0); |
93 | | -}, 'Not setting sendEncodings results in no mode info before negotiation'); |
94 | | - |
95 | | -promise_test(async t => { |
96 | | - const pc = new RTCPeerConnection(); |
97 | | - t.add_cleanup(() => pc.close()); |
98 | | - const { sender } = pc.addTransceiver('video', { |
99 | | - sendEncodings: [{}], |
100 | | - }); |
101 | | - const param = sender.getParameters(); |
102 | | - const encoding = getFirstEncoding(param); |
103 | | - |
104 | | - assert_true(!('scalabilityMode' in encoding)); |
105 | | -}, 'Not setting a scalability mode results in no mode set before negotiation'); |
106 | | - |
107 | | -promise_test(async t => { |
108 | | - const pc1 = new RTCPeerConnection(); |
109 | | - const pc2 = new RTCPeerConnection(); |
110 | | - t.add_cleanup(() => pc1.close()); |
111 | | - t.add_cleanup(() => pc2.close()); |
112 | | - const { sender } = pc1.addTransceiver('video', { |
113 | | - sendEncodings: [{}], |
114 | | - }); |
115 | | - const param = sender.getParameters(); |
116 | | - const encoding = getFirstEncoding(param); |
117 | | - |
118 | | - exchangeIceCandidates(pc1, pc2); |
119 | | - await exchangeOfferAnswer(pc1, pc2); |
120 | | - const param2 = sender.getParameters(); |
121 | | - const encoding2 = getFirstEncoding(param); |
122 | | - assert_true('scalabilityMode' in encoding2); |
123 | | -}, 'Not setting a scalability mode results in some mode set after negotiation'); |
| 48 | + promise_test(async t => { |
| 49 | + const pc = new RTCPeerConnection(); |
| 50 | + t.add_cleanup(() => pc.close()); |
| 51 | + const { sender } = pc.addTransceiver('video'); |
| 52 | + const param = sender.getParameters(); |
| 53 | + assert_equals(param.encodings.length, 0); |
| 54 | + }, 'Not setting sendEncodings results in no mode info before negotiation'); |
124 | 55 |
|
125 | | -promise_test(async t => { |
| 56 | + promise_test(async t => { |
126 | 57 | const pc = new RTCPeerConnection(); |
127 | | - t.add_cleanup(() => pc.close()); |
128 | | - assert_throws_dom('OperationError', () => { |
129 | | - pc.addTransceiver('video', { |
130 | | - sendEncodings: [{scalabilityMode: 'TotalNonsense'}], |
| 58 | + t.add_cleanup(() => pc.close()); |
| 59 | + const { sender } = pc.addTransceiver('video', { |
| 60 | + sendEncodings: [{}], |
131 | 61 | }); |
132 | | - }); |
133 | | -}, 'Setting a scalability mode to nonsense throws an exception'); |
| 62 | + const param = sender.getParameters(); |
| 63 | + const encoding = getFirstEncoding(param); |
134 | 64 |
|
| 65 | + assert_true(!('scalabilityMode' in encoding)); |
| 66 | + }, 'Not setting a scalability mode results in no mode set before negotiation'); |
| 67 | + |
| 68 | + promise_test(async t => { |
| 69 | + const pc1 = new RTCPeerConnection(); |
| 70 | + const pc2 = new RTCPeerConnection(); |
| 71 | + t.add_cleanup(() => pc1.close()); |
| 72 | + t.add_cleanup(() => pc2.close()); |
| 73 | + const { sender } = pc1.addTransceiver('video', { |
| 74 | + sendEncodings: [{}], |
| 75 | + }); |
| 76 | + const param = sender.getParameters(); |
| 77 | + const encoding = getFirstEncoding(param); |
135 | 78 |
|
136 | | -promise_test(async t => { |
137 | | - const v = document.createElement('video'); |
138 | | - v.autoplay = true; |
139 | | - const pc1 = new RTCPeerConnection(); |
140 | | - const pc2 = new RTCPeerConnection(); |
141 | | - t.add_cleanup(() => pc1.close()); |
142 | | - t.add_cleanup(() => pc2.close()); |
143 | | - const transceiver = pc1.addTransceiver('video', { |
144 | | - sendEncodings: [{ scalabilityMode: 'L3T3' }], |
145 | | - }); |
146 | | - // Before negotiation, the mode should be preserved. |
147 | | - const param = transceiver.sender.getParameters(); |
148 | | - const encoding = getFirstEncoding(param); |
149 | | - assert_true('scalabilityMode' in encoding); |
150 | | - // If L3T3 is not supported at all, abort test. |
151 | | - assert_implements_optional(encoding.scalabilityMode === 'L3T3'); |
152 | | - // Pick a codec known to not have L3T3 support |
153 | | - const capabilities = RTCRtpSender.getCapabilities('video'); |
154 | | - const codec = capabilities.codecs.find(c => c.mimeType === 'video/VP8'); |
155 | | - assert_true(codec !== undefined); |
156 | | - transceiver.setCodecPreferences([codec]); |
157 | | - exchangeIceCandidates(pc1, pc2); |
158 | | - await exchangeOfferAnswer(pc1, pc2); |
159 | | - const sendParams = pc1.getSenders()[0].getParameters(); |
160 | | - assert_not_equals(sendParams.encodings[0].scalabilityMode, 'L3T3'); |
161 | | -}, 'L3T3 on VP8 should return something other than L3T3'); |
| 79 | + exchangeIceCandidates(pc1, pc2); |
| 80 | + await exchangeOfferAnswer(pc1, pc2); |
| 81 | + const param2 = sender.getParameters(); |
| 82 | + const encoding2 = getFirstEncoding(param); |
| 83 | + assert_true('scalabilityMode' in encoding2); |
| 84 | + }, 'Not setting a scalability mode results in some mode set after negotiation'); |
162 | 85 |
|
| 86 | + promise_test(async t => { |
| 87 | + const pc = new RTCPeerConnection(); |
| 88 | + t.add_cleanup(() => pc.close()); |
| 89 | + assert_throws_dom('OperationError', () => { |
| 90 | + pc.addTransceiver('video', { |
| 91 | + sendEncodings: [{scalabilityMode: 'TotalNonsense'}], |
| 92 | + }); |
| 93 | + }); |
| 94 | + }, 'Setting a scalability mode to nonsense throws an exception'); |
163 | 95 |
|
| 96 | + promise_test(async t => { |
| 97 | + const v = document.createElement('video'); |
| 98 | + v.autoplay = true; |
| 99 | + const pc1 = new RTCPeerConnection(); |
| 100 | + const pc2 = new RTCPeerConnection(); |
| 101 | + t.add_cleanup(() => pc1.close()); |
| 102 | + t.add_cleanup(() => pc2.close()); |
| 103 | + const transceiver = pc1.addTransceiver('video', { |
| 104 | + sendEncodings: [{ scalabilityMode: 'L3T3' }], |
| 105 | + }); |
| 106 | + // Before negotiation, the mode should be preserved. |
| 107 | + const param = transceiver.sender.getParameters(); |
| 108 | + const encoding = getFirstEncoding(param); |
| 109 | + assert_true('scalabilityMode' in encoding); |
| 110 | + // If L3T3 is not supported at all, abort test. |
| 111 | + assert_implements_optional(encoding.scalabilityMode === 'L3T3'); |
| 112 | + // Pick a codec known to not have L3T3 support |
| 113 | + const capabilities = RTCRtpSender.getCapabilities('video'); |
| 114 | + const codec = capabilities.codecs.find(c => c.mimeType === 'video/VP8'); |
| 115 | + assert_true(codec !== undefined); |
| 116 | + transceiver.setCodecPreferences([codec]); |
| 117 | + exchangeIceCandidates(pc1, pc2); |
| 118 | + await exchangeOfferAnswer(pc1, pc2); |
| 119 | + const sendParams = pc1.getSenders()[0].getParameters(); |
| 120 | + assert_not_equals(sendParams.encodings[0].scalabilityMode, 'L3T3'); |
| 121 | + }, 'L3T3 on VP8 should return something other than L3T3'); |
164 | 122 | </script> |
0 commit comments