use crate::*;
use crate::AMDGPU::*;
use core::mem::{size_of, MaybeUninit};
pub use bindings::{drm_amdgpu_info_video_caps, drm_amdgpu_info_video_codec_info};
#[derive(Debug, Clone, Copy)]
pub struct VideoCapsInfo {
pub cap_type: CAP_TYPE,
pub mpeg2: Option<drm_amdgpu_info_video_codec_info>,
pub mpeg4: Option<drm_amdgpu_info_video_codec_info>,
pub vc1: Option<drm_amdgpu_info_video_codec_info>,
pub mpeg4_avc: Option<drm_amdgpu_info_video_codec_info>,
pub hevc: Option<drm_amdgpu_info_video_codec_info>,
pub jpeg: Option<drm_amdgpu_info_video_codec_info>,
pub vp9: Option<drm_amdgpu_info_video_codec_info>,
pub av1: Option<drm_amdgpu_info_video_codec_info>,
}
impl From<(&CAP_TYPE, &drm_amdgpu_info_video_caps)> for VideoCapsInfo {
fn from(caps: (&CAP_TYPE, &drm_amdgpu_info_video_caps)) -> Self {
let (cap_type, video_caps) = caps;
let [mpeg2, mpeg4, vc1, mpeg4_avc, hevc, jpeg, vp9, av1] = CODEC::LIST
.map(|codec| {
let info = video_caps.get_codec_info(codec);
(info.valid != 0).then_some(info)
});
Self {
cap_type: *cap_type,
mpeg2,
mpeg4,
vc1,
mpeg4_avc,
hevc,
jpeg,
vp9,
av1,
}
}
}
impl DeviceHandle {
pub fn get_video_caps_info(&self, cap_type: CAP_TYPE) -> Result<VideoCapsInfo, i32> {
let cap = self.get_video_caps(cap_type)?;
Ok(VideoCapsInfo::from((&cap_type, &cap)))
}
}
use bindings::{
AMDGPU_INFO_VIDEO_CAPS_DECODE,
AMDGPU_INFO_VIDEO_CAPS_ENCODE,
};
#[derive(Debug, Clone, Copy)]
#[repr(u32)]
pub enum CAP_TYPE {
DECODE = AMDGPU_INFO_VIDEO_CAPS_DECODE,
ENCODE = AMDGPU_INFO_VIDEO_CAPS_ENCODE,
}
impl DeviceHandle {
pub fn get_video_caps(&self, type_: CAP_TYPE) -> Result<drm_amdgpu_info_video_caps, i32> {
#[cfg(not(feature = "dynamic_loading"))]
let func = bindings::amdgpu_query_video_caps_info;
#[cfg(feature = "dynamic_loading")]
let func = self.libdrm_amdgpu.amdgpu_query_video_caps_info;
unsafe {
let mut video_caps: MaybeUninit<drm_amdgpu_info_video_caps> = MaybeUninit::zeroed();
let r = func(
self.amdgpu_dev,
type_ as u32,
size_of::<drm_amdgpu_info_video_caps>() as u32,
video_caps.as_mut_ptr() as *mut ::core::ffi::c_void,
);
let video_caps = video_caps.assume_init();
query_error!(r);
Ok(video_caps)
}
}
}
impl drm_amdgpu_info_video_caps {
pub fn get_codec_info(&self, codec: CODEC) -> drm_amdgpu_info_video_codec_info {
self.codec_info[codec as usize]
}
}
use bindings::{
AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2,
AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4,
AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1,
AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC,
AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC,
AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG,
AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9,
AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_AV1,
AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_COUNT,
};
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd)]
#[repr(u32)]
pub enum CODEC {
MPEG2 = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2,
MPEG4 = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4,
VC1 = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1,
MPEG4_AVC = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC,
HEVC = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC,
JPEG = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG,
VP9 = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9,
AV1 = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_AV1,
}
impl CODEC {
pub const LIST: [Self; AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_COUNT as usize] = [
Self::MPEG2,
Self::MPEG4,
Self::VC1,
Self::MPEG4_AVC,
Self::HEVC,
Self::JPEG,
Self::VP9,
Self::AV1,
];
}
use std::fmt;
impl fmt::Display for CODEC {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{:?}", self)
}
}
impl drm_amdgpu_info_video_codec_info {
pub fn is_supported(&self) -> bool {
self.valid != 0
}
}