CaptureManager SDK

в 12:20, , рубрики: C#, c++, python, видео

Эта статья представляет мой «Hobby» проект — CaptureManager для настольной платформы Windows. Этот проект является простым набором функционала (SDK) для включения поддержки широкого набора видео и аудио источников в разрабатываемое приложение.

CaptureManager построен на основе Microsoft Media Foundation — нового поколения медиа технологий, заменившем объявленное устаревшем DirectShow. Microsoft Media Foundation была впервые включена в Windows Vista и получила поддержку видео и аудио источников начиная с Windows 7. Достоинством Microsoft Media Foundation является новая модель конвейера обработки медиа данных, оптимальная для многопроцессорных систем, и продолжающееся её развитие, и поддержка со стороны Microsoft.
В проекте CaptureManager я хотел решить ряд проблем, с которыми столкнулся при написании приложений с использованием Microsoft Media Foundation:

  1. Реализация СОМ функционала. Как-бы странно это не звучало, но с технологией Microsoft Media Foundation корпорация Microsoft отступила от своей-же модели приложений – от СОМ. Конечно, все интерфейсы классов в Microsoft Media Foundation всё также являются производными от IUnknown и связаны с GUID. Но сами классы создаются через прямые «С» вызовы функций из статически линкованных системных библиотек. Это отличается от реализации DirectShow, которая требует вызова CoCreateInstance и обращения через СОМ абстракцию. На мой взгляд, данное решение корпорация Microsoft является недостатком – во-первых, затрудняется интеграция Microsoft Media Foundation в проекты, написанные не на С/С++, к примеру С# проекты, которые, кстати, на Windows взаимодействуют с СОМ объектами практически бесшовно, генерируя требуемые определения интерфейсов из TLB. Во-вторых, повышается риск потери совместимости приложения со следующей версией Windows при миграции функции из одной статически линкованной библиотеки в другую – с Microsoft Media Foundation это уже произошло однажды: Library Changes in Windows 7 — «Starting in Windows 7, certain Media Foundation functions are exported from different DLL files than previous versions.».
  2. На мой взгляд Microsoft Media Foundation черезмерно перегружена функциями и интерфейсами – было-бы неплохо спрятать большинство из них за дополнительным уровнем абстракции для оптимизации задачи захвата и записи видео и аудио данных.
  3. Значительным недостатком, на мой взгляд, является ограничения в поддержке записи видео и аудио в Microsoft Media Foundation. Microsoft Media Foundation предоставляет два механизма работы с медиа данными: через граф-топологию и SourceReader-SinkWriter. Первый предполагает сборку требуемой конфигурации из узлов-преобразователей и позволяет гибко настроить требуемую конфигурацию. Второй предлагает получение порций медиа данных от SourceReader и отправки их в SinkWriter в контексте разрабатываемого приложения. Граф-топология весьма удобна, на мой взгляд, и позволяет легко генерировать требуемую конфигурацию записи по требованию пользователя. Однако, данное решение от Microsoft не позволяет решить задачу записи – дело в том, что объект для создания рабочей сессии записи на базе топологии с интерфейсом IMFMediaSession из функции MFCreateMediaSession оптимизирован для воспроизведения медиа данных, и не выполняет ряд требуемых операций – к примеру, при окончании записи в файл, требуется выполнить расчёт метрик – подсчитать средний скорость потоков и рассчитать длительность воспроизведения – но IMFMediaSession из функции MFCreateMediaSession этого не делает – для задачи воспроизведения операция расчёта метрик бессмысленна. Также существует проблема с таймингом — IMFMediaSession из функции MFCreateMediaSession рассматривает начало воспроизведения с нулевого времени – это логично при воспроизведении медиа файла. Однако, видео и аудио источники, такие как веб-камеры или микрофоны используют текущее системное время – согласно документации Microsoft Media Foundation они должны инициализироваться нулевым значением времени, но они не выполняют данное требование.

Я полагаю, и думаю многие согласятся, что указанные выше проблемы существенны и было-бы желательно их разрешить. Это и послужило причиной начала проекта CaptureManager (а также задача захвата видео с двух веб-камер и записи этого видео в один медиа файл).
Вкратце, что из себя представляет CaptureManager:

  1. Полноценный СОМ In-Process Server – или как иногда называют – ActiveX. Он включает TLB и может быть интегрирован в проекты на С++, С#, Python наравне с DirectShow.
  2. CaptureManager связан с библиотеками Microsoft Media Foundation, но использует «отложенное связывание» — библиотеки Microsoft Media Foundation загружаются в коде CaptureManager и связываются с соответствующими функциями во время выполнения приложения. При невозможности найти функцию в библиотеках, она замещается на функцию-пробку, возвращающую код ошибки – E_NOTIMPL. Таким образом, CaptureManager позволяет уменьшить риск аварийного прекращения работы целевого приложения в ситуации миграции функций из одной библиотеки Microsoft Media Foundation в другую.
  3. CaptureManager имеет упрощённый набор интерфейсов. Важной особенностью является генерация данных, описывающих медиа источники, кодеки и медиа контейнеры в формате XML документа – обрабатывать XML документ намного легче, чем многочисленные Variant и PropVariant, особенно на высокоуровневых API, как WPF.
  4. CaptureManager включает в себя ряд видео и аудио источников, отсутствующих в исходном Microsoft Media Foundation: Screen Capture – для захвата изображений с дисплея (или нескольких дисплеев), AudioLoop Capture – для захвата звукового потока с аудио выхода, DirectShow-Crossbar Capture – для захвата видео с карт видео захвата.
  5. CaptureManager включает в себя «аккумулятор кадров», позволяющий получить серию крайних кадров.
  6. CaptureManager включает собственную реализацию IMFMediaSession интерфейса, оптимизированную для задачи записи – т.е. реализован полный отказ от вызова MFCreateMediaSession функции.
  7. CaptureManager включает функционал для изменения параметров видео процессора веб-камеры и параметров камеры (фокус, экспозиция, и т.п.).

