hylarana_common/frame.rs
1//! Describe the structure of audio and video data
2//!
3//! It should be noted that pointers to internal data are temporary. If you need
4//! to hold them for a long time, you need to actively copy the data pointed to
5//! by the pointer. Therefore, the passed VideoFrame or AudioFrame are temporary
6//! references, and there will be no situation where a static structure is
7//! passed.
8//!
9//! # Audio
10//!
11//! Pulse-code modulation
12//!
13//! Pulse-code modulation (PCM) is a method used to digitally represent analog
14//! signals. It is the standard form of digital audio in computers, compact
15//! discs, digital telephony and other digital audio applications. In a PCM
16//! stream, the amplitude of the analog signal is sampled at uniform intervals,
17//! and each sample is quantized to the nearest value within a range of digital
18//! steps.
19//!
20//! Linear pulse-code modulation (LPCM) is a specific type of PCM in which the
21//! quantization levels are linearly uniform. This is in contrast to PCM
22//! encodings in which quantization levels vary as a function of amplitude (as
23//! with the A-law algorithm or the μ-law algorithm). Though PCM is a more
24//! general term, it is often used to describe data encoded as LPCM.
25//!
26//! A PCM stream has two basic properties that determine the stream's fidelity
27//! to the original analog signal: the sampling rate, which is the number of
28//! times per second that samples are taken; and the bit depth, which determines
29//! the number of possible digital values that can be used to represent each
30//! sample.
31//!
32//! # Video
33//!
34//! YCbCr (NV12)
35//!
36//! YCbCr, Y′CbCr, or Y Pb/Cb Pr/Cr, also written as YCBCR or Y′CBCR, is a
37//! family of color spaces used as a part of the color image pipeline in video
38//! and digital photography systems. Y′ is the luma component and CB and CR are
39//! the blue-difference and red-difference chroma components. Y′ (with prime) is
40//! distinguished from Y, which is luminance, meaning that light intensity is
41//! nonlinearly encoded based on gamma corrected RGB primaries.
42//!
43//! Y′CbCr color spaces are defined by a mathematical coordinate transformation
44//! from an associated RGB primaries and white point. If the underlying RGB
45//! color space is absolute, the Y′CbCr color space is an absolute color space
46//! as well; conversely, if the RGB space is ill-defined, so is Y′CbCr. The
47//! transformation is defined in equations 32, 33 in ITU-T H.273. Nevertheless
48//! that rule does not apply to P3-D65 primaries used by Netflix with
49//! BT.2020-NCL matrix, so that means matrix was not derived from primaries, but
50//! now Netflix allows BT.2020 primaries (since 2021). The same happens with
51//! JPEG: it has BT.601 matrix derived from System M primaries, yet the
52//! primaries of most images are BT.709.
53
54use std::{ffi::c_void, ptr::null};
55
56use serde_repr::{Deserialize_repr, Serialize_repr};
57
58/// A sample from the audio stream.
59#[repr(C)]
60#[derive(Debug)]
61pub struct AudioFrame {
62 pub sample_rate: u32,
63 /// The number of samples in the current audio frame.
64 pub frames: u32,
65 /// Pointer to the sample raw buffer.
66 pub data: *const i16,
67}
68
69unsafe impl Sync for AudioFrame {}
70unsafe impl Send for AudioFrame {}
71
72impl Default for AudioFrame {
73 fn default() -> Self {
74 Self {
75 frames: 0,
76 data: null(),
77 sample_rate: 0,
78 }
79 }
80}
81
82/// Video frame format.
83#[repr(i32)]
84#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize_repr, Serialize_repr)]
85pub enum VideoFormat {
86 BGRA,
87 RGBA,
88 NV12,
89 I420,
90}
91
92/// Subtype of the video frame.
93#[repr(i32)]
94#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize_repr, Serialize_repr)]
95pub enum VideoSubFormat {
96 /// This video frame is from Core video, a type exclusive to the Macos
97 /// platform.
98 CvPixelBufferRef,
99 /// Inside this video frame is ID3D11Texture2D.
100 D3D11,
101 /// Video frames contain buffers that can be accessed directly through
102 /// software.
103 SW,
104}
105
106/// A frame in a video stream.
107#[repr(C)]
108#[derive(Debug)]
109pub struct VideoFrame {
110 pub format: VideoFormat,
111 pub sub_format: VideoSubFormat,
112 pub width: u32,
113 pub height: u32,
114 /// If the subformat is SW, the data layout is determined according to the
115 /// format and the data corresponds to the plane of the corresponding
116 /// format, All other sub formats use `data[0]`.
117 pub data: [*const c_void; 3],
118 pub linesize: [u32; 3],
119}
120
121unsafe impl Sync for VideoFrame {}
122unsafe impl Send for VideoFrame {}
123
124impl Default for VideoFrame {
125 fn default() -> Self {
126 Self {
127 width: 0,
128 height: 0,
129 linesize: [0, 0, 0],
130 data: [null(), null(), null()],
131 format: VideoFormat::RGBA,
132 sub_format: VideoSubFormat::SW,
133 }
134 }
135}