Coverage Report

Created: 2025-10-14 06:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/rav1e-0.7.1/src/api/util.rs
Line
Count
Source
1
// Copyright (c) 2018-2022, The rav1e contributors. All rights reserved
2
//
3
// This source code is subject to the terms of the BSD 2 Clause License and
4
// the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
5
// was not distributed with this source code in the LICENSE file, you can
6
// obtain it at www.aomedia.org/license/software. If the Alliance for Open
7
// Media Patent License 1.0 was not distributed with this source code in the
8
// PATENTS file, you can obtain it at www.aomedia.org/license/patent.
9
#![deny(missing_docs)]
10
11
use crate::frame::*;
12
use crate::serialize::{Deserialize, Serialize};
13
use crate::stats::EncoderStats;
14
use crate::util::Pixel;
15
16
use std::any::Any;
17
use std::fmt;
18
use std::sync::Arc;
19
20
use thiserror::*;
21
22
/// Opaque type to be passed from Frame to Packet
23
#[derive(Debug)]
24
pub struct Opaque(Box<dyn Any + Send + Sync>);
25
26
impl Opaque {
27
  /// Wrap a type in the opaque struct
28
0
  pub fn new<T: Any + Send + Sync>(t: T) -> Self {
29
0
    Opaque(Box::new(t) as Box<dyn Any + Send + Sync>)
30
0
  }
31
32
  /// Attempt to downcast the opaque to a concrete type.
33
  ///
34
  /// # Errors
35
  ///
36
  /// Returns `Err(Self)` if the value could not be downcast to `T`.
37
0
  pub fn downcast<T: Any + Send + Sync>(self) -> Result<Box<T>, Opaque> {
38
0
    if self.0.is::<T>() {
39
      // SAFETY: We verified the type of `T` before this cast.
40
      unsafe {
41
0
        let raw: *mut (dyn Any + Send + Sync) = Box::into_raw(self.0);
42
0
        Ok(Box::from_raw(raw as *mut T))
43
      }
44
    } else {
45
0
      Err(self)
46
    }
47
0
  }
48
}
49
50
// TODO: use the num crate?
51
/// A rational number.
52
#[derive(Clone, Copy, Debug)]
53
#[repr(C)]
54
pub struct Rational {
55
  /// Numerator.
56
  pub num: u64,
57
  /// Denominator.
58
  pub den: u64,
59
}
60
61
impl Rational {
62
  /// Creates a rational number from the given numerator and denominator.
63
0
  pub const fn new(num: u64, den: u64) -> Self {
64
0
    Rational { num, den }
65
0
  }
66
67
  /// Returns a rational number that is the reciprocal of the given one.
68
0
  pub const fn from_reciprocal(reciprocal: Self) -> Self {
69
0
    Rational { num: reciprocal.den, den: reciprocal.num }
70
0
  }
71
72
  /// Returns the rational number as a floating-point number.
73
0
  pub fn as_f64(self) -> f64 {
74
0
    self.num as f64 / self.den as f64
75
0
  }
76
}
77
78
#[cfg(feature = "serialize")]
79
impl serde::Serialize for Rational {
80
  fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
81
  where
82
    S: serde::Serializer,
83
  {
84
    (self.num, self.den).serialize(serializer)
85
  }
86
}
87
88
#[cfg(feature = "serialize")]
89
impl<'a> serde::Deserialize<'a> for Rational {
90
  fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
91
  where
92
    D: serde::Deserializer<'a>,
93
  {
94
    let (num, den) = serde::Deserialize::deserialize(deserializer)?;
95
96
    Ok(Rational::new(num, den))
97
  }
98
}
99
100
/// Possible types of a frame.
101
#[allow(dead_code, non_camel_case_types)]
102
#[derive(Debug, Eq, PartialEq, Clone, Copy, Serialize, Deserialize)]
103
#[repr(C)]
104
pub enum FrameType {
105
  /// Key frame.
106
  KEY,
107
  /// Inter-frame.
108
  INTER,
109
  /// Intra-only frame.
110
  INTRA_ONLY,
111
  /// Switching frame.
112
  SWITCH,
113
}
114
115
impl FrameType {
116
  /// Returns whether frame can have inter blocks
117
  #[inline]
118
0
  pub fn has_inter(self) -> bool {
119
0
    self == FrameType::INTER || self == FrameType::SWITCH
120
0
  }
Unexecuted instantiation: <rav1e::api::util::FrameType>::has_inter
Unexecuted instantiation: <rav1e::api::util::FrameType>::has_inter
121
  /// Returns whether frame is only intra blocks
122
  #[inline]
123
0
  pub fn all_intra(self) -> bool {
124
0
    self == FrameType::KEY || self == FrameType::INTRA_ONLY
125
0
  }
126
}
127
128
impl fmt::Display for FrameType {
129
0
  fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
130
    use self::FrameType::*;
131
0
    match self {
132
0
      KEY => write!(f, "Key frame"),
133
0
      INTER => write!(f, "Inter frame"),
134
0
      INTRA_ONLY => write!(f, "Intra only frame"),
135
0
      SWITCH => write!(f, "Switching frame"),
136
    }
137
0
  }
