Encoders

Encoders convert decoded Limef::frame::DecodedFrames into encoded Limef::frame::PacketFrames. The abstract interface is Limef::encode::Encoder; the main implementation is Limef::encode::FFmpegEncoder.

namespace encode

Typedefs

using VideoEncoderParams = std::variant<FFmpegEncoderParams, V4L2EncoderParams, V4L2NVEncoderParams>

Variant type for encoder parameters.

All backend param types are always present - no compile-time ifdefs. Use isEncoderAvailable() to check runtime availability before creating.

Example:

// FFmpeg backend (always available)
FFmpegEncoderParams ffmpeg_params;
ffmpeg_params.codec_id = AV_CODEC_ID_H264;
VideoEncoderParams params = ffmpeg_params;

// V4L2 backend (check availability first)
if (isEncoderAvailable(EncoderBackend::V4L2)) {
    V4L2EncoderParams v4l2_params;
    v4l2_params.device = "/dev/video2";
    VideoEncoderParams params = v4l2_params;
}

Enums

enum class EncoderBackend

Available encoder backends.

Values:

enumerator FFmpeg

FFmpeg-based software/hardware encoding.

enumerator V4L2

V4L2 Memory-to-Memory API (Jetson vicodec, generic M2M)

enumerator V4L2NV

V4L2 M2M with NvBufSurface DMABUF+EGL+CUDA (Jetson NVENC)

enum class EncoderStatus

Status codes returned by encoder.

Values:

enumerator NeedsMoreData

Ready to accept more frames via push()

enumerator NeedsRead

Encoded packet available, call getPacket()

enumerator EndOfStream

End of stream (flushing complete)

enumerator Error

Something went wrong.

Functions

std::vector<EncoderBackend> getAvailableEncoders()

Query available encoder backends at runtime.

Returns backends that were compiled in and are functional. For V4L2, also checks if required devices exist.

Returns:

std::vector<EncoderBackend> List of available backends

bool isEncoderAvailable(EncoderBackend backend)

Check if a specific encoder backend is available.

EncoderBackend getBackend(const VideoEncoderParams &params)

Get the backend type from encoder params.

Encoder *createEncoder(const std::string &name, const VideoEncoderParams &params)

Create an encoder from variant parameters.

Factory function that creates the appropriate encoder based on the active type in the params variant.

Parameters:
  • name – Identifier for logging

  • params – Encoder parameters (variant of FFmpegEncoderParams, V4L2EncoderParams, etc.)

Throws:

std::runtime_error – if backend not compiled in or not available

Returns:

Encoder* Newly created encoder (caller owns)

std::string getEncoderName(AVCodecID codec_id, HWAccel hw_accel)

Get FFmpeg encoder name for codec + acceleration combination.

Maps (codec_id, hw_accel) to FFmpeg encoder name. Returns empty string if combination is not supported.

Examples:

  • (H264, VAAPI) -> “h264_vaapi”

  • (VP9, SW) -> “libvpx_vp9”

  • (H264, SW) -> “” (no GPL software encoder)

Parameters:
  • codec_id – Target codec

  • hw_accel – Hardware acceleration type

Returns:

std::string FFmpeg encoder name, or empty if unsupported

class Encoder
#include <encoder.h>

Abstract encoder interface for a single video or audio stream.

State machine that encodes decoded frames into packets. Call status() to determine what operation to do next.

Implementations:

  • FFmpegEncoder: FFmpeg-based software/hardware encoding

  • V4L2Encoder: V4L2 Memory-to-Memory API (Jetson, embedded Linux)

Example usage:

std::unique_ptr<Encoder> enc = std::make_unique<FFmpegEncoder>("my-encoder", params);
enc->setPacketFrame(packet_frame);

// Encoding loop:
EncoderStatus stat = enc->status();
if (stat == EncoderStatus::NeedsMoreData) {
    enc->push(&decoded_frame);
}
if (stat == EncoderStatus::NeedsRead) {
    const PacketFrame& pkt = enc->getPacket();
    // send packet downstream
}

Encoder has this contract (similar to decoder): the PacketFrame returned by getPacket() is not mutated while the status() is not called: so its safe to send the PacketFrame downstream between calls to status()

All calls to encoder are non-blocking.

Subclassed by Limef::encode::FFmpegEncoder, Limef::encode::V4L2Encoder, Limef::encode::V4L2NVEncoder

Public Functions

virtual void setLogger(std::shared_ptr<spdlog::logger> logger) = 0

Set logger for this encoder.

