ffmpeg/
avutil.rs

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
5use crate::avcodec::AvError;
6use crate::avcodec::AvPixelFormat;
7use crate::ffi;
8
9pub const AV_NOPTS_VALUE: u64 = 0x8000000000000000;
10const MAX_FFMPEG_PLANES: usize = 4;
11
12/// Get the maximum data alignment that may be required by FFmpeg.
13/// This could change depending on FFmpeg's build configuration (AVX etc.).
14pub fn max_buffer_alignment() -> usize {
15    // SAFETY:
16    // Safe because this function has no side effects and just returns an integer.
17    unsafe { ffi::av_cpu_max_align() }
18}
19
20// See AvPixelFormat::line_size.
21pub(crate) fn av_image_line_size(
22    format: AvPixelFormat,
23    width: u32,
24    plane: usize,
25) -> Result<usize, AvError> {
26    // SAFETY:
27    // Safe because format is a valid format and this function is pure computation.
28    match unsafe { ffi::av_image_get_linesize(format.pix_fmt(), width as _, plane as _) } {
29        i if i >= 0 => Ok(i as _),
30        err => Err(AvError(err)),
31    }
32}
33
34// See AvPixelFormat::plane_sizes.
35pub(crate) fn av_image_plane_sizes<I: IntoIterator<Item = u32>>(
36    format: AvPixelFormat,
37    linesizes: I,
38    height: u32,
39) -> Result<Vec<usize>, AvError> {
40    let mut linesizes_buf = [0; MAX_FFMPEG_PLANES];
41    let mut planes = 0;
42    for (i, linesize) in linesizes.into_iter().take(MAX_FFMPEG_PLANES).enumerate() {
43        linesizes_buf[i] = linesize as _;
44        planes += 1;
45    }
46    let mut plane_sizes_buf = [0; MAX_FFMPEG_PLANES];
47    // SAFETY:
48    // Safe because plane_sizes_buf and linesizes_buf have the size specified by the API, format is
49    // valid, and this function doesn't have any side effects other than writing to plane_sizes_buf.
50    AvError::result(unsafe {
51        ffi::av_image_fill_plane_sizes(
52            plane_sizes_buf.as_mut_ptr(),
53            format.pix_fmt(),
54            height as _,
55            linesizes_buf.as_ptr(),
56        )
57    })?;
58    Ok(plane_sizes_buf
59        .into_iter()
60        .map(|x| x as _)
61        .take(planes)
62        .collect())
63}