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