【问题标题】:IMFTransform interface of Color Converter DSP giving E_INVALIDARG on SetInputType/SetOutputTypeColor Converter DSP 的 IMFTransform 接口在 SetInputType/SetOutputType 上给出 E_INVALIDARG
【发布时间】:2013-03-11 14:26:45
【问题描述】:

我正在尝试使用 Color Converter DMO (http://msdn.microsoft.com/en-us/library/windows/desktop/ff819079(v=vs.85).aspx) 通过 Media Foundation 将 RBG24 转换为 YV12/NV12。我通过 CLSID_CColorConvertDMO 创建了颜色转换器 DSP 的实例,然后尝试设置所需的输入/输出类型,但即使使用 GetOutputAvailableTypeGetInputAvailableType 返回的媒体类型,调用也总是返回 E_INVALIDARG。如果我将媒体类型设置为NULL,那么我会收到媒体类型无效的错误,这是有道理的。我从 MSDN 看到了一些例子,人们也这样做——枚举可用类型,然后将它们设置为输入类型——他们声称它有效,但我有点卡在 E_INVALIDARG 上。我知道如果没有代码示例,这很难回答,如果没有人有类似的经历,我会尝试发布一个片段,但也许有人遇到过同样的问题?

【问题讨论】:

    标签: winapi visual-c++ video ms-media-foundation


    【解决方案1】:

    此 DMO/DSP 是双接口的,既是带有 IMediaObject 的 DMO,又是带有 IMFTransform 的 MFT。这两个接口有很多共同点,这里有一段代码sn-p来测试初始化​​RGB24到YV12的转换:

    #include "stdafx.h"
    #include <dshow.h>
    #include <dmo.h>
    #include <wmcodecdsp.h>
    
    #pragma comment(lib, "strmiids.lib")
    #pragma comment(lib, "wmcodecdspuuid.lib")
    
    int _tmain(int argc, _TCHAR* argv[])
    {
        ATLVERIFY(SUCCEEDED(CoInitialize(NULL)));
        CComPtr<IMediaObject> pMediaObject;
        ATLVERIFY(SUCCEEDED(pMediaObject.CoCreateInstance(CLSID_CColorConvertDMO)));
        VIDEOINFOHEADER InputVideoInfoHeader;
        ZeroMemory(&InputVideoInfoHeader, sizeof InputVideoInfoHeader);
        InputVideoInfoHeader.bmiHeader.biSize = sizeof InputVideoInfoHeader.bmiHeader;
        InputVideoInfoHeader.bmiHeader.biWidth = 1920;
        InputVideoInfoHeader.bmiHeader.biHeight = 1080;
        InputVideoInfoHeader.bmiHeader.biPlanes = 1;
        InputVideoInfoHeader.bmiHeader.biBitCount = 24;
        InputVideoInfoHeader.bmiHeader.biCompression = BI_RGB;
        InputVideoInfoHeader.bmiHeader.biSizeImage = 1080 * (1920 * 3);
        DMO_MEDIA_TYPE InputMediaType;
        ZeroMemory(&InputMediaType, sizeof InputMediaType);
        InputMediaType.majortype = MEDIATYPE_Video;
        InputMediaType.subtype = MEDIASUBTYPE_RGB24;
        InputMediaType.bFixedSizeSamples = TRUE;
        InputMediaType.bTemporalCompression = FALSE;
        InputMediaType.lSampleSize = InputVideoInfoHeader.bmiHeader.biSizeImage;
        InputMediaType.formattype = FORMAT_VideoInfo;
        InputMediaType.cbFormat = sizeof InputVideoInfoHeader;
        InputMediaType.pbFormat = (BYTE*) &InputVideoInfoHeader;
        const HRESULT nSetInputTypeResult = pMediaObject->SetInputType(0, &InputMediaType, 0);
        _tprintf(_T("nSetInputTypeResult 0x%08x\n"), nSetInputTypeResult);
        VIDEOINFOHEADER OutputVideoInfoHeader = InputVideoInfoHeader;
        OutputVideoInfoHeader.bmiHeader.biBitCount = 12;
        OutputVideoInfoHeader.bmiHeader.biCompression = MAKEFOURCC('Y', 'V', '1', '2');
        OutputVideoInfoHeader.bmiHeader.biSizeImage = 1080 * 1920 * 12 / 8;
        DMO_MEDIA_TYPE OutputMediaType = InputMediaType;
        OutputMediaType.subtype = MEDIASUBTYPE_YV12;
        OutputMediaType.lSampleSize = OutputVideoInfoHeader.bmiHeader.biSizeImage;
        OutputMediaType.cbFormat = sizeof OutputVideoInfoHeader;
        OutputMediaType.pbFormat = (BYTE*) &OutputVideoInfoHeader;
        const HRESULT nSetOutputTypeResult = pMediaObject->SetOutputType(0, &OutputMediaType, 0);
        _tprintf(_T("nSetOutputTypeResult 0x%08x\n"), nSetOutputTypeResult);
        // TODO: ProcessInput, ProcessOutput
        pMediaObject.Release();
        CoUninitialize();
        return 0;
    }
    

    这应该可以正常工作并打印两个S_OKs ...

    【讨论】:

    • 由于这行得通,我使用MFInitMediaTypeFromAMMediaType 创建了相应的IMFMediaType,并与我传入的内容和GetInputAvailableType 返回的内容进行了比较-似乎对于媒体基金会设置的可用类型只有视频类型,但错过了一些参数,如隔行扫描、步幅等。希望这对其他人也有帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-03
    • 2012-01-17
    • 2013-02-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多