Я читаю файл mp4 (код H264 c) асинхронно, и я настраивал соответствующие параметры раньше, но когда я, наконец, передаю образец через CopyResource в целевую общую разделяемую текстуру, он всегда терпит неудачу, как показано ниже.
D3D11 ERROR: ID3D11DeviceContext::CopyResource: Cannot invoke CopyResource when the Formats of each Resource are not the same or at least castable to each other, unless one format is compressed (DXGI_FORMAT_R9G9B9E5_SHAREDEXP, or DXGI_FORMAT_BC[1,2,3,4,5]_* ) and the source format is similar to the dest according to: BC[1|4] ~= R16G16B16A16|R32G32, BC[2|3|5] ~= R32G32B32A32, R9G9B9E5_SHAREDEXP ~= R32. [ RESOURCE_MANIPULATION ERROR #284: COPYRESOURCE_INVALIDSOURCE]
Если я укажу MF_MT_SUBTYPE / MF_MT_FRAME_SIZE / MF_MT_FRAME_RATE и т. Д., Они действительно могут вступить в силу? Или я должен реализовать CResizerDMO, CColorConvertDMO, CFrameRateConvertDMO и так далее шаг за шагом? Я вижу, что IMFSinkWriter, кажется, способен достичь цели, пока эти параметры настроены.
HRESULT CAsyncFileReader::StartAsyncRead(PCWSTR pszURL)
{
CComPtr<IMFAttributes> pAttributes = NULL;
HRESULT hr = MFCreateAttributes(&pAttributes, 5);
RETURN_ON_FAIL(hr);
hr = pAttributes->SetUnknown(MF_SOURCE_READER_ASYNC_CALLBACK, this);
RETURN_ON_FAIL(hr);
hr = pAttributes->SetUnknown(MF_SOURCE_READER_D3D_MANAGER, _dxgi_device_manager);
RETURN_ON_FAIL(hr);
hr = pAttributes->SetUINT32(MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, TRUE);
RETURN_ON_FAIL(hr);
hr = pAttributes->SetUINT32(MF_LOW_LATENCY, 1);
RETURN_ON_FAIL(hr);
//MF_SOURCE_READER_ENABLE_VIDEO_PROCESSING (version < win8)
hr = pAttributes->SetUINT32(MF_SOURCE_READER_ENABLE_ADVANCED_VIDEO_PROCESSING, TRUE);
RETURN_ON_FAIL(hr);
hr = MFCreateSourceReaderFromURL(pszURL, pAttributes, &m_pReader);
RETURN_ON_FAIL(hr);
CComPtr<IMFMediaType> pType = NULL;
hr = m_pReader->GetNativeMediaType((DWORD)MF_SOURCE_READER_FIRST_VIDEO_STREAM, 0, &pType);
RETURN_ON_FAIL(hr);
hr = pType->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_RGB32);
MFSetAttributeSize(pType, MF_MT_FRAME_SIZE, Capture_Width, Capture_Height);
hr = m_pReader->SetCurrentMediaType((DWORD)MF_SOURCE_READER_FIRST_VIDEO_STREAM, NULL, pType);
RETURN_ON_FAIL(hr);
...
}
//called by OnReadSample callback
HRESULT CAsyncFileReader::Copy2Texture(IMFSample* sample)
{
CComPtr<IMFMediaBuffer> buffer;
HRESULT hr = sample->GetBufferByIndex(0, &buffer);
if (SUCCEEDED(hr))
{
CComPtr<IMFDXGIBuffer> dxgiBuffer;
hr = buffer->QueryInterface(IID_PPV_ARGS(&dxgiBuffer));
if (SUCCEEDED(hr))
{
CComPtr<ID3D11Texture2D> texture;
hr = dxgiBuffer->GetResource(IID_PPV_ARGS(&texture));
if (SUCCEEDED(hr))
{
// unsigned int subresource = 0;
// hr = dxgiBuffer->GetSubresourceIndex(&subresource);
if (SUCCEEDED(hr))
{
CComPtr<ID3D11DeviceContext> immediate_context;
_d3d_device->GetImmediateContext(&immediate_context);
//tbd, AcquireSync need restore if failed under certain conditions
UINT64 key = AllocKey();
hr = _dxgi_keyed_mutex->AcquireSync(key, 10);
RETURN_ON_FAIL(hr);
immediate_context->CopyResource(_shared_texture2d, texture); <-------mftrace as above
//immediate_context->CopySubresourceRegion(_shared_texture2d, 0, 0, 0, 0, texture, subresource, nullptr);
hr = _dxgi_keyed_mutex->ReleaseSync(key + 1);
RETURN_ON_FAIL(hr);
}
}
}
}
return hr;
}
HRESULT CreateSharedD3D11Texture2D(ID3D11Device* d3d11_device, const UINT32& w, const UINT32& h, ID3D11Texture2D** d3d11_texture_2d)
{
D3D11_TEXTURE2D_DESC texDesc;
texDesc.ArraySize = 1;
texDesc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
texDesc.CPUAccessFlags = 0;
texDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
texDesc.Width = w;
texDesc.Height = h;
texDesc.MipLevels = 1;
texDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX;
texDesc.Usage = D3D11_USAGE_DEFAULT;
texDesc.SampleDesc.Count = 1;
texDesc.SampleDesc.Quality = 0;
texDesc.Usage = D3D11_USAGE_DEFAULT;
return d3d11_device->CreateTexture2D(&texDesc, nullptr, d3d11_texture_2d);
}
Кроме того, текстура DXGI_FORMAT_B8G8R8A8_UNORM эквивалентна MFVideoFormat_RGB32, верно?