Skip to main content

VideoDecoderBuilder

Struct VideoDecoderBuilder 

Source
pub struct VideoDecoderBuilder { /* private fields */ }
Expand description

Builder for configuring and constructing a VideoDecoder.

This struct provides a fluent interface for setting up decoder options before opening a video file. It is created by calling VideoDecoder::open().

§Examples

§Basic Usage

use ff_decode::VideoDecoder;

let decoder = VideoDecoder::open("video.mp4")?
    .build()?;

§With Custom Format

use ff_decode::VideoDecoder;
use ff_format::PixelFormat;

let decoder = VideoDecoder::open("video.mp4")?
    .output_format(PixelFormat::Rgba)
    .build()?;

§With Hardware Acceleration

use ff_decode::{VideoDecoder, HardwareAccel};

let decoder = VideoDecoder::open("video.mp4")?
    .hardware_accel(HardwareAccel::Nvdec)
    .build()?;

§With Frame Pool

use ff_decode::{VideoDecoder, FramePool};
use std::sync::Arc;

let pool: Arc<dyn FramePool> = create_frame_pool();
let decoder = VideoDecoder::open("video.mp4")?
    .frame_pool(pool)
    .build()?;

Implementations§

Source§

impl VideoDecoderBuilder

Source

pub fn output_format(self, format: PixelFormat) -> Self

Sets the output pixel format for decoded frames.

If not set, frames are returned in the source format. Setting an output format enables automatic conversion during decoding.

§Common Formats
§Examples
use ff_decode::VideoDecoder;
use ff_format::PixelFormat;

let decoder = VideoDecoder::open("video.mp4")?
    .output_format(PixelFormat::Rgba)
    .build()?;
Source

pub fn output_size(self, width: u32, height: u32) -> Self

Scales decoded frames to the given exact dimensions.

The frame is scaled in the same libswscale pass as pixel-format conversion, so there is no extra copy. If output_format is not set, the source pixel format is preserved while scaling.

Width and height must be greater than zero. They are rounded up to the nearest even number if necessary (required by most pixel formats).

Calling this method overwrites any previous output_width or output_height call. The last setter wins.

§Errors

build() returns DecodeError::InvalidOutputDimensions if either dimension is zero after rounding.

§Examples
use ff_decode::VideoDecoder;

// Decode every frame at 320×240
let decoder = VideoDecoder::open("video.mp4")?
    .output_size(320, 240)
    .build()?;
Source

pub fn output_width(self, width: u32) -> Self

Scales decoded frames to the given width, preserving the aspect ratio.

The height is computed from the source aspect ratio and rounded to the nearest even number. Calling this method overwrites any previous output_size or output_height call. The last setter wins.

§Errors

build() returns DecodeError::InvalidOutputDimensions if width is zero.

§Examples
use ff_decode::VideoDecoder;

// Decode at 1280 px wide, preserving aspect ratio
let decoder = VideoDecoder::open("video.mp4")?
    .output_width(1280)
    .build()?;
Source

pub fn output_height(self, height: u32) -> Self

Scales decoded frames to the given height, preserving the aspect ratio.

The width is computed from the source aspect ratio and rounded to the nearest even number. Calling this method overwrites any previous output_size or output_width call. The last setter wins.

§Errors

build() returns DecodeError::InvalidOutputDimensions if height is zero.

§Examples
use ff_decode::VideoDecoder;

// Decode at 720 px tall, preserving aspect ratio
let decoder = VideoDecoder::open("video.mp4")?
    .output_height(720)
    .build()?;
Source

pub fn hardware_accel(self, accel: HardwareAccel) -> Self

Sets the hardware acceleration mode.

Hardware acceleration can significantly improve decoding performance, especially for high-resolution video (4K and above).

§Available Modes
§Fallback Behavior

If the requested hardware accelerator is unavailable, the decoder will fall back to software decoding unless DecodeError::HwAccelUnavailable is explicitly requested.

§Examples
use ff_decode::{VideoDecoder, HardwareAccel};

// Use NVIDIA NVDEC if available
let decoder = VideoDecoder::open("video.mp4")?
    .hardware_accel(HardwareAccel::Nvdec)
    .build()?;

// Force CPU decoding
let cpu_decoder = Decoder::open("video.mp4")?
    .hardware_accel(HardwareAccel::None)
    .build()?;
Source

pub fn thread_count(self, count: usize) -> Self

Sets the number of decoding threads.

More threads can improve decoding throughput, especially for high-resolution videos or codecs that support parallel decoding.

§Thread Count Values
  • 0 - Auto-detect based on CPU cores (default)
  • 1 - Single-threaded decoding
  • N - Use N threads for decoding
§Performance Notes
  • H.264/H.265: Benefit significantly from multi-threading
  • VP9: Good parallel decoding support
  • ProRes: Limited threading benefit

Setting too many threads may increase memory usage without proportional performance gains.

§Examples
use ff_decode::VideoDecoder;

// Use 4 threads for decoding
let decoder = VideoDecoder::open("video.mp4")?
    .thread_count(4)
    .build()?;

// Single-threaded for minimal memory
let decoder = VideoDecoder::open("video.mp4")?
    .thread_count(1)
    .build()?;
Source

pub fn frame_rate(self, fps: u32) -> Self

Sets the frame rate for image sequence decoding.

Only used when the path contains % (e.g. "frames/frame%04d.png"). Defaults to 25 fps when not set.

