From 6bf0a5cb5034a7e684dcc3500e841785237ce2dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 19:32:43 +0200 Subject: Adding upstream version 1:115.7.0. Signed-off-by: Daniel Baumann --- .../tests/webrtc-encoded-transform/META.yml | 1 + .../RTCEncodedAudioFrame-clone.https.html | 50 +++++ ...odedAudioFrame-serviceworker-failure.https.html | 60 +++++ .../RTCEncodedVideoFrame-clone.https.html | 61 ++++++ ...odedVideoFrame-serviceworker-failure.https.html | 60 +++++ ...rConnection-insertable-streams-audio.https.html | 212 ++++++++++++++++++ ...Connection-insertable-streams-errors.https.html | 87 ++++++++ ...nection-insertable-streams-simulcast.https.html | 89 ++++++++ ...tion-insertable-streams-video-frames.https.html | 80 +++++++ ...rConnection-insertable-streams-video.https.html | 149 +++++++++++++ ...Connection-insertable-streams-worker.https.html | 196 +++++++++++++++++ .../RTCPeerConnection-insertable-streams.js | 242 +++++++++++++++++++++ ...RTCPeerConnection-sender-worker-single-frame.js | 19 ++ .../RTCPeerConnection-worker-transform.js | 22 ++ .../codec-specific-metadata.https.html | 45 ++++ .../tests/webrtc-encoded-transform/helper.js | 26 +++ .../idlharness.https.window.js | 18 ++ .../webrtc-encoded-transform/resources/blank.html | 2 + .../resources/serviceworker-failure.js | 30 +++ .../tests/webrtc-encoded-transform/routines.js | 32 +++ .../script-audio-transform-worker.js | 30 +++ .../script-audio-transform.https.html | 69 ++++++ .../script-change-transform-worker.js | 39 ++++ .../script-change-transform.https.html | 61 ++++++ .../script-late-transform.https.html | 94 ++++++++ .../script-metadata-transform-worker.js | 24 ++ .../script-metadata-transform.https.html | 91 ++++++++ .../script-transform-worker.js | 25 +++ .../script-transform.https.html | 153 +++++++++++++ .../script-write-twice-transform-worker.js | 22 ++ .../script-write-twice-transform.https.html | 62 ++++++ .../set-metadata.https.html | 83 +++++++ .../sframe-keys.https.html | 69 ++++++ .../sframe-transform-buffer-source.html | 50 +++++ .../sframe-transform-in-worker.https.html | 61 ++++++ .../sframe-transform-readable.html | 19 ++ .../sframe-transform-worker.js | 7 + .../webrtc-encoded-transform/sframe-transform.html | 141 ++++++++++++ 38 files changed, 2581 insertions(+) create mode 100644 testing/web-platform/tests/webrtc-encoded-transform/META.yml create mode 100644 testing/web-platform/tests/webrtc-encoded-transform/RTCEncodedAudioFrame-clone.https.html create mode 100644 testing/web-platform/tests/webrtc-encoded-transform/RTCEncodedAudioFrame-serviceworker-failure.https.html create mode 100644 testing/web-platform/tests/webrtc-encoded-transform/RTCEncodedVideoFrame-clone.https.html create mode 100644 testing/web-platform/tests/webrtc-encoded-transform/RTCEncodedVideoFrame-serviceworker-failure.https.html create mode 100644 testing/web-platform/tests/webrtc-encoded-transform/RTCPeerConnection-insertable-streams-audio.https.html create mode 100644 testing/web-platform/tests/webrtc-encoded-transform/RTCPeerConnection-insertable-streams-errors.https.html create mode 100644 testing/web-platform/tests/webrtc-encoded-transform/RTCPeerConnection-insertable-streams-simulcast.https.html create mode 100644 testing/web-platform/tests/webrtc-encoded-transform/RTCPeerConnection-insertable-streams-video-frames.https.html create mode 100644 testing/web-platform/tests/webrtc-encoded-transform/RTCPeerConnection-insertable-streams-video.https.html create mode 100644 testing/web-platform/tests/webrtc-encoded-transform/RTCPeerConnection-insertable-streams-worker.https.html create mode 100644 testing/web-platform/tests/webrtc-encoded-transform/RTCPeerConnection-insertable-streams.js create mode 100644 testing/web-platform/tests/webrtc-encoded-transform/RTCPeerConnection-sender-worker-single-frame.js create mode 100644 testing/web-platform/tests/webrtc-encoded-transform/RTCPeerConnection-worker-transform.js create mode 100644 testing/web-platform/tests/webrtc-encoded-transform/codec-specific-metadata.https.html create mode 100644 testing/web-platform/tests/webrtc-encoded-transform/helper.js create mode 100644 testing/web-platform/tests/webrtc-encoded-transform/idlharness.https.window.js create mode 100644 testing/web-platform/tests/webrtc-encoded-transform/resources/blank.html create mode 100644 testing/web-platform/tests/webrtc-encoded-transform/resources/serviceworker-failure.js create mode 100644 testing/web-platform/tests/webrtc-encoded-transform/routines.js create mode 100644 testing/web-platform/tests/webrtc-encoded-transform/script-audio-transform-worker.js create mode 100644 testing/web-platform/tests/webrtc-encoded-transform/script-audio-transform.https.html create mode 100644 testing/web-platform/tests/webrtc-encoded-transform/script-change-transform-worker.js create mode 100644 testing/web-platform/tests/webrtc-encoded-transform/script-change-transform.https.html create mode 100644 testing/web-platform/tests/webrtc-encoded-transform/script-late-transform.https.html create mode 100644 testing/web-platform/tests/webrtc-encoded-transform/script-metadata-transform-worker.js create mode 100644 testing/web-platform/tests/webrtc-encoded-transform/script-metadata-transform.https.html create mode 100644 testing/web-platform/tests/webrtc-encoded-transform/script-transform-worker.js create mode 100644 testing/web-platform/tests/webrtc-encoded-transform/script-transform.https.html create mode 100644 testing/web-platform/tests/webrtc-encoded-transform/script-write-twice-transform-worker.js create mode 100644 testing/web-platform/tests/webrtc-encoded-transform/script-write-twice-transform.https.html create mode 100644 testing/web-platform/tests/webrtc-encoded-transform/set-metadata.https.html create mode 100644 testing/web-platform/tests/webrtc-encoded-transform/sframe-keys.https.html create mode 100644 testing/web-platform/tests/webrtc-encoded-transform/sframe-transform-buffer-source.html create mode 100644 testing/web-platform/tests/webrtc-encoded-transform/sframe-transform-in-worker.https.html create mode 100644 testing/web-platform/tests/webrtc-encoded-transform/sframe-transform-readable.html create mode 100644 testing/web-platform/tests/webrtc-encoded-transform/sframe-transform-worker.js create mode 100644 testing/web-platform/tests/webrtc-encoded-transform/sframe-transform.html (limited to 'testing/web-platform/tests/webrtc-encoded-transform') diff --git a/testing/web-platform/tests/webrtc-encoded-transform/META.yml b/testing/web-platform/tests/webrtc-encoded-transform/META.yml new file mode 100644 index 0000000000..6365c8d16a --- /dev/null +++ b/testing/web-platform/tests/webrtc-encoded-transform/META.yml @@ -0,0 +1 @@ +spec: https://w3c.github.io/webrtc-encoded-transform/ diff --git a/testing/web-platform/tests/webrtc-encoded-transform/RTCEncodedAudioFrame-clone.https.html b/testing/web-platform/tests/webrtc-encoded-transform/RTCEncodedAudioFrame-clone.https.html new file mode 100644 index 0000000000..ec99338772 --- /dev/null +++ b/testing/web-platform/tests/webrtc-encoded-transform/RTCEncodedAudioFrame-clone.https.html @@ -0,0 +1,50 @@ + + +RTCEncodedAudioFrame can be cloned and distributed + + + + + + + + + diff --git a/testing/web-platform/tests/webrtc-encoded-transform/RTCEncodedAudioFrame-serviceworker-failure.https.html b/testing/web-platform/tests/webrtc-encoded-transform/RTCEncodedAudioFrame-serviceworker-failure.https.html new file mode 100644 index 0000000000..d6d8578dbd --- /dev/null +++ b/testing/web-platform/tests/webrtc-encoded-transform/RTCEncodedAudioFrame-serviceworker-failure.https.html @@ -0,0 +1,60 @@ + + + +RTCEncodedVideoFrame cannot cross agent clusters, service worker edition + + + + + + + + + diff --git a/testing/web-platform/tests/webrtc-encoded-transform/RTCEncodedVideoFrame-clone.https.html b/testing/web-platform/tests/webrtc-encoded-transform/RTCEncodedVideoFrame-clone.https.html new file mode 100644 index 0000000000..29330729dc --- /dev/null +++ b/testing/web-platform/tests/webrtc-encoded-transform/RTCEncodedVideoFrame-clone.https.html @@ -0,0 +1,61 @@ + + +RTCEncodedVideoFrame can be cloned and distributed + + + + + + + + + diff --git a/testing/web-platform/tests/webrtc-encoded-transform/RTCEncodedVideoFrame-serviceworker-failure.https.html b/testing/web-platform/tests/webrtc-encoded-transform/RTCEncodedVideoFrame-serviceworker-failure.https.html new file mode 100644 index 0000000000..b95c673f41 --- /dev/null +++ b/testing/web-platform/tests/webrtc-encoded-transform/RTCEncodedVideoFrame-serviceworker-failure.https.html @@ -0,0 +1,60 @@ + + + +RTCEncodedVideoFrame cannot cross agent clusters, service worker edition + + + + + + + + + diff --git a/testing/web-platform/tests/webrtc-encoded-transform/RTCPeerConnection-insertable-streams-audio.https.html b/testing/web-platform/tests/webrtc-encoded-transform/RTCPeerConnection-insertable-streams-audio.https.html new file mode 100644 index 0000000000..d4b6b72a32 --- /dev/null +++ b/testing/web-platform/tests/webrtc-encoded-transform/RTCPeerConnection-insertable-streams-audio.https.html @@ -0,0 +1,212 @@ + + + +RTCPeerConnection Insertable Streams Audio + + + + + + + + + + + + diff --git a/testing/web-platform/tests/webrtc-encoded-transform/RTCPeerConnection-insertable-streams-errors.https.html b/testing/web-platform/tests/webrtc-encoded-transform/RTCPeerConnection-insertable-streams-errors.https.html new file mode 100644 index 0000000000..56ba3ee972 --- /dev/null +++ b/testing/web-platform/tests/webrtc-encoded-transform/RTCPeerConnection-insertable-streams-errors.https.html @@ -0,0 +1,87 @@ + + + +RTCPeerConnection Insertable Streams - Errors + + + + + + + + + + + + diff --git a/testing/web-platform/tests/webrtc-encoded-transform/RTCPeerConnection-insertable-streams-simulcast.https.html b/testing/web-platform/tests/webrtc-encoded-transform/RTCPeerConnection-insertable-streams-simulcast.https.html new file mode 100644 index 0000000000..cb33e458d1 --- /dev/null +++ b/testing/web-platform/tests/webrtc-encoded-transform/RTCPeerConnection-insertable-streams-simulcast.https.html @@ -0,0 +1,89 @@ + + +RTCPeerConnection Insertable Streams Simulcast + + + + + + + + + diff --git a/testing/web-platform/tests/webrtc-encoded-transform/RTCPeerConnection-insertable-streams-video-frames.https.html b/testing/web-platform/tests/webrtc-encoded-transform/RTCPeerConnection-insertable-streams-video-frames.https.html new file mode 100644 index 0000000000..d7fb088846 --- /dev/null +++ b/testing/web-platform/tests/webrtc-encoded-transform/RTCPeerConnection-insertable-streams-video-frames.https.html @@ -0,0 +1,80 @@ + + + +RTCPeerConnection Insertable Streams - Video Frames + + + + + + + + + + + + diff --git a/testing/web-platform/tests/webrtc-encoded-transform/RTCPeerConnection-insertable-streams-video.https.html b/testing/web-platform/tests/webrtc-encoded-transform/RTCPeerConnection-insertable-streams-video.https.html new file mode 100644 index 0000000000..378520c693 --- /dev/null +++ b/testing/web-platform/tests/webrtc-encoded-transform/RTCPeerConnection-insertable-streams-video.https.html @@ -0,0 +1,149 @@ + + + +RTCPeerConnection Insertable Streams - Video + + + + + + + + + + + + diff --git a/testing/web-platform/tests/webrtc-encoded-transform/RTCPeerConnection-insertable-streams-worker.https.html b/testing/web-platform/tests/webrtc-encoded-transform/RTCPeerConnection-insertable-streams-worker.https.html new file mode 100644 index 0000000000..cb31057cac --- /dev/null +++ b/testing/web-platform/tests/webrtc-encoded-transform/RTCPeerConnection-insertable-streams-worker.https.html @@ -0,0 +1,196 @@ + + + +RTCPeerConnection Insertable Streams - Worker + + + + + + + + + + + + diff --git a/testing/web-platform/tests/webrtc-encoded-transform/RTCPeerConnection-insertable-streams.js b/testing/web-platform/tests/webrtc-encoded-transform/RTCPeerConnection-insertable-streams.js new file mode 100644 index 0000000000..f1b872294b --- /dev/null +++ b/testing/web-platform/tests/webrtc-encoded-transform/RTCPeerConnection-insertable-streams.js @@ -0,0 +1,242 @@ +function areArrayBuffersEqual(buffer1, buffer2) +{ + if (buffer1.byteLength !== buffer2.byteLength) { + return false; + } + let array1 = new Int8Array(buffer1); + var array2 = new Int8Array(buffer2); + for (let i = 0 ; i < buffer1.byteLength ; ++i) { + if (array1[i] !== array2[i]) { + return false; + } + } + return true; +} + +function areArraysEqual(a1, a2) { + if (a1 === a1) + return true; + if (a1.length != a2.length) + return false; + for (let i = 0; i < a1.length; i++) { + if (a1[i] != a2[i]) + return false; + } + return true; +} + +function areMetadataEqual(metadata1, metadata2, type) { + return metadata1.synchronizationSource === metadata2.synchronizationSource && + metadata1.payloadType == metadata2.payloadType && + areArraysEqual(metadata1.contributingSources, metadata2.contributingSources) && + metadata1.frameId === metadata2.frameId && + areArraysEqual(metadata1.dependencies, metadata2.dependencies) && + metadata1.spatialIndex === metadata2.spatialIndex && + metadata1.temporalIndex === metadata2.temporalIndex && + // Width and height are reported only for key frames on the receiver side. + type == "key" + ? metadata1.width === metadata2.width && metadata1.height === metadata2.height + : true; +} + +function areFrameInfosEqual(frame1, frame2) { + return frame1.timestamp === frame2.timestamp && + frame1.type === frame2.type && + areMetadataEqual(frame1.getMetadata(), frame2.getMetadata(), frame1.type) && + areArrayBuffersEqual(frame1.data, frame2.data); +} + +function containsVideoMetadata(metadata) { + return metadata.synchronizationSource !== undefined && + metadata.width !== undefined && + metadata.height !== undefined && + metadata.spatialIndex !== undefined && + metadata.temporalIndex !== undefined && + metadata.dependencies !== undefined; +} + +function enableGFD(sdp) { + const GFD_V00_EXTENSION = + 'http://www.webrtc.org/experiments/rtp-hdrext/generic-frame-descriptor-00'; + if (sdp.indexOf(GFD_V00_EXTENSION) !== -1) + return sdp; + + const extensionIds = sdp.trim().split('\n') + .map(line => line.trim()) + .filter(line => line.startsWith('a=extmap:')) + .map(line => line.split(' ')[0].substr(9)) + .map(id => parseInt(id, 10)) + .sort((a, b) => a - b); + for (let newId = 1; newId <= 14; newId++) { + if (!extensionIds.includes(newId)) { + return sdp += 'a=extmap:' + newId + ' ' + GFD_V00_EXTENSION + '\r\n'; + } + } + if (sdp.indexOf('a=extmap-allow-mixed') !== -1) { // Pick the next highest one. + const newId = extensionIds[extensionIds.length - 1] + 1; + return sdp += 'a=extmap:' + newId + ' ' + GFD_V00_EXTENSION + '\r\n'; + } + throw 'Could not find free extension id to use for ' + GFD_V00_EXTENSION; +} + +async function exchangeOfferAnswer(pc1, pc2) { + const offer = await pc1.createOffer(); + // Munge the SDP to enable the GFD extension in order to get correct metadata. + const sdpGFD = enableGFD(offer.sdp); + await pc1.setLocalDescription({type: offer.type, sdp: sdpGFD}); + // Munge the SDP to disable bandwidth probing via RTX. + // TODO(crbug.com/1066819): remove this hack when we do not receive duplicates from RTX + // anymore. + const sdpRTX = sdpGFD.replace(new RegExp('rtx', 'g'), 'invalid'); + await pc2.setRemoteDescription({type: 'offer', sdp: sdpRTX}); + + const answer = await pc2.createAnswer(); + await pc2.setLocalDescription(answer); + await pc1.setRemoteDescription(answer); +} + +async function exchangeOfferAnswerReverse(pc1, pc2) { + const offer = await pc2.createOffer({offerToReceiveAudio: true, offerToReceiveVideo: true}); + // Munge the SDP to enable the GFD extension in order to get correct metadata. + const sdpGFD = enableGFD(offer.sdp); + // Munge the SDP to disable bandwidth probing via RTX. + // TODO(crbug.com/1066819): remove this hack when we do not receive duplicates from RTX + // anymore. + const sdpRTX = sdpGFD.replace(new RegExp('rtx', 'g'), 'invalid'); + await pc1.setRemoteDescription({type: 'offer', sdp: sdpRTX}); + await pc2.setLocalDescription({type: 'offer', sdp: sdpGFD}); + + const answer = await pc1.createAnswer(); + await pc2.setRemoteDescription(answer); + await pc1.setLocalDescription(answer); +} + +function createFrameDescriptor(videoFrame) { + const kMaxSpatialLayers = 8; + const kMaxTemporalLayers = 8; + const kMaxNumFrameDependencies = 8; + + const metadata = videoFrame.getMetadata(); + let frameDescriptor = { + beginningOfSubFrame: true, + endOfSubframe: false, + frameId: metadata.frameId & 0xFFFF, + spatialLayers: 1 << metadata.spatialIndex, + temporalLayer: metadata.temporalLayer, + frameDependenciesDiffs: [], + width: 0, + height: 0 + }; + + for (const dependency of metadata.dependencies) { + frameDescriptor.frameDependenciesDiffs.push(metadata.frameId - dependency); + } + if (metadata.dependencies.length == 0) { + frameDescriptor.width = metadata.width; + frameDescriptor.height = metadata.height; + } + return frameDescriptor; +} + +function additionalDataSize(descriptor) { + if (!descriptor.beginningOfSubFrame) { + return 1; + } + + let size = 4; + for (const fdiff of descriptor.frameDependenciesDiffs) { + size += (fdiff >= (1 << 6)) ? 2 : 1; + } + if (descriptor.beginningOfSubFrame && + descriptor.frameDependenciesDiffs.length == 0 && + descriptor.width > 0 && + descriptor.height > 0) { + size += 4; + } + + return size; +} + +// Compute the buffer reported in the additionalData field using the metadata +// provided by a video frame. +// Based on the webrtc::RtpDescriptorAuthentication() C++ function at +// https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/modules/rtp_rtcp/source/rtp_descriptor_authentication.cc +function computeAdditionalData(videoFrame) { + const kMaxSpatialLayers = 8; + const kMaxTemporalLayers = 8; + const kMaxNumFrameDependencies = 8; + + const metadata = videoFrame.getMetadata(); + if (metadata.spatialIndex < 0 || + metadata.temporalIndex < 0 || + metadata.spatialIndex >= kMaxSpatialLayers || + metadata.temporalIndex >= kMaxTemporalLayers || + metadata.dependencies.length > kMaxNumFrameDependencies) { + return new ArrayBuffer(0); + } + + const descriptor = createFrameDescriptor(videoFrame); + const size = additionalDataSize(descriptor); + const additionalData = new ArrayBuffer(size); + const data = new Uint8Array(additionalData); + + const kFlagBeginOfSubframe = 0x80; + const kFlagEndOfSubframe = 0x40; + const kFlagFirstSubframeV00 = 0x20; + const kFlagLastSubframeV00 = 0x10; + + const kFlagDependencies = 0x08; + const kFlagMoreDependencies = 0x01; + const kFlageXtendedOffset = 0x02; + + let baseHeader = + (descriptor.beginningOfSubFrame ? kFlagBeginOfSubframe : 0) | + (descriptor.endOfSubFrame ? kFlagEndOfSubframe : 0); + baseHeader |= kFlagFirstSubframeV00; + baseHeader |= kFlagLastSubframeV00; + + if (!descriptor.beginningOfSubFrame) { + data[0] = baseHeader; + return additionalData; + } + + data[0] = + baseHeader | + (descriptor.frameDependenciesDiffs.length == 0 ? 0 : kFlagDependencies) | + descriptor.temporalLayer; + data[1] = descriptor.spatialLayers; + data[2] = descriptor.frameId & 0xFF; + data[3] = descriptor.frameId >> 8; + + const fdiffs = descriptor.frameDependenciesDiffs; + let offset = 4; + if (descriptor.beginningOfSubFrame && + fdiffs.length == 0 && + descriptor.width > 0 && + descriptor.height > 0) { + data[offset++] = (descriptor.width >> 8); + data[offset++] = (descriptor.width & 0xFF); + data[offset++] = (descriptor.height >> 8); + data[offset++] = (descriptor.height & 0xFF); + } + for (let i = 0; i < fdiffs.length; i++) { + const extended = fdiffs[i] >= (1 << 6); + const more = i < fdiffs.length - 1; + data[offset++] = ((fdiffs[i] & 0x3f) << 2) | + (extended ? kFlageXtendedOffset : 0) | + (more ? kFlagMoreDependencies : 0); + if (extended) { + data[offset++] = fdiffs[i] >> 6; + } + } + return additionalData; +} + +function verifyNonstandardAdditionalDataIfPresent(videoFrame) { + if (videoFrame.additionalData === undefined) + return; + + const computedData = computeAdditionalData(videoFrame); + assert_true(areArrayBuffersEqual(videoFrame.additionalData, computedData)); +} + diff --git a/testing/web-platform/tests/webrtc-encoded-transform/RTCPeerConnection-sender-worker-single-frame.js b/testing/web-platform/tests/webrtc-encoded-transform/RTCPeerConnection-sender-worker-single-frame.js new file mode 100644 index 0000000000..c943dafe5b --- /dev/null +++ b/testing/web-platform/tests/webrtc-encoded-transform/RTCPeerConnection-sender-worker-single-frame.js @@ -0,0 +1,19 @@ +onmessage = async (event) => { + const readableStream = event.data.readableStream; + const reader = readableStream.getReader(); + const result = await reader.read(); + + // Post an object with individual fields so that the test side has + // values to verify the serialization of the RTCEncodedVideoFrame. + postMessage({ + type: result.value.type, + timestamp: result.value.timestamp, + data: result.value.data, + metadata: result.value.getMetadata(), + }); + + // Send the frame twice to verify that the frame does not change after the + // first serialization. + postMessage(result.value); + postMessage(result.value); +} diff --git a/testing/web-platform/tests/webrtc-encoded-transform/RTCPeerConnection-worker-transform.js b/testing/web-platform/tests/webrtc-encoded-transform/RTCPeerConnection-worker-transform.js new file mode 100644 index 0000000000..36e3949e4d --- /dev/null +++ b/testing/web-platform/tests/webrtc-encoded-transform/RTCPeerConnection-worker-transform.js @@ -0,0 +1,22 @@ +onmessage = async (event) => { + const readableStream = event.data.readableStream; + const writableStream = event.data.writableStream; + const insertError = event.data.insertError; + + try { + await readableStream.pipeThrough(new TransformStream({ + transform: (chunk, controller) => { + if (insertError) { + controller.enqueue("This is not a valid frame"); + } else { + controller.enqueue(chunk); + } + } + })).pipeTo(writableStream); + + postMessage({success:true}); + } catch(e) { + postMessage({success:false, error: e}); + } + +} diff --git a/testing/web-platform/tests/webrtc-encoded-transform/codec-specific-metadata.https.html b/testing/web-platform/tests/webrtc-encoded-transform/codec-specific-metadata.https.html new file mode 100644 index 0000000000..bef61b39f3 --- /dev/null +++ b/testing/web-platform/tests/webrtc-encoded-transform/codec-specific-metadata.https.html @@ -0,0 +1,45 @@ + + + + + + + + + + diff --git a/testing/web-platform/tests/webrtc-encoded-transform/helper.js b/testing/web-platform/tests/webrtc-encoded-transform/helper.js new file mode 100644 index 0000000000..d4cec39ffc --- /dev/null +++ b/testing/web-platform/tests/webrtc-encoded-transform/helper.js @@ -0,0 +1,26 @@ +"use strict"; + +async function setupLoopbackWithCodecAndGetReader(t, codec) { + const caller = new RTCPeerConnection({encodedInsertableStreams:true}); + t.add_cleanup(() => caller.close()); + const callee = new RTCPeerConnection(); + t.add_cleanup(() => callee.close()); + + await setMediaPermission("granted", ["camera"]); + const stream = await navigator.mediaDevices.getUserMedia({video:true}); + const videoTrack = stream.getVideoTracks()[0]; + t.add_cleanup(() => videoTrack.stop()); + + const transceiver = caller.addTransceiver(videoTrack); + const codecCapability = + RTCRtpSender.getCapabilities('video').codecs.find(capability => { + return capability.mimeType.includes(codec); + }); + assert_not_equals(codecCapability, undefined); + transceiver.setCodecPreferences([codecCapability]); + + const senderStreams = transceiver.sender.createEncodedStreams(); + exchangeIceCandidates(caller, callee); + await exchangeOfferAnswer(caller, callee); + return senderStreams.readable.getReader(); +} diff --git a/testing/web-platform/tests/webrtc-encoded-transform/idlharness.https.window.js b/testing/web-platform/tests/webrtc-encoded-transform/idlharness.https.window.js new file mode 100644 index 0000000000..2c6ef19ca8 --- /dev/null +++ b/testing/web-platform/tests/webrtc-encoded-transform/idlharness.https.window.js @@ -0,0 +1,18 @@ +// META: script=/resources/WebIDLParser.js +// META: script=/resources/idlharness.js +// META: script=./RTCPeerConnection-helper.js + +'use strict'; + +idl_test( + ['webrtc-encoded-transform'], + ['webrtc', 'streams', 'html', 'dom'], + async idlArray => { + idlArray.add_objects({ + // TODO: RTCEncodedVideoFrame + // TODO: RTCEncodedAudioFrame + RTCRtpSender: [`new RTCPeerConnection().addTransceiver('audio').sender`], + RTCRtpReceiver: [`new RTCPeerConnection().addTransceiver('audio').receiver`], + }); + } +); diff --git a/testing/web-platform/tests/webrtc-encoded-transform/resources/blank.html b/testing/web-platform/tests/webrtc-encoded-transform/resources/blank.html new file mode 100644 index 0000000000..a3c3a4689a --- /dev/null +++ b/testing/web-platform/tests/webrtc-encoded-transform/resources/blank.html @@ -0,0 +1,2 @@ + +Empty doc diff --git a/testing/web-platform/tests/webrtc-encoded-transform/resources/serviceworker-failure.js b/testing/web-platform/tests/webrtc-encoded-transform/resources/serviceworker-failure.js new file mode 100644 index 0000000000..e7aa8e11be --- /dev/null +++ b/testing/web-platform/tests/webrtc-encoded-transform/resources/serviceworker-failure.js @@ -0,0 +1,30 @@ +// Based on similar tests in html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/. +"use strict"; +self.importScripts("/resources/testharness.js"); + +let state = "start in worker"; + +self.onmessage = e => { + if (e.data === "start in window") { + assert_equals(state, "start in worker"); + e.source.postMessage(state); + state = "we are expecting a messageerror due to the window sending us an RTCEncodedVideoFrame or RTCEncodedAudioFrame"; + } else { + e.source.postMessage(`worker onmessage was reached when in state "${state}" and data ${e.data}`); + } +}; + +self.onmessageerror = e => { + if (state === "we are expecting a messageerror due to the window sending us an RTCEncodedVideoFrame or RTCEncodedAudioFrame") { + assert_equals(e.constructor.name, "ExtendableMessageEvent", "type"); + assert_equals(e.data, null, "data"); + assert_equals(e.origin, self.origin, "origin"); + assert_not_equals(e.source, null, "source"); + assert_equals(e.ports.length, 0, "ports length"); + + state = "onmessageerror was received in worker"; + e.source.postMessage(state); + } else { + e.source.postMessage(`worker onmessageerror was reached when in state "${state}" and data ${e.data}`); + } +}; diff --git a/testing/web-platform/tests/webrtc-encoded-transform/routines.js b/testing/web-platform/tests/webrtc-encoded-transform/routines.js new file mode 100644 index 0000000000..4db7f39621 --- /dev/null +++ b/testing/web-platform/tests/webrtc-encoded-transform/routines.js @@ -0,0 +1,32 @@ +async function createConnections(test, setupLocalConnection, setupRemoteConnection, doNotCloseAutmoatically) { + const localConnection = new RTCPeerConnection(); + const remoteConnection = new RTCPeerConnection(); + + remoteConnection.onicecandidate = (event) => { localConnection.addIceCandidate(event.candidate); }; + localConnection.onicecandidate = (event) => { remoteConnection.addIceCandidate(event.candidate); }; + + await setupLocalConnection(localConnection); + await setupRemoteConnection(remoteConnection); + + const offer = await localConnection.createOffer(); + await localConnection.setLocalDescription(offer); + await remoteConnection.setRemoteDescription(offer); + + const answer = await remoteConnection.createAnswer(); + await remoteConnection.setLocalDescription(answer); + await localConnection.setRemoteDescription(answer); + + if (!doNotCloseAutmoatically) { + test.add_cleanup(() => { + localConnection.close(); + remoteConnection.close(); + }); + } + + return [localConnection, remoteConnection]; +} + +function waitFor(test, duration) +{ + return new Promise((resolve) => test.step_timeout(resolve, duration)); +} diff --git a/testing/web-platform/tests/webrtc-encoded-transform/script-audio-transform-worker.js b/testing/web-platform/tests/webrtc-encoded-transform/script-audio-transform-worker.js new file mode 100644 index 0000000000..7cb43713d3 --- /dev/null +++ b/testing/web-platform/tests/webrtc-encoded-transform/script-audio-transform-worker.js @@ -0,0 +1,30 @@ +class MockRTCRtpTransformer { + constructor(transformer) { + this.context = transformer; + this.start(); + } + start() + { + this.reader = this.context.readable.getReader(); + this.writer = this.context.writable.getWriter(); + this.process(); + this.context.options.port.postMessage("started " + this.context.options.mediaType + " " + this.context.options.side); + } + + process() + { + this.reader.read().then(chunk => { + if (chunk.done) + return; + + this.writer.write(chunk.value); + this.process(); + }); + } +}; + +onrtctransform = (event) => { + new MockRTCRtpTransformer(event.transformer); +}; + +self.postMessage("registered"); diff --git a/testing/web-platform/tests/webrtc-encoded-transform/script-audio-transform.https.html b/testing/web-platform/tests/webrtc-encoded-transform/script-audio-transform.https.html new file mode 100644 index 0000000000..0d7f401582 --- /dev/null +++ b/testing/web-platform/tests/webrtc-encoded-transform/script-audio-transform.https.html @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + diff --git a/testing/web-platform/tests/webrtc-encoded-transform/script-change-transform-worker.js b/testing/web-platform/tests/webrtc-encoded-transform/script-change-transform-worker.js new file mode 100644 index 0000000000..84a7aaac18 --- /dev/null +++ b/testing/web-platform/tests/webrtc-encoded-transform/script-change-transform-worker.js @@ -0,0 +1,39 @@ +function appendToBuffer(buffer, value) { + const result = new ArrayBuffer(buffer.byteLength + 1); + const byteResult = new Uint8Array(result); + byteResult.set(new Uint8Array(buffer), 0); + byteResult[buffer.byteLength] = value; + return result; +} + +onrtctransform = (event) => { + const transformer = event.transformer; + + transformer.reader = transformer.readable.getReader(); + transformer.writer = transformer.writable.getWriter(); + + function process(transformer) + { + transformer.reader.read().then(chunk => { + if (chunk.done) + return; + if (transformer.options.name === 'sender1') + chunk.value.data = appendToBuffer(chunk.value.data, 1); + else if (transformer.options.name === 'sender2') + chunk.value.data = appendToBuffer(chunk.value.data, 2); + else { + const value = new Uint8Array(chunk.value.data)[chunk.value.data.byteLength - 1]; + if (value !== 1 && value !== 2) + self.postMessage("unexpected value: " + value); + else if (value === 2) + self.postMessage("got value 2"); + chunk.value.data = chunk.value.data.slice(0, chunk.value.data.byteLength - 1); + } + transformer.writer.write(chunk.value); + process(transformer); + }); + } + + process(transformer); +}; +self.postMessage("registered"); diff --git a/testing/web-platform/tests/webrtc-encoded-transform/script-change-transform.https.html b/testing/web-platform/tests/webrtc-encoded-transform/script-change-transform.https.html new file mode 100644 index 0000000000..9ec82a9484 --- /dev/null +++ b/testing/web-platform/tests/webrtc-encoded-transform/script-change-transform.https.html @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + diff --git a/testing/web-platform/tests/webrtc-encoded-transform/script-late-transform.https.html b/testing/web-platform/tests/webrtc-encoded-transform/script-late-transform.https.html new file mode 100644 index 0000000000..726852bad9 --- /dev/null +++ b/testing/web-platform/tests/webrtc-encoded-transform/script-late-transform.https.html @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + diff --git a/testing/web-platform/tests/webrtc-encoded-transform/script-metadata-transform-worker.js b/testing/web-platform/tests/webrtc-encoded-transform/script-metadata-transform-worker.js new file mode 100644 index 0000000000..03ba1f4ee6 --- /dev/null +++ b/testing/web-platform/tests/webrtc-encoded-transform/script-metadata-transform-worker.js @@ -0,0 +1,24 @@ +onrtctransform = (event) => { + const transformer = event.transformer; + + transformer.reader = transformer.readable.getReader(); + transformer.writer = transformer.writable.getWriter(); + + let isFirstFrame = true; + function process(transformer) + { + transformer.reader.read().then(chunk => { + if (chunk.done) + return; + + if (isFirstFrame) { + isFirstFrame = false; + self.postMessage({ name: transformer.options.name, timestamp: chunk.value.timestamp, metadata: chunk.value.getMetadata() }); + } + transformer.writer.write(chunk.value); + process(transformer); + }); + } + process(transformer); +}; +self.postMessage("registered"); diff --git a/testing/web-platform/tests/webrtc-encoded-transform/script-metadata-transform.https.html b/testing/web-platform/tests/webrtc-encoded-transform/script-metadata-transform.https.html new file mode 100644 index 0000000000..c565caba7d --- /dev/null +++ b/testing/web-platform/tests/webrtc-encoded-transform/script-metadata-transform.https.html @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + diff --git a/testing/web-platform/tests/webrtc-encoded-transform/script-transform-worker.js b/testing/web-platform/tests/webrtc-encoded-transform/script-transform-worker.js new file mode 100644 index 0000000000..5ea99cd2bf --- /dev/null +++ b/testing/web-platform/tests/webrtc-encoded-transform/script-transform-worker.js @@ -0,0 +1,25 @@ +onrtctransform = (event) => { + const transformer = event.transformer; + transformer.options.port.onmessage = (event) => transformer.options.port.postMessage(event.data); + + self.postMessage("started"); + transformer.reader = transformer.readable.getReader(); + transformer.writer = transformer.writable.getWriter(); + + function process(transformer) + { + transformer.reader.read().then(chunk => { + if (chunk.done) + return; + if (chunk.value instanceof RTCEncodedVideoFrame) + self.postMessage("video chunk"); + else if (chunk.value instanceof RTCEncodedAudioFrame) + self.postMessage("audio chunk"); + transformer.writer.write(chunk.value); + process(transformer); + }); + } + + process(transformer); +}; +self.postMessage("registered"); diff --git a/testing/web-platform/tests/webrtc-encoded-transform/script-transform.https.html b/testing/web-platform/tests/webrtc-encoded-transform/script-transform.https.html new file mode 100644 index 0000000000..e02982f470 --- /dev/null +++ b/testing/web-platform/tests/webrtc-encoded-transform/script-transform.https.html @@ -0,0 +1,153 @@ + + + + + + + + + + + + + + + + + diff --git a/testing/web-platform/tests/webrtc-encoded-transform/script-write-twice-transform-worker.js b/testing/web-platform/tests/webrtc-encoded-transform/script-write-twice-transform-worker.js new file mode 100644 index 0000000000..5d428c81b3 --- /dev/null +++ b/testing/web-platform/tests/webrtc-encoded-transform/script-write-twice-transform-worker.js @@ -0,0 +1,22 @@ +onrtctransform = (event) => { + const transformer = event.transformer; + + self.postMessage("started"); + + transformer.reader = transformer.readable.getReader(); + transformer.writer = transformer.writable.getWriter(); + function process(transformer) + { + transformer.reader.read().then(chunk => { + if (chunk.done) + return; + + transformer.writer.write(chunk.value); + transformer.writer.write(chunk.value); + process(transformer); + }); + } + + process(transformer); +}; +self.postMessage("registered"); diff --git a/testing/web-platform/tests/webrtc-encoded-transform/script-write-twice-transform.https.html b/testing/web-platform/tests/webrtc-encoded-transform/script-write-twice-transform.https.html new file mode 100644 index 0000000000..c4a49af7ac --- /dev/null +++ b/testing/web-platform/tests/webrtc-encoded-transform/script-write-twice-transform.https.html @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + diff --git a/testing/web-platform/tests/webrtc-encoded-transform/set-metadata.https.html b/testing/web-platform/tests/webrtc-encoded-transform/set-metadata.https.html new file mode 100644 index 0000000000..712971a626 --- /dev/null +++ b/testing/web-platform/tests/webrtc-encoded-transform/set-metadata.https.html @@ -0,0 +1,83 @@ + + + + + + + + + + diff --git a/testing/web-platform/tests/webrtc-encoded-transform/sframe-keys.https.html b/testing/web-platform/tests/webrtc-encoded-transform/sframe-keys.https.html new file mode 100644 index 0000000000..c87ac12e29 --- /dev/null +++ b/testing/web-platform/tests/webrtc-encoded-transform/sframe-keys.https.html @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + diff --git a/testing/web-platform/tests/webrtc-encoded-transform/sframe-transform-buffer-source.html b/testing/web-platform/tests/webrtc-encoded-transform/sframe-transform-buffer-source.html new file mode 100644 index 0000000000..99b45f22c9 --- /dev/null +++ b/testing/web-platform/tests/webrtc-encoded-transform/sframe-transform-buffer-source.html @@ -0,0 +1,50 @@ + + + + + + + + + + + diff --git a/testing/web-platform/tests/webrtc-encoded-transform/sframe-transform-in-worker.https.html b/testing/web-platform/tests/webrtc-encoded-transform/sframe-transform-in-worker.https.html new file mode 100644 index 0000000000..f5d7b5a930 --- /dev/null +++ b/testing/web-platform/tests/webrtc-encoded-transform/sframe-transform-in-worker.https.html @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + diff --git a/testing/web-platform/tests/webrtc-encoded-transform/sframe-transform-readable.html b/testing/web-platform/tests/webrtc-encoded-transform/sframe-transform-readable.html new file mode 100644 index 0000000000..2afce1b271 --- /dev/null +++ b/testing/web-platform/tests/webrtc-encoded-transform/sframe-transform-readable.html @@ -0,0 +1,19 @@ + + + + + + + + + + + + diff --git a/testing/web-platform/tests/webrtc-encoded-transform/sframe-transform-worker.js b/testing/web-platform/tests/webrtc-encoded-transform/sframe-transform-worker.js new file mode 100644 index 0000000000..617cf0a38a --- /dev/null +++ b/testing/web-platform/tests/webrtc-encoded-transform/sframe-transform-worker.js @@ -0,0 +1,7 @@ +onrtctransform = (event) => { + const sframeTransform = new SFrameTransform({ role : "decrypt", authenticationSize: "10", compatibilityMode: "H264" }); + crypto.subtle.importKey("raw", new Uint8Array([143, 77, 43, 10, 72, 19, 37, 67, 236, 219, 24, 93, 26, 165, 91, 178]), "HKDF", false, ["deriveBits", "deriveKey"]).then(key => sframeTransform.setEncryptionKey(key)); + const transformer = event.transformer; + transformer.readable.pipeThrough(sframeTransform).pipeTo(transformer.writable); +} +self.postMessage("registered"); diff --git a/testing/web-platform/tests/webrtc-encoded-transform/sframe-transform.html b/testing/web-platform/tests/webrtc-encoded-transform/sframe-transform.html new file mode 100644 index 0000000000..2e40135b04 --- /dev/null +++ b/testing/web-platform/tests/webrtc-encoded-transform/sframe-transform.html @@ -0,0 +1,141 @@ + + + + + + + + + + + -- cgit v1.2.3