RTCEncodedVideoFrame-metadata.https.html (7296B)
1 <!DOCTYPE html> 2 <script src="/resources/testharness.js"></script> 3 <script src="/resources/testharnessreport.js"></script> 4 <script src=/resources/testdriver.js></script> 5 <script src=/resources/testdriver-vendor.js></script> 6 <script src='../../mediacapture-streams/permission-helper.js'></script> 7 <script src="../../webrtc/RTCPeerConnection-helper.js"></script> 8 <script src="../../service-workers/service-worker/resources/test-helpers.sub.js"></script> 9 <script src='helper.js'></script> 10 <script> 11 "use strict"; 12 13 promise_test(async t => { 14 const senderReader = await setupLoopbackWithCodecAndGetReader(t, 'VP8'); 15 const result = await senderReader.read(); 16 const metadata = result.value.getMetadata(); 17 // TODO(https://crbug.com/webrtc/14709): When RTCEncodedVideoFrame has a 18 // constructor, create a new frame from scratch instead of cloning it to 19 // ensure that none of the metadata was carried over via structuredClone(). 20 // This would allow us to be confident that setMetadata() is doing all the 21 // work. 22 // 23 // At that point, we can refactor the structuredClone() implementation to be 24 // the same as constructor() + set data + setMetadata() to ensure that 25 // structuredClone() cannot do things that are not already exposed in 26 // JavaScript (no secret steps!). 27 const clone = structuredClone(result.value); 28 clone.setMetadata(metadata); 29 const cloneMetadata = clone.getMetadata(); 30 // Encoding-related metadata. 31 assert_equals(cloneMetadata.frameId, metadata.frameId, 'frameId'); 32 assert_array_equals(cloneMetadata.dependencies, metadata.dependencies, 33 'dependencies'); 34 assert_equals(cloneMetadata.width, metadata.width, 'width'); 35 assert_equals(cloneMetadata.height, metadata.height, 'height'); 36 assert_equals(cloneMetadata.spatialIndex, metadata.spatialIndex, 37 'spatialIndex'); 38 assert_equals(cloneMetadata.temporalIndex, metadata.temporalIndex, 39 'temporalIndex'); 40 // RTP-related metadata. 41 // TODO(https://crbug.com/webrtc/14709): This information also needs to be 42 // settable but isn't - the assertions only pass because structuredClone() 43 // copies them for us. It would be great if different layers didn't consider 44 // different subset of the struct as "the metadata". Can we consolidate into a 45 // single webrtc struct for all metadata? 46 assert_equals(cloneMetadata.synchronizationSource, 47 metadata.synchronizationSource, 'synchronizationSource'); 48 assert_array_equals(cloneMetadata.contributingSources, 49 metadata.contributingSources, 'contributingSources'); 50 assert_equals(cloneMetadata.payloadType, metadata.payloadType, 'payloadType'); 51 }, "[VP8] setMetadata() carries over codec-specific properties"); 52 53 promise_test(async t => { 54 const senderReader = await setupLoopbackWithCodecAndGetReader(t, 'VP8'); 55 const result = await senderReader.read(); 56 const metadata = result.value.getMetadata(); 57 const newFrame = new RTCEncodedVideoFrame(result.value); 58 const newMetadata = newFrame.getMetadata(); 59 60 // Encoding-related metadata. 61 assert_equals(newMetadata.frameId, metadata.frameId, 'frameId'); 62 assert_array_equals(newMetadata.dependencies, metadata.dependencies, 63 'dependencies'); 64 assert_equals(newMetadata.width, metadata.width, 'width'); 65 assert_equals(newMetadata.height, metadata.height, 'height'); 66 assert_equals(newMetadata.spatialIndex, metadata.spatialIndex, 67 'spatialIndex'); 68 assert_equals(newMetadata.temporalIndex, metadata.temporalIndex, 69 'temporalIndex'); 70 71 // RTP-related metadata. 72 assert_equals(newMetadata.synchronizationSource, 73 metadata.synchronizationSource, 'synchronizationSource'); 74 assert_array_equals(newMetadata.contributingSources, 75 metadata.contributingSources, 'contributingSources'); 76 assert_equals(newMetadata.payloadType, metadata.payloadType, 'payloadType'); 77 assert_equals(newMetadata.rtpTimestamp, metadata.rtpTimestamp, 'rtpTimestamp'); 78 }, "[VP8] constructor carries over codec-specific properties"); 79 80 promise_test(async t => { 81 const senderReader = await setupLoopbackWithCodecAndGetReader(t, 'VP8'); 82 const result = await senderReader.read(); 83 const frame_metadata = result.value.getMetadata(); 84 frame_metadata.rtpTimestamp = 100; 85 const newFrame = new RTCEncodedVideoFrame(result.value, {metadata: frame_metadata}); 86 const newMetadata = newFrame.getMetadata(); 87 88 // Encoding-related metadata. 89 assert_equals(newMetadata.frameId, frame_metadata.frameId, 'frameId'); 90 assert_array_equals(newMetadata.dependencies, frame_metadata.dependencies, 91 'dependencies'); 92 assert_equals(newMetadata.width, frame_metadata.width, 'width'); 93 assert_equals(newMetadata.height, frame_metadata.height, 'height'); 94 assert_equals(newMetadata.spatialIndex, frame_metadata.spatialIndex, 95 'spatialIndex'); 96 assert_equals(newMetadata.temporalIndex, frame_metadata.temporalIndex, 97 'temporalIndex'); 98 99 // RTP-related metadata. 100 assert_equals(newMetadata.synchronizationSource, 101 frame_metadata.synchronizationSource, 'synchronizationSource'); 102 assert_array_equals(newMetadata.contributingSources, 103 frame_metadata.contributingSources, 'contributingSources'); 104 assert_equals(newMetadata.payloadType, frame_metadata.payloadType, 'payloadType'); 105 assert_equals(newMetadata.rtpTimestamp, frame_metadata.rtpTimestamp, 'rtpTimestamp'); 106 assert_not_equals(newMetadata.rtpTimestamp, result.value.getMetadata().rtpTimestamp, 'rtpTimestamp'); 107 }, "[VP8] constructor with metadata carries over codec-specific properties"); 108 109 promise_test(async t => { 110 const senderReader = await setupLoopbackWithCodecAndGetReader(t, 'VP8'); 111 const result = await senderReader.read(); 112 const metadata = result.value.getMetadata(); 113 // Change the metadata by setting a new RTPTimestamp. 114 metadata.rtpTimestamp = 100; 115 const newFrame = new RTCEncodedVideoFrame(result.value); 116 const newMetadata = newFrame.getMetadata(); 117 118 // Encoding-related metadata. 119 assert_equals(newMetadata.frameId, metadata.frameId, 'frameId'); 120 assert_array_equals(newMetadata.dependencies, metadata.dependencies, 121 'dependencies'); 122 assert_equals(newMetadata.width, metadata.width, 'width'); 123 assert_equals(newMetadata.height, metadata.height, 'height'); 124 assert_equals(newMetadata.spatialIndex, metadata.spatialIndex, 125 'spatialIndex'); 126 assert_equals(newMetadata.temporalIndex, metadata.temporalIndex, 127 'temporalIndex'); 128 129 // RTP-related metadata. 130 assert_equals(newMetadata.synchronizationSource, 131 metadata.synchronizationSource, 'synchronizationSource'); 132 assert_array_equals(newMetadata.contributingSources, 133 metadata.contributingSources, 'contributingSources'); 134 assert_equals(newMetadata.payloadType, metadata.payloadType, 'payloadType'); 135 136 // RTPTimestamp don't match because the constructor did not use the metadata for construction. 137 assert_not_equals(newMetadata.rtpTimestamp, metadata.rtpTimestamp, 'rtpTimestamp'); 138 assert_equals(newMetadata.rtpTimestamp, result.value.getMetadata().rtpTimestamp, 'rtpTimestamp'); 139 }, "[VP8] constructor without metadata does not carry over modified metadata "); 140 </script>