Skip to main content

DecodeBuffer

Struct DecodeBuffer 

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

Pre-decodes frames from a video file into a ring buffer on a background thread.

DecodeBuffer decouples decoder latency from the presentation loop: the background thread keeps the buffer filled so pop_frame can return the next frame without waiting for the decoder.

The default ring buffer capacity is 8 frames. Use opencapacitybuild to configure a different size.

§Usage

let mut buf = DecodeBuffer::open(Path::new("clip.mp4"))
    .capacity(16)
    .build()?;

while let Some(frame) = buf.pop_frame() {
    // present frame…
}

§Thread safety

DecodeBuffer is Send but not Sync; it must be owned by a single consumer. The internal std::sync::mpsc::Receiver enforces this.

Implementations§

Source§

impl DecodeBuffer

Source

pub fn open(path: &Path) -> DecodeBufferBuilder

Open the video at path and return a builder for configuring the buffer.

Chain with DecodeBufferBuilder::capacity and DecodeBufferBuilder::build to start decoding.

Source

pub fn pop_frame(&mut self) -> FrameResult

Pop the next decoded frame.

Source

pub fn buffered_frames(&self) -> usize

Returns an approximation of the number of decoded frames currently waiting in the buffer.

This value is advisory only; it may lag the actual buffer state by one scheduling quantum. Use it for diagnostics, not flow control.

Source

pub fn seek_events(&self) -> &Receiver<SeekEvent>

Returns a reference to the seek event receiver.

After calling seek_async, poll this receiver to detect when the seek has completed:

  • try_recv() — non-blocking; returns Err(TryRecvError::Empty) while the seek is still in progress.
  • recv() — blocks until the seek finishes.

Events are delivered within ~200 ms for local files. Unconsumed events accumulate in the channel (one per completed seek).

Source

pub fn error_events(&self) -> &Receiver<String>

Returns the receiver for non-fatal decode error messages.

Poll with try_recv() in the presentation loop. Each message corresponds to one failed decode_one() call in the background thread. The background thread exits after sending the error, so pop_frame will return Eof shortly after.

Source

pub fn seek(&mut self, target_pts: Duration) -> Result<(), PreviewError>

Frame-accurate seek to target_pts.

Stops the background decode thread, seeks the underlying decoder to the nearest preceding I-frame (AVSEEK_FLAG_BACKWARD + codec buffer flush), then restarts the thread. The restarted thread discards frames until PTS ≥ target_pts before making them available via pop_frame.

Blocks until the thread has stopped and the seek has been accepted by the decoder. Frames are filled asynchronously after the method returns.

§Errors

Returns PreviewError::SeekFailed if the decode thread panicked or if the underlying FFmpeg seek fails.

Source

pub fn seek_coarse(&mut self, target_pts: Duration) -> Result<(), PreviewError>

Coarse seek to the nearest I-frame at or before target_pts.

Faster than seek because it skips the forward-decode discard step. The next pop_frame returns the frame at the I-frame position, which may be up to ±½ GOP before target_pts (typically ±1–2 s for H.264 at default settings).

Typical use: call repeatedly while a scrub-bar is being dragged; call seek on mouse-up for frame accuracy.

§Errors

Returns PreviewError::SeekFailed if the decode thread panicked or if the underlying FFmpeg seek fails.

Source

pub fn seek_async(&mut self, target_pts: Duration)

Initiate a frame-accurate seek on a background thread and return immediately.

While seeking is in progress, pop_frame returns FrameResult::Seeking with the last successfully decoded frame as a placeholder. Normal FrameResult::Frame values resume once the seek completes.

The seek uses the same frame-accurate strategy as seek: FFmpeg jumps to the nearest preceding I-frame, then frames before target_pts are discarded before the first frame is made available.

If called again before the previous seek completes, the new seek supersedes the old one; the old worker exits at the next cancel check.

§Panics

Panics (inside the background worker thread) if the previous decode thread panicked — an internal bug that should never occur in practice.

Trait Implementations§

Source§

impl Drop for DecodeBuffer

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

fn pin_drop(self: Pin<&mut Self>)

🔬This is a nightly-only experimental API. (pin_ergonomics)
Execute the destructor for this type, but different to Drop::drop, it requires self to be pinned. 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.