Режим без окон VMR
[Функция, связанная с этой страницей, DirectShow, является устаревшей функцией. Он был заменен MediaPlayer, IMFMediaEngineи аудио и видеозахват в Media Foundation. Эти функции оптимизированы для Windows 10 и Windows 11. Корпорация Майкрософт настоятельно рекомендует использовать новый код MediaPlayer, IMFMediaEngine и аудио-видеозахват в Media Foundation вместо DirectShowпо возможности. Корпорация Майкрософт предлагает, что существующий код, использующий устаревшие API, будет перезаписан для использования новых API, если это возможно.]
Режим без окон является предпочтительным способом отображения видео в окне приложения. В режиме без окон средство визуализации видео микширования не загружает свой компонент Диспетчера окон и поэтому не поддерживает интерфейсы IBasicVideo или IVideoWindow. Вместо этого приложение предоставляет окно воспроизведения и задает целевой прямоугольник в клиентской области для рисования видео виртуальной машины. VmR использует объект клиппера DirectDraw, чтобы убедиться, что видео обрезается в окне приложения и не отображается в других окнах. VmR не классифицирует окно приложения или устанавливает какие-либо системные или процессные перехватчики.
В режиме без окна последовательность событий во время подключения и переход к состоянию выполнения выглядит следующим образом:
- В вышестоящем фильтре предлагается тип носителя, который vmR принимает или отклоняет.
- Если тип носителя принимается, vmR вызывает объект allocator-докладчика для получения поверхности DirectDraw. Если поверхность создана успешно, контакты подключаются и vmR готовы перейти в состояние выполнения.
- При запуске графа фильтров декодировщик вызывает GetBuffer, чтобы получить образец носителя из распределителя. VmR запрашивает распределитель-выступающий, чтобы обеспечить совместимость пикселя глубины, прямоугольника и других параметров на поверхности DirectDraw с входящим видео. Если они совместимы, vmR возвращает поверхность DirectDraw декодатору. После декодирования декодировщика на поверхности модуль синхронизации VMR проверяет метки времени. Этот урок блокирует вызов получения до тех пор, пока не появится время презентации. На этом этапе VMR вызывает PresentImage на выступающих-распределителях, который представляет поверхность графической карточке.
На следующем рисунке показана виртуальная машина в режиме без окон с несколькими входными потоками.
Настройка vmR-7 для режима без окон
Чтобы настроить VMR-7 для режима без окон, выполните все следующие действия перед подключением любого из входных контактов VMR:
Создайте фильтр и добавьте его в граф.
Вызовите метод IVMRFilterConfig::SetRenderingMode с флагом VMRMode_Windowless.
При необходимости настройте VMR для нескольких входных потоков путем вызова IVMRFilterConfig::SetNumberOfStreams. VmR создает входной пин-код для каждого потока. Используйте интерфейс ivMRMixerControl, чтобы задать порядок Z и другие параметры для потока. Дополнительные сведения см. в VMR с несколькими потоками (режимом смешивания).
Если вы не вызываете SetNumberOfStreams, vmR-7 по умолчанию использует один входной пин-код. После подключения входных закреплений количество контактов невозможно изменить.
Вызовите IVMRWindowlessControl::SetVideoClippingWindow, чтобы указать окно, в котором будет отображаться отрисованное видео.
После завершения этих действий можно подключить входные закрепления фильтра VMR. Существует различные способы построения графа, например подключение пин-кодов напрямую с помощью методов Intelligent Connect, таких как IGraphBuilder::RenderFile, или использование метода ICaptureGraphBuilder2::RenderStream. Дополнительные сведения см. в разделе Общие методы Graph-Building.
Чтобы задать положение видео в окне приложения, вызовите метод IVMRWindowlessControl::SetVideoPosition. Метод IVMRWindowlessControl::GetNativeVideoSize возвращает собственный размер видео. Во время воспроизведения приложение должно уведомить VMR о следующих сообщениях Windows:
- WM_PAINT: вызовите IVMRWindowlessControl::RepaintVideo, чтобы перенаправить изображение.
- WM_DISPLAYCHANGE: вызов IVMRWindowlessControl::D isplayModeChanged. VMR выполняет любые действия, необходимые для отображения видео на новой глубине разрешения или цвета.
- WM_SIZE. Повторно вычислите положение видео и вызов SetVideoPosition при необходимости.
Заметка
Приложения MFC должны определять пустой обработчик сообщений WM_ERASEBKGND, а область отображения видео не будет правильно перенаправляться.
настройка vmR-9 для режима без окон
Чтобы настроить VMR-9 для режима без окон, выполните действия, описанные в vmR-7 для режима без окон, но используйте интерфейсы IVMRFilterConfig9 и IVMRWindowlessControl9. Единственное существенное различие заключается в том, что VMR-9 создает четыре входных пина по умолчанию, а не один входной пин-код. Поэтому необходимо вызывать только SetNumberOfStreams, если вы смешиваете более четырех видеопотоков.
пример кода
В следующем коде показано, как создать фильтр VMR-7, добавить его в граф фильтра DirectShow, а затем поместить vmR в режим без окон. Для VMR-9 используйте CLSID_VideoMixingRenderer9 в CoCreateInstance и соответствующие интерфейсы VMR-9.
HRESULT InitializeWindowlessVMR(
HWND hwndApp, // Application window.
IFilterGraph* pFG, // Pointer to the Filter Graph Manager.
IVMRWindowlessControl** ppWc, // Receives the interface.
DWORD dwNumStreams, // Number of streams to use.
BOOL fBlendAppImage // Are we alpha-blending a bitmap?
)
{
IBaseFilter* pVmr = NULL;
IVMRWindowlessControl* pWc = NULL;
*ppWc = NULL;
// Create the VMR and add it to the filter graph.
HRESULT hr = CoCreateInstance(CLSID_VideoMixingRenderer, NULL,
CLSCTX_INPROC, IID_IBaseFilter, (void**)&pVmr);
if (FAILED(hr))
{
return hr;
}
hr = pFG->AddFilter(pVmr, L"Video Mixing Renderer");
if (FAILED(hr))
{
pVmr->Release();
return hr;
}
// Set the rendering mode and number of streams.
IVMRFilterConfig* pConfig;
hr = pVmr->QueryInterface(IID_IVMRFilterConfig, (void**)&pConfig);
if (SUCCEEDED(hr))
{
pConfig->SetRenderingMode(VMRMode_Windowless);
// Set the VMR-7 to mixing mode if you want more than one video
// stream, or you want to mix a static bitmap over the video.
// (The VMR-9 defaults to mixing mode with four inputs.)
if (dwNumStreams > 1 || fBlendAppImage)
{
pConfig->SetNumberOfStreams(dwNumStreams);
}
pConfig->Release();
hr = pVmr->QueryInterface(IID_IVMRWindowlessControl, (void**)&pWc);
if (SUCCEEDED(hr))
{
pWc->SetVideoClippingWindow(hwndApp);
*ppWc = pWc; // The caller must release this interface.
}
}
pVmr->Release();
// Now the VMR can be connected to other filters.
return hr;
}
Связанные разделы