§Examples
use ff_decode::VideoDecoder;

let decoder = VideoDecoder::open("frames/frame%04d.png")?
    .frame_rate(30)
    .build()?;
Source

pub fn network(self, opts: NetworkOptions) -> Self

Sets network options for URL-based sources.

When set, the builder skips the file-existence check and passes connect and read timeouts to avformat_open_input via an AVDictionary. Call this before .build() when opening rtmp://, rtsp://, http://, https://, udp://, srt://, or rtp:// URLs.

§HLS / M3U8 Playlists

HLS playlists (.m3u8) are detected automatically by FFmpeg — no extra configuration is required beyond calling .network(). Pass the full HTTP(S) URL of the master or media playlist:

use ff_decode::VideoDecoder;
use ff_format::NetworkOptions;

let decoder = VideoDecoder::open("https://example.com/live/index.m3u8")
    .network(NetworkOptions::default())
    .build()?;
§DASH / MPD Streams

MPEG-DASH manifests (.mpd) are detected automatically by FFmpeg’s built-in dash demuxer. The demuxer downloads the manifest, selects the highest-quality representation, and fetches segments automatically:

use ff_decode::VideoDecoder;
use ff_format::NetworkOptions;

let decoder = VideoDecoder::open("https://example.com/dash/manifest.mpd")
    .network(NetworkOptions::default())
    .build()?;

Multi-period caveat: multi-period DASH streams are supported by FFmpeg but period boundaries may trigger an internal decoder reset, which can cause a brief gap in decoded frames.

Adaptive bitrate: representation selection (ABR switching) is handled internally by FFmpeg and is not exposed through this API.

§UDP / MPEG-TS

udp:// URLs are always live — is_live() returns true and seeking is not supported. Two extra AVDictionary options are set automatically to reduce packet loss on high-bitrate streams:

OptionValueReason
buffer_size65536Enlarges the UDP receive buffer
overrun_nonfatal1Discards excess data instead of erroring
use ff_decode::VideoDecoder;
use ff_format::NetworkOptions;

let decoder = VideoDecoder::open("udp://224.0.0.1:1234")
    .network(NetworkOptions::default())
    .build()?;
§SRT (Secure Reliable Transport)

SRT URLs (srt://host:port) require the srt feature flag and a libsrt-enabled FFmpeg build. Enable the feature in Cargo.toml:

[dependencies]
ff-decode = { version = "*", features = ["srt"] }

Without the srt feature, opening an srt:// URL returns DecodeError::ConnectionFailed. If the feature is enabled but the linked FFmpeg was not built with --enable-libsrt, the same error is returned with a message directing you to rebuild FFmpeg.

use ff_decode::VideoDecoder;
use ff_format::NetworkOptions;

let decoder = VideoDecoder::open("srt://ingest.example.com:4200")
    .network(NetworkOptions::default())
    .build()?;
§Credentials

HTTP basic-auth credentials must be embedded directly in the URL: https://user:password@cdn.example.com/live/index.m3u8. The password is redacted in log output.

§DRM Limitation

DRM-protected streams are not supported:

  • HLS: FairPlay, Widevine, AES-128 with external key servers
  • DASH: CENC, PlayReady, Widevine

FFmpeg can parse the manifest and fetch segments, but key delivery to a DRM license server is outside the scope of this API.

§Examples
use ff_decode::VideoDecoder;
use ff_format::NetworkOptions;

let decoder = VideoDecoder::open("rtmp://live.example.com/app/stream_key")
    .network(NetworkOptions::default())
    .build()?;
Source

pub fn frame_pool(self, pool: Arc<dyn FramePool>) -> Self

Sets a frame pool for memory reuse.

Using a frame pool can significantly reduce allocation overhead during continuous video playback by reusing frame buffers.

§Memory Management

When a frame pool is set:

  • Decoded frames attempt to acquire buffers from the pool
  • When frames are dropped, their buffers are returned to the pool
  • If the pool is exhausted, new buffers are allocated normally
§Examples
use ff_decode::{VideoDecoder, FramePool, PooledBuffer};
use std::sync::{Arc, Mutex};

// Create a simple frame pool
struct SimplePool {
    buffers: Mutex<Vec<Vec<u8>>>,
}

impl FramePool for SimplePool {
    fn acquire(&self, size: usize) -> Option<PooledBuffer> {
        // Implementation...
        None
    }
}

let pool = Arc::new(SimplePool {
    buffers: Mutex::new(vec![]),
});

let decoder = VideoDecoder::open("video.mp4")?
    .frame_pool(pool)
    .build()?;
Source

pub fn path(&self) -> &Path

Returns the configured file path.

Source

pub fn get_output_format(&self) -> Option<PixelFormat>

Returns the configured output format, if any.

Source

pub fn get_hardware_accel(&self) -> HardwareAccel

Returns the configured hardware acceleration mode.

Source

pub fn get_thread_count(&self) -> usize

Returns the configured thread count.

Source

pub fn build(self) -> Result<VideoDecoder, DecodeError>

Builds the decoder with the configured options.

This method opens the media file, initializes the decoder context, and prepares for frame decoding.

§Errors

Returns an error if:

§Examples
use ff_decode::VideoDecoder;

let decoder = VideoDecoder::open("video.mp4")?
    .build()?;

// Start decoding
for result in &mut decoder {
    let frame = result?;
    // Process frame...
}

Trait Implementations§

Source§

impl Debug for VideoDecoderBuilder

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.