alass_cli/video_decoder/
mod.rs

1#[cfg(feature = "ffmpeg-library")]
2mod ffmpeg_library;
3
4#[cfg(feature = "ffmpeg-library")]
5pub use ffmpeg_library::VideoDecoderFFmpegLibrary as VideoDecoder;
6
7#[cfg(feature = "ffmpeg-binary")]
8mod ffmpeg_binary;
9
10#[cfg(feature = "ffmpeg-binary")]
11pub use ffmpeg_binary::VideoDecoderFFmpegBinary as VideoDecoder;
12
13pub trait AudioReceiver {
14    type Output;
15    type Error: failure::Fail;
16
17    /// Samples are in 8000kHz mono/single-channel format.
18    fn push_samples(&mut self, samples: &[i16]) -> Result<(), Self::Error>;
19
20    fn finish(self) -> Result<Self::Output, Self::Error>;
21}
22
23pub struct ChunkedAudioReceiver<R: AudioReceiver> {
24    buffer: Vec<i16>,
25    filled: usize,
26    next: R,
27}
28
29impl<R: AudioReceiver> ChunkedAudioReceiver<R> {
30    pub fn new(size: usize, next: R) -> ChunkedAudioReceiver<R> {
31        ChunkedAudioReceiver {
32            buffer: std::vec::from_elem(0, size),
33            filled: 0,
34            next,
35        }
36    }
37}
38
39impl<R: AudioReceiver> AudioReceiver for ChunkedAudioReceiver<R> {
40    type Output = R::Output;
41    type Error = R::Error;
42
43    fn push_samples(&mut self, mut samples: &[i16]) -> Result<(), R::Error> {
44        assert!(self.buffer.len() > self.filled);
45
46        loop {
47            if samples.is_empty() {
48                break;
49            }
50
51            let sample_count = std::cmp::min(self.buffer.len() - self.filled, samples.len());
52            self.buffer[self.filled..self.filled + sample_count].clone_from_slice(&samples[..sample_count]);
53
54            samples = &samples[sample_count..];
55
56            self.filled = self.filled + sample_count;
57
58            if self.filled == self.buffer.len() {
59                self.next.push_samples(self.buffer.as_slice())?;
60                self.filled = 0;
61            }
62        }
63
64        Ok(())
65    }
66
67    fn finish(self) -> Result<R::Output, R::Error> {
68        self.next.finish()
69    }
70}
71
72/// Use this trait if you want more detailed information about the progress of operations.
73pub trait ProgressHandler {
74    /// Will be called one time before `inc()` is called. `steps` is the
75    /// number of times `inc()` will be called.
76    ///
77    /// The number of steps is around the number of lines in the "incorrect" subtitle.
78    /// Be aware that this number can be zero!
79    #[allow(unused_variables)]
80    fn init(&mut self, steps: i64) {}
81
82    /// We made (small) progress!
83    fn inc(&mut self) {}
84
85    /// Will be called after the last `inc()`, when `inc()` was called `steps` times.
86    fn finish(&mut self) {}
87}
88
89/*struct NoProgressHandler {}
90impl ProgressHandler for NoProgressHandler {}*/