playa_ffmpeg/codec/encoder/
audio.rs

1use std::{
2    ops::{Deref, DerefMut},
3    ptr,
4};
5
6use crate::ffi::*;
7#[cfg(not(feature = "ffmpeg_5_0"))]
8use libc::c_int;
9
10use super::Encoder as Super;
11use crate::{
12    ChannelLayout, Dictionary, Error,
13    codec::{Context, traits},
14    util::format,
15};
16#[cfg(not(feature = "ffmpeg_5_0"))]
17use {crate::frame, crate::packet};
18
19pub struct Audio(pub Super);
20
21impl Audio {
22    pub fn open(mut self) -> Result<Encoder, Error> {
23        unsafe {
24            match avcodec_open2(self.as_mut_ptr(), ptr::null(), ptr::null_mut()) {
25                0 => Ok(Encoder(self)),
26                e => Err(Error::from(e)),
27            }
28        }
29    }
30
31    pub fn open_as<E: traits::Encoder>(mut self, codec: E) -> Result<Encoder, Error> {
32        unsafe {
33            if let Some(codec) = codec.encoder() {
34                match avcodec_open2(self.as_mut_ptr(), codec.as_ptr(), ptr::null_mut()) {
35                    0 => Ok(Encoder(self)),
36                    e => Err(Error::from(e)),
37                }
38            } else {
39                Err(Error::EncoderNotFound)
40            }
41        }
42    }
43
44    pub fn open_with(mut self, options: Dictionary) -> Result<Encoder, Error> {
45        unsafe {
46            let mut opts = options.disown();
47            let res = avcodec_open2(self.as_mut_ptr(), ptr::null(), &mut opts);
48
49            Dictionary::own(opts);
50
51            match res {
52                0 => Ok(Encoder(self)),
53                e => Err(Error::from(e)),
54            }
55        }
56    }
57
58    pub fn open_as_with<E: traits::Encoder>(mut self, codec: E, options: Dictionary) -> 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>(&mut self, frame: &frame::Audio, out: &mut P) -> Result<bool, Error> {
180        unsafe {
181            if self.format() != frame.format() {
182                return Err(Error::InvalidData);
183            }
184
185            let mut got: c_int = 0;
186
187            match avcodec_encode_audio2(self.0.as_mut_ptr(), out.as_mut_ptr(), frame.as_ptr(), &mut got) {
188                e if e < 0 => Err(Error::from(e)),
189                _ => Ok(got != 0),
190            }
191        }
192    }
193
194    #[deprecated(
195        since = "4.4.0",
196        note = "Underlying API avcodec_encode_audio2 has been deprecated since FFmpeg 3.1; \
197        consider switching to send_eof() and receive_packet()"
198    )]
199    #[cfg(not(feature = "ffmpeg_5_0"))]
200    pub fn flush<P: packet::Mut>(&mut self, out: &mut P) -> Result<bool, Error> {
201        unsafe {
202            let mut got: c_int = 0;
203
204            match avcodec_encode_audio2(self.0.as_mut_ptr(), out.as_mut_ptr(), ptr::null(), &mut got) {
205                e if e < 0 => Err(Error::from(e)),
206                _ => Ok(got != 0),
207            }
208        }
209    }
210
211    pub fn frame_size(&self) -> u32 {
212        unsafe { (*self.as_ptr()).frame_size as u32 }
213    }
214}
215
216impl Deref for Encoder {
217    type Target = Audio;
218
219    fn deref(&self) -> &<Self as Deref>::Target {
220        &self.0
221    }
222}
223
224impl DerefMut for Encoder {
225    fn deref_mut(&mut self) -> &mut <Self as Deref>::Target {
226        &mut self.0
227    }
228}
229
230impl AsRef<Context> for Encoder {
231    fn as_ref(&self) -> &Context {
232        self
233    }
234}
235
236impl AsMut<Context> for Encoder {
237    fn as_mut(&mut self) -> &mut Context {
238        &mut self.0
239    }
240}