Skip to main content

lumen_ffmpeg/
lib.rs

1//! Small, Lumen-owned FFmpeg abstraction.
2//!
3//! This crate intentionally depends only on `ffmpeg-sys-next` for FFmpeg
4//! bindings and keeps raw FFmpeg pointers private to the implementation.
5
6pub mod audio;
7pub mod encode;
8pub(crate) mod ffi;
9pub mod format;
10pub mod gpu;
11pub mod video;
12
13pub use audio::{AudioDecoder, AudioFrame, AudioResampler, AudioResamplerConfig, SampleFormat};
14pub use encode::{
15    AudioEncoder, AudioEncoderConfig, GpuEncodeEvent, GpuEncodeOutcome, GpuEncodeStage,
16    GpuEncodeTelemetry, GpuTextureEncodeSupport, GpuUploadDescriptor, MuxedEncoder, OutputContext,
17    VideoEncoder, VideoEncoderConfig, gpu_texture_encode_support,
18};
19pub use format::{AudioStreamInfo, InputContext, MediaInfo, Rational, VideoStreamInfo};
20#[cfg(feature = "cuda")]
21pub use gpu::CudaDecodedFrame;
22#[cfg(feature = "vulkan")]
23pub use gpu::VulkanVideoFrame;
24#[cfg(all(feature = "cuda", target_os = "linux"))]
25pub use gpu::{
26    CudaContext, CudaDeviceAllocation, CudaDriver, CudaNv12ToRgbaConverter,
27    ImportedCudaExternalImage, import_owned_vulkan_opaque_fd_image, import_vulkan_opaque_fd_image,
28};
29#[cfg(feature = "cuda")]
30pub use gpu::{
31    CudaExternalMemoryHandle, CudaExternalSemaphoreHandle, CudaVideoFrame, VulkanToCudaExport,
32};
33pub use gpu::{GpuBackend, GpuVideoFrame, GpuVideoInput};
34#[cfg(feature = "metal")]
35pub use gpu::{
36    MetalDecodedFrame, MetalPixelBufferFrame, MetalPixelBufferPool, MetalTextureCache,
37    Objc2MetalDevice, Objc2MetalTexture,
38};
39pub use video::{
40    CpuVideoFrame, DecodeMode, EncodeMode, PixelFormat, VideoCodec, VideoDecoder,
41    VideoDecoderConfig,
42};
43
44pub type Result<T> = std::result::Result<T, FfmpegError>;
45
46#[derive(Debug, Clone, PartialEq, Eq)]
47pub struct FfmpegError {
48    pub operation: &'static str,
49    pub path: Option<String>,
50    pub code: Option<i32>,
51    pub message: String,
52    pub backend: Option<GpuBackend>,
53    pub codec: Option<VideoCodec>,
54    pub stream_index: Option<usize>,
55}
56
57impl FfmpegError {
58    pub fn new(operation: &'static str, message: impl Into<String>) -> Self {
59        Self {
60            operation,
61            path: None,
62            code: None,
63            message: message.into(),
64            backend: None,
65            codec: None,
66            stream_index: None,
67        }
68    }
69
70    pub fn with_path(mut self, path: impl Into<String>) -> Self {
71        self.path = Some(path.into());
72        self
73    }
74
75    pub fn with_backend(mut self, backend: GpuBackend) -> Self {
76        self.backend = Some(backend);
77        self
78    }
79
80    pub fn with_codec(mut self, codec: VideoCodec) -> Self {
81        self.codec = Some(codec);
82        self
83    }
84
85    pub fn with_stream_index(mut self, stream_index: usize) -> Self {
86        self.stream_index = Some(stream_index);
87        self
88    }
89}
90
91impl std::fmt::Display for FfmpegError {
92    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
93        write!(f, "{} failed: {}", self.operation, self.message)?;
94        if let Some(code) = self.code {
95            write!(f, " ({code})")?;
96        }
97        if let Some(path) = &self.path {
98            write!(f, " [{path}]")?;
99        }
100        Ok(())
101    }
102}
103
104impl std::error::Error for FfmpegError {}