Winapi IMFSourceReader硬件加速

Winapi IMFSourceReader硬件加速,winapi,video,direct3d,ms-media-foundation,dxgi,Winapi,Video,Direct3d,Ms Media Foundation,Dxgi,我正试图通过IMFSourceReader来加速视频解码 当我不用它时,一切都很好。当我使用它时,它不起作用。以下是步骤: 创建DirectX 11设备 HRESULT CreateDirectXDevice(IDXGIAdapter1* g, ID3D11Device** device, ID3D11DeviceContext** context) { HRESULT hr = S_OK; // Driver types supported D3D_DRIVER_TYPE DriverTyp

我正试图通过IMFSourceReader来加速视频解码

当我不用它时,一切都很好。当我使用它时,它不起作用。以下是步骤:

创建DirectX 11设备

HRESULT CreateDirectXDevice(IDXGIAdapter1* g, ID3D11Device** device, ID3D11DeviceContext** context)
{
HRESULT hr = S_OK;

// Driver types supported
D3D_DRIVER_TYPE DriverTypes[] =
{
    D3D_DRIVER_TYPE_HARDWARE,
    D3D_DRIVER_TYPE_WARP,
    D3D_DRIVER_TYPE_REFERENCE,
};
UINT NumDriverTypes = ARRAYSIZE(DriverTypes);

// Feature levels supported
D3D_FEATURE_LEVEL FeatureLevels[] =
{
    D3D_FEATURE_LEVEL_11_0,
    D3D_FEATURE_LEVEL_10_1,
    D3D_FEATURE_LEVEL_10_0,
    D3D_FEATURE_LEVEL_9_3,
    D3D_FEATURE_LEVEL_9_2,
    D3D_FEATURE_LEVEL_9_1
};
UINT NumFeatureLevels = ARRAYSIZE(FeatureLevels);

D3D_FEATURE_LEVEL FeatureLevel;

// Create device
for (UINT DriverTypeIndex = 0; DriverTypeIndex < NumDriverTypes; ++DriverTypeIndex)
{
    hr = D3D11CreateDevice(g, DriverTypes[DriverTypeIndex], nullptr, D3D11_CREATE_DEVICE_VIDEO_SUPPORT, FeatureLevels, NumFeatureLevels,
        D3D11_SDK_VERSION, device, &FeatureLevel, context);
    if (SUCCEEDED(hr))
    {
        // Device creation success, no need to loop anymore
        break;
    }
}
return hr;
}
HRESULT CreateDirectXDevice(IDXGIAdapter1*g,ID3D11Device**device,ID3D11DeviceContext**context)
{
HRESULT hr=S_正常;
//支持的驱动程序类型
D3D_驱动程序_类型驱动程序类型[]=
{
D3D_驱动器_类型_硬件,
D3D_驱动器_类型_翘曲,
D3D驱动程序类型参考,
};
UINT NumDriverTypes=阵列化(驱动器类型);
//支持的功能级别
D3D_功能_级别功能级别[]=
{
D3D_特征_等级_11_0,
D3D_功能_级别_10_1,
D3D_功能_级别_10_0,
D3D_功能_级别_9_3,
D3D_功能_级别_9_2,
D3D_功能_级别_9_1
};
UINT NumFeatureLevels=阵列化(FeatureLevels);
D3D_特征级特征级;
//创建设备
对于(UINT DriverTypeIndex=0;DriverTypeIndex
然后,创建源读取器:

HRESULT CreateSourceReader(const wchar_t* file, IMFSourceReader** r,bool Hw,bool D11)
{
    CComPtr<IMFAttributes> attrs;
    MFCreateAttributes(&attrs, 0);
    if (Hw)
        attrs->SetUINT32(MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, true);
    if (D11)
    {
            CComPtr<IMFDXGIDeviceManager > rr = 0;
            MFCreateDXGIDeviceManager(&dm9rt, &rr);
            rr->ResetDevice(GenericDirect3DDevice,dm9rt);
            attrs->SetUnknown(MF_SOURCE_READER_D3D_MANAGER,rr);
    }
    auto hr = MFCreateSourceReaderFromURL(f, attrs, r);
    return hr;
}
HRESULT CreateSourceReader(常量wchar\u t*文件,IMFSourceReader**r,bool Hw,bool D11)
{
会计科目;
MFCreateAttributes(&attrs,0);
如果(硬件)
属性->设置单元32(MF\u读写\u启用\u硬件\u转换,真);
如果(D11)
{
CComPtr rr=0;
MFCreateDXGIDeviceManager(&dm9rt和&rr);
rr->ResetDevice(通用Direct3DDevice,dm9rt);
属性->设置未知(MF\U源\U读卡器\U D3D\U管理器,rr);
}
auto hr=MFCreateSourceReaderFromURL(f,attrs,r);
返回人力资源;
}
之后,源读取器将不工作。当我尝试调整样本大小时,IMFTTransform resizer在SetInput()上崩溃。当我尝试将样本传递给接收器写入程序时,它会随机失败,有时会返回DXGI\u错误\u驱动程序\u内部错误/图形设备已删除(原因0X887A0020)

我做错了什么


非常感谢。

首先,您对创建带有标志的D3D设备感兴趣,这样您就可以在调试输出中看到与故障相关的提示

其次,我猜这个问题的根本原因是您没有使用接口启用多线程保护,请参见示例

D3DDevMT->setmulti-threadprotected(TRUE)

这是强制性的,因为媒体基金会的性质是多方面的,不受保护的,你很快就会受到腐败的影响。