Media Foundation: got error when tried to create stream reader by following media source and non attributes

can someone help me please with winapi, media foundation particularly? the following list crashes at line 69 (located by shot in the dark) and I have no idea why.

https://gist.github.com/exldna/6efe8c43349c3b45e8a4d860c3fab5c8

[dependencies]
text_io = "0.1.12"
windows = { version = "0.58.0", features = [
    "Win32_System_Com",
    "Win32_Media_MediaFoundation",
    "Win32_Media_KernelStreaming",
] }
use windows::core::*;
use windows::Win32::Media::MediaFoundation::*;
use windows::Win32::System::Com::{CoInitializeEx, COINIT_MULTITHREADED};

fn main() -> Result<()> {
    unsafe {
        CoInitializeEx(None, COINIT_MULTITHREADED).ok()?;

        MFStartup(MF_VERSION, 0)?;

        let devices: &[Option<IMFActivate>];

        let mut attrs: Option<IMFAttributes> = None;
        MFCreateAttributes(&mut attrs, 1)?;
        let attrs = attrs.unwrap();

        attrs.SetGUID(
            &MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE,
            &MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_AUDCAP_GUID,
        )?;

        let chosen_device = {
            let mut devices_ptr: *mut Option<IMFActivate> = std::ptr::null_mut();
            let mut count: u32 = 0;
            MFEnumDeviceSources(&attrs, &mut devices_ptr, &mut count)?;

            devices = std::slice::from_raw_parts(std::mem::transmute(devices_ptr), count as usize);

            for (i, device) in devices.iter().enumerate() {
                if let Some(device) = device {
                    let mut name: PWSTR = PWSTR::null();
                    let mut name_len: u32 = 0;
                    device.GetAllocatedString(
                        &MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME,
                        &mut name,
                        &mut name_len,
                    )?;
                    println!("{i}: {}", name.display())
                }
            }

            let mut device_n: usize;
            loop {
                device_n = text_io::read!();
                if device_n < devices.len() {
                    break;
                }
                println!("Unexpected device");
            }

            devices[device_n].as_ref().unwrap()
        };

        let mut chosen_device_id: PWSTR = PWSTR::null();
        let mut _skip_parameter: u32 = 0;
        chosen_device.GetAllocatedString(
            &MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_AUDCAP_ENDPOINT_ID,
            &mut chosen_device_id,
            &mut _skip_parameter,
        )?;

        attrs.SetString(
            &MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_AUDCAP_ENDPOINT_ID,
            chosen_device_id,
        )?;

        let media_source = MFCreateDeviceSource(&attrs)?;

        let source_reader = MFCreateSourceReaderFromMediaSource(&media_source, None)?;
        
        let mut timestamp: i64 = 0;
        let mut sample: Option<IMFSample> = None;
        
        source_reader.ReadSample(
            MF_SOURCE_READER_FIRST_AUDIO_STREAM.0 as u32,
            0,
            None,
            None,
            Some(&mut timestamp),
            Some(&mut sample),
        )?;

        MFShutdown()?;
    }

    Ok(())
}

here is an error message:

Error: Error { code: HRESULT(0x80004003), message: "Invalid pointer" }

That what I've tried: Pass NULL, Empty Attributes and already existed attributes into MFCreateSourceReaderFromMediaSource. In every such case I walked with debugger and make sure that pointers were valid. I had some research into the official documentation and some other usage examples, but it still didn't help.

PS rust almost like c, particularly in unsafe mode, so if you know winapi, I think the problem is in api usage.

Upvotes: 0

Views: 61

Answers (0)

Related Questions