luv

Workshop wiki

frame.lisp

libav/frame.lisp

system luv/libav · 18 definitions · on GitHub

An explicitly owned AVFrame.

AVFrame has two lifetimes stacked on top of each other: the struct itself, allocated by av_frame_alloc and released by av_frame_free, and the reference-counted buffers it points at, which av_frame_unref drops without disturbing the struct. A decode loop reuses one frame across thousands of pictures by unreferencing between them, so the two are kept separate here rather than folded into one "close".

Nothing in this file copies pixels. A hardware frame does not have any to copy -- its `data[3]' is a CVPixelBuffer, a VASurfaceID, or an AVVkFrame -- and the software path wants its planes uploaded straight from the decoder's memory rather than through a Lisp array.

in-package#:luv.libav
defclassframe
pointer:initarg:pointer:readerframe-pointer
:documentation

An explicitly owned AVFrame.

cffi:defcfun
"av_frame_clone"%av-frame-clone
:pointer
source:pointer
defunframe-live-p
not
cffi:null-pointer-p
frame-pointerframe
defunensure-frame-live
unless
error"The AVFrame ~S has been released."frame
frame
defunmake-frame

Allocate an empty AVFrame. It carries no picture until something fills it.

let
pointer
%av-frame-alloc
when
cffi:null-pointer-ppointer
error"av_frame_alloc could not allocate an AVFrame."
make-instance'frame:pointerpointer
defunclone-frame

Return a new reference to frame and all buffers backing its picture.

let
pointer
%av-frame-clone
when
cffi:null-pointer-ppointer
error"av_frame_clone could not retain the decoded picture."
make-instance'frame:pointerpointer
defunrelease-frame

Release frame and any buffers it holds. Repeated calls are harmless.

when

av_frame_free takes the address of the pointer and nulls it, so hand it a cell rather than the pointer itself.

cffi:with-foreign-object
cell:pointer
setf
cffi:mem-refcell:pointer
frame-pointerframe
%av-frame-freecell
setf
slot-valueframe'pointer
cffi:null-pointer
frame
defmacrowith-frame
&bodybody

Evaluate body with variable bound to a fresh frame, releasing it after.

`
let
unwind-protect
progn,@body
defununreference-frame

Drop frame's buffers, leaving the struct ready to receive another picture.

%av-frame-unref
frame-pointerframe
frame
macrolet
define-frame-slot`
progn
defun,name,documentation
cffi:foreign-slot-value'
:structav-frame
',slot
defun
setf,name
valueframe
setf
cffi:foreign-slot-value'
:structav-frame
',slot
value
define-frame-slotframe-widthwidth"FRAME's width in pixels."
define-frame-slotframe-heightheight"FRAME's height in pixels."
define-frame-slotframe-presentation-timestamppresentation-timestamp"FRAME's presentation timestamp, in its stream's time base."
define-frame-slotframe-durationduration"FRAME's duration, in its stream's time base."
defunframe-pixel-format

frame's pixel format as a keyword, or its raw integer when unrecognised.

A hardware format -- :VIDEOTOOLBOX, :VAAPI, :VULKAN -- means the picture never touched the CPU and frame's third plane holds a platform surface.

let
format
cffi:foreign-slot-value'
:structav-frame
'format
or
cffi:foreign-enum-keyword'pixel-formatformat:errorpnil
format
defun
formatframe
setf
cffi:foreign-slot-value'
:structav-frame
'format
if
keywordpformat
cffi:foreign-enum-value'pixel-formatformat
format
format
defunframe-key-p

True when frame is a key frame.

logtest+frame-flag-key+
cffi:foreign-slot-value'
:structav-frame
'flags
defunframe-hardware-p

True when frame's picture lives in a hardware frames pool, not in memory.

not
cffi:null-pointer-p
cffi:foreign-slot-value'
:structav-frame
'hardware-frames-context
defunframe-plane-pointer
frameplane

Return the foreign pointer to frame's plane, counting from zero.

check-typeplane
integer07
cffi:mem-aref
cffi:foreign-slot-pointer'
:structav-frame
'data
:pointerplane
defunframe-videotoolbox-pixel-buffer

Return frame's borrowed CVPixelBuffer, or NIL for a non-VideoToolbox frame.

when
let
unless
cffi:null-pointer-pbuffer
buffer
defunframe-vulkan-frame

Return frame's borrowed AVVkFrame, or NIL for a non-Vulkan frame.

when
let
unless
cffi:null-pointer-pvulkan-frame
vulkan-frame
defunframe-plane-pitch
frameplane

Return the byte stride of frame's plane, which exceeds its width when padded.

check-typeplane
integer07
cffi:mem-aref
cffi:foreign-slot-pointer'
:structav-frame
'pitches
:intplane
defunallocate-frame-buffer
frame&key
alignment0

Allocate buffers for frame's current width, height, and pixel format.

An alignment of zero lets FFmpeg choose the alignment its own SIMD paths want, which is what a decoder would do.

check-code
%av-frame-get-buffer
frame-pointerframe
alignment
'allocate-frame-buffer
frame