1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
use std::error::Error;
use std::ffi::{c_int, c_uint};
use std::fmt::{self, Display, Formatter};
use strum::FromRepr;
/// Error enum return by various `rav1d` operations.
#[derive(Clone, Copy, PartialEq, Eq, FromRepr, Debug)]
#[repr(u8)]
#[non_exhaustive]
pub enum Rav1dError {
/// This represents a generic `rav1d` error.
/// It has nothing to do with the other `errno`-based ones.
///
/// Normally `EPERM = 1`, but `dav1d` never uses `EPERM`,
/// but does use `-1`, as opposed to the normal `DAV1D_ERR(E*)`.
///
/// Also note that this forces `0` to be the niche,
/// which is more optimal since `0` is no error for [`Dav1dResult`].
Other = 1,
/// No entity.
///
/// No Sequence Header OBUs were found in the buffer.
NoEntity = libc::ENOENT as u8,
/// Try again.
///
/// If this is returned by [`rav1d_send_data`], then there
/// are decoded frames pending that first have to be retrieved via [`rav1d_get_picture`]
/// before processing any further pending data.
///
/// If this is returned by [`rav1d_get_picture`], then no decoded frames are pending
/// currently and more data needs to be sent to the decoder.
TryAgain = libc::EAGAIN as u8,
/// Out of memory.
///
/// Not enough memory is currently available for performing this operation.
OutOfMemory = libc::ENOMEM as u8,
/// Invalid argument.
///
/// One of the arguments passed to the function, including the bitstream, is invalid.
InvalidArgument = libc::EINVAL as u8,
/// Out of range.
///
/// The frame size is larger than the limit.
OutOfRange = libc::ERANGE as u8,
/// Unsupported bitstream.
///
/// The provided bitstream is not supported by `rav1d`.
UnsupportedBitstream = libc::ENOPROTOOPT as u8,
}
impl Rav1dError {
pub const fn as_str(&self) -> &'static str {
match self {
Rav1dError::TryAgain => "Try again",
Rav1dError::InvalidArgument => "Invalid argument",
Rav1dError::OutOfMemory => "Not enough memory available",
Rav1dError::UnsupportedBitstream => "Unsupported bitstream",
Rav1dError::Other => "Other error",
Rav1dError::NoEntity => "No sequence header found",
Rav1dError::OutOfRange => "Out of range",
}
}
}
impl Display for Rav1dError {
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
write!(fmt, "{}", self.as_str())
}
}
impl Error for Rav1dError {}
pub type Rav1dResult<T = ()> = Result<T, Rav1dError>;
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
#[repr(transparent)]
pub struct Dav1dResult(pub c_int);
impl From<Rav1dResult> for Dav1dResult {
#[inline]
fn from(value: Rav1dResult) -> Self {
// Doing the `-` negation on both branches
// makes the code short and branchless.
Dav1dResult(
-(match value {
Ok(()) => 0,
Err(e) => e as c_int,
}),
)
}
}
impl From<Rav1dResult<c_uint>> for Dav1dResult {
#[inline]
fn from(value: Rav1dResult<c_uint>) -> Self {
Dav1dResult(match value {
Ok(value) => value as c_int,
Err(e) => e as c_int,
})
}
}
impl TryFrom<Dav1dResult> for Rav1dResult {
type Error = Dav1dResult;
#[inline]
fn try_from(value: Dav1dResult) -> Result<Self, Self::Error> {
match value.0 {
0 => Ok(Ok(())),
e => {
let e = (-e).try_into().map_err(|_| value)?;
let e = Rav1dError::from_repr(e).ok_or(value)?;
Ok(Err(e))
}
}
}
}