138
}
139
140
/// A single T.35 metadata packet.
141
#[derive(Clone, Debug, Default)]
142
pub struct T35 {
143
  /// Country code.
144
  pub country_code: u8,
145
  /// Country code extension bytes (if country_code == 0xFF)
146
  pub country_code_extension_byte: u8,
147
  /// T.35 payload.
148
  pub data: Box<[u8]>,
149
}
150
151
/// Status that can be returned by [`Context`] functions.
152
///
153
/// [`Context`]: struct.Context.html
154
#[derive(Clone, Copy, Debug, Eq, PartialEq, Error)]
155
pub enum EncoderStatus {
156
  /// The encoder needs more data to produce an output packet.
157
  ///
158
  /// May be emitted by [`Context::receive_packet()`] when frame reordering is
159
  /// enabled.
160
  ///
161
  /// [`Context::receive_packet()`]: struct.Context.html#method.receive_packet
162
  #[error("need more data")]
163
  NeedMoreData,
164
  /// There are enough frames in the queue.
165
  ///
166
  /// May be emitted by [`Context::send_frame()`] when trying to send a frame
167
  /// after the encoder has been flushed.
168
  ///
169
  /// [`Context::send_frame()`]: struct.Context.html#method.send_frame
170
  #[error("enough data")]
171
  EnoughData,
172
  /// The encoder has already produced the number of frames requested.
173
  ///
174
  /// May be emitted by [`Context::receive_packet()`] after a flush request had
175
  /// been processed or the frame limit had been reached.
176
  ///
177
  /// [`Context::receive_packet()`]: struct.Context.html#method.receive_packet
178
  #[error("limit reached")]
179
  LimitReached,
180
  /// A frame had been encoded but not emitted yet.
181
  #[error("encoded")]
182
  Encoded,
183
  /// Generic fatal error.
184
  #[error("failure")]
185
  Failure,
186
  /// A frame was encoded in the first pass of a 2-pass encode, but its stats
187
  /// data was not retrieved with [`Context::twopass_out()`], or not enough
188
  /// stats data was provided in the second pass of a 2-pass encode to encode
189
  /// the next frame.
190
  ///
191
  /// [`Context::twopass_out()`]: struct.Context.html#method.twopass_out
192
  #[error("not ready")]
193
  NotReady,
194
}
195
196
/// Represents a packet.
197
///
198
/// A packet contains one shown frame together with zero or more additional
199
/// frames.
200
#[derive(Debug, Serialize, Deserialize)]
201
pub struct Packet<T: Pixel> {
202
  /// The packet data.
203
  pub data: Vec<u8>,
204
  /// The reconstruction of the shown frame.
205
  #[cfg_attr(feature = "serialize", serde(skip))]
206
  pub rec: Option<Arc<Frame<T>>>,
207
  /// The Reference Frame
208
  #[cfg_attr(feature = "serialize", serde(skip))]
209
  pub source: Option<Arc<Frame<T>>>,
210
  /// The number of the input frame corresponding to the one shown frame in the
211
  /// TU stored in this packet. Since AV1 does not explicitly reorder frames,
212
  /// these will increase sequentially.
213
  // TODO: When we want to add VFR support, we will need a more explicit time
214
  // stamp here.
215
  pub input_frameno: u64,
216
  /// Type of the shown frame.
217
  pub frame_type: FrameType,
218
  /// QP selected for the frame.
219
  pub qp: u8,
220
  /// Block-level encoding stats for the frame
221
  pub enc_stats: EncoderStats,
222
  /// Optional user-provided opaque data
223
  #[cfg_attr(feature = "serialize", serde(skip))]
224
  pub opaque: Option<Opaque>,
225
}
226
227
impl<T: Pixel> PartialEq for Packet<T> {
228
0
  fn eq(&self, other: &Self) -> bool {
229
0
    self.data == other.data
230
0
      && self.input_frameno == other.input_frameno
231
0
      && self.frame_type == other.frame_type
232
0
      && self.qp == other.qp
233
0
  }
234
}
235
236
impl<T: Pixel> fmt::Display for Packet<T> {
237
0
  fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
238
0
    write!(
239
0
      f,
240
0
      "Frame {} - {} - {} bytes",
241
      self.input_frameno,
242
      self.frame_type,
243
0
      self.data.len()
244
    )
245
0
  }
