playa_ffmpeg/codec/encoder/
audio.rs1use 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}