fune/testing/web-platform/tests/webcodecs/video-frame-serialization.any.js
Dan Sanders a7cd0e6bd2 Bug 1692633 [wpt PR 27618] - [webcodecs] Clone VideoFrame when serializing, a=testonly
Automatic update from web-platform-tests
[webcodecs] Clone VideoFrame when serializing

This changes the serialization semantics of VideoFrame so that the
lifetimes of the serialized (source) frame and deserialized (received)
frames are separate. The source and received frames must both be closed.

In the case that there are multiple receivers (eg. BroadcastChannel),
they still share a single handle, and only one of them should be closed.
This is necessary to ensure that no dangling references remain that
would require waiting for GC to destroy the underlying frames.

Bug: 1178038
Change-Id: I2199246b9d7caf9fd317b3c1dc8ae310ced9662d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2694166
Reviewed-by: Jeremy Roman <jbroman@chromium.org>
Reviewed-by: Thomas Guilbert <tguilbert@chromium.org>
Commit-Queue: Dan Sanders <sandersd@chromium.org>
Cr-Commit-Position: refs/heads/master@{#854516}

--

wpt-commits: 07e370ad43485c3b4019fefc3c43f0da512faf7b
wpt-pr: 27618
2021-02-22 16:08:09 +00:00

93 lines
2.2 KiB
JavaScript

// META: global=window,dedicatedworker
// META: script=/common/media.js
// META: script=/webcodecs/utils.js
var defaultInit = {
timestamp : 100,
duration : 33,
}
function createDefaultVideoFrame() {
let image = makeImageBitmap(32,16);
return new VideoFrame(image, defaultInit);
}
test(t => {
let frame = createDefaultVideoFrame();
let clone = frame.clone();
assert_equals(frame.timestamp, clone.timestamp);
assert_equals(frame.duration, clone.duration);
assert_equals(frame.cropWidth, clone.cropWidth);
assert_equals(frame.cropHeight, clone.cropHeight);
assert_equals(frame.cropWidth, clone.cropWidth);
assert_equals(frame.cropHeight, clone.cropHeight);
frame.close();
clone.close();
}, 'Test we can clone a VideoFrame.');
test(t => {
let frame = createDefaultVideoFrame();
let copy = frame;
let clone = frame.clone();
frame.close();
assert_not_equals(copy.timestamp, defaultInit.timestamp);
assert_equals(clone.timestamp, defaultInit.timestamp);
clone.close();
}, 'Verify closing a frame doesn\'t affect its clones.');
test(t => {
let frame = createDefaultVideoFrame();
frame.close();
assert_throws_dom("InvalidStateError", () => {
let clone = frame.clone();
});
}, 'Verify cloning a closed frame throws.');
async_test(t => {
let localFrame = createDefaultVideoFrame();
let channel = new MessageChannel();
let localPort = channel.port1;
let externalPort = channel.port2;
externalPort.onmessage = t.step_func((e) => {
let externalFrame = e.data;
externalFrame.close();
externalPort.postMessage("Done");
})
localPort.onmessage = t.step_func_done((e) => {
assert_equals(localFrame.timestamp, defaultInit.timestamp);
localFrame.close();
})
localPort.postMessage(localFrame);
}, 'Verify closing frames does not propagate accross contexts.');
async_test(t => {
let localFrame = createDefaultVideoFrame();
let channel = new MessageChannel();
let localPort = channel.port1;
localPort.onmessage = t.unreached_func();
localFrame.close();
assert_throws_dom("DataCloneError", () => {
localPort.postMessage(localFrame);
});
t.done();
}, 'Verify posting closed frames throws.');