1use std::ops::{Deref, DerefMut};
2use std::ptr;
3
4use ffi::*;
5#[cfg(not(feature = "ffmpeg_5_0"))]
6use libc::c_int;
7
8use super::Encoder as Super;
9use codec::{traits, Context};
10use util::format;
11#[cfg(not(feature = "ffmpeg_5_0"))]
12use {frame, packet};
13use {ChannelLayout, Dictionary, Error};
14
15pub struct Audio(pub Super);
16
17impl Audio {
18 pub fn open(mut self) -> Result<Encoder, Error> {
19 unsafe {
20 match avcodec_open2(self.as_mut_ptr(), ptr::null(), ptr::null_mut()) {
21 0 => Ok(Encoder(self)),
22 e => Err(Error::from(e)),
23 }
24 }
25 }
26
27 pub fn open_as<E: traits::Encoder>(mut self, codec: E) -> Result<Encoder, Error> {
28 unsafe {
29 if let Some(codec) = codec.encoder() {
30 match avcodec_open2(self.as_mut_ptr(), codec.as_ptr(), ptr::null_mut()) {
31 0 => Ok(Encoder(self)),
32 e => Err(Error::from(e)),
33 }
34 } else {
35 Err(Error::EncoderNotFound)
36 }
37 }
38 }
39
40 pub fn open_with(mut self, options: Dictionary) -> Result<Encoder, Error> {
41 unsafe {
42 let mut opts = options.disown();
43 let res = avcodec_open2(self.as_mut_ptr(), ptr::null(), &mut opts);
44
45 Dictionary::own(opts);
46
47 match res {
48 0 => Ok(Encoder(self)),
49 e => Err(Error::from(e)),
50 }
51 }
52 }
53
54 pub fn open_as_with<E: traits::Encoder>(
55 mut self,
56 codec: E,
57 options: Dictionary,
58 ) -> Result<Encoder, Error> {
59 unsafe {
60 if let Some(codec) = codec.encoder() {
61 let mut opts = options.disown();
62 let res = avcodec_open2(self.as_mut_ptr(), codec.as_ptr(), &mut opts);
63
64 Dictionary::own(opts);
65
66 match res {
67 0 => Ok(Encoder(self)),
68 e => Err(Error::from(e)),
69 }
70 } else {
71 Err(Error::EncoderNotFound)
72 }
73 }
74 }
75
76 pub fn set_rate(&mut self, rate: i32) {
77 unsafe {
78 (*self.as_mut_ptr()).sample_rate = rate;
79 }
80 }
81
82 pub fn rate(&self) -> u32 {
83 unsafe { (*self.as_ptr()).sample_rate as u32 }
84 }
85
86 pub fn set_format(&mut self, value: format::Sample) {
87 unsafe {
88 (*self.as_mut_ptr()).sample_fmt = value.into();
89 }
90 }
91
92 pub fn format(&self) -> format::Sample {
93 unsafe { format::Sample::from((*self.as_ptr()).sample_fmt) }
94 }
95
96 pub fn set_channel_layout(&mut self, value: ChannelLayout) {
97 unsafe {
98 #[cfg(not(feature = "ffmpeg_7_0"))]
99 {
100 (*self.as_mut_ptr()).channel_layout = value.bits();
101 }
102
103 #[cfg(feature = "ffmpeg_7_0")]
104 {
105 (*self.as_mut_ptr()).ch_layout = value.into();
106 }
107 }
108 }
109
110 pub fn channel_layout(&self) -> ChannelLayout {
111 unsafe {
112 #[cfg(not(feature = "ffmpeg_7_0"))]
113 {
114 ChannelLayout::from_bits_truncate((*self.as_ptr()).channel_layout)
115 }
116
117 #[cfg(feature = "ffmpeg_7_0")]
118 {
119 ChannelLayout::from((*self.as_ptr()).ch_layout)
120 }
121 }
122 }
123
124 #[cfg(not(feature = "ffmpeg_7_0"))]
125 pub fn set_channels(&mut self, value: i32) {
126 unsafe {
127 (*self.as_mut_ptr()).channels = value;
128 }
129 }
130
131 pub fn channels(&self) -> u16 {
132 #[cfg(not(feature = "ffmpeg_7_0"))]
133 unsafe {
134 (*self.as_ptr()).channels as u16
135 }
136
137 #[cfg(feature = "ffmpeg_7_0")]
138 {
139 self.channel_layout().channels() as u16
140 }
141 }
142}
143
144impl Deref for Audio {
145 type Target = Super;
146
147 fn deref(&self) -> &<Self as Deref>::Target {
148 &self.0
149 }
150}
151
152impl DerefMut for Audio {
153 fn deref_mut(&mut self) -> &mut <Self as Deref>::Target {
154 &mut self.0
155 }
156}
157
158impl AsRef<Context> for Audio {
159 fn as_ref(&self) -> &Context {
160 self
161 }
162}
163
164impl AsMut<Context> for Audio {
165 fn as_mut(&mut self) -> &mut Context {
166 &mut self.0
167 }
168}
169
170pub struct Encoder(pub Audio);
171
172impl Encoder {
173 #[deprecated(
174 since = "4.4.0",
175 note = "Underlying API avcodec_encode_audio2 has been deprecated since FFmpeg 3.1; \
176 consider switching to send_frame() and receive_packet()"
177 )]
178 #[cfg(not(feature = "ffmpeg_5_0"))]
179 pub fn encode<P: packet::Mut>(
180 &mut self,
181 frame: &frame::Audio,
182 out: &mut P,
183 ) -> Result<bool, Error> {
184 unsafe {
185 if self.format() != frame.format() {
186 return Err(Error::InvalidData);
187 }
188
189 let mut got: c_int = 0;
190
191 match avcodec_encode_audio2(
192 self.0.as_mut_ptr(),
193 out.as_mut_ptr(),
194 frame.as_ptr(),
195 &mut got,
196 ) {
197 e if e < 0 => Err(Error::from(e)),
198 _ => Ok(got != 0),
199 }
200 }
201 }
202
203 #[deprecated(
204 since = "4.4.0",
205 note = "Underlying API avcodec_encode_audio2 has been deprecated since FFmpeg 3.1; \
206 consider switching to send_eof() and receive_packet()"
207 )]
208 #[cfg(not(feature = "ffmpeg_5_0"))]
209 pub fn flush<P: packet::Mut>(&mut self, out: &mut P) -> Result<bool, Error> {
210 unsafe {
211 let mut got: c_int = 0;
212
213 match avcodec_encode_audio2(
214 self.0.as_mut_ptr(),
215 out.as_mut_ptr(),
216 ptr::null(),
217 &mut got,
218 ) {
219 e if e < 0 => Err(Error::from(e)),
220 _ => Ok(got != 0),
221 }
222 }
223 }
224
225 pub fn frame_size(&self) -> u32 {
226 unsafe { (*self.as_ptr()).frame_size as u32 }
227 }
228}
229
230impl Deref for Encoder {
231 type Target = Audio;
232
233 fn deref(&self) -> &<Self as Deref>::Target {
234 &self.0
235 }
236}
237
238impl DerefMut for Encoder {
239 fn deref_mut(&mut self) -> &mut <Self as Deref>::Target {
240 &mut self.0
241 }
242}
243
244impl AsRef<Context> for Encoder {
245 fn as_ref(&self) -> &Context {
246 self
247 }
248}
249
250impl AsMut<Context> for Encoder {
251 fn as_mut(&mut self) -> &mut Context {
252 &mut self.0
253 }
254}
255