use windows::Win32::Graphics::Direct3D11::ID3D11Device;
use windows::Win32::Media::MediaFoundation::{
IMFDXGIDeviceManager, MF_VERSION, MFCreateDXGIDeviceManager, MFSTARTUP_FULL, MFShutdown, MFStartup,
};
use windows::Win32::System::Com::{COINIT_MULTITHREADED, CoInitializeEx, CoUninitialize};
use crate::Error;
use crate::frame::d3d11;
pub(crate) fn mf_err(ctx: &str, e: windows::core::Error) -> Error {
Error::Codec(anyhow::anyhow!("{ctx}: {e}"))
}
pub(crate) fn pack_2x32(hi: u32, lo: u32) -> u64 {
((hi as u64) << 32) | lo as u64
}
pub(crate) fn unpack_2x32(v: u64) -> (u32, u32) {
((v >> 32) as u32, v as u32)
}
pub(crate) fn create_d3d_device() -> Result<(ID3D11Device, IMFDXGIDeviceManager), Error> {
let device = d3d11::create_device()?;
let mut token: u32 = 0;
let mut manager: Option<IMFDXGIDeviceManager> = None;
unsafe {
MFCreateDXGIDeviceManager(&mut token, &mut manager).map_err(|e| mf_err("MFCreateDXGIDeviceManager", e))?;
}
let manager = manager.ok_or_else(|| Error::Codec(anyhow::anyhow!("MFCreateDXGIDeviceManager returned null")))?;
unsafe {
manager
.ResetDevice(&device, token)
.map_err(|e| mf_err("ResetDevice", e))?;
}
Ok((device, manager))
}
pub(crate) struct ComGuard;
impl ComGuard {
pub(crate) fn new() -> Result<Self, Error> {
unsafe {
CoInitializeEx(None, COINIT_MULTITHREADED)
.ok()
.map_err(|e| mf_err("CoInitializeEx", e))?;
MFStartup(MF_VERSION, MFSTARTUP_FULL).map_err(|e| mf_err("MFStartup", e))?;
}
Ok(Self)
}
}
impl Drop for ComGuard {
fn drop(&mut self) {
unsafe {
let _ = MFShutdown();
CoUninitialize();
}
}
}