Module webcodecs
WebCodecs (src/page/bindings_webcodecs.odin, webcodecs_frame.odin): the pixel model, memory accounting and format conversions of a VideoFrame are native. The engine (native/js/runtime/web_webcodecs.c) holds the VideoFrame wrapper, builds the VideoFrameInit / VideoFrameBufferInit / VideoFrameCopyToOptions dictionaries, resolves copyTo's promise and transfers the handle in a postMessage. A VideoFrame is a host object (OBJECT_TAG); drawImage and createImageBitmap resolve it through the canvas image-source path. Decoders and encoders come in later modules.
Exposed to: Window, Worker. Source: api/webcodecs.widl.
Odin: import "wren:webcodecs".
Types
handle VideoFrame : Object
Checked by the browser on every call (lookup_VideoFrame).
enum VideoPixelFormat : i32
WebCodecs VideoPixelFormat, in the order webcodecs_frame.odin's Frame_Format uses (format() returns -1 for a closed frame, which the engine maps to null).
| member | value | |
|---|---|---|
None | 0 | |
I420 | 1 | |
I420A | 2 | |
I422 | 3 | |
I444 | 4 | |
NV12 | 5 | |
RGBA | 6 | |
RGBX | 7 | |
BGRA | 8 | |
BGRX | 9 |
Functions
VideoFrame_fromImage
VideoFrame VideoFrame_fromImage(u64 source, i64 timestamp, bool has_ts, i64 duration, bool has_duration) raises/////////////////////////////
new VideoFrame(image, init): build from a drawable source (an element handle img / canvas / video, or an object
handle ImageBitmap / OffscreenCanvas / VideoFrame). The source's pixels are captured now. timestamp (microseconds)
is required for a source without an intrinsic one; has_ts says it was given. Invalid_State when the source has no
pixels (not loaded, empty, a GPU-only video), Quota when it is too large, Not_Supported when WebCodecs is off.
Raises: returns an Error (see web).
Host: VideoFrame_fromImage :: proc(c: ^Call, source: u64, timestamp: i64, has_ts: bool, duration: i64, has_duration: bool) -> (u64, Api_Error)
VideoFrame_fromBuffer
VideoFrame VideoFrame_fromBuffer(bytes data, VideoPixelFormat format, i32 coded_w, i32 coded_h, i64 timestamp, i64 duration, bool has_duration, i32 vis_x, i32 vis_y, i32 vis_w, i32 vis_h, bool has_visible, i32 display_w, i32 display_h, bool has_display, i32[] layout_offsets, i32[] layout_strides, bool has_layout, i32 cp_prim, i32 cp_trans, i32 cp_matrix, i32 cp_full, i32 cp_has) raisesnew VideoFrame(bufferSource, init): build from raw pixel bytes with a VideoFrameBufferInit. format, coded_w,
coded_h and timestamp are required (the engine checks). has_visible / has_display carry the optional
visibleRect and displaySize; a custom plane layout gives layout_offsets / layout_strides (one per plane) when
has_layout. Colour space members are -1 when absent; cp_has says a colorSpace was given at all.
Raises: returns an Error (see web).
Host: VideoFrame_fromBuffer :: proc(c: ^Call, data: []u8, format: Api_VideoPixelFormat, coded_w: i32, coded_h: i32, timestamp: i64, duration: i64, has_duration: bool, vis_x: i32, vis_y: i32, vis_w: i32, vis_h: i32, has_visible: bool, display_w: i32, display_h: i32, has_display: bool, layout_offsets: []i32, layout_strides: []i32, has_layout: bool, cp_prim: i32, cp_trans: i32, cp_matrix: i32, cp_full: i32, cp_has: i32) -> (u64, Api_Error)
VideoFrame_format
i32 VideoFrame_format(VideoFrame frame)///////////////////////////// frame.format: -1 (null) for a closed frame.
Host: VideoFrame_format :: proc(c: ^Call, frame: Api_VideoFrame) -> i32
VideoFrame_codedWidth
u32 VideoFrame_codedWidth(VideoFrame frame)Host: VideoFrame_codedWidth :: proc(c: ^Call, frame: Api_VideoFrame) -> u32
VideoFrame_codedHeight
u32 VideoFrame_codedHeight(VideoFrame frame)Host: VideoFrame_codedHeight :: proc(c: ^Call, frame: Api_VideoFrame) -> u32
VideoFrame_displayWidth
u32 VideoFrame_displayWidth(VideoFrame frame)Host: VideoFrame_displayWidth :: proc(c: ^Call, frame: Api_VideoFrame) -> u32
VideoFrame_displayHeight
u32 VideoFrame_displayHeight(VideoFrame frame)Host: VideoFrame_displayHeight :: proc(c: ^Call, frame: Api_VideoFrame) -> u32
VideoFrame_timestamp
i64 VideoFrame_timestamp(VideoFrame frame)frame.timestamp / duration, in microseconds (duration is -1 when the frame has none, which the engine maps to null).
Host: VideoFrame_timestamp :: proc(c: ^Call, frame: Api_VideoFrame) -> i64
VideoFrame_duration
i64 VideoFrame_duration(VideoFrame frame)Host: VideoFrame_duration :: proc(c: ^Call, frame: Api_VideoFrame) -> i64
VideoFrame_visibleRect
f64 VideoFrame_visibleRect(VideoFrame frame, i32 which)frame.visibleRect: which 0..3 selects x, y, width, height. -1 for a closed frame (null).
Host: VideoFrame_visibleRect :: proc(c: ^Call, frame: Api_VideoFrame, which: i32) -> f64
VideoFrame_colorSpace
i32 VideoFrame_colorSpace(VideoFrame frame, i32 which)frame.colorSpace: which selects primaries (0), transfer (1), matrix (2) or full-range (3); -1 means null (absent), else the enum index (VideoColorPrimaries / VideoTransferCharacteristics / VideoMatrixCoefficients) or the bool.
Host: VideoFrame_colorSpace :: proc(c: ^Call, frame: Api_VideoFrame, which: i32) -> i32
VideoFrame_isClosed
bool VideoFrame_isClosed(VideoFrame frame)Whether the frame has been closed (its pixels freed).
Host: VideoFrame_isClosed :: proc(c: ^Call, frame: Api_VideoFrame) -> bool
VideoFrame_allocationSize
i32 VideoFrame_allocationSize(VideoFrame frame, i32 format, i32 rx, i32 ry, i32 rw, i32 rh, bool has_rect, i32[] layout_offsets, i32[] layout_strides, bool has_layout) raises/////////////////////////////
frame.allocationSize(options): the bytes copyTo needs. format -1 keeps the frame's own; has_rect gives a crop
rectangle; a custom layout's strides are honoured when has_layout.
Raises: returns an Error (see web).
Host: VideoFrame_allocationSize :: proc(c: ^Call, frame: Api_VideoFrame, format: i32, rx: i32, ry: i32, rw: i32, rh: i32, has_rect: bool, layout_offsets: []i32, layout_strides: []i32, has_layout: bool) -> (i32, Api_Error)
VideoFrame_copyTo
i32 VideoFrame_copyTo(VideoFrame frame, out bytes dst, i32 format, i32 rx, i32 ry, i32 rw, i32 rh, bool has_rect, i32[] in_offsets, i32[] in_strides, bool has_layout) raisesframe.copyTo(destination, options): copies the frame (or its crop rectangle) into dst as format (-1 = own).
The plane layout used is kept on the frame (read it with VideoFrame_copyLayout); the return is the plane
count. The engine wraps this in a promise resolving to a PlaneLayout[]. Range for a rectangle outside the picture,
Not_Supported for an unsupported conversion, Invalid_State for a closed frame.
Raises: returns an Error (see web).
Host: VideoFrame_copyTo :: proc(c: ^Call, frame: Api_VideoFrame, dst: []u8, format: i32, rx: i32, ry: i32, rw: i32, rh: i32, has_rect: bool, in_offsets: []i32, in_strides: []i32, has_layout: bool) -> (i32, Api_Error)
VideoFrame_copyLayout
i32 VideoFrame_copyLayout(VideoFrame frame, i32 plane, i32 which)The plane layout the last copyTo of frame used: which 0 is the offset, 1 the stride, of plane plane.
Host: VideoFrame_copyLayout :: proc(c: ^Call, frame: Api_VideoFrame, plane: i32, which: i32) -> i32
VideoFrame_clone
VideoFrame VideoFrame_clone(VideoFrame frame) raises///////////////////////////// frame.clone(): a new VideoFrame sharing the timing, with its own copy of the pixels.
Raises: returns an Error (see web).
Host: VideoFrame_clone :: proc(c: ^Call, frame: Api_VideoFrame) -> (u64, Api_Error)
VideoFrame_close
void VideoFrame_close(VideoFrame frame)frame.close(): free the pixels; the handle stays valid but closed.
Host: VideoFrame_close :: proc(c: ^Call, frame: Api_VideoFrame)
VideoFrame_transfer
VideoFrame VideoFrame_transfer(VideoFrame frame, u32 owner) raisespostMessage transfer within one realm: move the pixels into a new object (owner = the receiving realm's instance), closing the original. Data_Clone when it is already detached.
Raises: returns an Error (see web).
Host: VideoFrame_transfer :: proc(c: ^Call, frame: Api_VideoFrame, owner: u32) -> (u64, Api_Error)
VideoFrame_takeForTransfer
u64 VideoFrame_takeForTransfer(VideoFrame frame)Cross-realm transfer (postMessage to a worker): the source realm detaches the frame into a process-wide token; the destination realm adopts it. The pixels stay host-owned throughout. Both are used by structured clone (native/js/runtime/clone.c). takeForTransfer returns 0 when the frame is already closed; adoptTransfer returns 0 when the token is unknown or the destination is over its memory budget.
Host: VideoFrame_takeForTransfer :: proc(c: ^Call, frame: Api_VideoFrame) -> u64
VideoFrame_adoptTransfer
VideoFrame VideoFrame_adoptTransfer(u64 token)Host: VideoFrame_adoptTransfer :: proc(c: ^Call, token: u64) -> u64