use core::ffi::c_void;
use core::ptr;
use apple_cf::cf::{CFDictionary, CFType};
use crate::error::VTError;
use crate::ffi;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum Codec {
H264,
HEVC,
ProRes422,
ProRes422HQ,
ProRes422LT,
ProRes422Proxy,
ProRes4444,
}
impl Codec {
#[must_use]
pub const fn as_cm_codec_type(self) -> ffi::CMVideoCodecType {
match self {
Self::H264 => ffi::kCMVideoCodecType_H264,
Self::HEVC => ffi::kCMVideoCodecType_HEVC,
Self::ProRes422 => ffi::kCMVideoCodecType_AppleProRes422,
Self::ProRes422HQ => ffi::kCMVideoCodecType_AppleProRes422HQ,
Self::ProRes422LT => ffi::kCMVideoCodecType_AppleProRes422LT,
Self::ProRes422Proxy => ffi::kCMVideoCodecType_AppleProRes422Proxy,
Self::ProRes4444 => ffi::kCMVideoCodecType_AppleProRes4444,
}
}
}
pub(crate) unsafe fn copy_property(
session: *mut c_void,
key: ffi::CFStringRef,
) -> Result<Option<CFType>, VTError> {
let mut value: *mut c_void = ptr::null_mut();
let status = unsafe {
ffi::VTSessionCopyProperty(
session,
key,
ffi::kCFAllocatorDefault,
(&raw mut value).cast(),
)
};
if status != 0 {
return Err(VTError::ApiFailed {
api: "VTSessionCopyProperty",
status,
});
}
Ok(CFType::from_raw(value))
}
pub(crate) unsafe fn copy_supported_property_dictionary(
session: *mut c_void,
) -> Result<CFDictionary, VTError> {
let mut out: ffi::CFDictionaryRef = ptr::null();
let status = unsafe { ffi::VTSessionCopySupportedPropertyDictionary(session, &mut out) };
if status != 0 || out.is_null() {
return Err(VTError::ApiFailed {
api: "VTSessionCopySupportedPropertyDictionary",
status,
});
}
CFDictionary::from_raw(out.cast_mut().cast()).ok_or(VTError::ApiFailed {
api: "VTSessionCopySupportedPropertyDictionary",
status,
})
}
pub(crate) unsafe fn copy_serializable_properties(
session: *mut c_void,
) -> Result<CFDictionary, VTError> {
let mut out: ffi::CFDictionaryRef = ptr::null();
let status = unsafe {
ffi::VTSessionCopySerializableProperties(session, ffi::kCFAllocatorDefault, &mut out)
};
if status != 0 || out.is_null() {
return Err(VTError::ApiFailed {
api: "VTSessionCopySerializableProperties",
status,
});
}
CFDictionary::from_raw(out.cast_mut().cast()).ok_or(VTError::ApiFailed {
api: "VTSessionCopySerializableProperties",
status,
})
}
pub(crate) unsafe fn set_properties(
session: *mut c_void,
properties: &CFDictionary,
) -> Result<(), VTError> {
let status = unsafe { ffi::VTSessionSetProperties(session, properties.as_ptr().cast()) };
if status == 0 {
Ok(())
} else {
Err(VTError::ApiFailed {
api: "VTSessionSetProperties",
status,
})
}
}