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