ffmpeg-pipeline 0.2.0

Composable FFmpeg decoding, encoding, remuxing, and media I/O for Rust
Documentation
use super::*;
use ffmpeg_next::{
    format::Pixel,
    software::scaling::{context::Context as ScalerContext, flag::Flags as ScalerFlags},
    Stream,
};

pub struct Scaler {
    scaler: ScalerContext,
}

#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub enum ScalingAlgorithm {
    Bilinear,
    Bicubic,
    #[default]
    Spline,
    Lanczos,
}

impl Scaler {
    pub fn new(size: &FrameSize, src_format: Pixel, dst_format: Pixel) -> FFmpegResult<Self> {
        Self::with_algorithm(size, src_format, dst_format, ScalingAlgorithm::default())
    }

    pub fn with_algorithm(
        size: &FrameSize,
        src_format: Pixel,
        dst_format: Pixel,
        algorithm: ScalingAlgorithm,
    ) -> FFmpegResult<Self> {
        let flags = match algorithm {
            ScalingAlgorithm::Bilinear => ScalerFlags::BILINEAR,
            ScalingAlgorithm::Bicubic => ScalerFlags::BICUBIC,
            ScalingAlgorithm::Spline => ScalerFlags::SPLINE,
            ScalingAlgorithm::Lanczos => ScalerFlags::LANCZOS,
        };
        Ok(Self {
            scaler: ScalerContext::get(
                src_format,
                size.width as u32,
                size.height as u32,
                dst_format,
                size.width as u32,
                size.height as u32,
                flags,
            )?,
        })
    }

    pub fn from_info(info: &VideoInfo, dst_format: Pixel) -> FFmpegResult<Self> {
        Self::new(&info.size, info.pixel, dst_format)
    }

    pub fn from_stream(stream: &Stream, dst_format: Pixel) -> FFmpegResult<Self> {
        let info = parse::parse_stream_info(stream)?;
        debug!(
            "stream: {}, size: {} x {}, pixel: {:?}",
            info.stream, info.size.width, info.size.height, info.pixel
        );
        Self::from_info(&info, dst_format)
    }

    pub fn from_path(path: &Path, index: usize, dst_format: Pixel) -> FFmpegResult<Self> {
        let input = input_file(path)?;
        let stream = input
            .stream(index)
            .ok_or(FFmpegError::StreamNotFound(index))?;
        Self::from_stream(&stream, dst_format)
    }

    pub fn scale_frame(&mut self, frame: &VideoFrame) -> FFmpegResult<VideoFrame> {
        let mut rgb_frame = VideoFrame::empty();
        self.scaler.run(frame, &mut rgb_frame)?;
        Ok(rgb_frame)
    }
}