ffmpeg_the_third/codec/encoder/
video.rs

1use 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}