Decoders¶
Decoders convert encoded Limef::frame::PacketFrames into
decoded Limef::frame::DecodedFrames.
The abstract interface is Limef::decode::Decoder; the main
implementation is Limef::decode::FFmpegDecoder.
-
namespace decode¶
Decoding utilities.
Typedefs
-
using VideoDecoderParams = std::variant<FFmpegDecoderParams, V4L2DecoderParams, V4L2NVDecoderParams>¶
Variant type for decoder parameters.
All backend param types are always present - no compile-time ifdefs. Use isDecoderAvailable() to check runtime availability before creating.
Example:
// FFmpeg backend (always available) FFmpegDecoderParams ffmpeg_params; ffmpeg_params.thread_count = 4; VideoDecoderParams params = ffmpeg_params; // V4L2 backend (check availability first) if (isDecoderAvailable(DecoderBackend::V4L2)) { V4L2NVDecoderParams v4l2_params; v4l2_params.device = "/dev/video0"; VideoDecoderParams params = v4l2_params; }
Enums
Functions
-
std::vector<DecoderBackend> getAvailableDecoders()¶
Get list of available decoder backends.
Returns backends that are both compiled in AND have runtime support. FFmpeg is always available; V4L2 requires device files to exist.
-
bool isDecoderAvailable(DecoderBackend backend)¶
Check if a specific decoder backend is available.
-
DecoderBackend getBackend(const VideoDecoderParams ¶ms)¶
Get the backend type from decoder params.
-
Decoder *createDecoder(const std::string &name, const AVStream *stream, const VideoDecoderParams ¶ms)¶
Create a decoder from variant parameters.
Factory function that creates the appropriate decoder based on the active type in the params variant.
Note: Decoders require stream information at creation time (unlike encoders which can be configured lazily). The stream comes from CodecFrame.
- Parameters:
name – Identifier for logging
stream – AVStream to decode (from CodecFrame)
params – Decoder parameters (variant of FFmpegDecoderParams, V4L2NVDecoderParams, etc.)
- Throws:
std::runtime_error – if backend not compiled in or not available
- Returns:
Decoder* Newly created decoder (caller owns)
-
class Decoder¶
- #include <decoder.h>
Abstract decoder interface for a single video or audio stream.
State machine that decodes packets into frames. Call status() to determine what operation to do next. Decoder may attach resources to the DecodedFrame which lifetime it manages As decoder is going to be used with filterchains, i.e. with blocking callbacks and synchronous operations, this contract holds:
call to status() releases the resources associated with the previous frame
getFrame() reserves resources for the new frame
resources must be hold between calls to getFrame() -> status(), after that they can be freed
..the DecodedFrame is typically pushed down the filterchain between getFrame() and status() calls
Implementations:
FFmpegDecoder: FFmpeg-based software/hardware decoding
V4L2NVDecoder: V4L2 Memory-to-Memory API (Jetson, embedded Linux)
Example usage:
std::unique_ptr<Decoder> dec = std::make_unique<FFmpegDecoder>("my-decoder", stream); DecoderStatus stat; dec->setDecodedFrame(decoded_frame); // the following lines would be put inside a while loop stat = dec->status(); if (stat == DecoderStatus::NeedsMoreData) { dec->push(packet_frame); } if (stat == DecoderStatus::NeedsRead) { const DecodedFrame& decframe = dec->getFrame(); // if the decoder has reserved resources (fds, shmem) from the previous // frame, those can be released when the client calls getFrame() // decframe now has the bitmap (typically YUV420P) or decoded audio } if (stat == DecoderStatus::EndOfStream) { // just exit } if (stat == DecoderStatus::Error) { // something went wrong }
All calls to decoder are non-blocking.
Subclassed by Limef::decode::FFmpegDecoder, Limef::decode::V4L2Decoder, Limef::decode::V4L2NVDecoder
Public Functions
Set logger for this decoder.
-
virtual void setDecodedFrame(Limef::frame::DecodedFrame &frame) = 0¶
Set output frame.
Must be called before decoder can be used. Frame will be reused for decoded output.
- Parameters:
frame – Frame to use for decoded output
-
virtual DecoderStatus status() = 0¶
Get current decoder status.
Call this to determine what operation to do next:
NeedsMoreData: Call push() with next packet
NeedsRead: Call getFrame() to get decoded frame
Error: Handle error condition
- Returns:
DecoderStatus Current status
-
virtual void push(const Limef::frame::PacketFrame *frame) = 0¶
Push packet for decoding.
Only call when status() returns NeedsMoreData
- Parameters:
frame – PacketFrame to decode
- Throws:
std::runtime_error – if decoder not properly initialized
-
virtual const Limef::frame::DecodedFrame &getFrame() = 0¶
Get decoded frame.
Only call when status() returns NeedsRead
- Returns:
const DecodedFrame& Reference to decoded frame
-
virtual int getStreamIndex() const = 0¶
Get stream index this decoder handles.
-
virtual void flush() = 0¶
Flush the decoder.
Forces decoder to output any buffered frames. Check status() after this to get remaining frames.
-
class FFmpegDecoder : public Limef::decode::Decoder¶
- #include <ffmpeg_decoder.h>
FFmpeg-based decoder for video and audio streams.
Supports both software decoding and hardware-accelerated decoding via FFmpeg’s hwaccel infrastructure (VAAPI, NVDEC, etc.)
Example usage:
FFmpegDecoderParams params; params.hw_accel = HWAccel::VAAPI; // or HWAccel::CUDA // stream comes from CodecFrame or AVFormatContext FFmpegDecoder dec("my-decoder", stream, params); // Set output frame: dec.setDecodedFrame(decoded_frame); // Decoding loop: DecoderStatus stat = dec.status(); if (stat == DecoderStatus::NeedsMoreData) { dec.push(&packet_frame); } if (stat == DecoderStatus::NeedsRead) { const DecodedFrame& frame = dec.getFrame(); // process frame }
Public Functions
-
FFmpegDecoder(const std::string &name, const AVStream *stream, const FFmpegDecoderParams ¶ms = FFmpegDecoderParams{})¶
Construct decoder for given stream.
- Parameters:
name – Identifier for logging
stream – Stream to decode
params – Decoding parameters (hw_accel, threading, etc.)
- Throws:
std::runtime_error – if decoder initialization fails
Set logger for this decoder.
-
virtual void setDecodedFrame(Limef::frame::DecodedFrame &frame) override¶
Set output frame.
Must be called before decoder can be used. Frame will be reused for decoded output.
- Parameters:
frame – Frame to use for decoded output
-
virtual DecoderStatus status() override¶
Get current decoder status.
Call this to determine what operation to do next:
NeedsMoreData: Call push() with next packet
NeedsRead: Call getFrame() to get decoded frame
Error: Handle error condition
- Returns:
DecoderStatus Current status
-
virtual void push(const Limef::frame::PacketFrame *frame) override¶
Push packet for decoding.
Only call when status() returns NeedsMoreData
- Parameters:
frame – PacketFrame to decode
- Throws:
std::runtime_error – if decoder not properly initialized
-
inline virtual const Limef::frame::DecodedFrame &getFrame() override¶
Get decoded frame.
Only call when status() returns NeedsRead
- Returns:
const DecodedFrame& Reference to decoded frame
-
inline virtual int getStreamIndex() const override¶
Get stream index this decoder handles.
-
virtual void flush() override¶
Flush the decoder.
Forces decoder to output any buffered frames. Check status() after this to get remaining frames.
-
inline bool isUsingHardware() const¶
Check if using hardware decoder.
-
FFmpegDecoder(const std::string &name, const AVStream *stream, const FFmpegDecoderParams ¶ms = FFmpegDecoderParams{})¶
-
struct FFmpegDecoderParams¶
- #include <ffmpeg_decoder.h>
Decoding parameters for FFmpegDecoder.
Contains threading and hardware acceleration settings. The stream itself is passed separately to the constructor since it varies per-stream (comes from CodecFrame at runtime).
Example usage:
// Software decoding (default) FFmpegDecoderParams params; // hw_accel = HWAccel::NONE by default // VAAPI hardware decoding FFmpegDecoderParams params; params.hw_accel = HWAccel::VAAPI; // params.hw_device = "/dev/dri/renderD128"; // optional, auto-detected
-
class V4L2Decoder : public Limef::decode::Decoder¶
- #include <v4l2_decoder.h>
V4L2 Memory-to-Memory decoder.
Implements the Decoder interface using V4L2 M2M API. Developed against vicodec, deployable to Jetson.
Unlike FFmpegDecoder, this does NOT require AVStream. Codec information comes from V4L2DecoderParams. Initialization is lazy (on first packet) like V4L2Encoder.
V4L2 M2M uses two buffer queues:
OUTPUT: Encoded packets go IN (confusing naming from V4L2)
CAPTURE: Decoded frames come OUT
Example:
V4L2DecoderParams params; params.device = "/dev/video3"; // vicodec decoder params.codec_fourcc = V4L2_PIX_FMT_FWHT; V4L2Decoder dec("v4l2-dec", params); dec.setDecodedFrame(decoded_frame); // Push encoded packet (e.g., from V4L2Encoder) dec.push(&packet_frame); // Check for decoded output if (dec.status() == DecoderStatus::NeedsRead) { const DecodedFrame& frame = dec.getFrame(); }
Public Functions
-
V4L2Decoder(const std::string &name, const V4L2DecoderParams ¶ms)¶
Construct V4L2 decoder.
NOTE: Unlike FFmpegDecoder, does NOT take AVStream. Initialization is lazy - device is opened on first push().
- Parameters:
name – Identifier for logging
params – V4L2-specific decoder parameters (codec_fourcc, device, etc.)
Set logger for this decoder.
-
virtual void setDecodedFrame(Limef::frame::DecodedFrame &frame) override¶
Set output frame.
Must be called before decoder can be used. Frame will be reused for decoded output.
- Parameters:
frame – Frame to use for decoded output
-
virtual DecoderStatus status() override¶
Get current decoder status.
Call this to determine what operation to do next:
NeedsMoreData: Call push() with next packet
NeedsRead: Call getFrame() to get decoded frame
Error: Handle error condition
- Returns:
DecoderStatus Current status
-
virtual void push(const Limef::frame::PacketFrame *frame) override¶
Push packet for decoding.
Only call when status() returns NeedsMoreData
- Parameters:
frame – PacketFrame to decode
- Throws:
std::runtime_error – if decoder not properly initialized
-
inline virtual const Limef::frame::DecodedFrame &getFrame() override¶
Get decoded frame.
Only call when status() returns NeedsRead
- Returns:
const DecodedFrame& Reference to decoded frame
-
inline virtual int getStreamIndex() const override¶
Get stream index this decoder handles.
-
virtual void flush() override¶
Flush the decoder.
Forces decoder to output any buffered frames. Check status() after this to get remaining frames.
-
struct V4L2DecoderBuffer¶
- #include <v4l2_decoder.h>
Buffer info for mmap’d V4L2 buffers.
-
struct V4L2DecoderParams¶
- #include <v4l2_decoder.h>
Decoding parameters for V4L2Decoder.
V4L2-specific parameters using fourcc codes. Unlike FFmpegDecoder, this does NOT use AVStream/AVCodecID.
If codec_fourcc is left at default (FWHT) and the decoder is created via the factory with an AVStream, the codec will be auto-detected.
Public Members
-
std::string device = {"/dev/video0"}¶
V4L2 device path (vicodec decoder: /dev/video3)
-
uint32_t codec_fourcc = {V4L2_PIX_FMT_FWHT}¶
Input codec fourcc (e.g., V4L2_PIX_FMT_FWHT, V4L2_PIX_FMT_H264)
-
uint32_t output_fourcc = {V4L2_PIX_FMT_NV12}¶
Preferred output pixel format (decoder may override based on hardware)
-
int width = {0}¶
Expected dimensions (0 = detect from bitstream, for stateful decoders)
-
int num_output_buffers = {4}¶
Number of OUTPUT (encoded) buffers.
-
int num_capture_buffers = {4}¶
Number of CAPTURE (decoded frame) buffers.
-
std::string device = {"/dev/video0"}¶
-
class V4L2NVDecoder : public Limef::decode::Decoder¶
- #include <v4l2_nv_decoder.h>
V4L2 Memory-to-Memory decoder.
Implements the Decoder interface using V4L2 M2M API. Hardware NVDEC decoder for Jetson Orin (tegra234) via V4L2 M2M API.
Codec identity and initial dimensions come from the AVStream passed at construction (matches FFmpegDecoder’s signature). Initialization is lazy (on first packet) like V4L2Encoder.
V4L2 M2M uses two buffer queues:
OUTPUT: Encoded packets go IN (confusing naming from V4L2)
CAPTURE: Decoded frames come OUT
Public Functions
-
V4L2NVDecoder(const std::string &name, const AVStream *stream, const V4L2NVDecoderParams ¶ms)¶
Construct V4L2 decoder.
Initialization is lazy - device is opened on first push().
- Parameters:
name – Identifier for logging
stream – AVStream the bitstream belongs to. codec_id is mapped to a V4L2 fourcc; width/height seed the stateless-decoder path (stateful decoders override via SOURCE_CHANGE).
params – Backend parameters (device path, buffer counts, target).
Set logger for this decoder.
-
virtual void setDecodedFrame(Limef::frame::DecodedFrame &frame) override¶
Set output frame.
Must be called before decoder can be used. Frame will be reused for decoded output.
- Parameters:
frame – Frame to use for decoded output
-
virtual DecoderStatus status() override¶
Get current decoder status.
Call this to determine what operation to do next:
NeedsMoreData: Call push() with next packet
NeedsRead: Call getFrame() to get decoded frame
Error: Handle error condition
- Returns:
DecoderStatus Current status
-
virtual void push(const Limef::frame::PacketFrame *frame) override¶
Push packet for decoding.
Only call when status() returns NeedsMoreData
- Parameters:
frame – PacketFrame to decode
- Throws:
std::runtime_error – if decoder not properly initialized
-
inline virtual const Limef::frame::DecodedFrame &getFrame() override¶
Get decoded frame.
Only call when status() returns NeedsRead
- Returns:
const DecodedFrame& Reference to decoded frame
-
inline virtual int getStreamIndex() const override¶
Get stream index this decoder handles.
-
virtual void flush() override¶
Flush the decoder.
Forces decoder to output any buffered frames. Check status() after this to get remaining frames.
-
struct V4L2NVDecoderBuffer¶
- #include <v4l2_nv_decoder.h>
Buffer info for V4L2 CAPTURE buffers.
Public Members
-
void *start = {nullptr}¶
Y-plane CPU address (EXPBUF mmap, MPLANE) or mmap’d (single-plane)
-
size_t length = {0}¶
Y-plane size in bytes.
-
void *uv_start = {nullptr}¶
UV-plane CPU address (MPLANE NM12 only)
-
size_t uv_length = {0}¶
UV-plane size in bytes.
-
int index = {-1}¶
Buffer index.
-
bool queued = {false}¶
Currently queued to driver.
-
int expfd = {-1}¶
EXPBUF dma-buf fd — kept open (MPLANE); needed by nv_bl2pl_transform.
-
void *start = {nullptr}¶
-
struct V4L2NVDecoderParams¶
- #include <v4l2_nv_decoder.h>
Backend parameters for V4L2NVDecoder.
Holds only backend-level configuration. Codec identity, dimensions and pixel format are obtained from the AVStream passed at construction (or, for stateful decoders, negotiated with the driver on V4L2_EVENT_SOURCE_CHANGE).
Public Members
-
std::string device = {"/dev/video0"}¶
V4L2 device path (vicodec decoder: /dev/video3)
-
uint32_t output_fourcc = {V4L2_PIX_FMT_NV12}¶
Preferred output pixel format (decoder may override based on hardware)
-
int num_output_buffers = {32}¶
Number of OUTPUT (encoded) buffers.
-
int num_capture_buffers = {16}¶
Number of CAPTURE (decoded frame) buffers.
-
Limef::frame::BufferLocation target = {Limef::frame::BufferLocation::CPU}¶
Output frame memory target: CPU (default) or CUDA (Jetson only, requires LIMEF_V4L2_NV).
-
std::string device = {"/dev/video0"}¶
-
using VideoDecoderParams = std::variant<FFmpegDecoderParams, V4L2DecoderParams, V4L2NVDecoderParams>¶