forked from mirrors/gecko-dev
		
	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
		
			
				
	
	
		
			93 lines
		
	
	
	
		
			2.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			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.');
 |