I'm having trouble with the MFTEnumEx function. It's documentation says that I'm supposed to call Release on each of the returned IMFActivate pointers, which as far as I could tell is a Drop impl on ::windows::core::IUnknown (there are no methods to call explicitly like in C++).
I was a bit confused getting this to compile at all, in particular the maybe_activate line; there's some stuff going on with references that I don't fully understand, but just dereferencing the pointer without borowing resulted in a move which didn't compile because Option<IMFActivate> does not implement Copy.
As you can see I'm calling drop on whatever I get out of the array, though I suspect this is incorrect. If I place a breakpoint on IUnknown's Drop function, it is not hit. So I guess I'm freeing the reference (a no-op) instead of the IMFActivate object that I'm supposed to free.
Can anyone explain how to use this function correctly?
use windows::Win32::{Media::MediaFoundation::{
IMFActivate, MFShutdown, MFStartup, MFTEnumEx, MFSTARTUP_NOSOCKET, MFT_CATEGORY_VIDEO_ENCODER,
MFT_ENUM_FLAG_HARDWARE, MF_API_VERSION, MF_SDK_VERSION,
}, System::Com::CoTaskMemFree};
fn main() -> windows::core::Result<()> {
let mf_version = (MF_SDK_VERSION << 16) | MF_API_VERSION;
unsafe {
let res = MFStartup(mf_version, MFSTARTUP_NOSOCKET);
if res.is_ok() {
println!("Media Foundation initialized!");
let mut tmp: Option<IMFActivate> = None;
let mut activate_ptrs = &mut tmp as *mut Option<IMFActivate>;
let mut activate_ptr_count = 0u32;
let res = MFTEnumEx(
MFT_CATEGORY_VIDEO_ENCODER,
MFT_ENUM_FLAG_HARDWARE.0.try_into().unwrap(),
std::ptr::null(),
std::ptr::null(),
&mut activate_ptrs,
&mut activate_ptr_count,
);
if res.is_ok() {
println!("MFTEnumEx succeeded, {} MFTs returned!", activate_ptr_count);
//call release on every IMFActivate pointer
for i in 0..activate_ptr_count {
let maybe_activate = &mut *activate_ptrs.add(i as usize);
if let Some(activate) = maybe_activate {
drop(activate);
}
}
CoTaskMemFree(activate_ptrs as *const std::ffi::c_void);
println!("Freed activate_ptrs");
}
let res = MFShutdown();
assert_eq!(res.is_ok(), true);
} else {
println!("{:?}", res.err());
}
}
Ok(())
}
I'm having trouble with the
MFTEnumExfunction. It's documentation says that I'm supposed to callReleaseon each of the returnedIMFActivatepointers, which as far as I could tell is aDropimpl on::windows::core::IUnknown(there are no methods to call explicitly like in C++).I was a bit confused getting this to compile at all, in particular the
maybe_activateline; there's some stuff going on with references that I don't fully understand, but just dereferencing the pointer without borowing resulted in a move which didn't compile becauseOption<IMFActivate>does not implementCopy.As you can see I'm calling drop on whatever I get out of the array, though I suspect this is incorrect. If I place a breakpoint on
IUnknown'sDropfunction, it is not hit. So I guess I'm freeing the reference (a no-op) instead of theIMFActivateobject that I'm supposed to free.Can anyone explain how to use this function correctly?