crosvm: Add missing virtio-video profiles and convert to correct virtio profile in decoder.

Add missing virtio-video profiles and convert to them from libvda profiles.

BUG=b:161261612
BUG=b:140082257
TEST=cargo clippy
TEST=emerge-$BOARD dev-rust/libvda crosvm, start arcvm and play video in YouTube

Cq-Depend: chromium:2299802, chromium:2301325
Change-Id: I061c7eddc881eb785aa7c06cf587cc747007cb74
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/2299604
Reviewed-by: Alex Lau <alexlau@chromium.org>
Tested-by: Alex Lau <alexlau@chromium.org>
Commit-Queue: Alex Lau <alexlau@chromium.org>
This commit is contained in:
Alex Lau 2020-07-15 19:35:54 +09:00 committed by Commit Bot
parent 2135787b74
commit 48a494bafd
2 changed files with 127 additions and 37 deletions

View file

@ -4,24 +4,13 @@
//! Capablities of the virtio video decoder device.
use std::collections::btree_map::Entry;
use std::collections::BTreeMap;
use sys_util::warn;
use crate::virtio::video::control::*;
use crate::virtio::video::format::*;
fn from_input_format(fmt: &libvda::decode::InputFormat, mask: u64) -> FormatDesc {
let format = match fmt.profile {
libvda::Profile::VP8 => Format::VP8,
libvda::Profile::VP9Profile0 => Format::VP9,
libvda::Profile::H264 => Format::H264,
};
FormatDesc {
mask,
format,
frame_formats: vec![Default::default()],
}
}
fn from_pixel_format(
fmt: &libvda::PixelFormat,
mask: u64,
@ -60,11 +49,42 @@ impl Capability {
// Raise the first |# of supported raw formats|-th bits because we can assume that any
// combination of (a coded format, a raw format) is valid in Chrome.
let mask = !(u64::max_value() << caps.output_formats.len());
let in_fmts = caps
.input_formats
.iter()
.map(|fmt| from_input_format(fmt, mask))
.collect();
let mut in_fmts = vec![];
let mut profiles: BTreeMap<Format, Vec<Profile>> = Default::default();
for fmt in caps.input_formats.iter() {
match Profile::from_libvda_profile(fmt.profile) {
Some(profile) => {
let format = profile.to_format();
in_fmts.push(FormatDesc {
mask,
format,
frame_formats: vec![Default::default()],
});
match profiles.entry(format) {
Entry::Occupied(mut e) => e.get_mut().push(profile),
Entry::Vacant(e) => {
e.insert(vec![profile]);
}
}
}
None => {
warn!(
"No virtio-video equivalent for libvda profile, skipping: {:?}",
fmt.profile
);
}
}
}
let levels: BTreeMap<Format, Vec<Level>> = if profiles.contains_key(&Format::H264) {
// We only support Level 1.0 for H.264.
vec![(Format::H264, vec![Level::H264_1_0])]
.into_iter()
.collect()
} else {
Default::default()
};
// Prepare {min, max} of {width, height}.
// While these values are associated with each input format in libvda,
@ -94,23 +114,6 @@ impl Capability {
.map(|fmt| from_pixel_format(fmt, mask, width_range, height_range))
.collect();
let mut profiles: BTreeMap<Format, Vec<Profile>> = Default::default();
let mut levels: BTreeMap<Format, Vec<Level>> = Default::default();
for fmt in caps.input_formats.iter() {
match fmt.profile {
libvda::Profile::VP8 => {
profiles.insert(Format::VP8, vec![Profile::VP8Profile0]);
}
libvda::Profile::VP9Profile0 => {
profiles.insert(Format::VP9, vec![Profile::VP9Profile0]);
}
libvda::Profile::H264 => {
profiles.insert(Format::H264, vec![Profile::H264Baseline]);
levels.insert(Format::H264, vec![Level::H264_1_0]);
}
};
}
Capability {
in_fmts,
out_fmts,

View file

@ -19,12 +19,98 @@ use crate::virtio::Writer;
#[derive(PartialEq, Eq, PartialOrd, Ord, N, Clone, Copy, Debug)]
#[repr(u32)]
pub enum Profile {
VP8Profile0 = VIRTIO_VIDEO_PROFILE_VP8_PROFILE0,
VP9Profile0 = VIRTIO_VIDEO_PROFILE_VP9_PROFILE0,
H264Baseline = VIRTIO_VIDEO_PROFILE_H264_BASELINE,
H264Main = VIRTIO_VIDEO_PROFILE_H264_MAIN,
H264Extended = VIRTIO_VIDEO_PROFILE_H264_EXTENDED,
H264High = VIRTIO_VIDEO_PROFILE_H264_HIGH,
H264High10 = VIRTIO_VIDEO_PROFILE_H264_HIGH10PROFILE,
H264High422 = VIRTIO_VIDEO_PROFILE_H264_HIGH422PROFILE,
H264High444PredictiveProfile = VIRTIO_VIDEO_PROFILE_H264_HIGH444PREDICTIVEPROFILE,
H264ScalableBaseline = VIRTIO_VIDEO_PROFILE_H264_SCALABLEBASELINE,
H264ScalableHigh = VIRTIO_VIDEO_PROFILE_H264_SCALABLEHIGH,
H264StereoHigh = VIRTIO_VIDEO_PROFILE_H264_STEREOHIGH,
H264MultiviewHigh = VIRTIO_VIDEO_PROFILE_H264_MULTIVIEWHIGH,
HevcMain = VIRTIO_VIDEO_PROFILE_HEVC_MAIN,
HevcMain10 = VIRTIO_VIDEO_PROFILE_HEVC_MAIN10,
HevcMainStillPicture = VIRTIO_VIDEO_PROFILE_HEVC_MAIN_STILL_PICTURE,
VP8Profile0 = VIRTIO_VIDEO_PROFILE_VP8_PROFILE0,
VP8Profile1 = VIRTIO_VIDEO_PROFILE_VP8_PROFILE1,
VP8Profile2 = VIRTIO_VIDEO_PROFILE_VP8_PROFILE2,
VP8Profile3 = VIRTIO_VIDEO_PROFILE_VP8_PROFILE3,
VP9Profile0 = VIRTIO_VIDEO_PROFILE_VP9_PROFILE0,
VP9Profile1 = VIRTIO_VIDEO_PROFILE_VP9_PROFILE1,
VP9Profile2 = VIRTIO_VIDEO_PROFILE_VP9_PROFILE2,
VP9Profile3 = VIRTIO_VIDEO_PROFILE_VP9_PROFILE3,
}
impl_try_from_le32_for_enumn!(Profile, "profile");
macro_rules! impl_libvda_conversion {
( $( ( $x:ident, $y:ident ) ),* ) => {
pub fn from_libvda_profile(p: libvda::Profile) -> Option<Self> {
match p {
$(libvda::Profile::$x => Some(Self::$y),)*
_ => None
}
}
// TODO(alexlau): Remove this after encoder CL lands.
#[allow(dead_code)]
pub fn to_libvda_profile(&self) -> Option<libvda::Profile> {
match self {
$(Self::$y => Some(libvda::Profile::$x),)*
_ => None
}
}
}
}
impl Profile {
pub fn to_format(&self) -> Format {
use Profile::*;
match self {
H264Baseline
| H264Main
| H264Extended
| H264High
| H264High10
| H264High422
| H264High444PredictiveProfile
| H264ScalableBaseline
| H264ScalableHigh
| H264StereoHigh
| H264MultiviewHigh => Format::H264,
HevcMain | HevcMain10 | HevcMainStillPicture => Format::HEVC,
VP8Profile0 | VP8Profile1 | VP8Profile2 | VP8Profile3 => Format::VP8,
VP9Profile0 | VP9Profile1 | VP9Profile2 | VP9Profile3 => Format::VP9,
}
}
impl_libvda_conversion!(
(H264ProfileBaseline, H264Baseline),
(H264ProfileMain, H264Main),
(H264ProfileExtended, H264Extended),
(H264ProfileHigh, H264High),
(H264ProfileHigh10Profile, H264High10),
(H264ProfileHigh422Profile, H264High422),
(
H264ProfileHigh444PredictiveProfile,
H264High444PredictiveProfile
),
(H264ProfileScalableBaseline, H264ScalableBaseline),
(H264ProfileScalableHigh, H264ScalableHigh),
(H264ProfileStereoHigh, H264StereoHigh),
(H264ProfileMultiviewHigh, H264MultiviewHigh),
(HevcProfileMain, HevcMain),
(HevcProfileMain10, HevcMain10),
(HevcProfileMainStillPicture, HevcMainStillPicture),
(VP8, VP8Profile0),
(VP9Profile0, VP9Profile0),
(VP9Profile1, VP9Profile1),
(VP9Profile2, VP9Profile2),
(VP9Profile3, VP9Profile3)
);
}
#[derive(PartialEq, Eq, PartialOrd, Ord, N, Clone, Copy, Debug)]
#[repr(u32)]
pub enum Level {
@ -41,6 +127,7 @@ pub enum Format {
// Bitstream formats
H264 = VIRTIO_VIDEO_FORMAT_H264,
HEVC = VIRTIO_VIDEO_FORMAT_HEVC,
VP8 = VIRTIO_VIDEO_FORMAT_VP8,
VP9 = VIRTIO_VIDEO_FORMAT_VP9,
}