decodingInfo-webrtc.any.js (9929B)
1 // META: timeout=long 2 'use strict'; 3 4 const isWorkerEnvironment = typeof self.WorkerGlobalScope !== 'undefined'; 5 6 // Minimal VideoConfiguration that will be allowed per spec. All optional 7 // properties are missing. 8 const minimalVideoConfiguration = { 9 contentType: 'video/VP9; profile-level="0"', 10 width: 800, 11 height: 600, 12 bitrate: 3000, 13 framerate: 24, 14 }; 15 16 // Minimal AudioConfiguration that will be allowed per spec. All optional 17 // properties are missing. 18 const minimalAudioConfiguration = { 19 contentType: 'audio/opus', 20 }; 21 22 const videoConfigurationWithDynamicRange = { 23 contentType: 'video/webm; codecs="vp09.00.10.08.00.09.16.09.00"', 24 width: 800, 25 height: 600, 26 bitrate: 3000, 27 framerate: 24, 28 hdrMetadataType: 'smpteSt2086', 29 colorGamut: 'rec2020', 30 transferFunction: 'pq', 31 }; 32 33 promise_test(t => { 34 return promise_rejects_js(t, TypeError, navigator.mediaCapabilities.decodingInfo({ 35 type: 'webrtc', 36 })); 37 }, "Test that decodingInfo rejects if the configuration doesn't have an audio or video field"); 38 39 promise_test(t => { 40 return promise_rejects_js(t, TypeError, navigator.mediaCapabilities.decodingInfo({ 41 type: 'webrtc', 42 video: { 43 contentType: 'video/VP9', 44 width: 800, 45 height: 600, 46 bitrate: 3000, 47 framerate: -1, 48 }, 49 })); 50 }, "Test that decodingInfo rejects if the video configuration has a negative framerate"); 51 52 promise_test(t => { 53 return promise_rejects_js(t, TypeError, navigator.mediaCapabilities.decodingInfo({ 54 type: 'webrtc', 55 video: { 56 contentType: 'video/VP9"', 57 width: 800, 58 height: 600, 59 bitrate: 3000, 60 framerate: 0, 61 }, 62 })); 63 }, "Test that decodingInfo rejects if the video configuration has a framerate set to 0"); 64 65 promise_test(t => { 66 return promise_rejects_js(t, TypeError, navigator.mediaCapabilities.decodingInfo({ 67 type: 'webrtc', 68 video: { 69 contentType: 'video/VP9"', 70 width: 800, 71 height: 600, 72 bitrate: 3000, 73 framerate: Infinity, 74 }, 75 })); 76 }, "Test that decodingInfo rejects if the video configuration has a framerate set to Infinity"); 77 78 promise_test(t => { 79 return promise_rejects_js(t, TypeError, navigator.mediaCapabilities.decodingInfo({ 80 type: 'webrtc', 81 video: { 82 contentType: 'fgeoa', 83 width: 800, 84 height: 600, 85 bitrate: 3000, 86 framerate: 24, 87 }, 88 })); 89 }, "Test that decodingInfo rejects if the video configuration contentType doesn't parse"); 90 91 promise_test(t => { 92 return promise_rejects_js(t, TypeError, navigator.mediaCapabilities.decodingInfo({ 93 type: 'webrtc', 94 video: { 95 contentType: 'audio/fgeoa', 96 width: 800, 97 height: 600, 98 bitrate: 3000, 99 framerate: 24, 100 }, 101 })); 102 }, "Test that decodingInfo rejects if the video configuration contentType isn't of type video"); 103 104 promise_test(t => { 105 return promise_rejects_js(t, TypeError, navigator.mediaCapabilities.decodingInfo({ 106 type: 'webrtc', 107 video: { 108 contentType: 'application/ogg; codecs=vorbis', 109 width: 800, 110 height: 600, 111 bitrate: 3000, 112 framerate: 24, 113 }, 114 })); 115 }, "Test that decodingInfo rejects if the video configuration contentType is of type audio"); 116 117 promise_test(t => { 118 return promise_rejects_js(t, TypeError, navigator.mediaCapabilities.decodingInfo({ 119 type: 'webrtc', 120 audio: { contentType: 'fgeoa' }, 121 })); 122 }, "Test that decodingInfo rejects if the audio configuration contentType doesn't parse"); 123 124 promise_test(t => { 125 return promise_rejects_js(t, TypeError, navigator.mediaCapabilities.decodingInfo({ 126 type: 'webrtc', 127 audio: { contentType: 'video/fgeoa' }, 128 })); 129 }, "Test that decodingInfo rejects if the audio configuration contentType isn't of type audio"); 130 131 promise_test(t => { 132 return promise_rejects_js(t, TypeError, navigator.mediaCapabilities.decodingInfo({ 133 type: 'webrtc', 134 audio: { 135 contentType: 'application/ogg; codecs=theora', 136 channels: 2, 137 }, 138 })); 139 }, "Test that decodingInfo rejects if the audio configuration contentType is of type video"); 140 141 promise_test(t => { 142 return promise_rejects_js(t, TypeError, navigator.mediaCapabilities.decodingInfo({ 143 type: 'webrtc', 144 video: { 145 contentType: 'video/webm; codecs="vp09.00.10.08"; foo="bar"', 146 width: 800, 147 height: 600, 148 bitrate: 3000, 149 framerate: 24, 150 }, 151 })); 152 }, "Test that decodingInfo rejects if the video configuration contentType has more than one parameter"); 153 154 promise_test(t => { 155 return promise_rejects_js(t, TypeError, navigator.mediaCapabilities.decodingInfo({ 156 type: 'webrtc', 157 video: { 158 contentType: 'video/webm; foo="bar"', 159 width: 800, 160 height: 600, 161 bitrate: 3000, 162 framerate: 24, 163 }, 164 })); 165 }, "Test that decodingInfo rejects if the video configuration contentType has one parameter that isn't codecs"); 166 167 promise_test(t => { 168 return promise_rejects_js(t, TypeError, navigator.mediaCapabilities.decodingInfo({ 169 type: 'webrtc', 170 audio: { contentType: 'fgeoa' }, 171 })); 172 }, "Test that decodingInfo rejects if the audio configuration contenType doesn't parse"); 173 174 promise_test(t => { 175 return navigator.mediaCapabilities.decodingInfo({ 176 type: 'webrtc', 177 video: minimalVideoConfiguration, 178 audio: minimalAudioConfiguration, 179 }).then(ability => { 180 assert_equals(typeof ability.supported, "boolean"); 181 assert_equals(typeof ability.smooth, "boolean"); 182 assert_equals(typeof ability.powerEfficient, "boolean"); 183 }); 184 }, "Test that decodingInfo returns a valid MediaCapabilitiesInfo objects"); 185 186 promise_test(t => { 187 return navigator.mediaCapabilities.decodingInfo({ 188 type: 'webrtc', 189 video: { 190 contentType: 'video/webm; codecs="vp09.00.10.08"', 191 width: 800, 192 height: 600, 193 bitrate: 3000, 194 framerate: 24, 195 }, 196 audio: minimalAudioConfiguration, 197 }).then(ability => { 198 assert_false(ability.supported); 199 assert_false(ability.smooth); 200 assert_false(ability.powerEfficient); 201 }); 202 }, "Test that decodingInfo returns supported, smooth, and powerEfficient set to false for non-webrtc video content type."); 203 204 promise_test(t => { 205 return navigator.mediaCapabilities.decodingInfo({ 206 type: 'webrtc', 207 video: minimalVideoConfiguration, 208 audio: { 209 contentType: 'audio/webm; codecs="opus"', 210 }, 211 }).then(ability => { 212 assert_false(ability.supported); 213 assert_false(ability.smooth); 214 assert_false(ability.powerEfficient); 215 }); 216 }, "Test that decodingInfo returns supported, smooth, and powerEfficient set to false for non-webrtc audio content type."); 217 218 const validAudioCodecs = (() => { 219 // Some codecs that are returned by getCapabilities() are not real codecs, 220 // exclude these from the test. 221 const excludeList = [ 'audio/CN', 'audio/telephone-event', 'audio/red' ]; 222 const audioCodecs = []; 223 if (isWorkerEnvironment) { 224 // Test with one specific codec since RTCRtpReceiver is not exposed to workers. 225 audioCodecs.push(minimalAudioConfiguration.contentType); 226 } 227 else { 228 RTCRtpReceiver.getCapabilities("audio")['codecs'].forEach(codec => { 229 if (excludeList.indexOf(codec.mimeType) < 0 && 230 audioCodecs.indexOf(codec.mimeType) < 0) { 231 audioCodecs.push(codec.mimeType); 232 } 233 }); 234 } 235 return audioCodecs; 236 })(); 237 238 validAudioCodecs.forEach(codec => { 239 promise_test(t => { 240 return navigator.mediaCapabilities.decodingInfo({ 241 type: 'webrtc', 242 audio: { 243 contentType: codec 244 } 245 }).then(ability => { 246 assert_true(ability.supported); 247 }); 248 }, "Test that decodingInfo returns supported true for the codec " + codec + (isWorkerEnvironment ? "" : " returned by RTCRtpReceiver.getCapabilities()"))} 249 ); 250 251 const validVideoCodecs = (() => { 252 // Some codecs that are returned by getCapabilities() are not real codecs but 253 // only used for error correction, exclude these from the test. 254 const excludeList = [ 'video/rtx', 'video/red', 'video/ulpfec', 255 'video/flexfec-03' ]; 256 const videoCodecs = []; 257 258 if (isWorkerEnvironment) { 259 // Test with one specific codec since RTCRtpReceiver is not exposed to workers. 260 videoCodecs.push(minimalVideoConfiguration.contentType); 261 } 262 else { 263 RTCRtpReceiver.getCapabilities("video")['codecs'].forEach(codec => { 264 if (excludeList.indexOf(codec.mimeType) < 0) { 265 let mimeType = codec.mimeType; 266 if ('sdpFmtpLine' in codec) { 267 mimeType += "; " + codec.sdpFmtpLine; 268 } 269 if (!(mimeType in videoCodecs)) { 270 videoCodecs.push(mimeType); 271 } 272 } 273 }); 274 } 275 return videoCodecs; 276 })(); 277 278 validVideoCodecs.forEach(codec => { 279 promise_test(t => { 280 return navigator.mediaCapabilities.decodingInfo({ 281 type: 'webrtc', 282 video: { 283 contentType: codec, 284 width: 800, 285 height: 600, 286 bitrate: 3000, 287 framerate: 24, 288 } 289 }).then(ability => { 290 assert_true(ability.supported); 291 }); 292 }, "Test that decodingInfo returns supported true for the codec " + codec + (isWorkerEnvironment ? "" : " returned by RTCRtpReceiver.getCapabilities()"))} 293 ); 294 295 promise_test(t => { 296 return promise_rejects_js(t, TypeError, navigator.mediaCapabilities.decodingInfo({ 297 type: 'webrtc', 298 audio: { contentType: 'audio/webm; codecs="opus"; foo="bar"' }, 299 })); 300 }, "Test that decodingInfo rejects if the audio configuration contentType has more than one parameters"); 301 302 promise_test(t => { 303 return promise_rejects_js(t, TypeError, navigator.mediaCapabilities.decodingInfo({ 304 type: 'webrtc', 305 audio: { contentType: 'audio/webm; foo="bar"' }, 306 })); 307 }, "Test that decodingInfo rejects if the audio configuration contentType has one parameter that isn't codecs"); 308 309 promise_test(t => { 310 return promise_rejects_js(t, TypeError, navigator.mediaCapabilities.decodingInfo({ 311 type: 'webrtc', 312 video: videoConfigurationWithDynamicRange, 313 })); 314 }, "Test that decodingInfo rejects for type 'webrtc' if HDR members are set");