1 | use std::ops::{Deref, DerefMut}; |
2 | use std::ptr; |
3 | |
4 | use ffi::*; |
5 | #[cfg (not(feature = "ffmpeg_5_0" ))] |
6 | use libc::c_int; |
7 | |
8 | use super::Encoder as Super; |
9 | use codec::{traits, Context}; |
10 | use util::format; |
11 | #[cfg (not(feature = "ffmpeg_5_0" ))] |
12 | use {frame, packet}; |
13 | use {ChannelLayout, Dictionary, Error}; |
14 | |
15 | pub struct Audio(pub Super); |
16 | |
17 | impl 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 | |
144 | impl Deref for Audio { |
145 | type Target = Super; |
146 | |
147 | fn deref(&self) -> &<Self as Deref>::Target { |
148 | &self.0 |
149 | } |
150 | } |
151 | |
152 | impl DerefMut for Audio { |
153 | fn deref_mut(&mut self) -> &mut <Self as Deref>::Target { |
154 | &mut self.0 |
155 | } |
156 | } |
157 | |
158 | impl AsRef<Context> for Audio { |
159 | fn as_ref(&self) -> &Context { |
160 | self |
161 | } |
162 | } |
163 | |
164 | impl AsMut<Context> for Audio { |
165 | fn as_mut(&mut self) -> &mut Context { |
166 | &mut self.0 |
167 | } |
168 | } |
169 | |
170 | pub struct Encoder(pub Audio); |
171 | |
172 | impl 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 | |
230 | impl Deref for Encoder { |
231 | type Target = Audio; |
232 | |
233 | fn deref(&self) -> &<Self as Deref>::Target { |
234 | &self.0 |
235 | } |
236 | } |
237 | |
238 | impl DerefMut for Encoder { |
239 | fn deref_mut(&mut self) -> &mut <Self as Deref>::Target { |
240 | &mut self.0 |
241 | } |
242 | } |
243 | |
244 | impl AsRef<Context> for Encoder { |
245 | fn as_ref(&self) -> &Context { |
246 | self |
247 | } |
248 | } |
249 | |
250 | impl AsMut<Context> for Encoder { |
251 | fn as_mut(&mut self) -> &mut Context { |
252 | &mut self.0 |
253 | } |
254 | } |
255 | |