virtual void setPacketFrame(Limef::frame::PacketFrame &frame) = 0

Set output packet frame.

Must be called before encoder can be used. Frame will be reused for encoded output.

Parameters:

frame – Frame to use for encoded output

virtual EncoderStatus status() = 0

Get current encoder status.

Call this to determine what operation to do next:

  • NeedsMoreData: Call push() with next frame

  • NeedsRead: Call getPacket() to get encoded packet

  • Error: Handle error condition

Returns:

EncoderStatus Current status

virtual void push(const Limef::frame::DecodedFrame *frame) = 0

Push decoded frame for encoding.

Only call when status() returns NeedsMoreData. On first call, may initialize encoder dimensions from frame.

Parameters:

frame – DecodedFrame to encode

virtual const Limef::frame::PacketFrame &getPacket() = 0

Get encoded packet.

Only call when status() returns NeedsRead

Returns:

const PacketFrame& Reference to encoded packet

virtual void flush() = 0

Flush the encoder.

Forces encoder to output any buffered packets. Check status() after this to get remaining packets.

virtual int getStreamIndex() const = 0

Get the stream index this encoder produces.

virtual void setStreamIndex(int idx) = 0

Set stream index for output packets.

virtual bool isInitialized() const = 0

Check if encoder is fully initialized and ready to produce output.

virtual void configure(const AVStream *stream) = 0

Configure encoder timing from stream info.

Called when StreamFrame arrives. Extracts fps and timebase. Since StreamFrame uses AVFormatContext, all encoders receive AVStream*.

Parameters:

stream – Source stream info

virtual bool isConfigured() const = 0

Check if encoder has been configured (received stream info)

virtual const AVCodecParameters *getCodecParams() const = 0

Get codec parameters for muxer/decoder setup.

Returns codec parameters after encoder is initialized. Used to create CodecFrame for downstream decoders.

Returns:

const AVCodecParameters* Codec parameters, or nullptr if not yet initialized

inline virtual AVRational getTimeBase() const

Get encoder output timebase.

Returns the timebase of encoded packets. Used for CodecFrame creation.

Returns:

AVRational Timebase (e.g., {1, 90000} for 90kHz)

inline virtual AVRational getFrameRate() const

Get encoder output frame rate.

Returns:

AVRational Frame rate (e.g., {30, 1} for 30fps)

inline virtual void requestKeyFrame()

Request that the encoder produce a keyframe on its next output.

Typically triggered by a downstream client asking for a fresh intra frame (e.g. a WebRTC PLI/FIR, or a newly-joined RTSP client). May be called from a thread other than the one driving push()/status()/ getPacket() — implementations MUST be internally mutex-protected against concurrent encode calls.

Default implementation does nothing but log a warning — override for backends that support forcing a keyframe (see FFmpegEncoder, V4L2Encoder, V4L2NVEncoder).

class FFmpegEncoder : public Limef::encode::Encoder
#include <ffmpeg_encoder.h>

FFmpeg-based encoder for video and audio streams.

Supports both software encoding and hardware-accelerated encoding via FFmpeg’s hwaccel infrastructure (VAAPI, NVENC, etc.)

Initialization is two-phase:

  1. configure() - called when StreamFrame arrives (provides fps, timebase)

  2. initFromFrame() - called on first DecodedFrame (provides dimensions, format)

Example usage:

FFmpegEncoderParams params;
params.codec_id = AV_CODEC_ID_H264;
params.bitrate = 2000000;

FFmpegEncoder enc("my-encoder", params);

// When StreamFrame arrives:
enc.configure(stream_frame.getVideoStream());

// Set output packet frame:
enc.setPacketFrame(packet_frame);

// Encoding loop:
EncoderStatus stat = enc.status();
if (stat == EncoderStatus::NeedsMoreData) {
    enc.push(&decoded_frame);
}
if (stat == EncoderStatus::NeedsRead) {
    const PacketFrame& pkt = enc.getPacket();
    // send packet downstream
}

Public Functions

FFmpegEncoder(const std::string &name, const FFmpegEncoderParams &params)

Construct encoder with given parameters.

Parameters:
  • name – Identifier for logging

  • params – Encoding parameters (codec, bitrate, etc.)

inline virtual void setLogger(std::shared_ptr<spdlog::logger> logger) override

Set logger for this encoder.

virtual void setPacketFrame(Limef::frame::PacketFrame &frame) override

Set output packet frame.

Must be called before encoder can be used. Frame will be reused for encoded output.

Parameters:

frame – Frame to use for encoded output

