Инструменты пользователя

Инструменты сайта



// AvCpp: API-2 rework, веха вторая

Продолжаем отслеживать судьбу изменений, описанных в AvCpp: API-2 rework, веха первая.

Как обычно, объём работ отличается от того, что было запланировано. Итак, что сделано:

  1. Работа со словарями и поддержка оных во всех местах, где только можно. Это вызвало необходимость разнести открытие входного потока и поиск информации о стриме (Снова FFmpeg и low-latency). Как следствие, добавился новый вызов: av::FormatContext::findStreamInfo(). Он может принимать коллекцию словарей для каждого стрима в потоке.
  2. Начата работа над фильтрами. Уже появилась базовая инфраструктура. Но пока нет понимания в каком виде оно должно получиться на выходе.
  3. В рамках чистки кода тотально переработана обработка ошибок. Теперь это делается через std::error_code, который передаётся опциональным аргументом в те функции фейл которых может приводить к неоднозначностям в будущем. Если переменная для кода ошибки не передана, будет выброшено исключение av::Exception которое будет содержать данный код. Планируется, что набор исключений расширится под каждую сущность. Данные изменений повлекли достаточно сильные изменений в API, требующие изменений в коде приложений, которые их используют. При обработке ошибок стоит учитывать категорию оных. На дынный момент используется, как минимум три:
    • avcpp_category() - для внутренних ошибок AvCpp
    • ffmpeg_category() - для ошибок, пришедших от FFmpeg
    • system_category() - для системных ошибок, в основном так рапортуются ошибки выделения памяти при помощи встроенных av_alloc() (когда владение принимается FFmpeg'ом и он сам освобождает, как следствие, использовать new/new[] нет возможности). Целесообразность использовать std::bad_alloc обдумывается.

Ну и главное, реорганизация бранчей:

  • все наработки первой вехи выделены в отдельный бранч api-2.0 (исправляются только ошибки)
  • старый мастер стал бранчем api-legacy (для совместимости, самостоятельно тут ничего не исправляется, только принимаются мерж-реквесты)
  • вся разработка перемещена на бранч master

Что осталось:

  1. Интерфейс опций
  2. Доделать фильтры
  3. Ревизия и чистка кода в т.ч. примеров.

Планируется, что это будет сделано в следующей, третье вехе.

Как обычно, за отзывы, багрепорты и пул-реквесты буду благодарен.

// AvCpp: API-2 rework, веха первая

Для начала, что такое AvCpp - это C++ враппер над FFmpeg, позволяющий несколько упростить работу непосредственно с функциями FFmpeg.

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

Изначально структура классов опиралась на Xuggle API, ведь когда начинал его делать, многое не понимал - почему оно так. Со временем такой подход перестал мне нравится, начали вылазить всякие неприятные оверхеды, баги. Так появился подпроект API-2, цели которого:

  1. Уйти где только можно от shared_ptr (это получилось почти везде).
  2. Использовать по максимуму возможности новых версий FFmpeg, где появился reference-counting для AVFrame/AVPacket, при этом предоставить возможности создавать «тяжёлые» копии, где нужно.
  3. Более логично организовать мапинг сущностей FFmpeg в AvCpp, к примеру, если раньше AVCodecContext мапился в av::StreamCoder, то теперь av::CodecContext, аналогично для AVFormatContext (av::Container vs av::FormatContext).
  4. Корректно реализовать аудио-ресемплер
  5. Добавить побольше примеров использования API2
  6. Работа с av_options для поддерживаемых сущностей
  7. Поддержка передачи параметров через словари
  8. Тотальная переработка фильтров
  9. Чистка кода, удаление ненужных сущностей

На текущий момент на бранче api-2 уже лежат почти все эти наработки. Нереализованными остались последние 4 пункта. Приэтому, попутно, устранено несколько багов, особенно связанных с последовательностью уничтожения разных объектов (например Stream2 и FormatContext: стримом владеет FormatContext, Stream2 только предоставляет доступ к нему, при этом, даже если уничтожить объект контекста, объект Stream2 может теперь корректно рапортовать, что он инвалидировался).

Вторая веха, судя по всему, будет реализация поддержки AVOptions/AVDict, третья веха - фильтры (к слову их сейчас нет вообще в рамках API-2). Последующие вехи пока не сформированы, скорее всего нужно будет подумать над возможностями использования аппаратного ускорения для декодирования (оно достаточно некрасиво и в самом FFmpeg реализовано - нужно делать много телодвижений).

В любом случае, я уже настоятельно рекомендую начинать использовать ветку api-2. В скором времени она заместит master-ветку, а текущий мастер переедет на ветку legacy.

За отзывы, багрепорты и пул-реквесты буду благодарен.