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>¶
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)) { V4L2DecoderParams 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, V4L2DecoderParams, etc.)
- Throws:
std::runtime_error – if backend not compiled in or not available
- Returns:
Decoder* Newly created decoder (caller owns)
-
std::string getDecoderName(AVCodecID codec_id, HWAccel hw_accel)¶
Get FFmpeg decoder name for codec + acceleration combination.
Maps (codec_id, hw_accel) to FFmpeg decoder name. For software decoding, returns empty string (use avcodec_find_decoder). For hardware decoding, returns the hardware decoder name if available.
Examples:
(H264, SW) -> “” (use default decoder)
(H264, VAAPI) -> “h264” (VAAPI uses hwaccel, not separate decoder)
Note: VAAPI decoding works differently than encoding - it uses the standard decoder with hw_device_ctx set, not a separate decoder.
- Parameters:
codec_id – Target codec
hw_accel – Hardware acceleration type
- Returns:
std::string FFmpeg decoder name, or empty for default
-
uint32_t avCodecIdToV4L2Fourcc(AVCodecID codec_id)¶
Convert AVCodecID to V4L2 fourcc.
Maps FFmpeg codec IDs to V4L2 pixel format codes. Returns 0 for unsupported codecs.
- Parameters:
codec_id – FFmpeg codec ID
- Returns:
uint32_t V4L2 fourcc code, or 0 if unsupported
-
AVCodecID v4l2FourccToAvCodecId(uint32_t fourcc)¶
Convert V4L2 fourcc to AVCodecID.
Maps V4L2 pixel format codes to FFmpeg codec IDs. Returns AV_CODEC_ID_NONE for unsupported formats.
- Parameters:
fourcc – V4L2 fourcc code
- Returns:
AVCodecID FFmpeg codec ID, or AV_CODEC_ID_NONE if unsupported
-
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.
Implementations:
FFmpegDecoder: FFmpeg-based software/hardware decoding
V4L2Decoder: 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(); // 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
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; // 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 with multithreading FFmpegDecoderParams params; params.hw_accel = HWAccel::SW; params.thread_count = 4; // VAAPI hardware decoding FFmpegDecoderParams params; params.hw_accel = HWAccel::VAAPI; // hw_device uses sensible default, or specify: // params.hw_device = "/dev/dri/renderD128";
-
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"}¶
-
using VideoDecoderParams = std::variant<FFmpegDecoderParams, V4L2DecoderParams>¶