virtual EncoderStatus status() override

Get current encoder status.

Call this to determine what operation to do next:

  • NeedsMoreData: Call push() with next frame

  • NeedsRead: Call getPacket() to get encoded packet

  • Error: Handle error condition

Returns:

EncoderStatus Current status

virtual void push(const Limef::frame::DecodedFrame *frame) override

Push decoded frame for encoding.

Only call when status() returns NeedsMoreData. On first call, may initialize encoder dimensions from frame.

Parameters:

frame – DecodedFrame to encode

inline virtual const Limef::frame::PacketFrame &getPacket() override

Get encoded packet.

Only call when status() returns NeedsRead

Returns:

const PacketFrame& Reference to encoded packet

virtual void flush() override

Flush the encoder.

Forces encoder to output any buffered packets. Check status() after this to get remaining packets.

inline virtual int getStreamIndex() const override

Get the stream index this encoder produces.

inline virtual void setStreamIndex(int idx) override

Set stream index for output packets.

inline virtual bool isInitialized() const override

Check if encoder is fully initialized and ready to produce output.

virtual void configure(const AVStream *stream) override

Configure encoder timing from stream info.

Called when StreamFrame arrives. Extracts fps and timebase. Since StreamFrame uses AVFormatContext, all encoders receive AVStream*.

Parameters:

stream – Source stream info

inline virtual bool isConfigured() const override

Check if encoder has been configured (received stream info)

virtual const AVCodecParameters *getCodecParams() const override

Get codec parameters for muxer/decoder setup.

Returns codec parameters after encoder is initialized. Used to create CodecFrame for downstream decoders.

Returns:

const AVCodecParameters* Codec parameters, or nullptr if not yet initialized

inline virtual AVRational getTimeBase() const override

Get encoder output timebase.

Returns the timebase of encoded packets. Used for CodecFrame creation.

Returns:

AVRational Timebase (e.g., {1, 90000} for 90kHz)

inline virtual AVRational getFrameRate() const override

Get encoder output frame rate.

Returns:

AVRational Frame rate (e.g., {30, 1} for 30fps)

inline virtual void requestKeyFrame() override

Request that the encoder emit a keyframe on its next push()

Sets a flag (std::atomic, safe to call from any thread) that push() consumes on the next call: the AVFrame handed to avcodec_send_frame() has AVFrame::pict_type forced to AV_PICTURE_TYPE_I.

This is the mechanism all four encoder families produced by getEncoderName() honour for forcing a keyframe:

  • libvpx/libvpx-vp9 (libavcodec/libvpxenc.c): checks pict_type == AV_PICTURE_TYPE_I

  • libaom-av1 (libavcodec/libaomenc.c): checks pict_type == AV_PICTURE_TYPE_I

  • *_vaapi (libavcodec/vaapi_encode.c): pict_type == AV_PICTURE_TYPE_I -> force_idr

  • *_nvenc (libavcodec/nvenc.c): pict_type == AV_PICTURE_TYPE_I -> FORCEIDR/FORCEINTRA (nvenc additionally needs the “forced-idr” AVOption enabled, which initVideoEncoder() sets for CUDA/nvenc so a full IDR with SPS/PPS is produced rather than a plain forced-intra frame without parameter sets) mjpeg is intra-only so the flag is a no-op there (every frame already a keyframe).

struct FFmpegEncoderParams
#include <ffmpeg_encoder.h>

Encoding parameters for FFmpegEncoder.

Contains codec selection and quality settings. Dimensions and format come from the incoming DecodedFrame. Timing (fps, timebase) comes from StreamFrame via configure().

Example usage:

// VAAPI H.264 encoding (no GPL issues)
FFmpegEncoderParams params;
params.codec_id = AV_CODEC_ID_H264;
params.hw_accel = HWAccel::VAAPI;
// hw_device uses sensible default, or specify:
// params.hw_device = "/dev/dri/renderD128";

// Software VP9 encoding (royalty-free)
FFmpegEncoderParams params;
params.codec_id = AV_CODEC_ID_VP9;
params.hw_accel = HWAccel::NONE;  // uses libvpx

Public Members

AVCodecID codec_id = {AV_CODEC_ID_H264}

Target codec.

int64_t bitrate = {2000000}

Target bitrate in bits/sec.

HWAccel hw_accel = {HWAccel::NONE}

Hardware acceleration backend.

std::string hw_device

Device path (empty = auto-detect)

std::string preset = {"medium"}

