av_metrics/video/
decode.rs1use crate::video::pixel::Pixel;
5use crate::video::{ChromaSamplePosition, ChromaSampling};
6use std::cmp;
7use v_frame::frame::Frame;
8use v_frame::pixel::CastFromPrimitive;
9use v_frame::plane::Plane;
10
11pub trait Decoder: Send {
17 fn read_video_frame<T: Pixel>(&mut self) -> Option<Frame<T>>;
21 fn read_specific_frame<T: Pixel>(&mut self, frame_number: usize) -> Option<Frame<T>> {
25 let mut frame_no = 0;
26 while frame_no <= frame_number {
27 let frame = self.read_video_frame();
28 if frame_no == frame_number && frame.is_some() {
29 return frame;
30 }
31 frame_no += 1;
32 }
33 None
34 }
35 fn get_bit_depth(&self) -> usize;
37 fn get_video_details(&self) -> VideoDetails;
39}
40
41#[derive(Debug, Clone, Copy)]
43pub struct VideoDetails {
44 pub width: usize,
46 pub height: usize,
48 pub bit_depth: usize,
50 pub chroma_sampling: ChromaSampling,
52 pub chroma_sample_position: ChromaSamplePosition,
54 pub time_base: Rational,
56 pub luma_padding: usize,
58}
59
60impl Default for VideoDetails {
61 fn default() -> Self {
62 VideoDetails {
63 width: 640,
64 height: 480,
65 bit_depth: 8,
66 chroma_sampling: ChromaSampling::Cs420,
67 chroma_sample_position: ChromaSamplePosition::Unknown,
68 time_base: Rational { num: 30, den: 1 },
69 luma_padding: 0,
70 }
71 }
72}
73
74#[derive(Clone, Copy, Debug)]
76#[repr(C)]
77pub struct Rational {
78 pub num: u64,
80 pub den: u64,
82}
83
84impl Rational {
85 pub const fn new(num: u64, den: u64) -> Self {
87 Rational { num, den }
88 }
89 pub const fn from_reciprocal(reciprocal: Self) -> Self {
91 Rational {
92 num: reciprocal.den,
93 den: reciprocal.num,
94 }
95 }
96 pub fn as_f64(self) -> f64 {
98 self.num as f64 / self.den as f64
99 }
100}
101
102pub fn convert_chroma_data<T: Pixel>(
106 plane_data: &mut Plane<T>,
107 chroma_pos: ChromaSamplePosition,
108 bit_depth: usize,
109 source: &[u8],
110 source_stride: usize,
111 source_bytewidth: usize,
112) {
113 if chroma_pos != ChromaSamplePosition::Vertical {
114 plane_data.copy_from_raw_u8(source, source_stride, source_bytewidth);
116 return;
117 }
118
119 let get_pixel = if source_bytewidth == 1 {
120 fn convert_u8(line: &[u8], index: usize) -> i32 {
121 i32::cast_from(line[index])
122 }
123 convert_u8
124 } else {
125 fn convert_u16(line: &[u8], index: usize) -> i32 {
126 let index = index * 2;
127 i32::cast_from(u16::cast_from(line[index + 1]) << 8 | u16::cast_from(line[index]))
128 }
129 convert_u16
130 };
131
132 let output_data = &mut plane_data.data;
133 let width = plane_data.cfg.width;
134 let height = plane_data.cfg.height;
135 for y in 0..height {
136 let in_row = &source[(y * source_stride)..];
138 let out_row = &mut output_data[(y * width)..];
139 let breakpoint = cmp::min(width, 2);
140 for x in 0..breakpoint {
141 out_row[x] = T::cast_from(clamp(
142 (4 * get_pixel(in_row, 0) - 17 * get_pixel(in_row, x.saturating_sub(1))
143 + 114 * get_pixel(in_row, x)
144 + 35 * get_pixel(in_row, cmp::min(x + 1, width - 1))
145 - 9 * get_pixel(in_row, cmp::min(x + 2, width - 1))
146 + get_pixel(in_row, cmp::min(x + 3, width - 1))
147 + 64)
148 >> 7,
149 0,
150 (1 << bit_depth) - 1,
151 ));
152 }
153 let breakpoint2 = width - 3;
154 for x in breakpoint..breakpoint2 {
155 out_row[x] = T::cast_from(clamp(
156 (4 * get_pixel(in_row, x - 2) - 17 * get_pixel(in_row, x - 1)
157 + 114 * get_pixel(in_row, x)
158 + 35 * get_pixel(in_row, x + 1)
159 - 9 * get_pixel(in_row, x + 2)
160 + get_pixel(in_row, x + 3)
161 + 64)
162 >> 7,
163 0,
164 (1 << bit_depth) - 1,
165 ));
166 }
167 for x in breakpoint2..width {
168 out_row[x] = T::cast_from(clamp(
169 (4 * get_pixel(in_row, x - 2) - 17 * get_pixel(in_row, x - 1)
170 + 114 * get_pixel(in_row, x)
171 + 35 * get_pixel(in_row, cmp::min(x + 1, width - 1))
172 - 9 * get_pixel(in_row, cmp::min(x + 2, width - 1))
173 + get_pixel(in_row, width - 1)
174 + 64)
175 >> 7,
176 0,
177 (1 << bit_depth) - 1,
178 ));
179 }
180 }
181}
182
183#[inline]
184fn clamp<T: PartialOrd>(input: T, min: T, max: T) -> T {
185 if input < min {
186 min
187 } else if input > max {
188 max
189 } else {
190 input
191 }
192}