246
}
247
248
/// Types which can be converted into frames.
249
///
250
/// This trait is used in [`Context::send_frame`] to allow for passing in
251
/// frames with optional frame parameters and optionally frames wrapped in
252
/// `Arc` (to allow for zero-copy, since the encoder uses frames in `Arc`
253
/// internally).
254
///
255
/// [`Context::send_frame`]: struct.Context.html#method.send_frame
256
pub trait IntoFrame<T: Pixel> {
257
  /// Converts the type into a tuple of frame and parameters.
258
  fn into(self) -> (Option<Arc<Frame<T>>>, Option<FrameParameters>);
259
}
260
261
impl<T: Pixel> IntoFrame<T> for Option<Arc<Frame<T>>> {
262
0
  fn into(self) -> (Option<Arc<Frame<T>>>, Option<FrameParameters>) {
263
0
    (self, None)
264
0
  }
Unexecuted instantiation: <core::option::Option<alloc::sync::Arc<v_frame::frame::Frame<u16>>> as rav1e::api::util::IntoFrame<u16>>::into
Unexecuted instantiation: <core::option::Option<alloc::sync::Arc<v_frame::frame::Frame<u8>>> as rav1e::api::util::IntoFrame<u8>>::into
265
}
266
267
impl<T: Pixel> IntoFrame<T> for Arc<Frame<T>> {
268
0
  fn into(self) -> (Option<Arc<Frame<T>>>, Option<FrameParameters>) {
269
0
    (Some(self), None)
270
0
  }
271
}
272
273
impl<T: Pixel> IntoFrame<T> for (Arc<Frame<T>>, FrameParameters) {
274
0
  fn into(self) -> (Option<Arc<Frame<T>>>, Option<FrameParameters>) {
275
0
    (Some(self.0), Some(self.1))
276
0
  }
277
}
278
279
impl<T: Pixel> IntoFrame<T> for (Arc<Frame<T>>, Option<FrameParameters>) {
280
0
  fn into(self) -> (Option<Arc<Frame<T>>>, Option<FrameParameters>) {
281
0
    (Some(self.0), self.1)
282
0
  }
283
}
284
285
impl<T: Pixel> IntoFrame<T> for Frame<T> {
286
0
  fn into(self) -> (Option<Arc<Frame<T>>>, Option<FrameParameters>) {
287
0
    (Some(Arc::new(self)), None)
288
0
  }
Unexecuted instantiation: <v_frame::frame::Frame<u8> as rav1e::api::util::IntoFrame<u8>>::into
Unexecuted instantiation: <v_frame::frame::Frame<u16> as rav1e::api::util::IntoFrame<u16>>::into
Unexecuted instantiation: <v_frame::frame::Frame<_> as rav1e::api::util::IntoFrame<_>>::into
289
}
290
291
impl<T: Pixel> IntoFrame<T> for (Frame<T>, FrameParameters) {
292
0
  fn into(self) -> (Option<Arc<Frame<T>>>, Option<FrameParameters>) {
293
0
    (Some(Arc::new(self.0)), Some(self.1))
294
0
  }
295
}
296
297
impl<T: Pixel> IntoFrame<T> for (Frame<T>, Option<FrameParameters>) {
298
0
  fn into(self) -> (Option<Arc<Frame<T>>>, Option<FrameParameters>) {
299
0
    (Some(Arc::new(self.0)), self.1)
300
0
  }
301
}