video-codecs.https.html (3899B)
1 <!doctype html> 2 <meta charset=utf-8> 3 <title>RTCPeerConnection.prototype.createOffer</title> 4 <script src="/resources/testharness.js"></script> 5 <script src="/resources/testharnessreport.js"></script> 6 <script src="../RTCPeerConnection-helper.js"></script> 7 <script> 8 'use strict'; 9 10 /* 11 * Chromium note: this requires build bots with H264 support. See 12 * https://bugs.chromium.org/p/chromium/issues/detail?id=840659 13 * for details on how to enable support. 14 */ 15 // Tests for conformance to RFC 7742, 16 // "WebRTC Video Processing and Codec Requirements" 17 // The document was formerly known as draft-ietf-rtcweb-video-codecs. 18 // 19 // This tests that the browser is a WebRTC Browser as defined there. 20 21 // TODO: Section 3.2: screen capture video MUST be prepared 22 // to handle resolution changes. 23 24 // TODO: Section 4: MUST support generating CVO (orientation) 25 26 // Section 5: Browsers MUST implement VP8 and H.264 Constrained Baseline 27 promise_test(async t => { 28 const pc = new RTCPeerConnection(); 29 const offer = await generateVideoReceiveOnlyOffer(pc); 30 let video_section_found = false; 31 for (let section of offer.sdp.split(/\r\nm=/)) { 32 if (section.search('video') != 0) { 33 continue; 34 } 35 video_section_found = true; 36 // RTPMAP lines have the format a=rtpmap:<pt> <codec>/<clock rate> 37 let rtpmap_regex = /\r\na=rtpmap:(\d+) (\S+)\/\d+\r\n/g; 38 let match = rtpmap_regex.exec(offer.sdp); 39 let payload_type_map = new Array(); 40 while (match) { 41 payload_type_map[match[1]] = match[2]; 42 match = rtpmap_regex.exec(offer.sdp); 43 } 44 assert_true(payload_type_map.indexOf('VP8') > -1, 45 'VP8 is supported'); 46 assert_true(payload_type_map.indexOf('H264') > -1, 47 'H.264 is supported'); 48 // TODO: Verify that one of the H.264 PTs supports constrained baseline 49 } 50 assert_true(video_section_found); 51 }, 'H.264 and VP8 should be supported in initial offer'); 52 53 async function negotiateParameters() { 54 const pc1 = new RTCPeerConnection(); 55 const pc2 = new RTCPeerConnection(); 56 let [track, streams] = await getTrackFromUserMedia('video'); 57 const sender = pc1.addTrack(track); 58 await exchangeOfferAnswer(pc1, pc2); 59 return sender.getParameters(); 60 } 61 62 function parseFmtp(fmtp) { 63 const params = fmtp.split(';'); 64 return params.map(param => param.split('=')); 65 } 66 67 promise_test(async t => { 68 const params = await negotiateParameters(); 69 assert_true(!!params.codecs.find(codec => codec.mimeType.toLowerCase() === 'video/h264')); 70 assert_true(!!params.codecs.find(codec => codec.mimeType.toLowerCase() === 'video/vp8')); 71 }, 'H.264 and VP8 should be negotiated after handshake'); 72 73 // TODO: Section 6: Recipients MUST be able to decode 320x240@20 fps 74 // TODO: Section 6.1: VP8 MUST support RFC 7741 payload formats 75 // TODO: Section 6.1: VP8 MUST respect max-fr/max-fs 76 // TODO: Section 6.1: VP8 MUST encode and decode square pixels 77 // TODO: Section 6.2: H.264 MUST support RFC 6184 payload formats 78 // TODO: Section 6.2: MUST support Constrained Baseline level 1.2 79 // TODO: Section 6.2: SHOULD support Constrained High level 1.3 80 // TODO: Section 6.2: MUST support packetization mode 1. 81 promise_test(async t => { 82 const params = await negotiateParameters(); 83 const h264 = params.codecs.filter(codec => codec.mimeType === 'video/H264'); 84 h264.map(codec => { 85 const codec_params = parseFmtp(codec.sdpFmtpLine); 86 assert_true(!!codec_params.find(x => x[0] === 'profile-level-id')); 87 }) 88 }, 'All H.264 codecs MUST include profile-level-id'); 89 90 // TODO: Section 6.2: SHOULD interpret max-mbps, max-smbps, max-fs et al 91 // TODO: Section 6.2: MUST NOT include sprop-parameter-sets 92 // TODO: Section 6.2: MUST support SEI "filler payload" 93 // TODO: Section 6.2: MUST support SEI "full frame freeze" 94 // TODO: Section 6.2: MUST be prepared to receive User Data messages 95 // TODO: Section 6.2: MUST encode and decode square pixels unless signaled 96 </script>