mirror of
https://chromium.googlesource.com/crosvm/crosvm
synced 2025-01-27 02:28:22 +00:00
media: ffmpeg: Add helpers for determining line and plane sizes.
These are wrappers of av_image_get_linesize and av_image_fill_plane_sizes, and will be used for bounds checking and mmap bounds calculation purposes. It's kind of weird that one is singular and the other is plural, but we should probably blame FFmpeg for not having a singular version of av_image_fill_plane_sizes. BUG=b:239897269 TEST=cargo test --features "video-decoder,ffmpeg" -p ffmpeg -p devices Change-Id: I34104f5062089377aeab0d4a4ab0534837e56d6f Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/3868595 Reviewed-by: Alexandre Courbot <acourbot@chromium.org>
This commit is contained in:
parent
40ba620f0a
commit
55d8d9b4eb
2 changed files with 62 additions and 0 deletions
|
@ -329,6 +329,22 @@ impl AvPixelFormat {
|
|||
// handles any value passed as argument.
|
||||
unsafe { ffi::avcodec_pix_fmt_to_codec_tag(self.0) }.to_le_bytes()
|
||||
}
|
||||
|
||||
/// Given the width and plane index, returns the line size (data pointer increment per row) in
|
||||
/// bytes.
|
||||
pub fn line_size(&self, width: u32, plane: usize) -> Result<usize, AvError> {
|
||||
av_image_line_size(*self, width, plane)
|
||||
}
|
||||
|
||||
/// Given an iterator of line sizes and height, return the size required for each plane's buffer
|
||||
/// in bytes.
|
||||
pub fn plane_sizes<I: IntoIterator<Item = u32>>(
|
||||
&self,
|
||||
linesizes: I,
|
||||
height: u32,
|
||||
) -> Result<Vec<usize>, AvError> {
|
||||
av_image_plane_sizes(*self, linesizes, height)
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for AvPixelFormat {
|
||||
|
|
|
@ -2,9 +2,12 @@
|
|||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
use crate::avcodec::AvError;
|
||||
use crate::avcodec::AvPixelFormat;
|
||||
use crate::ffi;
|
||||
|
||||
pub const AV_NOPTS_VALUE: u64 = 0x8000000000000000;
|
||||
const MAX_FFMPEG_PLANES: usize = 4;
|
||||
|
||||
/// Get the maximum data alignment that may be required by FFmpeg.
|
||||
/// This could change depending on FFmpeg's build configuration (AVX etc.).
|
||||
|
@ -12,3 +15,46 @@ pub fn max_buffer_alignment() -> usize {
|
|||
// Safe because this function has no side effects and just returns an integer.
|
||||
unsafe { ffi::av_cpu_max_align() as usize }
|
||||
}
|
||||
|
||||
// See AvPixelFormat::line_size.
|
||||
pub(crate) fn av_image_line_size(
|
||||
format: AvPixelFormat,
|
||||
width: u32,
|
||||
plane: usize,
|
||||
) -> Result<usize, AvError> {
|
||||
// Safe because format is a valid format and this function is pure computation.
|
||||
match unsafe { ffi::av_image_get_linesize(format.pix_fmt(), width as _, plane as _) } {
|
||||
i if i >= 0 => Ok(i as _),
|
||||
err => Err(AvError(err)),
|
||||
}
|
||||
}
|
||||
|
||||
// See AvPixelFormat::plane_sizes.
|
||||
pub(crate) fn av_image_plane_sizes<I: IntoIterator<Item = u32>>(
|
||||
format: AvPixelFormat,
|
||||
linesizes: I,
|
||||
height: u32,
|
||||
) -> Result<Vec<usize>, AvError> {
|
||||
let mut linesizes_buf = [0; MAX_FFMPEG_PLANES];
|
||||
let mut planes = 0;
|
||||
for (i, linesize) in linesizes.into_iter().take(MAX_FFMPEG_PLANES).enumerate() {
|
||||
linesizes_buf[i] = linesize as _;
|
||||
planes += 1;
|
||||
}
|
||||
let mut plane_sizes_buf = [0; MAX_FFMPEG_PLANES];
|
||||
// Safe because plane_sizes_buf and linesizes_buf have the size specified by the API, format is
|
||||
// valid, and this function doesn't have any side effects other than writing to plane_sizes_buf.
|
||||
AvError::result(unsafe {
|
||||
ffi::av_image_fill_plane_sizes(
|
||||
plane_sizes_buf.as_mut_ptr(),
|
||||
format.pix_fmt(),
|
||||
height as _,
|
||||
linesizes_buf.as_ptr(),
|
||||
)
|
||||
})?;
|
||||
Ok(plane_sizes_buf
|
||||
.into_iter()
|
||||
.map(|x| x as _)
|
||||
.take(planes)
|
||||
.collect())
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue