【问题标题】:QueryInterface on IMFMediaBuffer to IMFDXGIBuffer returns E_NOINTERFACEIMFMediaBuffer 到 IMFDXGIBuffer 上的 QueryInterface 返回 E_NOINTERFACE
【发布时间】:2021-08-22 23:02:06
【问题描述】:

我有一个函数将IMFSample 指针作为参数。我能够成功地将其转换为 IMFMediaBuffer 对象。但是,当我为 IMFMediaBuffer 对象上的 IMFDXGIBuffer 调用 QueryInterface 时,返回的 HRESULTE_NOINTERFACE

这是发生这种情况的方法的一个非常基本的版本(作为参考,真正的功能基于 Microsoft 的 DX11VideoRenderer 项目中的 CPresenter::ProcessFrame 方法)。

HRESULT TPresenter::ProcessFrame(IMFMediaType* pCurrentType, IMFSample* pSample, UINT32* punInterlaceMode, BOOL* pbDeviceChanged, IMFSample** ppOutputSample)
{
    TObject::ThreadLock();

    // Code to Check Shutdown and pointers

    *pbDeviceChanged = FALSE;
    DWORD cBuffers = 0;
    HRESULT res = pSample->GetBufferCount(&cBuffers);

    if (FAILED(res))
    {
        TObject::ThreadRelease();
        return res;
    }
    IMFMediaBuffer* pBuffer = nullptr;
    IMFMediaBuffer* pEVBuffer = nullptr;
    if (1 == cBuffers)
    {
        res = pSample->GetBufferByIndex(0, &pBuffer);
    }
    else
        res = pSample->ConvertToContiguousBuffer(&pBuffer);

    // Code to Check Interlace mode

    // Code to get the Device and Device Context for Direct3D

    IMFDXGIBuffer* mfdxgiBuff = nullptr;
    ID3D11Texture2D* d3dText = nullptr;
    UINT resourceIndex = 0;
    res = pBuffer.QueryInterface<IMFDXGIBuffer>(&mfdxgiBuff);      // Currently returns E_NOINTERFACE
    if (SUCCEEDED(res))
        res = mfdxgiBuff->QueryInterface<ID3D11Texture2D>(&d3dText);
    if (SUCCEEDED(res))
        res = mfdxgiBuff->GetSubresourceIndex(&resourceIndex);
    if (FAILED(res))
    {
        ThreadRelease();
        return res;
    }

    // Continues on
}

操作系统:Windows 10 家庭版(20H2 版)

VS:社区 2019(版本 16.10.0)

我所看到的与从IMFMediaBuffer 获取IMFDXGIBuffer 相关的每个资源都在说要使用QueryInterface 方法。媒体基金会是否有可能更新了有关此程序的要求(我们必须这样做的新方法)?或者有什么我应该告诉媒体基金会的,这样当提供这些样本时,IMFDXGIBuffer 是可用的?

【问题讨论】:

    标签: c++ visual-c++ com ms-media-foundation direct3d11


    【解决方案1】:

    您看到的是设计行为。

    一些缓冲区由系统内存支持,其他缓冲区由 D3D11 2D 纹理支持。您假设输入是一个纹理,而实际上它是一个普通的内存缓冲区。

    您需要一个单独的代码路径来处理这种情况(或者您可能有一个额外的转换,可能包括第三方转换,将数据上传到视频内存并确保样本由纹理支持)。

    【讨论】:

    • 我已经对此进行了大量研究,现在看来添加一个 Transform 节点是更好的选择。但是,是否有我应该使用的内置转换,或者我应该考虑实现自己的转换?我真的认为应该有一个内置的,但要找到一个支持 Direct3D 11 的东西是难以捉摸的。
    • 没有这种内置的 MFT。
    • 但是应该可以编写一个转换,其唯一的工作就是接收样本并确保输出样本有一个支持它们的表面?您是否预见到任何陷阱(我应该知道)?
    • 这是可能的,应该可以解决。
    猜你喜欢
    • 2021-08-17
    • 2012-01-04
    • 1970-01-01
    • 2012-01-15
    • 1970-01-01
    • 2021-03-15
    • 1970-01-01
    • 2010-12-19
    • 2016-07-10
    相关资源
    最近更新 更多