Режим vmr без окон

[Функция, связанная с этой страницей DirectShow, является устаревшей функцией. Он был заменен MediaPlayer, IMFMediaEngine, и аудио/ видео захвата в Media Foundation. Эти функции оптимизированы для Windows 10 и Windows 11. Корпорация Майкрософт настоятельно рекомендует, чтобы новый код использовал MediaPlayer, IMFMediaEngine и аудио- и видеозахват в Media Foundation вместо DirectShow, когда это возможно. Корпорация Майкрософт предлагает переписать существующий код, использующий устаревшие API, чтобы по возможности использовать новые API.]

Режим без окон является предпочтительным для приложений способом отрисовки видео в окне приложения. В режиме без окон отрисовщик микширования видео не загружает компонент Диспетчера окон и поэтому не поддерживает интерфейсы IBasicVideo или IVideoWindow . Вместо этого приложение предоставляет окно воспроизведения и задает целевой прямоугольник в клиентской области для виртуальной машины для рисования видео. VmR использует объект clipper DirectDraw, чтобы убедиться, что видео обрезается в окне приложения и не отображается в других окнах. VMR не содержит подкласс окна приложения и не устанавливает какие-либо системные или процессные обработчики.

В режиме без окон последовательность событий во время подключения и перехода в состояние выполнения выглядит следующим образом:

  • Фильтр вышестоящий предлагает тип носителя, который vmr принимает или отклоняет.
  • Если тип носителя принимается, VMR вызывает распределителя-докладчика, чтобы получить поверхность DirectDraw. Если поверхность успешно создана, контакты подключаются, и VMR готова к переходу в состояние выполнения.
  • При запуске графа фильтра декодер вызывает GetBuffer , чтобы получить образец мультимедиа из распределителя. VMR запрашивает распределителя и докладчика, чтобы убедиться, что глубина пикселей, размер прямоугольника и другие параметры на его поверхности DirectDraw совместимы с входящим видео. Если они совместимы, VMR возвращает поверхность DirectDraw декодеру. После декодирования декодера на поверхность базовая единица синхронизации ВИРТУАЛЬНОй машины проверяет метки времени. Этот урок блокирует вызов Receive до тех пор, пока не поступит время презентации. На этом этапе VMR вызывает PresentImage для распределителя-докладчика, который представляет поверхность графическому карта.

На следующем рисунке показана виртуальная машина в режиме без окон с несколькими входными потоками.

vmr в режиме без окон

Настройка VMR-7 для режима без окон

Чтобы настроить VMR-7 для режима без окон, выполните все следующие действия перед подключением любых входных контактов VMR:

  1. Создайте фильтр и добавьте его в граф.

  2. Вызовите метод IVMRFilterConfig::SetRenderingMode с флагом VMRMode_Windowless.

  3. При необходимости настройте VMR для нескольких входных потоков, вызвав IVMRFilterConfig::SetNumberOfStreams. VMR создает входной контакт для каждого потока. Используйте интерфейс IVMRMixerControl , чтобы задать Z-порядок и другие параметры для потока. Дополнительные сведения см. в статье VMR с несколькими потоками (режим микширования).

    Если вы не вызываете SetNumberOfStreams, VMR-7 по умолчанию будет использовать один входной контакт. После подключения входных контактов количество контактов изменить нельзя.

  4. Вызовите IVMRWindowlessControl::SetVideoClippingWindow, чтобы указать окно, в котором будет отображаться отрисованное видео.

После выполнения этих действий можно подключить входные контакты фильтра VMR. Существует несколько способов построения графа, например подключение контактов напрямую, использование методов Intelligent Connect, таких как IGraphBuilder::RenderFile, или метод ICaptureGraphBuilder2::RenderStream для Захвата Graph Builder. Дополнительные сведения см. в разделе Общие методы 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;
}

Использование режима без окон