Branch: refs/heads/main
  Home:   https://github.com/WebKit/WebKit
  Commit: 0db3c1ac8328c2ebb580ddaebfb075b9a1bda3d7
      
https://github.com/WebKit/WebKit/commit/0db3c1ac8328c2ebb580ddaebfb075b9a1bda3d7
  Author: Jean-Yves Avenard <[email protected]>
  Date:   2026-09-23 (Wed, 23 Sep 2026)

  Changed paths:
    M Source/WebCore/Modules/webcodecs/WebCodecsAudioDecoder.cpp
    M Source/WebCore/Modules/webcodecs/WebCodecsEncodedAudioChunk.cpp
    M Source/WebCore/Modules/webcodecs/WebCodecsEncodedAudioChunk.h
    M Source/WebCore/Modules/webcodecs/WebCodecsEncodedVideoChunk.cpp
    M Source/WebCore/Modules/webcodecs/WebCodecsEncodedVideoChunk.h
    M Source/WebCore/Modules/webcodecs/WebCodecsVideoDecoder.cpp
    M Source/WebCore/platform/AudioDecoder.cpp
    M Source/WebCore/platform/AudioDecoder.h
    M Source/WebCore/platform/VideoDecoder.cpp
    M Source/WebCore/platform/VideoDecoder.h
    M Source/WebCore/platform/audio/cocoa/AudioDecoderCocoa.cpp
    M Source/WebCore/platform/audio/gstreamer/AudioDecoderGStreamer.cpp
    M Source/WebCore/platform/graphics/cocoa/WebCoreDecompressionSession.mm
    M Source/WebCore/platform/graphics/gstreamer/GStreamerCommon.cpp
    M Source/WebCore/platform/graphics/gstreamer/GStreamerCommon.h
    M Source/WebCore/platform/graphics/gstreamer/VideoDecoderGStreamer.cpp
    M Source/WebCore/platform/libwebrtc/LibWebRTCVPXVideoDecoder.cpp
    M Source/WebKit/WebProcess/GPU/media/RemoteVideoCodecFactory.cpp
    M Source/WebKit/WebProcess/GPU/webrtc/LibWebRTCCodecs.cpp
    M Source/WebKit/WebProcess/GPU/webrtc/LibWebRTCCodecs.h

  Log Message:
  -----------
  {Audio,Video}Decoder should take a Ref<SharedBuffer> instead of a span
https://bugs.webkit.org/show_bug.cgi?id=324679
rdar://187949806

Reviewed by Youenn Fablet and Philippe Normand.

VideoDecoder::EncodedFrame and AudioDecoder::EncodedData held the bytes in a
std::span, which does not own them, so they were only valid for the duration of
the decode() call. Every platform decoder therefore copied the frame into its
own storage before dispatching to its work queue, not because decoding needed a
copy but because the span did not own the bytes. When the page had transferred
its ArrayBuffer, that copy gave back the allocation the transfer had saved.

Both structs now hold a Ref<SharedBuffer>, which owns the bytes, so the decoders
keep the buffer instead of copying it; every caller already had one to hand
over. AudioDecoderCocoa and the GStreamer decoders are copy-free from the page's
ArrayBuffer through to the platform decoder. The bytes are still copied into the
IPC message on the way to the GPU process.

* Source/WebCore/Modules/webcodecs/WebCodecsAudioDecoder.cpp:
(WebCore::WebCodecsAudioDecoder::decode): Pass the chunk's buffer instead of its
span.
* Source/WebCore/Modules/webcodecs/WebCodecsVideoDecoder.cpp:
(WebCore::WebCodecsVideoDecoder::decode): Ditto.
* Source/WebCore/Modules/webcodecs/WebCodecsEncodedAudioChunk.h:
* Source/WebCore/Modules/webcodecs/WebCodecsEncodedVideoChunk.h:
Replace span() with buffer(), which exposes the SharedBuffer the storage already
held.
* Source/WebCore/Modules/webcodecs/WebCodecsEncodedAudioChunk.cpp:
(WebCore::WebCodecsEncodedAudioChunk::copyTo): Take the span from the buffer.
* Source/WebCore/Modules/webcodecs/WebCodecsEncodedVideoChunk.cpp:
(WebCore::WebCodecsEncodedVideoChunk::copyTo): Ditto.
* Source/WebCore/platform/AudioDecoder.h:
* Source/WebCore/platform/VideoDecoder.h:
Hold a Ref<SharedBuffer>, and declare the destructor so that a forward
declaration of SharedBuffer remains sufficient.
* Source/WebCore/platform/AudioDecoder.cpp:
* Source/WebCore/platform/VideoDecoder.cpp:
Define that destructor.
* Source/WebCore/platform/audio/cocoa/AudioDecoderCocoa.cpp:
(WebCore::AudioDecoderCocoa::decode): Move the buffer onto the queue rather than
copying it into a new one; createCMBlockBuffer() already wraps it without
copying, so this path no longer copies at all.
* Source/WebCore/platform/libwebrtc/LibWebRTCVPXVideoDecoder.cpp:
(WebCore::LibWebRTCVPXVideoDecoder::decode): Capture the buffer instead of a
Vector. It keeps the bytes alive for the synchronous call into libwebrtc.
* Source/WebCore/platform/graphics/gstreamer/GStreamerCommon.h:
* Source/WebCore/platform/graphics/gstreamer/GStreamerCommon.cpp:
(WebCore::wrapSharedBuffer): Added. Wraps a SharedBuffer in a GstBuffer without
copying, and keeps the buffer alive until GStreamer releases the GstBuffer.
* Source/WebCore/platform/audio/gstreamer/AudioDecoderGStreamer.cpp:
(WebCore::GStreamerAudioDecoder::decode):
(WebCore::GStreamerInternalAudioDecoder::decode): Use wrapSharedBuffer() in
place of wrapSpanData(), which copied.
* Source/WebCore/platform/graphics/gstreamer/VideoDecoderGStreamer.cpp:
(WebCore::GStreamerVideoDecoder::decode):
(WebCore::GStreamerInternalVideoDecoder::decode): Ditto.
* Source/WebKit/WebProcess/GPU/webrtc/LibWebRTCCodecs.h:
* Source/WebKit/WebProcess/GPU/webrtc/LibWebRTCCodecs.cpp:
(WebKit::LibWebRTCCodecs::decodeFrame): Take a Ref<SharedBuffer>.
(WebKit::LibWebRTCCodecs::decodeFrameInternal): Make it a template over the two
kinds of input. WebCodecs hands over a buffer, while decodeWebRTCFrame() keeps
its span because libwebrtc owns those bytes. Only the branch that queues frames
until the GPU process connection is ready builds a buffer from the span, and
that branch copied already.
* Source/WebKit/WebProcess/GPU/media/RemoteVideoCodecFactory.cpp:
(WebKit::RemoteVideoDecoder::decode): Move the buffer through.
* Source/WebCore/platform/graphics/cocoa/WebCoreDecompressionSession.mm:
(WebCore::WebCoreDecompressionSession::decodeSampleInternal): Use
sharedBufferFromCMBlockBuffer(), which also makes the block buffer contiguous,
so drop the code that did that here. It returns an empty buffer when that fails,
which is now reported as kVTAllocationFailedErr.

Canonical link: https://commits.webkit.org/321694@main



To unsubscribe from these emails, change your notification settings at 
https://github.com/WebKit/WebKit/settings/notifications

Reply via email to