playa_ffmpeg/codec/decoder/
opened.rs

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