Skip to content

Instantly share code, notes, and snippets.

@Djuffin
Last active November 27, 2023 22:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Djuffin/1c8fac486ca9f402be85074166e89a16 to your computer and use it in GitHub Desktop.
Save Djuffin/1c8fac486ca9f402be85074166e89a16 to your computer and use it in GitHub Desktop.
Explainer for allow transferring ArrayBuffer into VideoFrame, AudioData, EncodedVideoChunk, EncodedAudioChunk, ImageDecoder constructors

Allow transferring ArrayBuffer into VideoFrame, AudioData, EncodedVideoChunk, EncodedAudioChunk, ImageDecoder constructors

Problem and Motivation

Currently when creating any of the VideoFrame, AudioData, EncodedVideoChunk, EncodedAudioChunk, ImageDecoder objects from corresponding *Init objects constructors make a copy of ArrayBuffer contents into an internal memory buffer.

In many cases the ArrayBuffer is never used again for anything else after a WebCodecs object is created. It means that this copy can be avoided by transfering (moving) ArrayBuffer contents into the WebCodecs objects.

Remember, memcpy is murder.

Proposed solutions

Transfer list

Let's add a transfer list to WebCodecs *Init objects, that would allow developers to signal when they don't need the ArrayBuffer after the object is created. If the transfer list contains the data ArrayBuffer, the ArrayBuffer is detached and its contents are used in the WebCodecs objects without a copy. This is consistent with the approach taken by structuredClone and postMessage

dictionary VideoFrameBufferInit {
   .......
  sequence<ArrayBuffer> transfer = [];  
};

dictionary ImageDecoderInit {
   .....
  sequence<ArrayBuffer> transfer = [];  
};

dictionary EncodedVideoChunkInit {
   .....
  sequence<ArrayBuffer> transfer = [];  
};

dictionary AudioDataInit {
   .....
  sequence<ArrayBuffer> transfer = [];  
}

dictionary  EncodedAudioChunkInit {
   .....
  sequence<ArrayBuffer> transfer = [];  
}

Sample

  
    let prototype_frame = new VideoFrame(canvas, { timestamp: 0 });
    let size = prototype_frame.allocationSize();
    let buf = new ArrayBuffer(size);
    let layout = await prototype_frame.copyTo(buf);
    let init = {
      format: prototype_frame.format,
      timestamp: prototype_frame.timestamp,
      codedWidth: prototype_frame.codedWidth,
      codedHeight: prototype_frame.codedHeight,
      layout: layout,
      transfer: [buf]
    };
    // |buf| is transfered here and becomes detached
    let new_frame = new VideoFrame(buf, init);
  

Links

  1. WebCodecs github issue: w3c/webcodecs#104
  2. Prototype CL for VideoFrame: https://chromium-review.googlesource.com/c/chromium/src/+/4529012
  3. w3c Media Working Group discussion: https://www.w3.org/2023/05/30-mediawg-minutes.html#t01

Self-Review Questionnaire: Security and Privacy

Questions to Consider

  1. What information might this feature expose to Web sites or other parties, and for what purposes is that exposure necessary?

    no new information

  2. Do features in your specification expose the minimum amount of information necessary to enable their intended uses? yes

  3. How do the features in your specification deal with personal information, personally-identifiable information (PII), or information derived from them?

    No new personal information is handled

  4. How do the features in your specification deal with sensitive information?

    The feature doesn't deail with sensitive information

  5. Do the features in your specification introduce new state for an origin that persists across browsing sessions?

    No

  6. Do the features in your specification expose information about the underlying platform to origins?

    No

  7. Does this specification allow an origin to send data to the underlying platform?

    No

  8. Do features in this specification enable access to device sensors?

    No

  9. Do features in this specification enable new script execution/loading mechanisms?

    No

  10. Do features in this specification allow an origin to access other devices?

    No

  11. Do features in this specification allow an origin some measure of control over a user agent’s native UI?

    No

  12. What temporary identifiers do the features in this specification create or expose to the web?

    No

  13. How does this specification distinguish between behavior in first-party and third-party contexts?

    Doesn't distinguish

  14. How do the features in this specification work in the context of a browser’s Private Browsing or Incognito mode?

    No difference.

  15. Does this specification have both "Security Considerations" and "Privacy Considerations" sections?

  16. Do features in your specification enable origins to downgrade default security protections?

    No

  17. How does your feature handle non-"fully active" documents?

    N/A

  18. What should this questionnaire have asked?

    Too many questions already.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment