• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2022 The ChromiumOS Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 pub mod decoders;
6 pub mod utils;
7 
8 #[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
9 pub struct Resolution {
10     pub width: u32,
11     pub height: u32,
12 }
13 
14 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
15 pub enum DecodedFormat {
16     NV12,
17     I420,
18 }
19 
20 /// Copies `src` into `dst` as NV12, removing any extra padding.
nv12_copy( src: &[u8], mut dst: &mut [u8], width: u32, height: u32, strides: [u32; 3], offsets: [u32; 3], )21 pub fn nv12_copy(
22     src: &[u8],
23     mut dst: &mut [u8],
24     width: u32,
25     height: u32,
26     strides: [u32; 3],
27     offsets: [u32; 3],
28 ) {
29     let width = width.try_into().unwrap();
30     let height = height.try_into().unwrap();
31     let data = src;
32 
33     let mut src = &data[offsets[0] as usize..];
34 
35     // Copy luma
36     for _ in 0..height {
37         dst[..width].copy_from_slice(&src[..width]);
38         dst = &mut dst[width..];
39         src = &src[strides[0] as usize..];
40     }
41 
42     // Advance to the offset of the chroma plane
43     let mut src = &data[offsets[1] as usize..];
44 
45     // Copy chroma
46     for _ in 0..height / 2 {
47         dst[..width].copy_from_slice(&src[..width]);
48         dst = &mut dst[width..];
49         src = &src[strides[1] as usize..];
50     }
51 }
52 
53 /// Copies `src` into `dst` as I420, removing any extra padding.
i420_copy( src: &[u8], mut dst: &mut [u8], width: u32, height: u32, strides: [u32; 3], offsets: [u32; 3], )54 pub fn i420_copy(
55     src: &[u8],
56     mut dst: &mut [u8],
57     width: u32,
58     height: u32,
59     strides: [u32; 3],
60     offsets: [u32; 3],
61 ) {
62     let width = width.try_into().unwrap();
63     let height = height.try_into().unwrap();
64     let data = src;
65 
66     let mut src = &data[offsets[0] as usize..];
67 
68     // Copy luma
69     for _ in 0..height {
70         dst[..width].copy_from_slice(&src[..width]);
71         dst = &mut dst[width..];
72         src = &src[strides[0] as usize..];
73     }
74 
75     // Advance to the offset of the U plane
76     let mut src = &data[offsets[1] as usize..];
77 
78     // Copy U
79     for _ in 0..height / 2 {
80         dst[..width].copy_from_slice(&src[..width]);
81         dst = &mut dst[width..];
82         src = &src[strides[1] as usize..];
83     }
84 
85     // Advance to the offset of the V plane
86     let mut src = &data[offsets[2] as usize..];
87 
88     // Copy V
89     for _ in 0..height / 2 {
90         dst[..width].copy_from_slice(&src[..width]);
91         dst = &mut dst[width..];
92         src = &src[strides[2] as usize..];
93     }
94 }
95 
96 /// Returns the size required to store a frame of `format` with size `width`x`height`, without any
97 /// padding. This is the minimum size of the destination buffer passed to `nv12_copy` or
98 /// `i420_copy`.
decoded_frame_size(format: DecodedFormat, width: u16, height: u16) -> usize99 pub fn decoded_frame_size(format: DecodedFormat, width: u16, height: u16) -> usize {
100     match format {
101         DecodedFormat::I420 | DecodedFormat::NV12 => width as usize * height as usize * 3 / 2,
102     }
103 }
104