libdav1d/
lib.rs

1use dav1d_sys::*;
2use dav1d_sys::Dav1dInloopFilterType::*;
3use dav1d_sys::Dav1dPixelLayout::*;
4
5use std::ffi::c_void;
6use std::fmt;
7use std::i64;
8use std::mem;
9use std::ptr;
10use std::sync::Arc;
11
12/// Error enum return by various `dav1d` operations.
13#[derive(Debug, Copy, Clone, PartialEq, Eq)]
14#[non_exhaustive]
15pub enum Error {
16    /// Try again.
17    ///
18    /// If this is returned by [`Decoder::send_data`] or [`Decoder::send_pending_data`] then there
19    /// are decoded frames pending that first have to be retrieved via [`Decoder::get_picture`]
20    /// before processing any further pending data.
21    ///
22    /// If this is returned by [`Decoder::get_picture`] then no decoded frames are pending
23    /// currently and more data needs to be sent to the decoder.
24    Again,
25    /// Invalid argument.
26    ///
27    /// One of the arguments passed to the function was invalid.
28    InvalidArgument,
29    /// Not enough memory.
30    ///
31    /// Not enough memory is currently available for performing this operation.
32    NotEnoughMemory,
33    /// Unsupported bitstream.
34    ///
35    /// The provided bitstream is not supported by `dav1d`.
36    UnsupportedBitstream,
37    /// Unknown error.
38    UnknownError(i32),
39}
40
41impl From<i32> for Error {
42    fn from(err: i32) -> Self {
43        assert!(err < 0);
44
45        match err {
46            DAV1D_ERR_AGAIN => Error::Again,
47            DAV1D_ERR_INVAL => Error::InvalidArgument,
48            DAV1D_ERR_NOMEM => Error::NotEnoughMemory,
49            DAV1D_ERR_NOPROTOOPT => Error::UnsupportedBitstream,
50            _ => Error::UnknownError(err),
51        }
52    }
53}
54
55impl Error {
56    pub const fn is_again(&self) -> bool {
57        matches!(self, Error::Again)
58    }
59}
60
61impl fmt::Display for Error {
62    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
63        match self {
64            Error::Again => write!(fmt, "Try again"),
65            Error::InvalidArgument => write!(fmt, "Invalid argument"),
66            Error::NotEnoughMemory => write!(fmt, "Not enough memory available"),
67            Error::UnsupportedBitstream => write!(fmt, "Unsupported bitstream"),
68            Error::UnknownError(err) => write!(fmt, "Unknown error {}", err),
69        }
70    }
71}
72
73impl std::error::Error for Error {}
74
75/// Settings for creating a new [`Decoder`] instance.
76/// See documentation for native `Dav1dSettings` struct.
77#[derive(Debug)]
78pub struct Settings {
79    dav1d_settings: Dav1dSettings,
80}
81
82impl Default for Settings {
83    fn default() -> Self {
84        Self::new()
85    }
86}
87
88impl Settings {
89    /// Creates a new [`Settings`] instance with default settings.
90    pub fn new() -> Self {
91        unsafe {
92            let mut dav1d_settings = mem::MaybeUninit::uninit();
93
94            dav1d_default_settings(dav1d_settings.as_mut_ptr());
95
96            Self {
97                dav1d_settings: dav1d_settings.assume_init(),
98            }
99        }
100    }
101
102    pub fn set_n_threads(&mut self, n_threads: u32) {
103        self.dav1d_settings.n_threads = n_threads as i32;
104    }
105
106    pub fn get_n_threads(&self) -> u32 {
107        self.dav1d_settings.n_threads as u32
108    }
109
110    pub fn set_max_frame_delay(&mut self, max_frame_delay: u32) {
111        self.dav1d_settings.max_frame_delay = max_frame_delay as i32;
112    }
113
114    pub fn get_max_frame_delay(&self) -> u32 {
115        self.dav1d_settings.max_frame_delay as u32
116    }
117
118    pub fn set_apply_grain(&mut self, apply_grain: bool) {
119        self.dav1d_settings.apply_grain = i32::from(apply_grain);
120    }
121
122    pub fn get_apply_grain(&self) -> bool {
123        self.dav1d_settings.apply_grain != 0
124    }
125
126    pub fn set_operating_point(&mut self, operating_point: u32) {
127        self.dav1d_settings.operating_point = operating_point as i32;
128    }
129
130    pub fn get_operating_point(&self) -> u32 {
131        self.dav1d_settings.operating_point as u32
132    }
133
134    pub fn set_all_layers(&mut self, all_layers: bool) {
135        self.dav1d_settings.all_layers = i32::from(all_layers);
136    }
137
138    pub fn get_all_layers(&self) -> bool {
139        self.dav1d_settings.all_layers != 0
140    }
141
142    pub fn set_frame_size_limit(&mut self, frame_size_limit: u32) {
143        self.dav1d_settings.frame_size_limit = frame_size_limit;
144    }
145
146    pub fn get_frame_size_limit(&self) -> u32 {
147        self.dav1d_settings.frame_size_limit
148    }
149
150    pub fn set_strict_std_compliance(&mut self, strict_std_compliance: bool) {
151        self.dav1d_settings.strict_std_compliance = i32::from(strict_std_compliance);
152    }
153
154    pub fn get_strict_std_compliance(&self) -> bool {
155        self.dav1d_settings.strict_std_compliance != 0
156    }
157
158    pub fn set_output_invisible_frames(&mut self, output_invisible_frames: bool) {
159        self.dav1d_settings.output_invisible_frames = i32::from(output_invisible_frames);
160    }
161
162    pub fn get_output_invisible_frames(&self) -> bool {
163        self.dav1d_settings.output_invisible_frames != 0
164    }
165
166    pub fn set_inloop_filters(&mut self, inloop_filters: InloopFilterType) {
167        self.dav1d_settings.inloop_filters = inloop_filters.bits();
168    }
169
170    pub fn get_inloop_filters(&self) -> InloopFilterType {
171        InloopFilterType::from_bits_truncate(self.dav1d_settings.inloop_filters)
172    }
173
174    pub fn set_decode_frame_type(&mut self, decode_frame_type: DecodeFrameType) {
175        use dav1d_sys::Dav1dDecodeFrameType::*;
176        self.dav1d_settings.decode_frame_type = match decode_frame_type {
177            DecodeFrameType::All => DAV1D_DECODEFRAMETYPE_ALL,
178            DecodeFrameType::Reference => DAV1D_DECODEFRAMETYPE_REFERENCE,
179            DecodeFrameType::Intra => DAV1D_DECODEFRAMETYPE_INTRA,
180            DecodeFrameType::Key => DAV1D_DECODEFRAMETYPE_KEY,
181        }
182    }
183
184    pub fn get_decode_frame_type(&self) -> DecodeFrameType {
185        DecodeFrameType::try_from(self.dav1d_settings.decode_frame_type as u32)
186            .expect("Invalid Dav1dDecodeFrameType")
187    }
188}
189
190bitflags::bitflags! {
191    #[derive(Copy, Clone, Debug, PartialEq, Eq, Default)]
192    pub struct InloopFilterType: u32 {
193        const DEBLOCK = DAV1D_INLOOPFILTER_DEBLOCK as u32;
194        const CDEF = DAV1D_INLOOPFILTER_CDEF as u32;
195        const RESTORATION = DAV1D_INLOOPFILTER_RESTORATION as u32;
196    }
197}
198
199#[derive(Debug, Copy, Clone, PartialEq, Eq)]
200pub enum DecodeFrameType {
201    All,
202    Reference,
203    Intra,
204    Key,
205}
206
207impl Default for DecodeFrameType {
208    fn default() -> Self {
209        DecodeFrameType::All
210    }
211}
212
213impl TryFrom<u32> for DecodeFrameType {
214    type Error = TryFromEnumError;
215
216    fn try_from(value: u32) -> Result<Self, Self::Error> {
217        use dav1d_sys::Dav1dDecodeFrameType::*;
218        match value {
219            x if x == DAV1D_DECODEFRAMETYPE_ALL as _ => Ok(DecodeFrameType::All),
220            x if x == DAV1D_DECODEFRAMETYPE_REFERENCE as _ => Ok(DecodeFrameType::Reference),
221            x if x == DAV1D_DECODEFRAMETYPE_INTRA as _ => Ok(DecodeFrameType::Intra),
222            x if x == DAV1D_DECODEFRAMETYPE_KEY as _ => Ok(DecodeFrameType::Key),
223            _ => Err(TryFromEnumError(())),
224        }
225    }
226}
227
228impl From<DecodeFrameType> for u32 {
229    fn from(v: DecodeFrameType) -> u32 {
230        use dav1d_sys::Dav1dDecodeFrameType::*;
231        match v {
232            DecodeFrameType::All => DAV1D_DECODEFRAMETYPE_ALL as _,
233            DecodeFrameType::Reference => DAV1D_DECODEFRAMETYPE_REFERENCE as _,
234            DecodeFrameType::Intra => DAV1D_DECODEFRAMETYPE_INTRA as _,
235            DecodeFrameType::Key => DAV1D_DECODEFRAMETYPE_KEY as _,
236        }
237    }
238}
239
240/// The error type returned when a conversion from a C enum fails.
241#[derive(Debug, Copy, Clone, PartialEq, Eq)]
242pub struct TryFromEnumError(());
243
244impl std::fmt::Display for TryFromEnumError {
245    fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
246        fmt.write_str("Invalid enum value")
247    }
248}
249
250impl From<std::convert::Infallible> for TryFromEnumError {
251    fn from(x: std::convert::Infallible) -> TryFromEnumError {
252        match x {}
253    }
254}
255
256impl std::error::Error for TryFromEnumError {}
257
258/// A `dav1d` decoder instance.
259#[derive(Debug)]
260pub struct Decoder {
261    dec: ptr::NonNull<Dav1dContext>,
262    pending_data: Option<Dav1dData>,
263}
264
265unsafe extern "C" fn release_wrapped_data<T: AsRef<[u8]>>(_data: *const u8, cookie: *mut c_void) {
266    let buf = Box::from_raw(cookie as *mut T);
267    drop(buf);
268}
269
270impl Decoder {
271    /// Creates a new [`Decoder`] instance with given [`Settings`].
272    pub fn with_settings(settings: &Settings) -> Result<Self, Error> {
273        unsafe {
274            let mut dec = mem::MaybeUninit::uninit();
275
276            let ret = dav1d_open(dec.as_mut_ptr(), &settings.dav1d_settings);
277
278            if ret < 0 {
279                return Err(Error::from(ret));
280            }
281
282            Ok(Decoder {
283                dec: ptr::NonNull::new(dec.assume_init()).unwrap(),
284                pending_data: None,
285            })
286        }
287    }
288
289    /// Creates a new [`Decoder`] instance with the default settings.
290    pub fn new() -> Result<Self, Error> {
291        Self::with_settings(&Settings::default())
292    }
293
294    /// Flush the decoder.
295    ///
296    /// This flushes all delayed frames in the decoder and clears the internal decoder state.
297    ///
298    /// All currently pending frames are available afterwards via [`Decoder::get_picture`].
299    pub fn flush(&mut self) {
300        unsafe {
301            dav1d_flush(self.dec.as_ptr());
302            if let Some(mut pending_data) = self.pending_data.take() {
303                dav1d_data_unref(&mut pending_data);
304            }
305        }
306    }
307
308    /// Send new AV1 data to the decoder.
309    ///
310    /// After this returned `Ok(())` or `Err([Error::Again])` there might be decoded frames
311    /// available via [`Decoder::get_picture`].
312    ///
313    /// # Panics
314    ///
315    /// If a previous call returned [`Error::Again`] then this must not be called again until
316    /// [`Decoder::send_pending_data`] has returned `Ok(())`.
317    pub fn send_data<T: AsRef<[u8]> + Send + 'static>(
318        &mut self,
319        buf: T,
320        offset: Option<i64>,
321        timestamp: Option<i64>,
322        duration: Option<i64>,
323    ) -> Result<(), Error> {
324        assert!(
325            self.pending_data.is_none(),
326            "Have pending data that needs to be handled first"
327        );
328
329        let buf = Box::new(buf);
330        let slice = (*buf).as_ref();
331        let len = slice.len();
332
333        unsafe {
334            let mut data: Dav1dData = mem::zeroed();
335            let _ret = dav1d_data_wrap(
336                &mut data,
337                slice.as_ptr(),
338                len,
339                Some(release_wrapped_data::<T>),
340                Box::into_raw(buf) as *mut c_void,
341            );
342            if let Some(offset) = offset {
343                data.m.offset = offset;
344            }
345            if let Some(timestamp) = timestamp {
346                data.m.timestamp = timestamp;
347            }
348            if let Some(duration) = duration {
349                data.m.duration = duration;
350            }
351
352            let ret = dav1d_send_data(self.dec.as_ptr(), &mut data);
353            if ret < 0 {
354                let ret = Error::from(ret);
355
356                if ret.is_again() {
357                    self.pending_data = Some(data);
358                } else {
359                    dav1d_data_unref(&mut data);
360                }
361
362                return Err(ret);
363            }
364
365            if data.sz > 0 {
366                self.pending_data = Some(data);
367                return Err(Error::Again);
368            }
369
370            Ok(())
371        }
372    }
373
374    /// Sends any pending data to the decoder.
375    ///
376    /// This has to be called after [`Decoder::send_data`] has returned `Err([Error::Again])` to
377    /// consume any futher pending data.
378    ///
379    /// After this returned `Ok(())` or `Err([Error::Again])` there might be decoded frames
380    /// available via [`Decoder::get_picture`].
381    pub fn send_pending_data(&mut self) -> Result<(), Error> {
382        let mut data = match self.pending_data.take() {
383            None => {
384                return Ok(());
385            }
386            Some(data) => data,
387        };
388
389        unsafe {
390            let ret = dav1d_send_data(self.dec.as_ptr(), &mut data);
391            if ret < 0 {
392                let ret = Error::from(ret);
393
394                if ret.is_again() {
395                    self.pending_data = Some(data);
396                } else {
397                    dav1d_data_unref(&mut data);
398                }
399
400                return Err(ret);
401            }
402
403            if data.sz > 0 {
404                self.pending_data = Some(data);
405                return Err(Error::Again);
406            }
407
408            Ok(())
409        }
410    }
411
412    /// Get the next decoded frame from the decoder.
413    ///
414    /// If this returns `Err([Error::Again])` then further data has to be sent to the decoder
415    /// before further decoded frames become available.
416    ///
417    /// To make most use of frame threading this function should only be called once per submitted
418    /// input frame and not until it returns `Err([Error::Again])`. Calling it in a loop should
419    /// only be done to drain all pending frames at the end.
420    pub fn get_picture(&mut self) -> Result<Picture, Error> {
421        unsafe {
422            let mut pic: Dav1dPicture = mem::zeroed();
423            let ret = dav1d_get_picture(self.dec.as_ptr(), &mut pic);
424
425            if ret < 0 {
426                Err(Error::from(ret))
427            } else {
428                let inner = InnerPicture { pic };
429                Ok(Picture {
430                    inner: Arc::new(inner),
431                })
432            }
433        }
434    }
435
436    /// Get the decoder delay.
437    pub fn get_frame_delay(&self) -> u32 {
438        unsafe { dav1d_get_frame_delay(self.dec.as_ptr() as *const _) as u32 }
439    }
440}
441
442impl Drop for Decoder {
443    fn drop(&mut self) {
444        unsafe {
445            if let Some(mut pending_data) = self.pending_data.take() {
446                dav1d_data_unref(&mut pending_data);
447            }
448            let mut dec = self.dec.as_ptr();
449            dav1d_close(&mut dec);
450        };
451    }
452}
453
454unsafe impl Send for Decoder {}
455unsafe impl Sync for Decoder {}
456
457#[derive(Debug)]
458struct InnerPicture {
459    pub pic: Dav1dPicture,
460}
461
462/// A decoded frame.
463#[derive(Debug, Clone)]
464pub struct Picture {
465    inner: Arc<InnerPicture>,
466}
467
468/// Pixel layout of a frame.
469#[derive(Debug, Eq, PartialEq, Copy, Clone)]
470pub enum PixelLayout {
471    /// Monochrome.
472    I400,
473    /// 4:2:0 planar.
474    I420,
475    /// 4:2:2 planar.
476    I422,
477    /// 4:4:4 planar.
478    I444,
479}
480
481/// Frame component.
482#[derive(Eq, PartialEq, Copy, Clone, Debug)]
483pub enum PlanarImageComponent {
484    /// Y component.
485    Y,
486    /// U component.
487    U,
488    /// V component.
489    V,
490}
491
492impl From<usize> for PlanarImageComponent {
493    fn from(index: usize) -> Self {
494        match index {
495            0 => PlanarImageComponent::Y,
496            1 => PlanarImageComponent::U,
497            2 => PlanarImageComponent::V,
498            _ => panic!("Invalid YUV index: {}", index),
499        }
500    }
501}
502
503impl From<PlanarImageComponent> for usize {
504    fn from(component: PlanarImageComponent) -> Self {
505        match component {
506            PlanarImageComponent::Y => 0,
507            PlanarImageComponent::U => 1,
508            PlanarImageComponent::V => 2,
509        }
510    }
511}
512
513/// A single plane of a decoded frame.
514///
515/// This can be used like a `&[u8]`.
516#[derive(Clone, Debug)]
517pub struct Plane(Picture, PlanarImageComponent);
518
519impl AsRef<[u8]> for Plane {
520    fn as_ref(&self) -> &[u8] {
521        let (stride, height) = self.0.plane_data_geometry(self.1);
522        unsafe {
523            std::slice::from_raw_parts(
524                self.0.plane_data_ptr(self.1) as *const u8,
525                (stride * height) as usize,
526            )
527        }
528    }
529}
530
531impl std::ops::Deref for Plane {
532    type Target = [u8];
533
534    fn deref(&self) -> &Self::Target {
535        self.as_ref()
536    }
537}
538
539unsafe impl Send for Plane {}
540unsafe impl Sync for Plane {}
541
542/// Number of bits per component.
543#[derive(Copy, Clone, Debug, PartialEq, Eq)]
544pub struct BitsPerComponent(pub usize);
545
546impl Picture {
547    /// Stride in pixels of the `component` for the decoded frame.
548    pub fn stride(&self, component: PlanarImageComponent) -> u32 {
549        let s = match component {
550            PlanarImageComponent::Y => 0,
551            _ => 1,
552        };
553        self.inner.pic.stride[s] as u32
554    }
555
556    /// Raw pointer to the data of the `component` for the decoded frame.
557    pub fn plane_data_ptr(&self, component: PlanarImageComponent) -> *mut c_void {
558        let index: usize = component.into();
559        self.inner.pic.data[index]
560    }
561
562    /// Plane geometry of the `component` for the decoded frame.
563    ///
564    /// This returns the stride and height.
565    pub fn plane_data_geometry(&self, component: PlanarImageComponent) -> (u32, u32) {
566        let height = match component {
567            PlanarImageComponent::Y => self.height(),
568            _ => match self.pixel_layout() {
569                PixelLayout::I420 => (self.height() + 1) / 2,
570                PixelLayout::I400 | PixelLayout::I422 | PixelLayout::I444 => self.height(),
571            },
572        };
573        (self.stride(component) as u32, height)
574    }
575
576    /// Plane data of the `component` for the decoded frame.
577    pub fn plane(&self, component: PlanarImageComponent) -> Plane {
578        Plane(self.clone(), component)
579    }
580
581    /// Bit depth of the plane data.
582    ///
583    /// This returns 8 or 16 for the underlying integer type used for the plane data.
584    ///
585    /// Check [`Picture::bits_per_component`] for the number of bits that are used.
586    pub fn bit_depth(&self) -> usize {
587        self.inner.pic.p.bpc as usize
588    }
589
590    /// Bits used per component of the plane data.
591    ///
592    /// Check [`Picture::bit_depth`] for the number of storage bits.
593    pub fn bits_per_component(&self) -> Option<BitsPerComponent> {
594        unsafe {
595            match (*self.inner.pic.seq_hdr).hbd {
596                0 => Some(BitsPerComponent(8)),
597                1 => Some(BitsPerComponent(10)),
598                2 => Some(BitsPerComponent(12)),
599                _ => None,
600            }
601        }
602    }
603
604    /// Width of the frame.
605    pub fn width(&self) -> u32 {
606        self.inner.pic.p.w as u32
607    }
608
609    /// Height of the frame.
610    pub fn height(&self) -> u32 {
611        self.inner.pic.p.h as u32
612    }
613
614    /// Pixel layout of the frame.
615    pub fn pixel_layout(&self) -> PixelLayout {
616        #[allow(non_upper_case_globals)]
617        match self.inner.pic.p.layout {
618            DAV1D_PIXEL_LAYOUT_I400 => PixelLayout::I400,
619            DAV1D_PIXEL_LAYOUT_I420 => PixelLayout::I420,
620            DAV1D_PIXEL_LAYOUT_I422 => PixelLayout::I422,
621            DAV1D_PIXEL_LAYOUT_I444 => PixelLayout::I444,
622            #[allow(unreachable_patterns)]
623            _ => unreachable!(),
624        }
625    }
626
627    /// Timestamp of the frame.
628    ///
629    /// This is the same timestamp as the one provided to [`Decoder::send_data`].
630    pub fn timestamp(&self) -> Option<i64> {
631        let ts = self.inner.pic.m.timestamp;
632        if ts == i64::MIN {
633            None
634        } else {
635            Some(ts)
636        }
637    }
638
639    /// Duration of the frame.
640    ///
641    /// This is the same duration as the one provided to [`Decoder::send_data`] or `0` if none was
642    /// provided.
643    pub fn duration(&self) -> i64 {
644        self.inner.pic.m.duration as i64
645    }
646
647    /// Offset of the frame.
648    ///
649    /// This is the same offset as the one provided to [`Decoder::send_data`] or `-1` if none was
650    /// provided.
651    pub fn offset(&self) -> i64 {
652        self.inner.pic.m.offset
653    }
654}
655
656unsafe impl Send for Picture {}
657unsafe impl Sync for Picture {}
658
659impl Drop for InnerPicture {
660    fn drop(&mut self) {
661        unsafe {
662            dav1d_picture_unref(&mut self.pic);
663        }
664    }
665}