ffmpeg_pipeline/
scaler.rs1use super::*;
2use ffmpeg_next::{
3 format::Pixel,
4 software::scaling::{context::Context as ScalerContext, flag::Flags as ScalerFlags},
5 Stream,
6};
7
8pub struct Scaler {
9 scaler: ScalerContext,
10}
11
12#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
13pub enum ScalingAlgorithm {
14 Bilinear,
15 Bicubic,
16 #[default]
17 Spline,
18 Lanczos,
19}
20
21impl Scaler {
22 pub fn new(size: &FrameSize, src_format: Pixel, dst_format: Pixel) -> FFmpegResult<Self> {
23 Self::with_algorithm(size, src_format, dst_format, ScalingAlgorithm::default())
24 }
25
26 pub fn with_algorithm(
27 size: &FrameSize,
28 src_format: Pixel,
29 dst_format: Pixel,
30 algorithm: ScalingAlgorithm,
31 ) -> FFmpegResult<Self> {
32 let flags = match algorithm {
33 ScalingAlgorithm::Bilinear => ScalerFlags::BILINEAR,
34 ScalingAlgorithm::Bicubic => ScalerFlags::BICUBIC,
35 ScalingAlgorithm::Spline => ScalerFlags::SPLINE,
36 ScalingAlgorithm::Lanczos => ScalerFlags::LANCZOS,
37 };
38 Ok(Self {
39 scaler: ScalerContext::get(
40 src_format,
41 size.width as u32,
42 size.height as u32,
43 dst_format,
44 size.width as u32,
45 size.height as u32,
46 flags,
47 )?,
48 })
49 }
50
51 pub fn from_info(info: &VideoInfo, dst_format: Pixel) -> FFmpegResult<Self> {
52 Self::new(&info.size, info.pixel, dst_format)
53 }
54
55 pub fn from_stream(stream: &Stream, dst_format: Pixel) -> FFmpegResult<Self> {
56 let info = parse::parse_stream_info(stream)?;
57 debug!(
58 "stream: {}, size: {} x {}, pixel: {:?}",
59 info.stream, info.size.width, info.size.height, info.pixel
60 );
61 Self::from_info(&info, dst_format)
62 }
63
64 pub fn from_path(path: &Path, index: usize, dst_format: Pixel) -> FFmpegResult<Self> {
65 let input = input_file(path)?;
66 let stream = input
67 .stream(index)
68 .ok_or(FFmpegError::StreamNotFound(index))?;
69 Self::from_stream(&stream, dst_format)
70 }
71
72 pub fn scale_frame(&mut self, frame: &VideoFrame) -> FFmpegResult<VideoFrame> {
73 let mut rgb_frame = VideoFrame::empty();
74 self.scaler.run(frame, &mut rgb_frame)?;
75 Ok(rgb_frame)
76 }
77}