| Soares Chen | d8b19bc | 2017-07-19 07:44:51 | [diff] [blame] | 1 | <!doctype html> |
| 2 | <meta charset=utf-8> |
| 3 | <title>RTCRtpTransceiver.prototype.setCodecPreferences</title> |
| 4 | <script src="/resources/testharness.js"></script> |
| 5 | <script src="/resources/testharnessreport.js"></script> |
| Philipp Hancke | ef0384e | 2020-09-07 09:12:42 | [diff] [blame] | 6 | <script src="./third_party/sdp/sdp.js"></script> |
| Soares Chen | d8b19bc | 2017-07-19 07:44:51 | [diff] [blame] | 7 | <script> |
| 8 | 'use strict'; |
| 9 | |
| Philipp Hancke | ef0384e | 2020-09-07 09:12:42 | [diff] [blame] | 10 | test((t) => { |
| Soares Chen | d8b19bc | 2017-07-19 07:44:51 | [diff] [blame] | 11 | const pc = new RTCPeerConnection(); |
| Philipp Hancke | ef0384e | 2020-09-07 09:12:42 | [diff] [blame] | 12 | t.add_cleanup(() => pc.close()); |
| Soares Chen | d8b19bc | 2017-07-19 07:44:51 | [diff] [blame] | 13 | const transceiver = pc.addTransceiver('audio'); |
| Blink WPT Bot | f664d06 | 2024-02-13 19:51:06 | [diff] [blame] | 14 | const capabilities = RTCRtpReceiver.getCapabilities('audio'); |
| Soares Chen | d8b19bc | 2017-07-19 07:44:51 | [diff] [blame] | 15 | transceiver.setCodecPreferences(capabilities.codecs); |
| Blink WPT Bot | f664d06 | 2024-02-13 19:51:06 | [diff] [blame] | 16 | }, `setCodecPreferences() on audio transceiver with codecs returned from RTCRtpReceiver.getCapabilities('audio') should succeed`); |
| Soares Chen | d8b19bc | 2017-07-19 07:44:51 | [diff] [blame] | 17 | |
| Philipp Hancke | ef0384e | 2020-09-07 09:12:42 | [diff] [blame] | 18 | test((t) => { |
| Soares Chen | d8b19bc | 2017-07-19 07:44:51 | [diff] [blame] | 19 | const pc = new RTCPeerConnection(); |
| Philipp Hancke | ef0384e | 2020-09-07 09:12:42 | [diff] [blame] | 20 | t.add_cleanup(() => pc.close()); |
| Soares Chen | d8b19bc | 2017-07-19 07:44:51 | [diff] [blame] | 21 | const transceiver = pc.addTransceiver('video'); |
| 22 | const capabilities = RTCRtpReceiver.getCapabilities('video'); |
| 23 | transceiver.setCodecPreferences(capabilities.codecs); |
| Soares Chen | d8b19bc | 2017-07-19 07:44:51 | [diff] [blame] | 24 | }, `setCodecPreferences() on video transceiver with codecs returned from RTCRtpReceiver.getCapabilities('video') should succeed`); |
| 25 | |
| Philipp Hancke | ef0384e | 2020-09-07 09:12:42 | [diff] [blame] | 26 | test((t) => { |
| Soares Chen | d8b19bc | 2017-07-19 07:44:51 | [diff] [blame] | 27 | const pc = new RTCPeerConnection(); |
| Philipp Hancke | ef0384e | 2020-09-07 09:12:42 | [diff] [blame] | 28 | t.add_cleanup(() => pc.close()); |
| Soares Chen | d8b19bc | 2017-07-19 07:44:51 | [diff] [blame] | 29 | const transceiver = pc.addTransceiver('audio'); |
| Soares Chen | d8b19bc | 2017-07-19 07:44:51 | [diff] [blame] | 30 | transceiver.setCodecPreferences([]); |
| Soares Chen | d8b19bc | 2017-07-19 07:44:51 | [diff] [blame] | 31 | }, `setCodecPreferences([]) should succeed`); |
| 32 | |
| Philipp Hancke | ef0384e | 2020-09-07 09:12:42 | [diff] [blame] | 33 | test((t) => { |
| Soares Chen | d8b19bc | 2017-07-19 07:44:51 | [diff] [blame] | 34 | const pc = new RTCPeerConnection(); |
| Philipp Hancke | ef0384e | 2020-09-07 09:12:42 | [diff] [blame] | 35 | t.add_cleanup(() => pc.close()); |
| Soares Chen | d8b19bc | 2017-07-19 07:44:51 | [diff] [blame] | 36 | const transceiver = pc.addTransceiver('audio'); |
| phancke@microsoft.com | 079a2cb | 2024-02-27 11:06:19 | [diff] [blame] | 37 | const capabilities = RTCRtpReceiver.getCapabilities('audio'); |
| Soares Chen | d8b19bc | 2017-07-19 07:44:51 | [diff] [blame] | 38 | const { codecs } = capabilities; |
| 39 | |
| 40 | if(codecs.length >= 2) { |
| 41 | const tmp = codecs[0]; |
| 42 | codecs[0] = codecs[1]; |
| 43 | codecs[1] = tmp; |
| 44 | } |
| 45 | |
| 46 | transceiver.setCodecPreferences(codecs); |
| Soares Chen | d8b19bc | 2017-07-19 07:44:51 | [diff] [blame] | 47 | }, `setCodecPreferences() with reordered codecs should succeed`); |
| 48 | |
| Philipp Hancke | ef0384e | 2020-09-07 09:12:42 | [diff] [blame] | 49 | test((t) => { |
| Soares Chen | d8b19bc | 2017-07-19 07:44:51 | [diff] [blame] | 50 | const pc = new RTCPeerConnection(); |
| Philipp Hancke | ef0384e | 2020-09-07 09:12:42 | [diff] [blame] | 51 | t.add_cleanup(() => pc.close()); |
| Harald Alvestrand | 3130f02 | 2020-02-06 10:50:27 | [diff] [blame] | 52 | const transceiver = pc.addTransceiver('video'); |
| Blink WPT Bot | f664d06 | 2024-02-13 19:51:06 | [diff] [blame] | 53 | const capabilities = RTCRtpReceiver.getCapabilities('video'); |
| Harald Alvestrand | 3130f02 | 2020-02-06 10:50:27 | [diff] [blame] | 54 | const { codecs } = capabilities; |
| 55 | // This test verifies that the mandatory VP8 codec is present |
| Blink WPT Bot | f664d06 | 2024-02-13 19:51:06 | [diff] [blame] | 56 | // and can be preferred. |
| 57 | const codec = codecs.find(c => c.mimeType === 'video/VP8'); |
| 58 | assert_true(!!codec, 'VP8 video codec was found'); |
| 59 | transceiver.setCodecPreferences([codec]); |
| youennf | b8ff087 | 2020-09-03 08:35:01 | [diff] [blame] | 60 | }, `setCodecPreferences() with only VP8 should succeed`); |
| 61 | |
| 62 | test(() => { |
| 63 | const pc = new RTCPeerConnection(); |
| 64 | const transceiver = pc.addTransceiver('video'); |
| Blink WPT Bot | f664d06 | 2024-02-13 19:51:06 | [diff] [blame] | 65 | const capabilities = RTCRtpReceiver.getCapabilities('video'); |
| youennf | b8ff087 | 2020-09-03 08:35:01 | [diff] [blame] | 66 | const { codecs } = capabilities; |
| 67 | // This test verifies that the mandatory H264 codec is present |
| Blink WPT Bot | f664d06 | 2024-02-13 19:51:06 | [diff] [blame] | 68 | // and can be preferred. |
| 69 | const codec = codecs.find(c => c.mimeType === 'video/H264'); |
| 70 | assert_true(!!codec, 'H264 video codec was found'); |
| 71 | transceiver.setCodecPreferences([codec]); |
| youennf | b8ff087 | 2020-09-03 08:35:01 | [diff] [blame] | 72 | }, `setCodecPreferences() with only H264 should succeed`); |
| 73 | |
| 74 | async function getRTPMapLinesWithCodecAsFirst(firstCodec) |
| 75 | { |
| Blink WPT Bot | f664d06 | 2024-02-13 19:51:06 | [diff] [blame] | 76 | const codecs = RTCRtpReceiver.getCapabilities('video').codecs; |
| 77 | codecs.forEach((codec, idx) => { |
| youennf | b8ff087 | 2020-09-03 08:35:01 | [diff] [blame] | 78 | if (codec.mimeType === firstCodec) { |
| Blink WPT Bot | f664d06 | 2024-02-13 19:51:06 | [diff] [blame] | 79 | codecs.splice(idx, 1); |
| 80 | codecs.unshift(codec); |
| youennf | b8ff087 | 2020-09-03 08:35:01 | [diff] [blame] | 81 | } |
| 82 | }); |
| 83 | |
| 84 | const pc = new RTCPeerConnection(); |
| 85 | const transceiver = pc.addTransceiver('video'); |
| Blink WPT Bot | f664d06 | 2024-02-13 19:51:06 | [diff] [blame] | 86 | transceiver.setCodecPreferences(codecs); |
| youennf | b8ff087 | 2020-09-03 08:35:01 | [diff] [blame] | 87 | const offer = await pc.createOffer(); |
| 88 | |
| Blink WPT Bot | f664d06 | 2024-02-13 19:51:06 | [diff] [blame] | 89 | return offer.sdp.split('\r\n').filter(line => line.startsWith('a=rtpmap:')); |
| youennf | b8ff087 | 2020-09-03 08:35:01 | [diff] [blame] | 90 | } |
| 91 | |
| 92 | promise_test(async () => { |
| 93 | const lines = await getRTPMapLinesWithCodecAsFirst('video/H264'); |
| 94 | |
| 95 | assert_greater_than(lines.length, 1); |
| Blink WPT Bot | f664d06 | 2024-02-13 19:51:06 | [diff] [blame] | 96 | assert_true(lines[0].indexOf('H264') !== -1, 'H264 should be the first codec'); |
| youennf | b8ff087 | 2020-09-03 08:35:01 | [diff] [blame] | 97 | }, `setCodecPreferences() should allow setting H264 as first codec`); |
| 98 | |
| 99 | promise_test(async () => { |
| 100 | const lines = await getRTPMapLinesWithCodecAsFirst('video/VP8'); |
| 101 | |
| 102 | assert_greater_than(lines.length, 1); |
| Blink WPT Bot | f664d06 | 2024-02-13 19:51:06 | [diff] [blame] | 103 | assert_true(lines[0].indexOf('VP8') !== -1, 'VP8 should be the first codec'); |
| youennf | b8ff087 | 2020-09-03 08:35:01 | [diff] [blame] | 104 | }, `setCodecPreferences() should allow setting VP8 as first codec`); |
| Harald Alvestrand | 3130f02 | 2020-02-06 10:50:27 | [diff] [blame] | 105 | |
| Philipp Hancke | ef0384e | 2020-09-07 09:12:42 | [diff] [blame] | 106 | test((t) => { |
| Harald Alvestrand | 3130f02 | 2020-02-06 10:50:27 | [diff] [blame] | 107 | const pc = new RTCPeerConnection(); |
| Philipp Hancke | ef0384e | 2020-09-07 09:12:42 | [diff] [blame] | 108 | t.add_cleanup(() => pc.close()); |
| Soares Chen | d8b19bc | 2017-07-19 07:44:51 | [diff] [blame] | 109 | const transceiver = pc.addTransceiver('audio'); |
| Blink WPT Bot | f664d06 | 2024-02-13 19:51:06 | [diff] [blame] | 110 | const capabilities = RTCRtpReceiver.getCapabilities('video'); |
| Stephen McGruer | d510304 | 2020-01-23 21:45:45 | [diff] [blame] | 111 | assert_throws_dom('InvalidModificationError', () => transceiver.setCodecPreferences(capabilities.codecs)); |
| Florent Castelli | dd2829c | 2019-05-08 15:36:36 | [diff] [blame] | 112 | }, `setCodecPreferences() on audio transceiver with codecs returned from getCapabilities('video') should throw InvalidModificationError`); |
| 113 | |
| Philipp Hancke | ef0384e | 2020-09-07 09:12:42 | [diff] [blame] | 114 | test((t) => { |
| Florent Castelli | dd2829c | 2019-05-08 15:36:36 | [diff] [blame] | 115 | const pc = new RTCPeerConnection(); |
| Philipp Hancke | ef0384e | 2020-09-07 09:12:42 | [diff] [blame] | 116 | t.add_cleanup(() => pc.close()); |
| Florent Castelli | dd2829c | 2019-05-08 15:36:36 | [diff] [blame] | 117 | const transceiver = pc.addTransceiver('audio'); |
| 118 | const codecs = [{ |
| 119 | mimeType: 'data', |
| 120 | clockRate: 2000, |
| 121 | channels: 2, |
| 122 | sdpFmtpLine: '0-15' |
| 123 | }]; |
| 124 | |
| Stephen McGruer | d510304 | 2020-01-23 21:45:45 | [diff] [blame] | 125 | assert_throws_dom('InvalidModificationError', () => transceiver.setCodecPreferences(codecs)); |
| Florent Castelli | dd2829c | 2019-05-08 15:36:36 | [diff] [blame] | 126 | }, `setCodecPreferences() with user defined codec with invalid mimeType should throw InvalidModificationError`); |
| Soares Chen | d8b19bc | 2017-07-19 07:44:51 | [diff] [blame] | 127 | |
| Philipp Hancke | ef0384e | 2020-09-07 09:12:42 | [diff] [blame] | 128 | test((t) => { |
| Soares Chen | d8b19bc | 2017-07-19 07:44:51 | [diff] [blame] | 129 | const pc = new RTCPeerConnection(); |
| Philipp Hancke | ef0384e | 2020-09-07 09:12:42 | [diff] [blame] | 130 | t.add_cleanup(() => pc.close()); |
| Soares Chen | d8b19bc | 2017-07-19 07:44:51 | [diff] [blame] | 131 | const transceiver = pc.addTransceiver('audio'); |
| 132 | const codecs = [{ |
| 133 | mimeType: 'audio/piepiper', |
| 134 | clockRate: 2000, |
| 135 | channels: 2, |
| Florent Castelli | dd2829c | 2019-05-08 15:36:36 | [diff] [blame] | 136 | sdpFmtpLine: '0-15' |
| Soares Chen | d8b19bc | 2017-07-19 07:44:51 | [diff] [blame] | 137 | }]; |
| 138 | |
| Stephen McGruer | d510304 | 2020-01-23 21:45:45 | [diff] [blame] | 139 | assert_throws_dom('InvalidModificationError', () => transceiver.setCodecPreferences(codecs)); |
| Florent Castelli | dd2829c | 2019-05-08 15:36:36 | [diff] [blame] | 140 | }, `setCodecPreferences() with user defined codec should throw InvalidModificationError`); |
| Soares Chen | d8b19bc | 2017-07-19 07:44:51 | [diff] [blame] | 141 | |
| Philipp Hancke | ef0384e | 2020-09-07 09:12:42 | [diff] [blame] | 142 | test((t) => { |
| Soares Chen | d8b19bc | 2017-07-19 07:44:51 | [diff] [blame] | 143 | const pc = new RTCPeerConnection(); |
| Philipp Hancke | ef0384e | 2020-09-07 09:12:42 | [diff] [blame] | 144 | t.add_cleanup(() => pc.close()); |
| Soares Chen | d8b19bc | 2017-07-19 07:44:51 | [diff] [blame] | 145 | const transceiver = pc.addTransceiver('audio'); |
| Blink WPT Bot | f664d06 | 2024-02-13 19:51:06 | [diff] [blame] | 146 | const capabilities = RTCRtpReceiver.getCapabilities('audio'); |
| Soares Chen | d8b19bc | 2017-07-19 07:44:51 | [diff] [blame] | 147 | const codecs = [ |
| 148 | ...capabilities.codecs, |
| 149 | { |
| 150 | mimeType: 'audio/piepiper', |
| 151 | clockRate: 2000, |
| 152 | channels: 2, |
| Florent Castelli | dd2829c | 2019-05-08 15:36:36 | [diff] [blame] | 153 | sdpFmtpLine: '0-15' |
| Soares Chen | d8b19bc | 2017-07-19 07:44:51 | [diff] [blame] | 154 | }]; |
| 155 | |
| Stephen McGruer | d510304 | 2020-01-23 21:45:45 | [diff] [blame] | 156 | assert_throws_dom('InvalidModificationError', () => transceiver.setCodecPreferences(codecs)); |
| Florent Castelli | dd2829c | 2019-05-08 15:36:36 | [diff] [blame] | 157 | }, `setCodecPreferences() with user defined codec together with codecs returned from getCapabilities() should throw InvalidModificationError`); |
| 158 | |
| Philipp Hancke | ef0384e | 2020-09-07 09:12:42 | [diff] [blame] | 159 | test((t) => { |
| Florent Castelli | dd2829c | 2019-05-08 15:36:36 | [diff] [blame] | 160 | const pc = new RTCPeerConnection(); |
| Philipp Hancke | ef0384e | 2020-09-07 09:12:42 | [diff] [blame] | 161 | t.add_cleanup(() => pc.close()); |
| Florent Castelli | dd2829c | 2019-05-08 15:36:36 | [diff] [blame] | 162 | const transceiver = pc.addTransceiver('audio'); |
| Blink WPT Bot | f664d06 | 2024-02-13 19:51:06 | [diff] [blame] | 163 | const capabilities = RTCRtpReceiver.getCapabilities('audio'); |
| Florent Castelli | dd2829c | 2019-05-08 15:36:36 | [diff] [blame] | 164 | const codecs = [capabilities.codecs[0]]; |
| 165 | codecs[0].clockRate = codecs[0].clockRate / 2; |
| 166 | |
| Stephen McGruer | d510304 | 2020-01-23 21:45:45 | [diff] [blame] | 167 | assert_throws_dom('InvalidModificationError', () => transceiver.setCodecPreferences(codecs)); |
| Florent Castelli | dd2829c | 2019-05-08 15:36:36 | [diff] [blame] | 168 | }, `setCodecPreferences() with modified codec clock rate should throw InvalidModificationError`); |
| 169 | |
| Philipp Hancke | ef0384e | 2020-09-07 09:12:42 | [diff] [blame] | 170 | test((t) => { |
| Florent Castelli | dd2829c | 2019-05-08 15:36:36 | [diff] [blame] | 171 | const pc = new RTCPeerConnection(); |
| Philipp Hancke | ef0384e | 2020-09-07 09:12:42 | [diff] [blame] | 172 | t.add_cleanup(() => pc.close()); |
| Florent Castelli | dd2829c | 2019-05-08 15:36:36 | [diff] [blame] | 173 | const transceiver = pc.addTransceiver('audio'); |
| Blink WPT Bot | f664d06 | 2024-02-13 19:51:06 | [diff] [blame] | 174 | const capabilities = RTCRtpReceiver.getCapabilities('audio'); |
| Florent Castelli | dd2829c | 2019-05-08 15:36:36 | [diff] [blame] | 175 | const codecs = [capabilities.codecs[0]]; |
| 176 | codecs[0].channels = codecs[0].channels + 11; |
| 177 | |
| Stephen McGruer | d510304 | 2020-01-23 21:45:45 | [diff] [blame] | 178 | assert_throws_dom('InvalidModificationError', () => transceiver.setCodecPreferences(codecs)); |
| Florent Castelli | dd2829c | 2019-05-08 15:36:36 | [diff] [blame] | 179 | }, `setCodecPreferences() with modified codec channel count should throw InvalidModificationError`); |
| 180 | |
| Philipp Hancke | ef0384e | 2020-09-07 09:12:42 | [diff] [blame] | 181 | test((t) => { |
| Florent Castelli | dd2829c | 2019-05-08 15:36:36 | [diff] [blame] | 182 | const pc = new RTCPeerConnection(); |
| Philipp Hancke | ef0384e | 2020-09-07 09:12:42 | [diff] [blame] | 183 | t.add_cleanup(() => pc.close()); |
| Florent Castelli | dd2829c | 2019-05-08 15:36:36 | [diff] [blame] | 184 | const transceiver = pc.addTransceiver('audio'); |
| Blink WPT Bot | f664d06 | 2024-02-13 19:51:06 | [diff] [blame] | 185 | const capabilities = RTCRtpReceiver.getCapabilities('audio'); |
| Florent Castelli | dd2829c | 2019-05-08 15:36:36 | [diff] [blame] | 186 | const codecs = [capabilities.codecs[0]]; |
| 187 | codecs[0].sdpFmtpLine = "modifiedparameter=1"; |
| 188 | |
| Stephen McGruer | d510304 | 2020-01-23 21:45:45 | [diff] [blame] | 189 | assert_throws_dom('InvalidModificationError', () => transceiver.setCodecPreferences(codecs)); |
| Florent Castelli | dd2829c | 2019-05-08 15:36:36 | [diff] [blame] | 190 | }, `setCodecPreferences() with modified codec parameters should throw InvalidModificationError`); |
| Soares Chen | d8b19bc | 2017-07-19 07:44:51 | [diff] [blame] | 191 | |
| Philipp Hancke | ef0384e | 2020-09-07 09:12:42 | [diff] [blame] | 192 | test((t) => { |
| Soares Chen | d8b19bc | 2017-07-19 07:44:51 | [diff] [blame] | 193 | const pc = new RTCPeerConnection(); |
| Philipp Hancke | ef0384e | 2020-09-07 09:12:42 | [diff] [blame] | 194 | t.add_cleanup(() => pc.close()); |
| Soares Chen | d8b19bc | 2017-07-19 07:44:51 | [diff] [blame] | 195 | const transceiver = pc.addTransceiver('audio'); |
| Blink WPT Bot | f664d06 | 2024-02-13 19:51:06 | [diff] [blame] | 196 | const capabilities = RTCRtpReceiver.getCapabilities('audio'); |
| Soares Chen | d8b19bc | 2017-07-19 07:44:51 | [diff] [blame] | 197 | |
| 198 | const { codecs } = capabilities; |
| 199 | assert_greater_than(codecs.length, 0, |
| 200 | 'Expect at least one codec available'); |
| 201 | |
| 202 | const [ codec ] = codecs; |
| 203 | const { channels=2 } = codec; |
| 204 | codec.channels = channels+1; |
| 205 | |
| Stephen McGruer | d510304 | 2020-01-23 21:45:45 | [diff] [blame] | 206 | assert_throws_dom('InvalidModificationError', () => transceiver.setCodecPreferences(codecs)); |
| Florent Castelli | dd2829c | 2019-05-08 15:36:36 | [diff] [blame] | 207 | }, `setCodecPreferences() with modified codecs returned from getCapabilities() should throw InvalidModificationError`); |
| Soares Chen | d8b19bc | 2017-07-19 07:44:51 | [diff] [blame] | 208 | |
| Philipp Hancke | ef0384e | 2020-09-07 09:12:42 | [diff] [blame] | 209 | promise_test(async (t) => { |
| 210 | const pc = new RTCPeerConnection(); |
| 211 | t.add_cleanup(() => pc.close()); |
| 212 | const transceiver = pc.addTransceiver('audio'); |
| Blink WPT Bot | f664d06 | 2024-02-13 19:51:06 | [diff] [blame] | 213 | const {codecs} = RTCRtpReceiver.getCapabilities('audio'); |
| Philipp Hancke | ef0384e | 2020-09-07 09:12:42 | [diff] [blame] | 214 | // Reorder codecs, put PCMU/PCMA first. |
| 215 | let firstCodec; |
| 216 | let i; |
| 217 | for (i = 0; i < codecs.length; i++) { |
| 218 | const codec = codecs[i]; |
| 219 | if (codec.mimeType === 'audio/PCMU' || codec.mimeType === 'audio/PCMA') { |
| 220 | codecs.splice(i, 1); |
| 221 | codecs.unshift(codec); |
| 222 | firstCodec = codec.mimeType.substr(6); |
| 223 | break; |
| 224 | } |
| 225 | } |
| 226 | assert_not_equals(firstCodec, undefined, 'PCMU or PCMA codec not found'); |
| 227 | transceiver.setCodecPreferences(codecs); |
| 228 | |
| 229 | const offer = await pc.createOffer(); |
| 230 | const mediaSection = SDPUtils.getMediaSections(offer.sdp)[0]; |
| 231 | const rtpParameters = SDPUtils.parseRtpParameters(mediaSection); |
| 232 | assert_equals(rtpParameters.codecs[0].name, firstCodec); |
| 233 | }, `setCodecPreferences() modifies the order of audio codecs in createOffer`); |
| 234 | |
| 235 | promise_test(async (t) => { |
| 236 | const pc = new RTCPeerConnection(); |
| 237 | t.add_cleanup(() => pc.close()); |
| 238 | const transceiver = pc.addTransceiver('video'); |
| Blink WPT Bot | f664d06 | 2024-02-13 19:51:06 | [diff] [blame] | 239 | const {codecs} = RTCRtpReceiver.getCapabilities('video'); |
| Philipp Hancke | ef0384e | 2020-09-07 09:12:42 | [diff] [blame] | 240 | // Reorder codecs, swap H264 and VP8. |
| 241 | let vp8 = -1; |
| 242 | let h264 = -1; |
| 243 | let firstCodec; |
| 244 | let i; |
| 245 | for (i = 0; i < codecs.length; i++) { |
| 246 | const codec = codecs[i]; |
| youennf | f8d620c | 2022-07-29 15:11:26 | [diff] [blame] | 247 | if (codec.mimeType === 'video/VP8' && vp8 === -1) { |
| Philipp Hancke | ef0384e | 2020-09-07 09:12:42 | [diff] [blame] | 248 | vp8 = i; |
| 249 | if (h264 !== -1) { |
| 250 | codecs[vp8] = codecs[h264]; |
| 251 | codecs[h264] = codec; |
| 252 | firstCodec = 'VP8'; |
| 253 | break; |
| 254 | } |
| 255 | } |
| youennf | f8d620c | 2022-07-29 15:11:26 | [diff] [blame] | 256 | if (codec.mimeType === 'video/H264' && h264 === -1) { |
| Philipp Hancke | ef0384e | 2020-09-07 09:12:42 | [diff] [blame] | 257 | h264 = i; |
| 258 | if (vp8 !== -1) { |
| 259 | codecs[h264] = codecs[vp8]; |
| 260 | codecs[vp8] = codec; |
| 261 | firstCodec = 'H264'; |
| 262 | break; |
| 263 | } |
| 264 | } |
| 265 | } |
| 266 | assert_not_equals(firstCodec, undefined, 'VP8 and H264 codecs not found'); |
| 267 | transceiver.setCodecPreferences(codecs); |
| 268 | |
| 269 | const offer = await pc.createOffer(); |
| 270 | const mediaSection = SDPUtils.getMediaSections(offer.sdp)[0]; |
| 271 | const rtpParameters = SDPUtils.parseRtpParameters(mediaSection); |
| 272 | assert_equals(rtpParameters.codecs[0].name, firstCodec); |
| 273 | }, `setCodecPreferences() modifies the order of video codecs in createOffer`); |
| 274 | |
| Philipp Hancke | 8d6d3ba | 2025-01-22 15:41:01 | [diff] [blame] | 275 | ['rtx', 'red', 'ulpfec'].forEach(resiliencyMechanism => { |
| 276 | promise_test(async (t) => { |
| 277 | const pc = new RTCPeerConnection(); |
| 278 | t.add_cleanup(() => pc.close()); |
| 279 | const transceiver = pc.addTransceiver('video'); |
| 280 | const {codecs} = RTCRtpReceiver.getCapabilities('video'); |
| 281 | const filteredCodecs = codecs. |
| 282 | filter(codec => codec.mimeType !== 'video/' + resiliencyMechanism); |
| 283 | assert_not_equals(codecs.length, filteredCodecs.length); |
| 284 | transceiver.setCodecPreferences(filteredCodecs); |
| 285 | |
| 286 | const offer = await pc.createOffer(); |
| 287 | const mediaSection = SDPUtils.getMediaSections(offer.sdp)[0]; |
| 288 | const rtpParameters = SDPUtils.parseRtpParameters(mediaSection); |
| 289 | assert_equals(rtpParameters.codecs.find(codec => codec.name === resiliencyMechanism), |
| 290 | undefined); |
| 291 | }, `setCodecPreferences() can remove ${resiliencyMechanism}`); |
| 292 | }); |
| 293 | |
| Philipp Hancke | 89d651c | 2024-02-21 12:06:07 | [diff] [blame] | 294 | // Tests the note removed as result of discussion in |
| 295 | // https://github.com/w3c/webrtc-pc/issues/2933 |
| 296 | promise_test(async (t) => { |
| 297 | const pc1 = new RTCPeerConnection(); |
| 298 | t.add_cleanup(() => pc1.close()); |
| 299 | const pc2 = new RTCPeerConnection(); |
| 300 | t.add_cleanup(() => pc2.close()); |
| 301 | |
| 302 | const transceiver = pc1.addTransceiver('video'); |
| 303 | const {codecs} = RTCRtpReceiver.getCapabilities('video'); |
| 304 | const vp8 = codecs.find(codec => codec.mimeType === 'video/VP8'); |
| 305 | const h264 = codecs.find(codec => codec.mimeType === 'video/H264'); |
| 306 | const thirdCodec = codecs.find(codec => ['video/VP9', 'video/AV1'].includes(codec.mimeType)); |
| 307 | assert_true(!!vp8); |
| 308 | assert_true(!!h264); |
| 309 | assert_true(!!thirdCodec); |
| 310 | |
| 311 | transceiver.setCodecPreferences([vp8, thirdCodec]); |
| 312 | await pc1.setLocalDescription(); |
| 313 | await pc2.setRemoteDescription(pc1.localDescription); |
| 314 | const transceiver2 = pc2.getTransceivers()[0]; |
| 315 | transceiver2.setCodecPreferences([h264, thirdCodec, vp8]); |
| 316 | await pc2.setLocalDescription(); |
| 317 | await pc1.setRemoteDescription(pc2.localDescription); |
| 318 | const mediaSection = SDPUtils.getMediaSections(pc2.localDescription.sdp)[0]; |
| 319 | const rtpParameters = SDPUtils.parseRtpParameters(mediaSection); |
| 320 | // Order is determined by pc2 but H264 is not present. |
| 321 | assert_equals(rtpParameters.codecs.length, 2); |
| 322 | assert_equals(rtpParameters.codecs[0].name, thirdCodec.mimeType.substring(6)); |
| 323 | assert_equals(rtpParameters.codecs[1].name, 'VP8'); |
| 324 | |
| 325 | }, `setCodecPreferences() filters on receiver and prefers receiver order`); |
| 326 | |
| Dan Baker | 06fc5f7 | 2024-05-29 00:13:01 | [diff] [blame] | 327 | ["audio", "video"].forEach(kind => promise_test(async (t) => { |
| 328 | const pc = new RTCPeerConnection(); |
| 329 | t.add_cleanup(() => pc.close()); |
| 330 | const [codec] = RTCRtpReceiver.getCapabilities(kind).codecs; |
| 331 | codec.mimeType = codec.mimeType.toUpperCase(); |
| 332 | const transceiver = pc.addTransceiver(kind); |
| 333 | transceiver.setCodecPreferences([codec]); |
| 334 | |
| 335 | codec.mimeType = codec.mimeType.toLowerCase(); |
| 336 | transceiver.setCodecPreferences([codec]); |
| 337 | }, `setCodecPreferences should accept ${kind} codecs regardless of mimeType case`)); |
| 338 | |
| Soares Chen | d8b19bc | 2017-07-19 07:44:51 | [diff] [blame] | 339 | </script> |