DxDev.narod.ru

Вывод видео на поверхность DirectX

Здесь хочу рассказать как сопоставить видео поток с поверхностью Direct3D.

DirectShow работает с медиа данными с помощью построителя графов GraphBuilder. GraphBuilder добавляет фильтр для нужной работы с медиа файлом

  IBaseFilter *pBaseFilter
  GraphBuilder->AddFilter(pBaseFilter);
и загружает медиа файл
  GraphBuilder->RenderFile("wFileName.avi”). 

Play Stop и Pause медиа файла получаем из ImediaControl который запрашиваем из GraphBuilder

  pGraphBuilder->QueryInterface(IID_IMediaControl, reinterpret_cast<void**>(&m_pMediaControl));

Теперь собственнно о медиа в сурфейс. Как было сказано GraphBuilder адд-ит фильтр к-рый мы настроили для нужной нам работы. В нашем случае создаётся VMR9 фильтр

  CComPtr pFilterVMR9
  pFilterVMR9.CoCreateInstance(CLSID_VideoMixingRenderer9, NULL, CLSCTX_INPROC_SERVER);

способный управлять аппаратными средствами Direct3D (ну а первоначальная версия 7 для DirectDraw) т.е. мы можем получить доступ к поверхности IDirect3DSurface9.

Запросим интерфейс IVMRSurfaceAllocatorNotify9 для реализации VMR9:

  IVMRSurfaceAllocatorNotify9 *pIVMRSurfAllocNotify;
  pFilterVMR9->QueryInterface(IID_IVMRSurfaceAllocatorNotify9,
				reinterpret_cast<void**>(&pIVMRSurfAllocNotify));

IVMRSurfaceAllocatorNotify9::AdviseSurfaceAllocator() создаст объект allocator-presenter для указания VMR-у использовать этот объект во время работы с сурфейсами

  pIVMRSurfAllocNotify->AdviseSurfaceAllocator( UserID, pVMRSurfaceAllocator);

А allocator-presenter в свою очередь вызовет AdviseNotify с указателем IVMRSurfaceAllocatorNotify9

  pVMRSurfaceAllocator->AdviseNotify(pIVMRSurfAllocNotify);

Последние два шага устанавливают взаимодействие между VMR и allocator-presenter.

И как только мы этот фильтр добавим к GraphBuilder-у и загрузим медиа файл управление получит метод объекта allocator-presenter AdviseNotify. Объект cоздан на базе IVMRSurfaceAllocator9 и IVMRImagePresenter9
Он содержит методы реализующие управления аппаратными средствами Direct3D парой VMR и allocator-presenter:

1. InitializeDevise создаёт поверхность размерами полученными из входной структуры VMR9AllocationInfo

  VMR9AllocationInfo *lpAllocInfo; // in parametr
  pIVMRSurfaceAllocatorNotify9->AllocateSurfaceHelper
			(lpAllocInfo, lpNumBuffers, &pd3dSurface );

2. AdviseNotify устанавливает устройство д3д

  HMONITOR hMonitor = pD3D->GetAdapterMonitor(D3DADAPTER_DEFAULT);
  pIVMRSurfaceAllocatorNotify9->SetD3DDevice(pd3dDevice, hMonitor);

3. GetSurface() здесь VMR9 получает сурфейс от allocator-presenter

4. PresentHelper() здесь VMR9 указывает allocator-presenter-у обработать сурфейс как видео фрейм



Источник: сэмпл DirectX SDK: DirectX 9.0\Samples\C++\DirectShow\VMR9\VMR9Allocator.

Hosted by uCoz