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

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

Примечание

Устаревший фильтр отрисовщика видео всегда использует оконный режим. Фильтры VMR-7 и VMR-9 по умолчанию используют оконный режим, но также поддерживают режим без окон.

 

В оконном режиме отрисовщик видео создает собственное окно, в котором закрашивает видеокадры. Если не указано иное, это окно является окном верхнего уровня с собственными границами и строкой заголовка. Однако в большинстве случаев вы будете присоединять окно видео к окну приложения, чтобы видео было интегрировано в пользовательский интерфейс приложения. Для этого необходимо выполнить следующие действия:

  1. Запрос IVideoWindow.
  2. Задайте родительское окно.
  3. Настройка новых стилей окна.
  4. Расположите окно видео в окне владельца.
  5. Уведомлять окно видео о WM_MOVE сообщениях.

Запрос для IVideoWindow

Перед началом воспроизведения запросите в диспетчере фильтров Graph интерфейс IVideoWindow :

IVideoWindow *pVidWin = NULL;
pGraph->QueryInterface(IID_IVideoWindow, (void **)&pVidWin);

Установка родительского окна

Чтобы задать родительское окно, вызовите метод IVideoWindow::p ut_Owner с дескриптором в окне приложения. Этот метод принимает переменную типа OAHWND, поэтому приведите дескриптор к этому типу:

pVidWin->put_Owner((OAHWND)hwnd);

Настройка новых стилей окна

Измените стиль окна видео, вызвав метод IVideoWindow::p ut_WindowStyle :

pVidWin->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS);

Флаг WS_CHILD задает для окна дочернее окно, а флаг WS_CLIPSIBLINGS не позволяет рисовать окно в клиентской области другого дочернего окна.

Расположение окна видео

Чтобы задать положение видео относительно клиентской области окна приложения, вызовите метод IVideoWindow::SetWindowPosition . Этот метод принимает прямоугольник, указывающий левый край, верхний край, ширину и высоту окна видео. Например, следующий код растягивает окно видео в соответствии со всей клиентской областью родительского окна:

RECT rc;
GetClientRect(hwnd, &rc);
pVidWin->SetWindowPosition(0, 0, rc.right, rc.bottom);

Чтобы получить собственный размер видео, вызовите метод IBasicVideo::GetVideoSize в диспетчере фильтров Graph. Эти сведения можно использовать для масштабирования видео и сохранения правильной пропорции.

Ответ на сообщения WM_MOVE

Для оптимальной производительности следует уведомлять отрисовщик видео всякий раз, когда окно перемещается во время приостановки графа. Вызовите метод IVideoWindow::NotifyOwnerMessage , чтобы переслать сообщение WM_MOVE:

// (Inside your WindowProc)
case WM_MOVE:
    pVidWin->NotifyOwnerMessage((OAHWND)hWnd, msg, wParam, lParam);
    break;

Если отрисовщик использует аппаратное наложение, это уведомление приводит к тому, что отрисовщик обновит положение наложения. (VMR-9 не использует наложения, поэтому не нужно вызывать этот метод, если используется VMR-9.)

Очистка

Перед завершением работы приложения остановите граф и сбросьте владельцу окна видео значение NULL. В противном случае сообщения окна могут быть отправлены в неправильное окно, что, скорее всего, приведет к ошибкам. Кроме того, скройте окно видео, иначе вы можете увидеть мгновенное мерцание видео на экране:

pControl->Stop(); 
pVidWin->put_Visible(OAFALSE);
pVidWin->put_Owner(NULL);  

Примечание

Если родительский элемент окна видео является дочерним для окна приложения main (другими словами, если видеоокно является дочерним), необходимо создать видеоокно с помощью CoCreateInstance и добавить его в граф, а не разрешать диспетчеру фильтров graph добавлять видео отрисовщик во время Intelligent Connect. Это гарантирует, что окно видео и дочернее окно будут перерисованы одновременно. В противном случае дочернее окно может закрасить окно видео.

 

Рендеринг видео