video_levels/
common.rs

1use yuv::color::ChromaSampling;
2use yuv::color::Depth;
3
4#[derive(Debug, Clone, PartialEq, Eq)]
5pub struct ProfileConstraint {
6    pub max_bit_depth: Depth,
7    pub chroma_formats: Vec<ChromaSampling>,
8}
9
10impl ProfileConstraint {
11    pub fn new(max_bit_depth: Depth, chroma_formats: Vec<ChromaSampling>) -> Self {
12        Self {
13            max_bit_depth,
14            chroma_formats,
15        }
16    }
17
18    pub fn max_chroma_format(&self) -> ChromaSampling {
19        if self.chroma_formats.contains(&ChromaSampling::Cs444) {
20            ChromaSampling::Cs444
21        } else if self.chroma_formats.contains(&ChromaSampling::Cs422) {
22            ChromaSampling::Cs422
23        } else if self.chroma_formats.contains(&ChromaSampling::Cs420) {
24            ChromaSampling::Cs420
25        } else {
26            ChromaSampling::Monochrome
27        }
28    }
29
30    pub fn supports_chroma_format(&self, chroma_format: ChromaSampling) -> bool {
31        self.chroma_formats.contains(&chroma_format)
32    }
33
34    pub fn supports_mono_chrome(&self) -> bool {
35        self.chroma_formats.contains(&ChromaSampling::Monochrome)
36    }
37}
38
39pub fn yuv_bitrate(
40    width: u32,
41    height: u32,
42    fps: f32,
43    subsampling: ChromaSampling,
44    bit_depth: Depth,
45) -> f32 {
46    let pixels = width * height;
47
48    dbg!(pixels);
49
50    // Calculate bits per pixel (bpp) for luma and chroma based on subsampling.
51    let bpp = match subsampling {
52        ChromaSampling::Cs444 => {
53            // 4:4:4 subsampling has 3 samples per pixel, all of equal bit depth.
54            3 * bit_depth as u32
55        }
56        ChromaSampling::Cs422 => {
57            // 4:2:2 subsampling has 2 chroma samples for every 2 pixels, plus 1 luma per pixel.
58            (2 * bit_depth as u32) + (bit_depth as u32)
59        }
60        ChromaSampling::Cs420 => {
61            // 4:2:0 subsampling has 1 chroma sample for every 4 pixels, plus 1 luma per pixel.
62            (bit_depth as u32) + (bit_depth as u32 / 2)
63        }
64        ChromaSampling::Monochrome => {
65            // 4:0:0 subsampling has only luma samples.
66            bit_depth as u32
67        }
68    };
69
70    // Calculate total bitrate.
71    (pixels as f32 * bpp as f32 * fps) / 1000.0
72}
73
74// pub fn chroma_multiplier(base: u64, subsampling: ChromaSampling, bit_depth: Depth) -> u64 {
75//     let multiplier = match subsampling {
76//         ChromaSampling::Cs444 => 1,
77//         ChromaSampling::Cs422 => 2,
78//         ChromaSampling::Cs420 => 3,
79//         ChromaSampling::Monochrome => 1,
80//     };
81
82//     let bpp = match subsampling {
83//         ChromaSampling::Cs444 => {
84//             // 4:4:4 subsampling has 3 samples per pixel, all of equal bit depth.
85//             3 * bit_depth as u32
86//         }
87//         ChromaSampling::Cs422 => {
88//             // 4:2:2 subsampling has 2 chroma samples for every 2 pixels, plus 1 luma per pixel.
89//             (2 * bit_depth as u32) + (bit_depth as u32)
90//         }
91//         ChromaSampling::Cs420 => {
92//             // 4:2:0 subsampling has 1 chroma sample for every 4 pixels, plus 1 luma per pixel.
93//             (bit_depth as u32) + (bit_depth as u32 / 2)
94//         }
95//         ChromaSampling::Monochrome => {
96//             // 4:0:0 subsampling has only luma samples.
97//             bit_depth as u32
98//         }
99//     };
100
101//     base * bpp as u64
102// }