Encoder preset (SW: “ultrafast”..”veryslow”; NVENC: “p1”..”p7”)

std::string profile = {}

Codec profile (H.264: “baseline”,”main”,”high”)

std::string tune = {}

Tuning (SW: “zerolatency”,”film”; NVENC: “ll”,”ull”,”hq”)

int gop_size = {30}

Keyframe interval (0 = codec default)

int max_b_frames = {-1}

Max B-frames (-1 = codec default)

int crf = {-1}

Constant Rate Factor (-1 = use bitrate instead)

int thread_count = {0}

Encoder threads (0 = auto)

bool global_header = {true}

Store SPS/PPS in extradata rather than inline in the stream.

NVENC note: h264_nvenc always outputs Annex B byte-stream packets regardless of this flag. The flag only controls where SPS/PPS parameter sets appear:

true — SPS/PPS in extradata only, absent from packets. RTPMuxerFrameFilter reads extradata from CodecFrame → SDP gets profile-level-id and sprop-parameter-sets. Required for RTSP. IDR packets carry no inline SPS/PPS — browsers cannot decode without them.

false — extradata empty, SPS/PPS prepended inline before every IDR packet. SDP lacks profile-level-id / sprop-parameter-sets. Required for WebRTC with NVENC.

std::map<std::string, std::string> options = {}

Extra AVOptions passed verbatim to the encoder via av_dict_set(). Use for encoder-private options not covered by named fields above. Example (NVENC): {“delay”, “0”}, {“rc”, “cbr”}

struct V4L2Buffer
#include <v4l2_encoder.h>

Buffer info for mmap’d V4L2 buffers.

Public Members

void *start = {nullptr}

mmap’d address

size_t length = {0}

Buffer size.

int index = {-1}

Buffer index.

bool queued = {false}

Currently queued to driver.

class V4L2Encoder : public Limef::encode::Encoder
#include <v4l2_encoder.h>

V4L2 Memory-to-Memory encoder.

Implements the Encoder interface using V4L2 M2M API. Developed against vicodec, deployable to Jetson.

V4L2 M2M uses two buffer queues:

  • OUTPUT: Raw frames go IN (confusing naming from V4L2)

  • CAPTURE: Encoded packets come OUT

State machine:

  1. Open device, set formats

  2. Request and mmap buffers for both queues

  3. Start streaming on both queues

  4. Queue raw frame to OUTPUT, dequeue encoded from CAPTURE

Example:

V4L2EncoderParams params;
params.device = "/dev/video2";  // vicodec encoder
params.codec_fourcc = V4L2_PIX_FMT_FWHT;

V4L2Encoder enc("v4l2-enc", params);
enc.setPacketFrame(packet_frame);

// First frame initializes dimensions
enc.push(&decoded_frame);

// Check for output
if (enc.status() == EncoderStatus::NeedsRead) {
    const PacketFrame& pkt = enc.getPacket();
}

Public Functions

inline virtual void setLogger(std::shared_ptr<spdlog::logger> logger) override

Set logger for this encoder.

virtual void setPacketFrame(Limef::frame::PacketFrame &frame) override

Set output packet frame.

Must be called before encoder can be used. Frame will be reused for encoded output.

Parameters:

frame – Frame to use for encoded output

virtual EncoderStatus status() override

Get current encoder status.

Call this to determine what operation to do next:

  • NeedsMoreData: Call push() with next frame

  • NeedsRead: Call getPacket() to get encoded packet

  • Error: Handle error condition

Returns:

EncoderStatus Current status

virtual void push(const Limef::frame::DecodedFrame *frame) override

Push decoded frame for encoding.

Only call when status() returns NeedsMoreData. On first call, may initialize encoder dimensions from frame.

Parameters:

frame – DecodedFrame to encode

inline virtual const Limef::frame::PacketFrame &getPacket() override

Get encoded packet.

Only call when status() returns NeedsRead

Returns:

const PacketFrame& Reference to encoded packet

virtual void flush() override

Flush the encoder.

Forces encoder to output any buffered packets. Check status() after this to get remaining packets.

inline virtual int getStreamIndex() const override

Get the stream index this encoder produces.

inline virtual void setStreamIndex(int idx) override

Set stream index for output packets.

inline virtual bool isInitialized() const override

Check if encoder is fully initialized and ready to produce output.

virtual void configure(const AVStream *stream) override

Configure encoder timing from stream info.

Called when StreamFrame arrives. Extracts fps and timebase. Since StreamFrame uses AVFormatContext, all encoders receive AVStream*.

Parameters:

