Я настраиваю VideoRenderer для своего приложения, которое использует интерфейсы Direct3D9Ex, но когда я использую большую текстуру (разрешение рабочего стола), видео начинает замедляться.
Я использовал DirectShow, но обнаружил некоторые проблемы сH264, и я решил пойти на Media Foundation.Я много об этом искал, но я не понял, как отобразить видео с помощью DXVA, и поэтому я читаю образец с помощью IMFSourceReader (Async), используя MF_SOURCE_READER_ENABLE_ADVANCED_VIDEO_PROCESSING и MFVideoFormat_RGB32, чтобы я мог скопировать его на мою поверхность, а затемсделать его нормальным.
Вот как я создаю SourceReader.
MFCreateAttributes(&m_Attributes, 4);
m_Attributes->SetUnknown(MF_SOURCE_READER_D3D_MANAGER, GRAPHICSDEVICE->GetDeviceManager());
m_Attributes->SetUnknown(MF_SOURCE_READER_ASYNC_CALLBACK, this);
m_Attributes->SetUINT32(MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, TRUE);
m_Attributes->SetUINT32(MF_SOURCE_READER_ENABLE_ADVANCED_VIDEO_PROCESSING, TRUE);
MFCreateSourceReaderFromURL(L"Video.mp4", m_Attributes, &m_SourceReader);
MFCreateMediaType(&m_MediaType);
MFSetAttributeSize(m_MediaType, MF_MT_FRAME_SIZE, m_VideoWidth, m_VideoHeight);
m_MediaType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video);
m_MediaType->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_RGB32);
Затем я публикую один ReadSample, и в моем методе Update я делаю это:
if (WaitForSingleObject(m_SampleEvent, 0) == WAIT_OBJECT_0)
{
if (m_SourceReader)
{
m_SourceReader->ReadSample(MF_SOURCE_READER_FIRST_VIDEO_STREAM, 0, nullptr, nullptr, nullptr, nullptr);
}
}
Это часть моего обратного вызова OnReadSample, который просто копирует одну поверхность на другую.
IDirect3DSurface9 * pSampleSurface = nullptr;
if (SUCCEEDED(GetD3DSurfaceFromSample(Sample, &pSampleSurface)))
{
D3DLOCKED_RECT SampleRect;
if (FAILED(pSampleSurface->LockRect(&SampleRect, nullptr, D3DLOCK_READONLY)))
{
pSampleSurface->Release();
goto Quit;
}
BYTE * pVideo = (BYTE*)SampleRect.pBits;
D3DLOCKED_RECT TextureRect;
if (FAILED(m_Texture->LockRect(0, &TextureRect, nullptr, D3DLOCK_DISCARD)))
{
pSampleSurface->UnlockRect();
pSampleSurface->Release();
goto Quit;
}
BYTE * pDest = (BYTE*)TextureRect.pBits;
for (unsigned int i = 0; i < m_VideoHeight; i++)
{
CopyMemory(pDest, pVideo, m_VideoWidth * 4);
pDest += TextureRect.Pitch;
pVideo += SampleRect.Pitch;
}
m_Texture->UnlockRect(0);
pSampleSurface->UnlockRect();
pSampleSurface->Release();
}
Итак, мои фактические результаты приемлемы для среды отладки, но когда я меняю разрешение своего приложения на настольное(от 800x600 до 1366x768) все становится намного медленнее.
Нужно ли использовать что-то в качестве DXVA?Могу ли я настроить текущий код, чтобы он работал быстрее?Где я могу найти хорошие образцы об этом?