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 | (*self.as_mut_ptr()).channel_layout = value.bits(); |
99 | } |
100 | } |
101 | |
102 | pub fn channel_layout(&self) -> ChannelLayout { |
103 | unsafe { ChannelLayout::from_bits_truncate((*self.as_ptr()).channel_layout) } |
104 | } |
105 | |
106 | pub fn set_channels(&mut self, value: i32) { |
107 | unsafe { |
108 | (*self.as_mut_ptr()).channels = value; |
109 | } |
110 | } |
111 | |
112 | pub fn channels(&self) -> u16 { |
113 | unsafe { (*self.as_ptr()).channels as u16 } |
114 | } |
115 | } |
116 | |
117 | impl Deref for Audio { |
118 | type Target = Super; |
119 | |
120 | fn deref(&self) -> &<Self as Deref>::Target { |
121 | &self.0 |
122 | } |
123 | } |
124 | |
125 | impl DerefMut for Audio { |
126 | fn deref_mut(&mut self) -> &mut <Self as Deref>::Target { |
127 | &mut self.0 |
128 | } |
129 | } |
130 | |
131 | impl AsRef<Context> for Audio { |
132 | fn as_ref(&self) -> &Context { |
133 | self |
134 | } |
135 | } |
136 | |
137 | impl AsMut<Context> for Audio { |
138 | fn as_mut(&mut self) -> &mut Context { |
139 | &mut self.0 |
140 | } |
141 | } |
142 | |
143 | pub struct Encoder(pub Audio); |
144 | |
145 | impl Encoder { |
146 | #[deprecated ( |
147 | since = "4.4.0" , |
148 | note = "Underlying API avcodec_encode_audio2 has been deprecated since FFmpeg 3.1; \ |
149 | consider switching to send_frame() and receive_packet()" |
150 | )] |
151 | #[cfg (not(feature = "ffmpeg_5_0" ))] |
152 | pub fn encode<P: packet::Mut>( |
153 | &mut self, |
154 | frame: &frame::Audio, |
155 | out: &mut P, |
156 | ) -> Result<bool, Error> { |
157 | unsafe { |
158 | if self.format() != frame.format() { |
159 | return Err(Error::InvalidData); |
160 | } |
161 | |
162 | let mut got: c_int = 0; |
163 | |
164 | match avcodec_encode_audio2( |
165 | self.0.as_mut_ptr(), |
166 | out.as_mut_ptr(), |
167 | frame.as_ptr(), |
168 | &mut got, |
169 | ) { |
170 | e if e < 0 => Err(Error::from(e)), |
171 | _ => Ok(got != 0), |
172 | } |
173 | } |
174 | } |
175 | |
176 | #[deprecated ( |
177 | since = "4.4.0" , |
178 | note = "Underlying API avcodec_encode_audio2 has been deprecated since FFmpeg 3.1; \ |
179 | consider switching to send_eof() and receive_packet()" |
180 | )] |
181 | #[cfg (not(feature = "ffmpeg_5_0" ))] |
182 | pub fn flush<P: packet::Mut>(&mut self, out: &mut P) -> Result<bool, Error> { |
183 | unsafe { |
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 | ptr::null(), |
190 | &mut got, |
191 | ) { |
192 | e if e < 0 => Err(Error::from(e)), |
193 | _ => Ok(got != 0), |
194 | } |
195 | } |
196 | } |
197 | |
198 | pub fn frame_size(&self) -> u32 { |
199 | unsafe { (*self.as_ptr()).frame_size as u32 } |
200 | } |
201 | } |
202 | |
203 | impl Deref for Encoder { |
204 | type Target = Audio; |
205 | |
206 | fn deref(&self) -> &<Self as Deref>::Target { |
207 | &self.0 |
208 | } |
209 | } |
210 | |
211 | impl DerefMut for Encoder { |
212 | fn deref_mut(&mut self) -> &mut <Self as Deref>::Target { |
213 | &mut self.0 |
214 | } |
215 | } |
216 | |
217 | impl AsRef<Context> for Encoder { |
218 | fn as_ref(&self) -> &Context { |
219 | self |
220 | } |
221 | } |
222 | |
223 | impl AsMut<Context> for Encoder { |
224 | fn as_mut(&mut self) -> &mut Context { |
225 | &mut self.0 |
226 | } |
227 | } |
228 | |