stream – Source stream info

inline virtual bool isConfigured() const override

Check if encoder has been configured (received stream info)

inline virtual const AVCodecParameters *getCodecParams() const override

Get codec parameters for muxer/decoder setup.

Returns codec parameters after encoder is initialized. Used to create CodecFrame for downstream decoders.

Returns:

const AVCodecParameters* Codec parameters, or nullptr if not yet initialized

inline virtual AVRational getTimeBase() const override

Get encoder output timebase.

Returns the timebase of encoded packets. Used for CodecFrame creation.

Returns:

AVRational Timebase (e.g., {1, 90000} for 90kHz)

inline virtual AVRational getFrameRate() const override

Get encoder output frame rate.

Returns:

AVRational Frame rate (e.g., {30, 1} for 30fps)

virtual void requestKeyFrame() override

Request that the encoder emit a keyframe on its next output.

Issues a VIDIOC_S_CTRL of V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME on the device fd. This is the mainline V4L2 stateful-encoder control (V4L2_CID_CODEC_BASE+229, see linux/v4l2-controls.h) implemented by vicodec and other generic V4L2 M2M encoder drivers this class targets — NOT the NVIDIA-specific V4L2_CID_MPEG_VIDEOENC_FORCE_IDR_FRAME used by V4L2NVEncoder’s LIMEF_V4L2_NV path.

Mutex-protected (ctrl_mutex_) since this may be called from a foreign thread concurrently with the driving thread’s push()/status() calls, which also touch fd_.

struct V4L2EncoderParams
#include <v4l2_encoder.h>

Encoding parameters for V4L2Encoder.

V4L2-specific parameters using fourcc codes instead of AVCodecID.

Public Members

std::string device = {"/dev/video2"}

V4L2 device path (vicodec encoder default)

uint32_t codec_fourcc = {V4L2_PIX_FMT_FWHT}

Output codec (FWHT, H264, HEVC)

uint32_t input_fourcc = {V4L2_PIX_FMT_NV12}

Input pixel format.

int64_t bitrate = {2000000}

Target bitrate in bits/sec.

int gop_size = {30}

Keyframe interval.

int num_output_buffers = {4}

Number of OUTPUT (raw frame) buffers.

int num_capture_buffers = {4}

Number of CAPTURE (encoded) buffers.

class V4L2NVEncoder : public Limef::encode::Encoder
#include <v4l2_nv_encoder.h>

V4L2 Memory-to-Memory encoder.

Implements the Encoder interface using V4L2 M2M API. Developed against vicodec, deployable to Jetson with LIMEF_V4L2_NV.

V4L2 M2M uses two buffer queues:

  • OUTPUT: Raw frames go IN (confusing naming from V4L2)

  • CAPTURE: Encoded packets come OUT

State machine:

  1. Open device, set formats (CAPTURE first, then OUTPUT — Jetson driver requirement)

  2. Request and map buffers for both queues

  3. Start streaming on both queues

  4. Queue raw frame to OUTPUT, dequeue encoded from CAPTURE

LIMEF_V4L2_NV path (Jetson Orin NVENC):

  • OUTPUT: DMABUF via NvBufSurface PL + EGL+CUDA registration

  • CAPTURE: MMAP with EXPBUF fallback (NVMM-backed compressed buffers)

  • Input: AV_PIX_FMT_CUDA frames (GPU pointers, D2D copy only)

Example:

V4L2NVEncoderParams params;
params.device = "/dev/v4l2-nvenc";
params.codec_fourcc = V4L2_PIX_FMT_H264;

V4L2NVEncoder enc("v4l2-nvenc", params);
enc.setPacketFrame(packet_frame);

// First frame initializes dimensions
enc.push(&decoded_frame);   // frame->format must be AV_PIX_FMT_CUDA

if (enc.status() == EncoderStatus::NeedsRead) {
    const PacketFrame& pkt = enc.getPacket();
}

Public Functions

inline virtual void setLogger(std::shared_ptr<spdlog::logger> logger) override

Set logger for this encoder.

virtual void setPacketFrame(Limef::frame::PacketFrame &frame) override

Set output packet frame.

Must be called before encoder can be used. Frame will be reused for encoded output.

Parameters:

frame – Frame to use for encoded output

virtual EncoderStatus status() override

Get current encoder status.

Call this to determine what operation to do next:

  • NeedsMoreData: Call push() with next frame

  • NeedsRead: Call getPacket() to get encoded packet

  • Error: Handle error condition

Returns:

EncoderStatus Current status

