av_scenechange/
decoder.rs

1use std::io::Read;
2
3use num_rational::Rational32;
4use v_frame::{
5    frame::Frame,
6    pixel::{ChromaSampling, Pixel},
7};
8
9#[cfg(feature = "ffmpeg")]
10use crate::ffmpeg::FfmpegDecoder;
11#[cfg(feature = "vapoursynth")]
12use crate::vapoursynth::VapoursynthDecoder;
13
14pub enum Decoder<R: Read> {
15    Y4m(y4m::Decoder<R>),
16    #[cfg(feature = "vapoursynth")]
17    Vapoursynth(VapoursynthDecoder),
18    #[cfg(feature = "ffmpeg")]
19    Ffmpeg(FfmpegDecoder),
20}
21
22impl<R: Read> Decoder<R> {
23    /// # Errors
24    ///
25    /// - If using a Vapoursynth script that contains an unsupported video
26    ///   format.
27    #[inline]
28    pub fn get_video_details(&self) -> anyhow::Result<VideoDetails> {
29        match self {
30            Decoder::Y4m(dec) => Ok(crate::y4m::get_video_details(dec)),
31            #[cfg(feature = "vapoursynth")]
32            Decoder::Vapoursynth(dec) => dec.get_video_details(),
33            #[cfg(feature = "ffmpeg")]
34            Decoder::Ffmpeg(dec) => Ok(dec.video_details),
35        }
36    }
37
38    /// # Errors
39    ///
40    /// - If a frame cannot be read.
41    #[inline]
42    pub fn read_video_frame<T: Pixel>(
43        &mut self,
44        video_details: &VideoDetails,
45    ) -> anyhow::Result<Frame<T>> {
46        match self {
47            Decoder::Y4m(dec) => crate::y4m::read_video_frame::<R, T>(dec, video_details),
48            #[cfg(feature = "vapoursynth")]
49            Decoder::Vapoursynth(dec) => dec.read_video_frame::<T>(video_details),
50            #[cfg(feature = "ffmpeg")]
51            Decoder::Ffmpeg(dec) => dec.read_video_frame::<T>(),
52        }
53    }
54}
55
56#[derive(Debug, Clone, Copy)]
57pub struct VideoDetails {
58    pub width: usize,
59    pub height: usize,
60    pub bit_depth: usize,
61    pub chroma_sampling: ChromaSampling,
62    pub time_base: Rational32,
63}
64
65impl Default for VideoDetails {
66    #[inline]
67    fn default() -> Self {
68        VideoDetails {
69            width: 640,
70            height: 480,
71            bit_depth: 8,
72            chroma_sampling: ChromaSampling::Cs420,
73            time_base: Rational32::new(1, 30),
74        }
75    }
76}