ffmpeg_the_third/codec/encoder/
video.rs1use std::ops::{Deref, DerefMut};
2use std::ptr;
3
4use crate::ffi::*;
5use libc::{c_float, c_int};
6
7use super::Encoder as Super;
8use super::{Comparison, Decision};
9#[cfg(not(feature = "ffmpeg_5_0"))]
10use super::{MotionEstimation, Prediction};
11use crate::codec::{traits, Context};
12use crate::{color, format, Dictionary, Error, Rational};
13#[cfg(not(feature = "ffmpeg_5_0"))]
14use crate::{frame, packet};
15
16pub struct Video(pub Super);
17
18impl Video {
19 #[inline]
20 pub fn open(mut self) -> Result<Encoder, Error> {
21 unsafe {
22 match avcodec_open2(self.as_mut_ptr(), ptr::null(), ptr::null_mut()) {
23 0 => Ok(Encoder(self)),
24 e => Err(Error::from(e)),
25 }
26 }
27 }
28
29 #[inline]
30 pub fn open_as<T, E: traits::Encoder<T>>(mut self, codec: E) -> Result<Encoder, Error> {
31 unsafe {
32 if let Some(codec) = codec.encoder() {
33 match avcodec_open2(self.as_mut_ptr(), codec.as_ptr(), ptr::null_mut()) {
34 0 => Ok(Encoder(self)),
35 e => Err(Error::from(e)),
36 }
37 } else {
38 Err(Error::EncoderNotFound)
39 }
40 }
41 }
42
43 #[inline]
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 #[inline]
59 pub fn open_as_with<T, E: traits::Encoder<T>>(
60 mut self,
61 codec: E,
62 options: Dictionary,
63 ) -> Result<Encoder, Error> {
64 unsafe {
65 if let Some(codec) = codec.encoder() {
66 let mut opts = options.disown();
67 let res = avcodec_open2(self.as_mut_ptr(), codec.as_ptr(), &mut opts);
68
69 Dictionary::own(opts);
70
71 match res {
72 0 => Ok(Encoder(self)),
73 e => Err(Error::from(e)),
74 }
75 } else {
76 Err(Error::EncoderNotFound)
77 }
78 }
79 }
80
81 #[inline]
82 pub fn set_width(&mut self, value: u32) {
83 unsafe {
84 (*self.as_mut_ptr()).width = value as c_int;
85 }
86 }
87
88 #[inline]
89 pub fn width(&self) -> u32 {
90 unsafe { (*self.as_ptr()).width as u32 }
91 }
92
93 #[inline]
94 pub fn set_height(&mut self, value: u32) {
95 unsafe {
96 (*self.as_mut_ptr()).height = value as c_int;
97 }
98 }
99
100 #[inline]
101 pub fn height(&self) -> u32 {
102 unsafe { (*self.as_ptr()).height as u32 }
103 }
104
105 #[inline]
106 pub fn set_gop(&mut self, value: u32) {
107 unsafe {
108 (*self.as_mut_ptr()).gop_size = value as c_int;
109 }
110 }
111
112 #[inline]
113 pub fn set_format(&mut self, value: format::Pixel) {
114 unsafe {
115 (*self.as_mut_ptr()).pix_fmt = value.into();
116 }
117 }
118
119 #[inline]
120 pub fn format(&self) -> format::Pixel {
121 unsafe { format::Pixel::from((*self.as_ptr()).pix_fmt) }
122 }
123
124 #[inline]
125 pub fn set_max_b_frames(&mut self, value: usize) {
126 unsafe {
127 (*self.as_mut_ptr()).max_b_frames = value as c_int;
128 }
129 }
130
131 #[inline]
132 pub fn set_b_quant_factor(&mut self, value: f32) {
133 unsafe {
134 (*self.as_mut_ptr()).b_quant_factor = value as c_float;
135 }
136 }
137
138 #[inline]
139 pub fn set_b_quant_offset(&mut self, value: f32) {
140 unsafe {
141 (*self.as_mut_ptr()).b_quant_offset = value as c_float;
142 }
143 }
144
145 #[inline]
146 pub fn set_i_quant_factor(&mut self, value: f32) {
147 unsafe {
148 (*self.as_mut_ptr()).i_quant_factor = value as c_float;
149 }
150 }
151
152 #[inline]
153 pub fn set_i_quant_offset(&mut self, value: f32) {
154 unsafe {
155 (*self.as_mut_ptr()).i_quant_offset = value as c_float;
156 }
157 }
158
159 #[inline]
160 pub fn set_lumi_masking(&mut self, value: f32) {
161 unsafe {
162 (*self.as_mut_ptr()).lumi_masking = value as c_float;
163 }
164 }
165
166 #[inline]
167 pub fn set_temporal_cplx_masking(&mut self, value: f32) {
168 unsafe {
169 (*self.as_mut_ptr()).temporal_cplx_masking = value as c_float;
170 }
171 }
172
173 #[inline]
174 pub fn set_spatial_cplx_masking(&mut self, value: f32) {
175 unsafe {
176 (*self.as_mut_ptr()).spatial_cplx_masking = value as c_float;
177 }
178 }
179
180 #[inline]
181 pub fn set_p_masking(&mut self, value: f32) {
182 unsafe {
183 (*self.as_mut_ptr()).p_masking = value as c_float;
184 }
185 }
186
187 #[inline]
188 pub fn set_dark_masking(&mut self, value: f32) {
189 unsafe {
190 (*self.as_mut_ptr()).dark_masking = value as c_float;
191 }
192 }
193
194 #[inline]
195 #[cfg(not(feature = "ffmpeg_5_0"))]
196 pub fn set_prediction(&mut self, value: Prediction) {
197 unsafe {
198 (*self.as_mut_ptr()).prediction_method = value.into();
199 }
200 }
201
202 #[inline]
203 pub fn set_aspect_ratio<R: Into<Rational>>(&mut self, value: R) {
204 unsafe {
205 (*self.as_mut_ptr()).sample_aspect_ratio = value.into().into();
206 }
207 }
208
209 #[inline]
210 pub fn set_me_comparison(&mut self, value: Comparison) {
211 unsafe {
212 (*self.as_mut_ptr()).me_cmp = value.into();
213 }
214 }
215
216 #[inline]
217 pub fn set_me_sub_comparison(&mut self, value: Comparison) {
218 unsafe {
219 (*self.as_mut_ptr()).me_sub_cmp = value.into();
220 }
221 }
222
223 #[inline]
224 pub fn set_mb_comparison(&mut self, value: Comparison) {
225 unsafe {
226 (*self.as_mut_ptr()).mb_cmp = value.into();
227 }
228 }
229
230 #[inline]
231 pub fn set_ildct_comparison(&mut self, value: Comparison) {
232 unsafe {
233 (*self.as_mut_ptr()).ildct_cmp = value.into();
234 }
235 }
236
237 #[inline]
238 pub fn set_dia_size(&mut self, value: usize) {
239 unsafe {
240 (*self.as_mut_ptr()).dia_size = value as c_int;
241 }
242 }
243
244 #[inline]
245 pub fn set_last_predictors(&mut self, value: usize) {
246 unsafe {
247 (*self.as_mut_ptr()).last_predictor_count = value as c_int;
248 }
249 }
250
251 #[inline]
252 #[cfg(not(feature = "ffmpeg_5_0"))]
253 pub fn set_pre_me(&mut self, value: MotionEstimation) {
254 unsafe {
255 (*self.as_mut_ptr()).pre_me = value.into();
256 }
257 }
258
259 #[inline]
260 pub fn set_me_pre_comparison(&mut self, value: Comparison) {
261 unsafe {
262 (*self.as_mut_ptr()).me_pre_cmp = value.into();
263 }
264 }
265
266 #[inline]
267 pub fn set_pre_dia_size(&mut self, value: usize) {
268 unsafe {
269 (*self.as_mut_ptr()).pre_dia_size = value as c_int;
270 }
271 }
272
273 #[inline]
274 pub fn set_me_subpel_quality(&mut self, value: usize) {
275 unsafe {
276 (*self.as_mut_ptr()).me_subpel_quality = value as c_int;
277 }
278 }
279
280 #[inline]
281 pub fn set_me_range(&mut self, value: usize) {
282 unsafe {
283 (*self.as_mut_ptr()).me_range = value as c_int;
284 }
285 }
286
287 #[inline]
288 pub fn set_mb_decision(&mut self, value: Decision) {
289 unsafe {
290 (*self.as_mut_ptr()).mb_decision = value.into();
291 }
292 }
293
294 #[inline]
295 pub fn set_mb_lmin(&mut self, value: i32) {
296 unsafe {
297 (*self.as_mut_ptr()).mb_lmin = value as c_int;
298 }
299 }
300
301 #[inline]
302 pub fn set_mb_lmax(&mut self, value: i32) {
303 unsafe {
304 (*self.as_mut_ptr()).mb_lmax = value as c_int;
305 }
306 }
307
308 #[inline]
309 pub fn set_intra_dc_precision(&mut self, value: u8) {
310 unsafe {
311 (*self.as_mut_ptr()).intra_dc_precision = i32::from(value);
312 }
313 }
314
315 #[inline]
316 pub fn set_qmin(&mut self, value: i32) {
317 unsafe {
318 (*self.as_mut_ptr()).qmin = value as c_int;
319 }
320 }
321
322 #[inline]
323 pub fn set_qmax(&mut self, value: i32) {
324 unsafe {
325 (*self.as_mut_ptr()).qmax = value as c_int;
326 }
327 }
328
329 #[inline]
330 pub fn set_global_quality(&mut self, value: i32) {
331 unsafe {
332 (*self.as_mut_ptr()).global_quality = value as c_int;
333 }
334 }
335
336 #[inline]
337 pub fn set_colorspace(&mut self, value: color::Space) {
338 unsafe {
339 (*self.as_mut_ptr()).colorspace = value.into();
340 }
341 }
342
343 #[inline]
344 pub fn colorspace(&self) -> color::Space {
345 unsafe { (*self.as_ptr()).colorspace.into() }
346 }
347
348 #[inline]
349 pub fn set_color_range(&mut self, value: color::Range) {
350 unsafe {
351 (*self.as_mut_ptr()).color_range = value.into();
352 }
353 }
354
355 #[inline]
356 pub fn color_range(&self) -> color::Range {
357 unsafe { (*self.as_ptr()).color_range.into() }
358 }
359}
360
361impl Deref for Video {
362 type Target = Super;
363
364 #[inline(always)]
365 fn deref(&self) -> &<Self as Deref>::Target {
366 &self.0
367 }
368}
369
370impl DerefMut for Video {
371 #[inline(always)]
372 fn deref_mut(&mut self) -> &mut <Self as Deref>::Target {
373 &mut self.0
374 }
375}
376
377impl AsRef<Context> for Video {
378 fn as_ref(&self) -> &Context {
379 self
380 }
381}
382
383impl AsMut<Context> for Video {
384 fn as_mut(&mut self) -> &mut Context {
385 &mut self.0
386 }
387}
388
389pub struct Encoder(pub Video);
390
391impl Encoder {
392 #[deprecated(
393 since = "4.4.0",
394 note = "Underlying API avcodec_encode_video2 has been deprecated since FFmpeg 3.1; \
395 consider switching to send_frame() and receive_packet()"
396 )]
397 #[inline]
398 #[cfg(not(feature = "ffmpeg_5_0"))]
399 pub fn encode<P: packet::Mut>(
400 &mut self,
401 frame: &frame::Video,
402 out: &mut P,
403 ) -> Result<bool, Error> {
404 unsafe {
405 if self.format() != frame.format()
406 || self.width() != frame.width()
407 || self.height() != frame.height()
408 {
409 return Err(Error::InvalidData);
410 }
411
412 let mut got: c_int = 0;
413
414 match avcodec_encode_video2(
415 self.0.as_mut_ptr(),
416 out.as_mut_ptr(),
417 frame.as_ptr(),
418 &mut got,
419 ) {
420 e if e < 0 => Err(Error::from(e)),
421 _ => Ok(got != 0),
422 }
423 }
424 }
425
426 #[deprecated(
427 since = "4.4.0",
428 note = "Underlying API avcodec_encode_video2 has been deprecated since FFmpeg 3.1; \
429 consider switching to send_frame() and receive_packet()"
430 )]
431 #[inline]
432 #[cfg(not(feature = "ffmpeg_5_0"))]
433 pub fn flush<P: packet::Mut>(&mut self, out: &mut P) -> Result<bool, Error> {
434 unsafe {
435 let mut got: c_int = 0;
436
437 match avcodec_encode_video2(
438 self.0.as_mut_ptr(),
439 out.as_mut_ptr(),
440 ptr::null(),
441 &mut got,
442 ) {
443 e if e < 0 => Err(Error::from(e)),
444 _ => Ok(got != 0),
445 }
446 }
447 }
448
449 #[inline]
450 pub fn frame_size(&self) -> u32 {
451 unsafe { (*self.as_ptr()).frame_size as u32 }
452 }
453}
454
455impl Deref for Encoder {
456 type Target = Video;
457
458 #[inline]
459 fn deref(&self) -> &<Self as Deref>::Target {
460 &self.0
461 }
462}
463
464impl DerefMut for Encoder {
465 #[inline]
466 fn deref_mut(&mut self) -> &mut <Self as Deref>::Target {
467 &mut self.0
468 }
469}
470
471impl AsRef<Context> for Encoder {
472 fn as_ref(&self) -> &Context {
473 self
474 }
475}
476
477impl AsMut<Context> for Encoder {
478 fn as_mut(&mut self) -> &mut Context {
479 &mut self.0
480 }
481}