virtual void push(const Limef::frame::DecodedFrame *frame) override

Push decoded frame for encoding.

Only call when status() returns NeedsMoreData. On first call, may initialize encoder dimensions from frame.

Parameters:

frame – DecodedFrame to encode

inline virtual const Limef::frame::PacketFrame &getPacket() override

Get encoded packet.

Only call when status() returns NeedsRead

Returns:

const PacketFrame& Reference to encoded packet

virtual void flush() override

Flush the encoder.

Forces encoder to output any buffered packets. Check status() after this to get remaining packets.

inline virtual int getStreamIndex() const override

Get the stream index this encoder produces.

inline virtual void setStreamIndex(int idx) override

Set stream index for output packets.

inline virtual bool isInitialized() const override

Check if encoder is fully initialized and ready to produce output.

virtual void configure(const AVStream *stream) override

Configure encoder timing from stream info.

Called when StreamFrame arrives. Extracts fps and timebase. Since StreamFrame uses AVFormatContext, all encoders receive AVStream*.

Parameters:

stream – Source stream info

inline virtual bool isConfigured() const override

Check if encoder has been configured (received stream info)

inline virtual const AVCodecParameters *getCodecParams() const override

Get codec parameters for muxer/decoder setup.

Returns codec parameters after encoder is initialized. Used to create CodecFrame for downstream decoders.

Returns:

const AVCodecParameters* Codec parameters, or nullptr if not yet initialized

inline virtual AVRational getTimeBase() const override

Get encoder output timebase.

Returns the timebase of encoded packets. Used for CodecFrame creation.

Returns:

AVRational Timebase (e.g., {1, 90000} for 90kHz)

inline virtual AVRational getFrameRate() const override

Get encoder output frame rate.

Returns:

AVRational Frame rate (e.g., {30, 1} for 30fps)

virtual void requestKeyFrame() override

Request that the encoder emit a keyframe on its next output.

LIMEF_V4L2_NV (Jetson NVENC): issues VIDIOC_S_CTRL of V4L2_CID_MPEG_VIDEOENC_FORCE_IDR_FRAME (V4L2_CID_MPEG_BASE+567, defined in NVIDIA’s v4l2_nv_extensions.h) - the NVENC-specific control for forcing a true IDR, distinct from mainline V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME used by V4L2Encoder/vicodec. Not verified on hardware — implemented from the NVIDIA Jetson Linux Multimedia API header/docs only (no Jetson device available in this dev environment).

Non-LIMEF_V4L2_NV build (vicodec fallback): uses the mainline V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME control, same as V4L2Encoder.

Mutex-protected (ctrl_mutex_) since this may be called from a foreign thread concurrently with the driving thread’s push()/status() calls, which also touch fd_.

struct V4L2NVEncoderParams
#include <v4l2_nv_encoder.h>

Encoding parameters for V4L2NVEncoder.

V4L2-specific parameters using fourcc codes instead of AVCodecID.

Public Members

std::string device = {"/dev/video2"}

V4L2 device path (vicodec encoder default)

uint32_t codec_fourcc = {V4L2_PIX_FMT_FWHT}

Output codec (FWHT, H264, HEVC)

uint32_t input_fourcc = {V4L2_PIX_FMT_NV12}

Input pixel format.

int64_t bitrate = {2000000}

Target bitrate in bits/sec.

int gop_size = {30}

Keyframe interval.

int num_output_buffers = {4}

Number of OUTPUT (raw frame) buffer slots.

int num_capture_buffers = {4}

Number of CAPTURE (encoded) buffer slots.

bool global_header = {true}

true: SPS/PPS in extradata (RTSP/SDP); false: prepend to each IDR in software

int h264_profile = {V4L2_MPEG_VIDEO_H264_PROFILE_HIGH}

H.264 profile (only applied when codec_fourcc == V4L2_PIX_FMT_H264). Supported values on Jetson NVENC: V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE (0), V4L2_MPEG_VIDEO_H264_PROFILE_MAIN (2), V4L2_MPEG_VIDEO_H264_PROFILE_HIGH (4).

int h264_level = {V4L2_MPEG_VIDEO_H264_LEVEL_4_1}

H.264 level (only applied when codec_fourcc == V4L2_PIX_FMT_H264). Default V4L2_MPEG_VIDEO_H264_LEVEL_4_1 (value 12) covers up to 1080p@30. WebRTC browsers require a valid non-zero level_idc; the Jetson driver otherwise defaults to level 0 which produces an invalid profile-level-id in the SDP.