ffmpeg_the_third/codec/decoder/
audio.rs1use 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 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}