Функционал CaptureManager представлен в демонстрационных программах, доступных на GitHub — CaptureManager-SDK-Demos:

  • CPPDemos:
    1. EVRWebCapViewerViaCOMServer – простое C++ приложение для демонстрации функционала просмотра видео источников через CaptureManager рендерер.
    2. OpenGLWebCamViewerViaCOMServer – простое C++ приложение для демонстрации функционала просмотра видео источников через OpenGL рендерер.
    3. TextInjectorDemo – простое C++ приложение для демонстрации функционала смешивания теста с видео потоком с камеры.
      image
    4. WaterMarkInjectorDemo – простое C++ приложение для демонстрации функционала смешивания изображений с видео потоком с камеры.
      image
    5. EVRVieweingAndRecording – простое C++ приложение для демонстрации функционала записи с видео и аудио источников в один медиа файл.
      image
    6. NativeMediaFoundationPlayer – простое C++ приложение для демонстрации воспроизведения множества видео файлов в общем рендерере.
      image

  • CSharpDemos:
    1. WPFMultiSourceRecorder – простое C# приложение для демонстрации функционала записи с одного, двух и более видео и аудио источников в один общий медиа файл.
      image
    2. WPFMediaFoundationPlayer – простое C# приложение для демонстрации воспроизведения множества видео файлов в общем рендерере.
      image
    3. WPFVideoAndAudioRecorder – простое C# приложение для демонстрации функционала записи с видео и аудио источников в один медиа файл.
      image
    4. WPFIPCameraMJPEGMultiSourceViewer – простое C# приложение для демонстрации функционала захвата видео с нескольких Интернет камер и воспроизведения их в общем рендерере.
      image
    5. WPFMultiSourceViewer – простое C# приложение для демонстрации функционала захвата видео с нескольких нескольких и воспроизведения их в общем рендерере.
      image
    6. WPFViewerEVRDisplay – простое C# приложение для демонстрации функционала интеграции CaptureManager рендерера в WPF приложение.
      image
    7. WPFIPCameraMJPEGViewer – простое C# приложение для демонстрации функционала захвата видео с Интернет камеры.
      image
    8. WPFImageViewer – простое C# приложение для демонстрации функционала захвата изображения из файла.
      image
    9. WindowsFormsDemo – простое C# приложение для демонстрации функционала просмотра и записи видео источников.
      image
    10. WPFWebCamSerialShots – простое C# приложение для демонстрации функционала «аккумулятор кадров».
    11. WPFWebCamShot – простое C# приложение для демонстрации функционала захвата кадров с видео источника.
    12. WPFRecorder – простое C# приложение для демонстрации функционала просмотра и записи видео источников.
      image
    13. WPFWebViewerEVR – простое C# приложение для демонстрации функционала просмотра видео источников через CaptureManager рендерер.
      image
    14. WPFWebViewerCallback – простое C# приложение для демонстрации функционала захвата кадров с видео источника через копирование из потока CaptureManager.
      image
    15. WPFWebViewerCall – простое C# приложение для демонстрации функционала захвата кадров с видео источника через прямой вызов методов CaptureManager.
      image
    16. WPFSourceInfoViewer – простое C# приложение для демонстрации функционала получения информации о доступных видео и аудио источников.
      image

  • PythonDemos:
    1. CaptureManagerSDKPythonDemo – простое Python приложение для демонстрации функционала просмотра и записи видео источников.
      image

  • QtMinGWDemos:
    1. CaptureManagerSDKQtMinGWDemo – простое С++ приложение на Qt для демонстрации функционала просмотра и записи видео источников.
      image

  • UnityDemos:
    1. UnityWebCamViewer — простое приложение для демонстрации функционала работы с видео источником в Unity3D.
      image

Больше информации о проекте можно найти сайте CaptureManager SDK. На NuGet существует C# оболочка CaptureManager.

Автор: Евгений Перегуда

Источник

Поделиться

* - обязательные к заполнению поля