blob: fdb584460f862825f2c695ec3cff678c14503fb4 [file] [log] [blame]
Soares Chen172fe9d2017-07-18 09:30:181<!doctype html>
2<meta charset=utf-8>
3<title>RTCRtpParameters codecs</title>
4<script src="/resources/testharness.js"></script>
5<script src="/resources/testharnessreport.js"></script>
6<script src="dictionary-helper.js"></script>
7<script src="RTCRtpParameters-helper.js"></script>
8<script>
9 'use strict';
10
11 // Test is based on the following editor draft:
12 // https://w3c.github.io/webrtc-pc/archives/20170605/webrtc.html
13
14 // The following helper functions are called from RTCRtpParameters-helper.js:
Henrik Boström36fb0332018-06-29 09:09:0415 // doOfferAnswerExchange
Soares Chen172fe9d2017-07-18 09:30:1816 // validateSenderRtpParameters
17
18 /*
19 5.2. RTCRtpSender Interface
20 interface RTCRtpSender {
21 Promise<void> setParameters(optional RTCRtpParameters parameters);
22 RTCRtpParameters getParameters();
23 };
24
25 dictionary RTCRtpParameters {
26 DOMString transactionId;
27 sequence<RTCRtpEncodingParameters> encodings;
28 sequence<RTCRtpHeaderExtensionParameters> headerExtensions;
29 RTCRtcpParameters rtcp;
30 sequence<RTCRtpCodecParameters> codecs;
31 RTCDegradationPreference degradationPreference;
32 };
33
34 dictionary RTCRtpCodecParameters {
35 [readonly]
36 unsigned short payloadType;
37
38 [readonly]
39 DOMString mimeType;
40
41 [readonly]
42 unsigned long clockRate;
43
44 [readonly]
45 unsigned short channels;
46
47 [readonly]
48 DOMString sdpFmtpLine;
49 };
50
51 getParameters
52 - The codecs sequence is populated based on the codecs that have been negotiated
53 for sending, and which the user agent is currently capable of sending.
54
55 If setParameters has removed or reordered codecs, getParameters MUST return
56 the shortened/reordered list. However, every time codecs are renegotiated by
57 a new offer/answer exchange, the list of codecs MUST be restored to the full
58 negotiated set, in the priority order indicated by the remote description,
59 in effect discarding the effects of setParameters.
60
61 codecs
62 - When using the setParameters method, the codecs sequence from the corresponding
63 call to getParameters can be reordered and entries can be removed, but entries
64 cannot be added, and the RTCRtpCodecParameters dictionary members cannot be modified.
65 */
66
67 // Get the first codec from param.codecs.
68 // Assert that param.codecs has at least one element
69 function getFirstCodec(param) {
70 const { codecs } = param;
71 assert_greater_than(codecs.length, 0);
72 return codecs[0];
73 }
74
75 /*
76 5.2. setParameters
77 7. If parameters.encodings.length is different from N, or if any parameter
78 in the parameters argument, marked as a Read-only parameter, has a value
79 that is different from the corresponding parameter value returned from
80 sender.getParameters(), abort these steps and return a promise rejected
81 with a newly created InvalidModificationError. Note that this also applies
82 to transactionId.
83 */
Henrik Boström36fb0332018-06-29 09:09:0484 promise_test(async t => {
Soares Chen172fe9d2017-07-18 09:30:1885 const pc = new RTCPeerConnection();
Philipp Hancke1622a022018-06-11 10:00:5386 t.add_cleanup(() => pc.close());
Henrik Boström36fb0332018-06-29 09:09:0487
Soares Chen172fe9d2017-07-18 09:30:1888 const { sender } = pc.addTransceiver('audio');
Henrik Boström36fb0332018-06-29 09:09:0489 await doOfferAnswerExchange(t, pc);
90
Soares Chen172fe9d2017-07-18 09:30:1891 const param = sender.getParameters();
92 validateSenderRtpParameters(param);
93
94 const codec = getFirstCodec(param);
95
96 if(codec.payloadType === undefined) {
97 codec.payloadType = 8;
98 } else {
99 codec.payloadType += 1;
100 }
101
Boris Zbarskyb7f2dd32020-02-04 21:26:48102 return promise_rejects_dom(t, 'InvalidModificationError',
Soares Chen172fe9d2017-07-18 09:30:18103 sender.setParameters(param));
Soares Chen172fe9d2017-07-18 09:30:18104 }, 'setParameters() with codec.payloadType modified should reject with InvalidModificationError');
105
Henrik Boström36fb0332018-06-29 09:09:04106 promise_test(async t => {
Soares Chen172fe9d2017-07-18 09:30:18107 const pc = new RTCPeerConnection();
Philipp Hancke1622a022018-06-11 10:00:53108 t.add_cleanup(() => pc.close());
Soares Chen172fe9d2017-07-18 09:30:18109 const { sender } = pc.addTransceiver('audio');
Henrik Boström36fb0332018-06-29 09:09:04110 await doOfferAnswerExchange(t, pc);
Soares Chen172fe9d2017-07-18 09:30:18111 const param = sender.getParameters();
112 validateSenderRtpParameters(param);
113
114 const codec = getFirstCodec(param);
115
116 if(codec.mimeType === undefined) {
117 codec.mimeType = 'audio/piedpiper';
118 } else {
119 codec.mimeType = `${codec.mimeType}-modified`;
120 }
121
Boris Zbarskyb7f2dd32020-02-04 21:26:48122 return promise_rejects_dom(t, 'InvalidModificationError',
Soares Chen172fe9d2017-07-18 09:30:18123 sender.setParameters(param));
Soares Chen172fe9d2017-07-18 09:30:18124 }, 'setParameters() with codec.mimeType modified should reject with InvalidModificationError');
125
Henrik Boström36fb0332018-06-29 09:09:04126 promise_test(async t => {
Soares Chen172fe9d2017-07-18 09:30:18127 const pc = new RTCPeerConnection();
Philipp Hancke1622a022018-06-11 10:00:53128 t.add_cleanup(() => pc.close());
Soares Chen172fe9d2017-07-18 09:30:18129 const { sender } = pc.addTransceiver('audio');
Henrik Boström36fb0332018-06-29 09:09:04130 await doOfferAnswerExchange(t, pc);
Soares Chen172fe9d2017-07-18 09:30:18131 const param = sender.getParameters();
132 validateSenderRtpParameters(param);
133
134 const codec = getFirstCodec(param);
135
136 if(codec.clockRate === undefined) {
137 codec.clockRate = 8000;
138 } else {
139 codec.clockRate += 1;
140 }
141
Boris Zbarskyb7f2dd32020-02-04 21:26:48142 return promise_rejects_dom(t, 'InvalidModificationError',
Soares Chen172fe9d2017-07-18 09:30:18143 sender.setParameters(param));
Soares Chen172fe9d2017-07-18 09:30:18144 }, 'setParameters() with codec.clockRate modified should reject with InvalidModificationError');
145
Henrik Boström36fb0332018-06-29 09:09:04146 promise_test(async t => {
Soares Chen172fe9d2017-07-18 09:30:18147 const pc = new RTCPeerConnection();
Philipp Hancke1622a022018-06-11 10:00:53148 t.add_cleanup(() => pc.close());
Soares Chen172fe9d2017-07-18 09:30:18149 const { sender } = pc.addTransceiver('audio');
Henrik Boström36fb0332018-06-29 09:09:04150 await doOfferAnswerExchange(t, pc);
Soares Chen172fe9d2017-07-18 09:30:18151 const param = sender.getParameters();
152 validateSenderRtpParameters(param);
153
154 const codec = getFirstCodec(param);
155
156 if(codec.channels === undefined) {
157 codec.channels = 6;
158 } else {
159 codec.channels += 1;
160 }
161
Boris Zbarskyb7f2dd32020-02-04 21:26:48162 return promise_rejects_dom(t, 'InvalidModificationError',
Soares Chen172fe9d2017-07-18 09:30:18163 sender.setParameters(param));
Soares Chen172fe9d2017-07-18 09:30:18164 }, 'setParameters() with codec.channels modified should reject with InvalidModificationError');
165
Henrik Boström36fb0332018-06-29 09:09:04166 promise_test(async t => {
Soares Chen172fe9d2017-07-18 09:30:18167 const pc = new RTCPeerConnection();
Philipp Hancke1622a022018-06-11 10:00:53168 t.add_cleanup(() => pc.close());
Soares Chen172fe9d2017-07-18 09:30:18169 const { sender } = pc.addTransceiver('audio');
Henrik Boström36fb0332018-06-29 09:09:04170 await doOfferAnswerExchange(t, pc);
Soares Chen172fe9d2017-07-18 09:30:18171 const param = sender.getParameters();
172 validateSenderRtpParameters(param);
173
174 const codec = getFirstCodec(param);
175
176 if(codec.sdpFmtpLine === undefined) {
177 codec.sdpFmtpLine = 'a=fmtp:98 0-15';
178 } else {
179 codec.sdpFmtpLine = `${codec.sdpFmtpLine};foo=1`;
180 }
181
Boris Zbarskyb7f2dd32020-02-04 21:26:48182 return promise_rejects_dom(t, 'InvalidModificationError',
Soares Chen172fe9d2017-07-18 09:30:18183 sender.setParameters(param));
Soares Chen172fe9d2017-07-18 09:30:18184 }, 'setParameters() with codec.sdpFmtpLine modified should reject with InvalidModificationError');
185
Henrik Boström36fb0332018-06-29 09:09:04186 promise_test(async t => {
Soares Chen172fe9d2017-07-18 09:30:18187 const pc = new RTCPeerConnection();
Philipp Hancke1622a022018-06-11 10:00:53188 t.add_cleanup(() => pc.close());
Soares Chen172fe9d2017-07-18 09:30:18189 const { sender } = pc.addTransceiver('audio');
Henrik Boström36fb0332018-06-29 09:09:04190 await doOfferAnswerExchange(t, pc);
Soares Chen172fe9d2017-07-18 09:30:18191 const param = sender.getParameters();
192 validateSenderRtpParameters(param);
193
194 const { codecs } = param;
195
196 codecs.push({
197 payloadType: 2,
198 mimeType: 'audio/piedpiper',
199 clockRate: 1000,
200 channels: 2
201 });
202
Boris Zbarskyb7f2dd32020-02-04 21:26:48203 return promise_rejects_dom(t, 'InvalidModificationError',
Soares Chen172fe9d2017-07-18 09:30:18204 sender.setParameters(param));
Soares Chen172fe9d2017-07-18 09:30:18205 }, 'setParameters() with new codecs inserted should reject with InvalidModificationError');
206
Soares Chen172fe9d2017-07-18 09:30:18207</script>