playa_ffmpeg/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;
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 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}