Skip to main content

ffmpeg_the_third/codec/decoder/
opened.rs

1use std::ops::{Deref, DerefMut};
2use std::ptr;
3
4use super::{Audio, Decoder, Subtitle, Video};
5use crate::codec::{Context, Profile};
6use crate::ffi::*;
7use crate::{media, packet, Error, Frame, Rational};
8
9#[cfg(feature = "ffmpeg_8_1")]
10use super::Flags;
11
12pub struct Opened(pub Decoder);
13
14impl Opened {
15    pub fn video(self) -> Result<Video, Error> {
16        if self.medium() == media::Type::Video {
17            Ok(Video(self))
18        } else {
19            Err(Error::InvalidData)
20        }
21    }
22
23    pub fn audio(self) -> Result<Audio, Error> {
24        if self.medium() == media::Type::Audio {
25            Ok(Audio(self))
26        } else {
27            Err(Error::InvalidData)
28        }
29    }
30
31    pub fn subtitle(self) -> Result<Subtitle, Error> {
32        if self.medium() == media::Type::Subtitle {
33            Ok(Subtitle(self))
34        } else {
35            Err(Error::InvalidData)
36        }
37    }
38
39    pub fn send_packet<P: packet::Ref>(&mut self, packet: &P) -> Result<(), Error> {
40        unsafe {
41            match avcodec_send_packet(self.as_mut_ptr(), packet.as_ptr()) {
42                e if e < 0 => Err(Error::from(e)),
43                _ => Ok(()),
44            }
45        }
46    }
47
48    /// Sends a NULL packet to the decoder to signal end of stream and enter
49    /// draining mode.
50    pub fn send_eof(&mut self) -> Result<(), Error> {
51        unsafe {
52            match avcodec_send_packet(self.as_mut_ptr(), ptr::null()) {
53                e if e < 0 => Err(Error::from(e)),
54                _ => Ok(()),
55            }
56        }
57    }
58
59    #[cfg(feature = "ffmpeg_8_1")]
60    pub fn receive_frame_with_flags(
61        &mut self,
62        frame: &mut Frame,
63        flags: Flags,
64    ) -> Result<(), Error> {
65        unsafe {
66            match avcodec_receive_frame_flags(self.as_mut_ptr(), frame.as_mut_ptr(), flags.bits()) {
67                e if e < 0 => Err(Error::from(e)),
68                _ => Ok(()),
69            }
70        }
71    }
72
73    pub fn receive_frame(&mut self, frame: &mut Frame) -> Result<(), Error> {
74        unsafe {
75            match avcodec_receive_frame(self.as_mut_ptr(), frame.as_mut_ptr()) {
76                e if e < 0 => Err(Error::from(e)),
77                _ => Ok(()),
78            }
79        }
80    }
81
82    pub fn bit_rate(&self) -> usize {
83        unsafe { (*self.as_ptr()).bit_rate as usize }
84    }
85
86    pub fn delay(&self) -> usize {
87        unsafe { (*self.as_ptr()).delay as usize }
88    }
89
90    pub fn profile(&self) -> Profile {
91        unsafe { Profile::from((self.id(), (*self.as_ptr()).profile)) }
92    }
93
94    pub fn frame_rate(&self) -> Option<Rational> {
95        unsafe {
96            let value = (*self.as_ptr()).framerate;
97
98            if value == (AVRational { num: 0, den: 1 }) {
99                None
100            } else {
101                Some(Rational::from(value))
102            }
103        }
104    }
105
106    pub fn flush(&mut self) {
107        unsafe {
108            avcodec_flush_buffers(self.as_mut_ptr());
109        }
110    }
111}
112
113// Intentionally no Drop impl; the underlying codec::Context frees itself.
114
115impl Deref for Opened {
116    type Target = Decoder;
117
118    fn deref(&self) -> &<Self as Deref>::Target {
119        &self.0
120    }
121}
122
123impl DerefMut for Opened {
124    fn deref_mut(&mut self) -> &mut <Self as Deref>::Target {
125        &mut self.0
126    }
127}
128
129impl AsRef<Context> for Opened {
130    fn as_ref(&self) -> &Context {
131        self
132    }
133}
134
135impl AsMut<Context> for Opened {
136    fn as_mut(&mut self) -> &mut Context {
137        &mut self.0
138    }
139}