RTCEncodedFrame-copy-construction.https.html (4259B)
1 <!doctype html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <meta name='timeout' content='long'> 6 <script src="/resources/testharness.js"></script> 7 <script src="/resources/testharnessreport.js"></script> 8 <script src=/resources/testdriver.js></script> 9 <script src=/resources/testdriver-vendor.js></script> 10 <script src="../webrtc/RTCPeerConnection-helper.js"></script> 11 <script src="helper.js"></script> 12 </head> 13 <body> 14 <script> 15 16 const assert_json_equals = (a, b) => assert_equals(JSON.stringify(a), JSON.stringify(b)); 17 const assert_json_not_equals = (a, b) => assert_not_equals(JSON.stringify(a), JSON.stringify(b)); 18 19 const reuse = {}; // speed up tests 20 21 promise_test(async t => { 22 const frame = await createRTCEncodedFrameFromScratch("video"); 23 reuse["video"] = frame; 24 assert_true(frame instanceof RTCEncodedVideoFrame); 25 assert_equals(frame.type, "key"); // first frame is key 26 27 const clone = new RTCEncodedVideoFrame(frame); 28 assert_true(clone instanceof RTCEncodedVideoFrame); 29 assert_equals(clone.type, frame.type); 30 assert_true(areArrayBuffersEqual(clone.data, frame.data)); 31 assert_json_equals(clone.getMetadata(), frame.getMetadata()); 32 }, "RTCEncodedVideoFrame copy construction on main thread."); 33 34 promise_test(async t => { 35 const frame = await createRTCEncodedFrameFromScratch("audio"); 36 reuse["audio"] = frame; 37 assert_true(frame instanceof RTCEncodedAudioFrame); 38 39 const clone = new RTCEncodedAudioFrame(frame); 40 assert_true(clone instanceof RTCEncodedAudioFrame); 41 assert_equals(clone.type, frame.type); 42 assert_true(areArrayBuffersEqual(clone.data, frame.data)); 43 assert_json_equals(clone.getMetadata(), frame.getMetadata()); 44 }, "RTCEncodedAudioFrame copy construction on main thread."); 45 46 function different(value) { 47 switch (typeof value) { 48 case "number": return value + 1; 49 case "string": return value + "2"; 50 case "object": return Array.isArray(value) ? value.concat([2]) : {}; 51 default: assert_unreached(`unexpected type ${typeof value}`); 52 } 53 } 54 55 ["RTCEncodedVideoFrame", "RTCEncodedAudioFrame"].forEach(constr => { 56 const kind = constr.includes("Video")? "video" : "audio"; 57 58 promise_test(async t => { 59 const frame = reuse[kind]; 60 const oldData = frame.getMetadata(); 61 // test single key replacement 62 for (const key of Object.keys(oldData)) { 63 const metadata = {[key]: different(oldData[key])}; 64 // Spec says "The new frame’s [[metadata]] is a deep copy 65 // of originalFrame.[[metadata]], with fields replaced with 66 // deep copies of the fields present in options.[metadata]." 67 // This compares well to how Object.assign() works 68 const expected = Object.assign(structuredClone(oldData), metadata); 69 const clone = new window[constr](frame, {metadata}); 70 assert_json_equals(clone.getMetadata(), expected); 71 assert_json_not_equals(clone.getMetadata(), oldData); 72 } 73 // test cumulative key replacement 74 let metadata = {}; 75 for (const key of Object.keys(oldData)) { 76 Object.assign(metadata, {[key]: different(oldData[key])}); 77 const expected = Object.assign(structuredClone(oldData), metadata); 78 const clone = new window[constr](frame, {metadata}); 79 assert_json_equals(clone.getMetadata(), expected); 80 assert_json_not_equals(clone.getMetadata(), oldData); 81 } 82 }, `${constr} copy construction metadata override on main thread.`); 83 84 promise_test(async t => { 85 const frame = reuse[kind]; 86 assert_greater_than(frame.data.byteLength, 0); 87 const length = frame.data.byteLength; 88 const clone = structuredClone(frame); 89 assert_equals(frame.data.byteLength, length, "not transferred"); 90 assert_true(areArrayBuffersEqual(clone.data, frame.data)); 91 assert_json_equals(clone.getMetadata(), frame.getMetadata()); 92 }, `${constr} structuredClone on main thread.`); 93 94 promise_test(async t => { 95 const frame = reuse[kind]; 96 assert_greater_than(frame.data.byteLength, 0); 97 const length = frame.data.byteLength; 98 const clone = structuredClone(frame, {transfer: [frame.data]}); 99 assert_equals(frame.data.byteLength, 0, "was transferred"); 100 assert_equals(clone.data.byteLength, length); 101 }, `${constr} structuredClone transfer on main thread.`); 102 103 }); 104 </script> 105 </body> 106 </html>