Am I unable to obtain raw MJPEG data from the Media Foundation mfcaptureengine?

why so many error 21 信誉分
2025-02-28T03:09:45.0333333+00:00

I have a UVC device that outputs in YUV and MJPEG formats. I am trying to capture data in both formats,I can successfully obtain YUV data, but I fail to capture MJPEG data.

The StartPreview call asynchronously returns an error: No suitable transform was found to encode or decode the content,Is it that mfcaptureengine cannot output compressed formats?Thank you very much for any answers and help

用户的图像

This is Set Device MediaType:

bool CameraClass::SetCurMediaType(MediaTypeInfoEx Type)
{
    MediaTypeInfoEx Out;
    if (!DeviceIsOpen())
    {
        return false;
    }
    HRESULT hr = S_OK;
    DWORD dwIndex = 0;
    IMFMediaType* pMediaType = NULL;
    IMFMediaType* pMediaType2 = NULL;
    ComPtr < IMFCaptureSink> pSink = NULL;
    // 获取第一个视频流的媒体类型
    hr = CaptureSource->GetCurrentDeviceMediaType(
        MF_CAPTURE_ENGINE_PREFERRED_SOURCE_STREAM_FOR_VIDEO_PREVIEW, // 第一个视频流
        &pMediaType                                // 接收媒体类型
    );
    while (SUCCEEDED(hr))
    {
        // 获取第一个视频流的媒体类型
        hr = CaptureSource->GetAvailableDeviceMediaType(
            MF_CAPTURE_ENGINE_PREFERRED_SOURCE_STREAM_FOR_VIDEO_PREVIEW, // 第一个视频流
            dwIndex,                                     // 媒体类型索引
            &pMediaType                                  // 接收媒体类型
        );
        if (SUCCEEDED(hr)) {
            // 输出媒体类型信息
            UINT32 numerator = 0, denominator = 0;
            GUID majorType, subtype, AmFormat;
            if (SUCCEEDED(pMediaType->GetGUID(MF_MT_MAJOR_TYPE, &majorType)) &&
                SUCCEEDED(pMediaType->GetGUID(MF_MT_SUBTYPE, &subtype)))
            {
                if (subtype == GetGUIDFromMediaTypeEnum(Type.TypeInfo.MediaType))
                {
                    UINT32 Width, height;
                    MFGetAttributeSize(pMediaType, MF_MT_FRAME_SIZE, &Width, &height);
                    if (Width == Type.TypeInfo.Width && height == Type.TypeInfo.Height)
                    {
                        break;
                    }
                }
            }
            // 准备下一个索引
            dwIndex++;
        }
    }
    hr = CaptureSource->SetCurrentDeviceMediaType(
        MF_CAPTURE_ENGINE_PREFERRED_SOURCE_STREAM_FOR_VIDEO_PREVIEW, // 第一个视频流
        pMediaType                                // 接收媒体类型
    );
    SafeRelease(&pMediaType);
    SafeRelease(&pMediaType2);
    UserMediaType = Type;
    return SUCCEEDED(hr);
}

this is StartPrevie

HRESULT CameraClass::StartPrevie()
{

    
    HRESULT hr = S_OK;
    hr = PreviewSink->RemoveAllStreams();
    if (!DeviceIsOpen())
    {
        return E_FAIL;
    }



    
    // Get a pointer to the preview sink.

   // hr = spCaptureEngine->GetSink(MF_CAPTURE_ENGINE_SINK_TYPE_PREVIEW, &PreviewSink);
    if (FAILED(hr))
    {
        return false;
    }
    IMFMediaType* pMediaType = NULL;
    IMFMediaType* pMediaType2 = NULL;
    DWORD Num;
    CaptureSource->GetDeviceStreamCount(&Num);
    // 获取第一个视频流的媒体类型
    hr = CaptureSource->GetCurrentDeviceMediaType(
        MF_CAPTURE_ENGINE_PREFERRED_SOURCE_STREAM_FOR_VIDEO_PREVIEW, // 第一个视频流
        &pMediaType                                // 接收媒体类型
    );
    
    if (!UserMediaType.TypeInfo.IsUnDefine())
    {
        hr = CloneVideoMediaType(pMediaType, UserMediaType.TypeInfo.GetMediaTypeGUID(), &pMediaType2);
        MFSetAttributeSize(pMediaType2, MF_MT_FRAME_SIZE, UserMediaType.TypeInfo.Width, UserMediaType.TypeInfo.Height);
        if (UserMediaType.CurFps > 0)
        {
            MFSetAttributeRatio(pMediaType2, MF_MT_FRAME_RATE, UserMediaType.CurFps, 1);
        }
        //pMediaType2->SetGUID(MF_MT_SUBTYPE, MEDIASUBTYPE_MJPG);
        hr = PreviewSink->AddStream(MF_CAPTURE_ENGINE_PREFERRED_SOURCE_STREAM_FOR_VIDEO_PREVIEW, pMediaType2, NULL, &StreamIndex);
        IMFCaptureSink2* Sink2;
        //PreviewSink->QueryInterface(IID_PPV_ARGS(&Sink2));
        //hr = Sink2->SetOutputMediaType(StreamIndex, pMediaType2, NULL);
    }
    else
    {

        hr = PreviewSink->AddStream(MF_CAPTURE_ENGINE_PREFERRED_SOURCE_STREAM_FOR_VIDEO_PREVIEW, pMediaType, NULL, &StreamIndex);
    }
    


    hr= PreviewSink->SetSampleCallback(StreamIndex, CallbackObj.Get());
    CurMediaType = MediaTypeInfoEx::FromMFMeidiaType(pMediaType);

    SafeRelease(&pMediaType);
    SafeRelease(&pMediaType2);
    hr = spCaptureEngine->StartPreview();
    if (SUCCEEDED(hr))
    {
        isPrevie = true;
    }
    return hr;
}

Windows API - Win32
Windows API - Win32
一组适用于桌面和服务器应用程序的核心 Windows 应用程序编程接口 (API)。 以前称为 Win32 API。
135 个问题
0 个注释 无注释
{count} 票

1 个答案

排序依据: 非常有帮助
  1. Jeanine Zhang-MSFT 10,856 信誉分 Microsoft External Staff
    2025-02-28T08:22:12.84+00:00

    你好,

    欢迎来到Q&A winapi中文论坛, 在这里你可以使用中文来描述你的问题。

    Microsoft Media Foundation 支持音频和视频捕获。视频捕获设备通过 UVC 类驱动程序受支持捕获设备在 Media Foundation 中由媒体源对象表示。媒体源是生成媒体数据的对象。

    IMFCaptureEngine用来控制一个或多个捕获设备。旨在捕获原始数据,本身并不包含编码器或者解码器,所以我认为IMFCaptureEngine不能输出压缩格式。你可以使用源读取器来控制捕获设备。如果媒体源提供压缩数据,则可以使用源读取器解码数据。 在这种情况下,源读取器将加载正确的解码器,并管理媒体源和解码器之间的数据流。

    Jeanine

    Thank you

    0 个注释 无注释

你的答案

问题作者可以将答案标记为“接受的答案”,这有助于用户了解已解决作者问题的答案。