ffmpeg_sidecar/
pix_fmt.rs

1//! A database of the pixel formats supported by FFmpeg and their size per pixel.
2
3use crate::event::VideoStream;
4
5/// Map from the pix_fmt identifier string (e.g. `rgb24`) to the number of bits
6/// per pixel (e.g. `24`). Returns `None` if the pix_fmt is unsupported/unrecognized.
7///
8/// Obtained from `ffmpeg -pix-fmts`.
9///
10/// ## Examples
11///
12/// ```rust
13/// use ffmpeg_sidecar::pix_fmt::get_bits_per_pixel;
14/// assert!(get_bits_per_pixel("rgb24") == Some(24));
15/// assert!(get_bits_per_pixel("asdf") == None);
16/// ```
17pub fn get_bits_per_pixel(pix_fmt: &str) -> Option<u32> {
18  match pix_fmt {
19    "yuv420p" => Some(12),
20    "yuyv422" => Some(16),
21    "rgb24" => Some(24),
22    "bgr24" => Some(24),
23    "yuv422p" => Some(16),
24    "yuv444p" => Some(24),
25    "yuv410p" => Some(9),
26    "yuv411p" => Some(12),
27    "gray" => Some(8),
28    "monow" => Some(1),
29    "monob" => Some(1),
30    "pal8" => Some(8),
31    "yuvj420p" => Some(12),
32    "yuvj422p" => Some(16),
33    "yuvj444p" => Some(24),
34    "uyvy422" => Some(16),
35    "uyyvyy411" => Some(12),
36    "bgr8" => Some(8),
37    "bgr4" => Some(4),
38    "rgb8" => Some(8),
39    "rgb4" => Some(4),
40    "nv12" => Some(12),
41    "nv21" => Some(12),
42    "argb" => Some(32),
43    "rgba" => Some(32),
44    "abgr" => Some(32),
45    "bgra" => Some(32),
46    "gray16be" => Some(16),
47    "gray16le" => Some(16),
48    "yuv440p" => Some(16),
49    "yuvj440p" => Some(16),
50    "yuva420p" => Some(20),
51    "rgb48be" => Some(48),
52    "rgb48le" => Some(48),
53    "rgb565be" => Some(16),
54    "rgb565le" => Some(16),
55    "rgb555be" => Some(15),
56    "rgb555le" => Some(15),
57    "bgr565be" => Some(16),
58    "bgr565le" => Some(16),
59    "bgr555be" => Some(15),
60    "bgr555le" => Some(15),
61    "vaapi" => Some(0),
62    "yuv420p16le" => Some(24),
63    "yuv420p16be" => Some(24),
64    "yuv422p16le" => Some(32),
65    "yuv422p16be" => Some(32),
66    "yuv444p16le" => Some(48),
67    "yuv444p16be" => Some(48),
68    "dxva2" => Some(0),
69    "rgb444le" => Some(12),
70    "rgb444be" => Some(12),
71    "bgr444le" => Some(12),
72    "bgr444be" => Some(12),
73    "ya8" => Some(16),
74    "bgr48be" => Some(48),
75    "bgr48le" => Some(48),
76    "yuv420p9be" => Some(13),
77    "yuv420p9le" => Some(13),
78    "yuv420p10be" => Some(15),
79    "yuv420p10le" => Some(15),
80    "yuv422p10be" => Some(20),
81    "yuv422p10le" => Some(20),
82    "yuv444p9be" => Some(27),
83    "yuv444p9le" => Some(27),
84    "yuv444p10be" => Some(30),
85    "yuv444p10le" => Some(30),
86    "yuv422p9be" => Some(18),
87    "yuv422p9le" => Some(18),
88    "gbrp" => Some(24),
89    "gbrp9be" => Some(27),
90    "gbrp9le" => Some(27),
91    "gbrp10be" => Some(30),
92    "gbrp10le" => Some(30),
93    "gbrp16be" => Some(48),
94    "gbrp16le" => Some(48),
95    "yuva422p" => Some(24),
96    "yuva444p" => Some(32),
97    "yuva420p9be" => Some(22),
98    "yuva420p9le" => Some(22),
99    "yuva422p9be" => Some(27),
100    "yuva422p9le" => Some(27),
101    "yuva444p9be" => Some(36),
102    "yuva444p9le" => Some(36),
103    "yuva420p10be" => Some(25),
104    "yuva420p10le" => Some(25),
105    "yuva422p10be" => Some(30),
106    "yuva422p10le" => Some(30),
107    "yuva444p10be" => Some(40),
108    "yuva444p10le" => Some(40),
109    "yuva420p16be" => Some(40),
110    "yuva420p16le" => Some(40),
111    "yuva422p16be" => Some(48),
112    "yuva422p16le" => Some(48),
113    "yuva444p16be" => Some(64),
114    "yuva444p16le" => Some(64),
115    "vdpau" => Some(0),
116    "xyz12le" => Some(36),
117    "xyz12be" => Some(36),
118    "nv16" => Some(16),
119    "nv20le" => Some(20),
120    "nv20be" => Some(20),
121    "rgba64be" => Some(64),
122    "rgba64le" => Some(64),
123    "bgra64be" => Some(64),
124    "bgra64le" => Some(64),
125    "yvyu422" => Some(16),
126    "ya16be" => Some(32),
127    "ya16le" => Some(32),
128    "gbrap" => Some(32),
129    "gbrap16be" => Some(64),
130    "gbrap16le" => Some(64),
131    "qsv" => Some(0),
132    "mmal" => Some(0),
133    "d3d11va" => Some(0),
134    "cuda" => Some(0),
135    "0rgb" => Some(24),
136    "rgb0" => Some(24),
137    "0bgr" => Some(24),
138    "bgr0" => Some(24),
139    "yuv420p12be" => Some(18),
140    "yuv420p12le" => Some(18),
141    "yuv420p14be" => Some(21),
142    "yuv420p14le" => Some(21),
143    "yuv422p12be" => Some(24),
144    "yuv422p12le" => Some(24),
145    "yuv422p14be" => Some(28),
146    "yuv422p14le" => Some(28),
147    "yuv444p12be" => Some(36),
148    "yuv444p12le" => Some(36),
149    "yuv444p14be" => Some(42),
150    "yuv444p14le" => Some(42),
151    "gbrp12be" => Some(36),
152    "gbrp12le" => Some(36),
153    "gbrp14be" => Some(42),
154    "gbrp14le" => Some(42),
155    "yuvj411p" => Some(12),
156    "bayer" => Some(3),
157    "xvmc" => Some(0),
158    "yuv440p10le" => Some(20),
159    "yuv440p10be" => Some(20),
160    "yuv440p12le" => Some(24),
161    "yuv440p12be" => Some(24),
162    "ayuv64le" => Some(64),
163    "ayuv64be" => Some(64),
164    "videotoolbox" => Some(0),
165    "p010le" => Some(15),
166    "p010be" => Some(15),
167    "gbrap12be" => Some(48),
168    "gbrap12le" => Some(48),
169    "gbrap10be" => Some(40),
170    "gbrap10le" => Some(40),
171    "mediacodec" => Some(0),
172    "gray12be" => Some(12),
173    "gray12le" => Some(12),
174    "gray10be" => Some(10),
175    "gray10le" => Some(10),
176    "p016le" => Some(24),
177    "p016be" => Some(24),
178    "d3d11" => Some(0),
179    "gray9be" => Some(9),
180    "gray9le" => Some(9),
181    "gbrpf32be" => Some(96),
182    "gbrpf32le" => Some(96),
183    "gbrapf32be" => Some(128),
184    "gbrapf32le" => Some(128),
185    "drm" => Some(0),
186    "opencl" => Some(0),
187    "gray14be" => Some(14),
188    "gray14le" => Some(14),
189    "grayf32be" => Some(32),
190    "grayf32le" => Some(32),
191    "yuva422p12be" => Some(36),
192    "yuva422p12le" => Some(36),
193    "yuva444p12be" => Some(48),
194    "yuva444p12le" => Some(48),
195    "nv24" => Some(24),
196    "nv42" => Some(24),
197    "vulkan" => Some(0),
198    "y210be" => Some(20),
199    "y210le" => Some(20),
200    "x2rgb10le" => Some(30),
201    "x2rgb10be" => Some(30),
202    "x2bgr10le" => Some(30),
203    "x2bgr10be" => Some(30),
204    "p210be" => Some(20),
205    "p210le" => Some(20),
206    "p410be" => Some(30),
207    "p410le" => Some(30),
208    "p216be" => Some(32),
209    "p216le" => Some(32),
210    "p416be" => Some(48),
211    "p416le" => Some(48),
212    "vuya" => Some(32),
213    "rgbaf16be" => Some(64),
214    "rgbaf16le" => Some(64),
215    "vuyx" => Some(24),
216    "p012le" => Some(18),
217    "p012be" => Some(18),
218    "y212be" => Some(24),
219    "y212le" => Some(24),
220    "xv30be" => Some(30),
221    "xv30le" => Some(30),
222    "xv36be" => Some(36),
223    "xv36le" => Some(36),
224    "rgbf32be" => Some(96),
225    "rgbf32le" => Some(96),
226    "rgbaf32be" => Some(128),
227    "rgbaf32le" => Some(128),
228    _ => None,
229  }
230}
231
232/// Computes `width * height * bits_per_pixel / 8`
233pub fn get_bytes_per_frame(video_data: &VideoStream) -> Option<u32> {
234  let bits_per_pixel = get_bits_per_pixel(&video_data.pix_fmt)?;
235  // Enforce byte-alignment, since we don't currently have buffer reads in
236  // sub-byte increments.
237  // Use the full frame buffer size for this, since formats like `yuvj420p` typically restrict a frame's size
238  // such that the buffer size has full bytes.
239  let num_bits = video_data.width * video_data.height * bits_per_pixel;
240  match num_bits % 8 {
241    0 => Some(num_bits / 8),
242    _ => None,
243  }
244}