ffmpeg_the_third/codec/decoder/
audio.rs

1use std::ops::{Deref, DerefMut};
2
3#[cfg(not(feature = "ffmpeg_5_0"))]
4use crate::ffi::*;
5#[cfg(not(feature = "ffmpeg_5_0"))]
6use libc::c_int;
7
8use super::Opened;
9use crate::codec::Context;
10#[cfg(not(feature = "ffmpeg_5_0"))]
11use crate::frame;
12use crate::util::format;
13use crate::AudioService;
14#[cfg(not(feature = "ffmpeg_5_0"))]
15use crate::{packet, Error};
16
17#[cfg(feature = "ffmpeg_5_1")]
18use crate::ChannelLayout;
19
20#[cfg(not(feature = "ffmpeg_7_0"))]
21use crate::ChannelLayoutMask;
22
23pub struct Audio(pub Opened);
24
25impl Audio {
26    #[deprecated(
27        since = "4.4.0",
28        note = "Underlying API avcodec_decode_audio4 has been deprecated since FFmpeg 3.1; \
29        consider switching to send_packet() and receive_frame()"
30    )]
31    #[cfg(not(feature = "ffmpeg_5_0"))]
32    pub fn decode<P: packet::Ref>(
33        &mut self,
34        packet: &P,
35        out: &mut frame::Audio,
36    ) -> Result<bool, Error> {
37        unsafe {
38            let mut got: c_int = 0;
39
40            match avcodec_decode_audio4(
41                self.as_mut_ptr(),
42                out.as_mut_ptr(),
43                &mut got,
44                packet.as_ptr(),
45            ) {
46                e if e < 0 => Err(Error::from(e)),
47                _ => Ok(got != 0),
48            }
49        }
50    }
51
52    pub fn rate(&self) -> u32 {
53        unsafe { (*self.as_ptr()).sample_rate as u32 }
54    }
55
56    #[cfg(not(feature = "ffmpeg_7_0"))]
57    pub fn channels(&self) -> u16 {
58        unsafe { (*self.as_ptr()).channels as u16 }
59    }
60
61    pub fn format(&self) -> format::Sample {
62        unsafe { format::Sample::from((*self.as_ptr()).sample_fmt) }
63    }
64
65    pub fn request_format(&mut self, value: format::Sample) {
66        unsafe {
67            (*self.as_mut_ptr()).request_sample_fmt = value.into();
68        }
69    }
70
71    #[cfg(not(feature = "ffmpeg_7_0"))]
72    pub fn frames(&self) -> usize {
73        unsafe { (*self.as_ptr()).frame_number as usize }
74    }
75
76    pub fn align(&self) -> usize {
77        unsafe { (*self.as_ptr()).block_align as usize }
78    }
79
80    #[cfg(not(feature = "ffmpeg_7_0"))]
81    pub fn channel_layout(&self) -> ChannelLayoutMask {
82        unsafe { ChannelLayoutMask::from_bits_truncate((*self.as_ptr()).channel_layout) }
83    }
84
85    #[cfg(not(feature = "ffmpeg_7_0"))]
86    pub fn set_channel_layout(&mut self, value: ChannelLayoutMask) {
87        unsafe {
88            (*self.as_mut_ptr()).channel_layout = value.bits();
89        }
90    }
91
92    #[cfg(not(feature = "ffmpeg_7_0"))]
93    pub fn request_channel_layout(&mut self, value: ChannelLayoutMask) {
94        unsafe {
95            (*self.as_mut_ptr()).request_channel_layout = value.bits();
96        }
97    }
98
99    #[cfg(feature = "ffmpeg_5_1")]
100    pub fn ch_layout(&self) -> ChannelLayout<'_> {
101        unsafe { ChannelLayout::from(&self.as_ptr().as_ref().unwrap().ch_layout) }
102    }
103
104    #[cfg(feature = "ffmpeg_5_1")]
105    pub fn set_ch_layout(&mut self, value: ChannelLayout) {
106        unsafe {
107            self.as_mut_ptr().as_mut().unwrap().ch_layout = value.into_owned();
108        }
109    }
110
111    pub fn audio_service(&mut self) -> AudioService {
112        unsafe { AudioService::from((*self.as_mut_ptr()).audio_service_type) }
113    }
114
115    pub fn max_bit_rate(&self) -> usize {
116        unsafe { (*self.as_ptr()).rc_max_rate as usize }
117    }
118
119    pub fn frame_size(&self) -> u32 {
120        unsafe { (*self.as_ptr()).frame_size as u32 }
121    }
122
123    #[cfg(not(feature = "ffmpeg_5_0"))]
124    pub fn frame_start(&self) -> Option<usize> {
125        unsafe {
126            // Removed in ffmpeg >= 5.0 in favor of using encoder
127            // private options.
128            match (*self.as_ptr()).timecode_frame_start {
129                -1 => None,
130                n => Some(n as usize),
131            }
132        }
133    }
134}
135
136impl Deref for Audio {
137    type Target = Opened;
138
139    fn deref(&self) -> &<Self as Deref>::Target {
140        &self.0
141    }
142}
143
144impl DerefMut for Audio {
145    fn deref_mut(&mut self) -> &mut <Self as Deref>::Target {
146        &mut self.0
147    }
148}
149
150impl AsRef<Context> for Audio {
151    fn as_ref(&self) -> &Context {
152        self
153    }
154}
155
156impl AsMut<Context> for Audio {
157    fn as_mut(&mut self) -> &mut Context {
158        &mut self.0
159    }
160}