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