mirror of
https://chromium.googlesource.com/crosvm/crosvm
synced 2025-02-10 04:07:23 +00:00
media: ffmpeg: add proper wrapper for AVProfile
Our ffmpeg crate should avoid returning native C avcodec types if possible, as this means client code could have to resort to unsafe code. Fix this for AVProfile by introducing a safe wrapper type that provides us all the useful methods we may need. BUG=b:169295147 TEST=cargo build --features "video-decoder,ffmpeg" Change-Id: I2436857d3878b5b6cf4eab35f5b3b0c57c8db60e Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/3782039 Commit-Queue: Alexandre Courbot <acourbot@chromium.org> Reviewed-by: Keiichi Watanabe <keiichiw@chromium.org> Tested-by: Alexandre Courbot <acourbot@chromium.org> Auto-Submit: Alexandre Courbot <acourbot@chromium.org>
This commit is contained in:
parent
4f8a3ac153
commit
89b7ba4512
2 changed files with 36 additions and 5 deletions
|
@ -633,7 +633,7 @@ impl DecoderBackend for FfmpegDecoder {
|
||||||
|
|
||||||
profile_iter
|
profile_iter
|
||||||
.filter_map(|p| {
|
.filter_map(|p| {
|
||||||
match p.profile as u32 {
|
match p.profile() {
|
||||||
FF_PROFILE_H264_BASELINE => Some(Profile::H264Baseline),
|
FF_PROFILE_H264_BASELINE => Some(Profile::H264Baseline),
|
||||||
FF_PROFILE_H264_MAIN => Some(Profile::H264Main),
|
FF_PROFILE_H264_MAIN => Some(Profile::H264Main),
|
||||||
FF_PROFILE_H264_EXTENDED => Some(Profile::H264Extended),
|
FF_PROFILE_H264_EXTENDED => Some(Profile::H264Extended),
|
||||||
|
@ -662,7 +662,7 @@ impl DecoderBackend for FfmpegDecoder {
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
Format::VP9 => profile_iter
|
Format::VP9 => profile_iter
|
||||||
.filter_map(|p| match p.profile as u32 {
|
.filter_map(|p| match p.profile() {
|
||||||
FF_PROFILE_VP9_0 => Some(Profile::VP9Profile0),
|
FF_PROFILE_VP9_0 => Some(Profile::VP9Profile0),
|
||||||
FF_PROFILE_VP9_1 => Some(Profile::VP9Profile1),
|
FF_PROFILE_VP9_1 => Some(Profile::VP9Profile1),
|
||||||
FF_PROFILE_VP9_2 => Some(Profile::VP9Profile2),
|
FF_PROFILE_VP9_2 => Some(Profile::VP9Profile2),
|
||||||
|
@ -671,7 +671,7 @@ impl DecoderBackend for FfmpegDecoder {
|
||||||
})
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
Format::Hevc => profile_iter
|
Format::Hevc => profile_iter
|
||||||
.filter_map(|p| match p.profile as u32 {
|
.filter_map(|p| match p.profile() {
|
||||||
FF_PROFILE_HEVC_MAIN => Some(Profile::HevcMain),
|
FF_PROFILE_HEVC_MAIN => Some(Profile::HevcMain),
|
||||||
FF_PROFILE_HEVC_MAIN_10 => Some(Profile::HevcMain10),
|
FF_PROFILE_HEVC_MAIN_10 => Some(Profile::HevcMain10),
|
||||||
FF_PROFILE_HEVC_MAIN_STILL_PICTURE => Some(Profile::HevcMainStillPicture),
|
FF_PROFILE_HEVC_MAIN_STILL_PICTURE => Some(Profile::HevcMainStillPicture),
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
//! low-level access as the libavcodec functions do.
|
//! low-level access as the libavcodec functions do.
|
||||||
|
|
||||||
use std::ffi::CStr;
|
use std::ffi::CStr;
|
||||||
|
use std::fmt::Debug;
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
|
@ -139,11 +140,41 @@ impl Iterator for AvCodecIterator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Simple wrapper over `AVProfile` that provides helpful methods.
|
||||||
|
pub struct AvProfile(&'static ffi::AVProfile);
|
||||||
|
|
||||||
|
impl AvProfile {
|
||||||
|
/// Return the profile id, which can be matched against FF_PROFILE_*.
|
||||||
|
pub fn profile(&self) -> u32 {
|
||||||
|
self.0.profile as u32
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return the name of this profile.
|
||||||
|
pub fn name(&self) -> &'static str {
|
||||||
|
const INVALID_PROFILE_STR: &str = "invalid profile";
|
||||||
|
|
||||||
|
// Safe because `CStr::from_ptr` is called on a valid zero-terminated C string.
|
||||||
|
unsafe { CStr::from_ptr(self.0.name).to_str() }.unwrap_or(INVALID_PROFILE_STR)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for AvProfile {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
f.write_str(self.name())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Debug for AvProfile {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
Display::fmt(self, f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Lightweight abstraction over the array of supported profiles for a given codec.
|
/// Lightweight abstraction over the array of supported profiles for a given codec.
|
||||||
pub struct AvProfileIterator(*const ffi::AVProfile);
|
pub struct AvProfileIterator(*const ffi::AVProfile);
|
||||||
|
|
||||||
impl Iterator for AvProfileIterator {
|
impl Iterator for AvProfileIterator {
|
||||||
type Item = &'static ffi::AVProfile;
|
type Item = AvProfile;
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
// Safe because the contract of `new` stipulates we have received a valid `AVCodec`
|
// Safe because the contract of `new` stipulates we have received a valid `AVCodec`
|
||||||
|
@ -158,7 +189,7 @@ impl Iterator for AvProfileIterator {
|
||||||
// Safe because we have been initialized to a static, valid profiles array
|
// Safe because we have been initialized to a static, valid profiles array
|
||||||
// which is terminated by FF_PROFILE_UNKNOWN.
|
// which is terminated by FF_PROFILE_UNKNOWN.
|
||||||
self.0 = unsafe { self.0.offset(1) };
|
self.0 = unsafe { self.0.offset(1) };
|
||||||
Some(profile)
|
Some(AvProfile(profile))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue