Vfx exe videofx decoder что это
Разбираемся с форматами и кодеками видео
Содержание
Содержание
Современные медийные платформы позволяют пользователям наслаждаться высокодетализированным видео и потрясающими аудиоэффектами в режиме онлайн.
Однако создание подобного контента было бы невозможно без существования кодеков и контейнеров.
Чем кодеки отличаются от контейнера — их часто путают
Для ответа на вопрос, чем кодеки отличаются от контейнеров, необходимо понять, что такое кодеки.
Смысл понятия «кодек» лежит прямо в его названии:
Фактически кодек — это цифровой инструмент компрессии и декомпрессии данных. Компрессия (сжатие данных) необходима для экономии занимаемого файлом места. Например, несжатое видео высокой четкости в raw-формате, при 60 кадрах в секунду способно достигать размеров в полтерабайта на каждый час записи.
Восьмиканальная аудиодорожка в 24-битном разрешении будет занимать 16 мегабит за одну секунду записи. Такие объемы данных не подходят ни для штатного хранения, ни для их передачи онлайн, поэтому для их сжатия применяются специальные формулы, которые и называются кодеками.
Для хранения сжатой информации создаются контейнеры-обертки в определенном формате. Современные контейнеры способны хранить информацию, обработанную разными кодеками. Такие обертки указывают устройству на то, какими кодеками была сжата информация, и по какой формуле ее восстанавливать.
Если разобрать стандартное видео со звуком на кодеки и контейнеры, в результате получится три составные части:
В случае если в видео нет звука, аудиокодек не нужен.
Популярные и прогрессивные кодеки
Большинство создаваемого видеоконтента обрабатывается кодеками XviD, MPEG-1\2, H.264, MPEG-4, DivX, WMV, MJPEG, RealVideo, Bink Video и их вариациями. Для аудиоформатов в основном используют AAC, Opus и MP3-кодеки. Из новинок стоит отметить кодек H.266/VVC, разрабатываемый для потоковой передачи видео в 4K и 8K.
Новый кодек позволяет вдвое сократить объем файла относительно H.265 кодека за счет более сложных алгоритмов. Сложные вычисления потребляют больше ресурсов, до 1000 % от потребления H.265 при кодировании, и до 200% при декодировании.
Какие кодеки в основном поддерживаются современными ТВ и обновляются ли они с прошивкой
Современные системы поддерживают большинство существующих кодеков.
Поддержка кодеков MPEG от первого до четвертого, вариации H.264 для воспроизведения Blu-Ray, а также XviD и DivX, входят в базовый пакет любого современного телевизора.
Ведущие производители всегда следят за ошибками и актуальностью своего программного обеспечения.
Обновление кодеков в процессе прошивки регулируется разработчиками индивидуально под каждую модель SmartTV.
Если новые кодеки необходимы, поддерживаются устройством на аппаратном уровне и не вызывают ошибок отображения, ничего не мешает разработчикам добавить их в ближайших обновлениях.
Не все устройства совместимы с новыми кодеками, поэтому установка неофициальных обновлений прошивки не рекомендуется потому как может привести к ошибкам воспроизведения.
Какие кодеки используются при проигрывании онлайн-видео (современные кодеки youtube)
В настоящее время стандартом большинства видеосервисов стали кодеки H.264 и MPEG-4, значительно реже встречаются кодеки FFDshow, XviD и DivX.
Одним из самых перспективных кодеков является бесплатный AV1-кодек. Разработан сообществом AOMedia, включающим в себя таких гигантов как AMD, Google, Netflix, Mozilla, Nvidia, Intel, ARM и Cisco. Исходный код кодека открыт и свободно распространяется без каких-либо лицензионных отчислений.
Что даст конечному пользователю переход ютуба на современный AV1
Кодек AV1 разрабатывался для воспроизведения видео онлайн, в браузерах Safari, Firefox, Edge и Chrome. Степень сжатия видео кодеком AV1 превосходит кодеки VP8 и H.264 от 30% до 50%, а кодек HEVC до 30–43 % на высоких битрейтах.
Полный переход видео платформы YouTube на AV1-кодек не только ускорит загрузку всех видеороликов от 20% до 50%, но и позволит стримить в разрешении 4K.
Для минимизации потерь качества, при сохранении и конвертации файла рекомендуется использовать кодеки AV1 для видео и Opus для аудио, обернутые в MP4-контейнер.
Что такое Ffdshow? Как скачать программу, установить и настроить?
Программа Ffdshow – это пакет аудио и видео кодеков в совокупности с системой постобработки потокового видео и аудио сигнала. Она работает по принципу DirectShow фильтра, что позволяет программе встраиваться в работу практически любого видеоплеера.
Что это за программа и для чего нужна?
Обычно в операционной системе стоит множество подпрограмм, которые отвечают за обработку аудио и видео данных и их последующий вывод. Все это подпрограммы можно назвать одним словом — фильтры. Также существуют сплиттеры, рендереры, которые также работают в связке с фильтрами. Они взаимодействуют между собой, чтобы пользователь в конечном итоге мог посмотреть фильм или послушать музыку.
Каждая из них отличается высоким уровнем стабильности в работе, поэтому видео или аудио файл обрабатывается быстро и без видимых проблем.
Отличительная черта данного программного обеспечения — отсутствие встроенного плеера для воспроизведения видео контента. То есть, Ffdshow будет интегрироваться в работу уже установленных плееров на вашем компьютере. Программное обеспечение распространяется по лицензии GNU General Public License version 2.0 (GPLv2). То есть, она передается бесплатно и может быть скачана любым пользователем для личных или коммерческих нужд.
Официальный язык программы — английский. Но при первоначальной установке можно выставить русскую версию. Вообще Ffdshow поддерживает огромное количество языков.
Программа Ffdshow впервые появилась в 2002 году и была альтернативой декодерам DivX 3.11 и DivX 5.02. До 2006 года разработка велась одним программистом Milan Cutka. Позже проект перешел в руки ffdshow-tryouts. Сегодня проектом занимается группа разработчиков, включая компанию Ffmpeg.
Как настраивать Video Decoder?
Условно область настроек можно разбить на две части:
В нижней части программы располагаются кнопки «отмена», «ок» и «подтвердить». Также есть отдельная кнопка под экспорт настроек.
Как скачать и установить эту программу?
Для оптимальной работы потребуется компьютер или ноутбук с минимальными системными требованиями:
Вообще данная программа очень нетребовательна к ресурсам компьютера.
Мощное «железо» может потребоваться именно для обработки видео хорошего качества. Например, в разрешении 720р или 1080р.
После скачивания нужно пройти стандартную установку. Рекомендуем не трогать настройки, которые выставляет система на каждом шагу инсталляции, если вы не опытный пользователь. В противном случае можно столкнуться с некоторыми трудностями при воспроизведении звука или видео в будущем.
Руководство по FFmpeg libav
Долго искал книгу, в которой было бы разжёвано, как использовать FFmpeg-подобную библиотеку, известную как libav (название расшифровывается как library audio video). Обнаружил учебник «Как написать видеоплеер и уложиться в менее чем тысячу строк». К сожалению, информация там устаревшая, так что пришлось создавать мануал своими силами.
Большая часть кода будет на C, однако не волнуйтесь: Вы легко всё поймёте и сможете применить на любимом языке. У FFmpeg libav уйма привязок ко многим языкам (в том числе и к Python и к Go). Но даже если Ваш язык прямой совместимости не имеет, всё равно можно привязаться через ffi (вот пример с Lua).
Начнём с краткого экскурса о том, что такое видео, аудио, кодеки и контейнеры. Затем перейдем к ускоренному курсу, посвященному использованию командной строки FFmpeg, и, наконец, напишем код. Не стесняйтесь переходить сразу в раздел «Тернистый путь изучения FFmpeg libav».
Есть мнение (и не только моё), что потоковое интернет-видео уже приняло эстафету от традиционного телевидения. Как бы то ни было, FFmpeg libav точно достоин изучения.
Оглавление
Статья переведена при поддержке компании EDISON.
Мы очень любим работать с видео! 😉
Вступление ↑
Видео — это то, что ты видишь! ↑
Если последовательность изображений менять с заданной частотой (скажем, 24 изображения в секунду), то создаётся иллюзия движения. Это и есть основная идея видео: серия изображений (кадров), движущихся с заданной скоростью.
Иллюстрация 1886 года.
Аудио — это то, что ты слышишь! ↑
Хотя немое видео может вызывать самые разные чувства, добавление звука резко повышает степень удовольствия.
Звук — это колебательные волны, распространяемые в воздухе или в любой других средах передачи (таких как газ, жидкость или твердое вещество).
В цифровой аудиосистеме микрофон преобразует звук в аналоговый электрический сигнал. Затем аналого-цифровой преобразователь (АЦП) — обычно с использованием импульсной кодовой модуляции (ИКМ) — преобразует аналоговый сигнал в цифровой.
Кодек — сжатие данных ↑
Кодек — это электронная схема или программное обеспечение, сжимающее или распаковывающее цифровое аудио/видео. Он преобразует необработанное (несжатое) цифровое аудио/видео в сжатый формат (или наоборот).
Но если мы решим упаковать миллионы изображений в один файл и назовем его фильмом, у нас может получиться огромный файл. Давайте посчитаем:
Допустим, создаём видео с разрешением 1080×1920 (высота × ширина). Тратим 3 байта на пиксель (минимальную точку на экране) для цветового кодирования (24-битного цвета, что дает нам разных цветов). Это видео работает со скоростью 24 кадра в секунду, общая продолжительность 30 минут.
Для этого видео потребуется приблизительно 250,28 Гб памяти или 1,11 Гбит/с! Вот поэтому и придётся использовать кодек.
Контейнер — удобный способ хранения аудио/видео ↑
Формат контейнера (оболочки) — это формат метафайла, спецификация которого описывает, как различные элементы данных и метаданных сосуществуют в компьютерном файле.
Это единый файл, содержащий все потоки (в основном, аудио и видео), обеспечивающий синхронизацию, содержащий общие метаданные (такие как заголовок, разрешение) и т.п.
Обычно формат файла определяется по его расширению: например, video.webm — это, скорее всего, видео с использованием контейнера webm.
Командная строка FFmpeg↑
Самодостаточное кроссплатформенное решение для записи, конвертации и потоковой передачи аудио/видео.
Для работы с мультимедиа у нас есть восхитительный инструмент — библиотека под названием FFmpeg. Даже если Вы не используете её в своём программном коде, то всё равно используете её (Вы ведь используете Chrome?).
В библиотеке есть консольная программка для ввода командной строки под названием ffmpeg (маленькими буквами, в отличие от названия самой библиотеки). Это простой и мощный бинарник. Например, можно конвертировать из mp4 в avi, просто набрав такую команду:
Мы только что сделали ремиксинг — сконвертировали из одного контейнера в другой. Технически FFmpeg также может выполнять транскодирование, но об этом позже.
Инструмент командной строки FFmpeg 101 ↑
У FFmpeg есть документация, где всё отлично объяснено, как что работает.
Схематично, программа командной строки FFmpeg ожидает, что следующий формат аргументов выполнит свои действия — ffmpeg <1> <2>-i <3> <4>, где:
— глобальные параметры
— параметры входного файла
— входящий URL
— параметры выходного файла
— исходящий URL
В частях <2>, <3>, <4>, <5>указывается столько аргументов, сколько нужно. Проще понять формат передачи аргументов на примере:
# ПРЕДУПРЕЖДЕНИЕ: файл по ссылке весит 300 МБ
Эта команда берет входящий mp4-файл, содержащий два потока (аудио, закодированный с помощью кодека aac, и видео, закодированный с использованием кодека h264), и преобразует его в webm, изменяя также кодеки аудио и видео.
Если упростить приведенную выше команду, то следует учесть, что FFmpeg примет значения по умолчанию вместо Вас. Например, если просто набрать
то, какой аудио/видео кодек он использует для создания output.mp4?
Вернер Робица написал руководство по чтению/исполнению, посвященное кодированию и редактированию с помощью FFmpeg.
Основные операции над видео↑
При работе с аудио/видео мы обычно выполняем ряд задач связанных с мультимедиа.
Транскодирование (перекодирование)↑
Что это? Процесс преобразования потокового или аудио или видео (или и то и другое одновременно) из одного кодека в другой. Формат файла (контейнер) при этом не меняется.
Для чего? Бывает, что некоторые устройства (телевизоры, смартфоны, консоли и т. д.) не поддерживают формат аудио/видео X, но поддерживают формат аудио/видео Y. Или же более новые кодеки предпочтительнее, поскольку обеспечивают лучшую степень сжатия.
Как? Преобразуем, к примеру, видео H264 (AVC) в H265 (HEVC):
Трансмультиплексирование↑
Что это? Преобразование из одного формата (контейнера) в другой.
Для чего? Бывает, что некоторые устройства (телевизоры, смартфоны, консоли и т. д.) не поддерживают формат файла X, но поддерживают формат файла Y. Или же более новые контейнеры, в отличие от устаревших, предоставляют современные требуемые функции.
Как? Конвертируем mp4 в webm:
Трансрейтинг↑
Что это? Изменение скорости передачи данных или создание другого представления.
Для чего? Пользователь может смотреть Ваше видео как в сети 2G на маломощном смартфоне, так и через оптоволоконную интернет-связь на 4K-телевизоре. Поэтому следует предлагать более одного варианта воспроизведения одного и того же видео с разными скоростями передачи данных.
Как? производит воспроизведение с битрейтом между 3856K и 2000K.
Обычно трансрейтинг осуществляется в связке с перекалибровкой. Вернер Робица написал еще одну обязательную для ознакомления статью о контроле скорости FFmpeg.
Трансайзинг (перекалибровка)↑
Что это? Изменение разрешающей способности. Как сказано выше, транссайзинг часто проводится одновременно с трансрейтингом.
Для чего? По тем же причинам, что и с трансрейтингом.
Как? Уменьшим разрешение 1080 до 480:
Бонус: адаптивный стриминг↑
Что это? Создание множества разрешений (битрейтов) и разбиение медиа на части и их передача по протоколу http.
Для чего? Ради обеспечения гибкого мультимедиа, которое можно просматривать хоть на бюджетном смартфоне хоть на 4K-плазме, чтобы можно было легко масштабировать и развертывать (но это может добавить задержку).
Как? Создадим адаптивный WebM с использованием DASH:
Выходя за рамки↑
Несть числа другим применениям FFmpeg. Я использую его вместе с iMovie для создания/правки некоторых видео для YouTube. И Вам, безусловно, использовать его профессионально тоже ничего не препятствует.
Тернистый путь изучения FFmpeg libav↑
Разве время от времени не поразительно то, что воспринимается через слух и зрение?
Биолог Дэвид Роберт Джонс
FFmpeg крайне полезен как инструмент в виде командной строки для выполнения важных операций с мультимедийными файлами. Может и в программах его тоже получится использовать?
FFmpeg состоит из нескольких библиотек, которые можно интегрировать в наши собственные программы. Обычно, при установке FFmpeg, автоматически устанавливаются все эти библиотеки. Я буду ссылаться на набор этих библиотек как FFmpeg libav.
Название раздела является данью уважения серии Зеда Шоу «Тернистый путь обучения [. ]», в частности его книге «Тернистый путь обучения языку C».
Глава 0 — простенький «Hello World»↑
В нашем Hello World на самом деле не будет приветствовать мир на языке консоли. Вместо этого распечатаем следующую информацию о видео: формат (контейнер), продолжительность, разрешение, аудиоканалы и, напоследок, расшифруем некоторые кадры и сохраним их как файлы изображений.
Архитектура FFmpeg libav↑
Но прежде чем начнём писать код, давайте посмотрим, как вообще работает архитектура FFmpeg libav и как ее компоненты взаимодействуют с другими.
Вот схема процесса декодирования видео:
Сначала медиафайл загружается в компонент по имени AVFormatContext (контейнер видео также является форматом). На самом деле он не полностью загружает весь файл: часто читается только заголовок.
Как только загрузили минимальный заголовок нашего контейнера, можно получить доступ к его потокам (их можно представить как элементарные аудио- и видео-данные). Каждый поток будет доступен в компоненте AVStream.
Предположим, наше видео имеет два потока: аудио, закодированное с помощью кодека AAC, и видео, закодированное с помощью кодека H264 (AVC). Из каждого потока можем извлечь фрагменты данных, называемые пакетами, которые загружаются в компоненты, называемые AVPacket.
Данные внутри пакетов по-прежнему кодируются (сжимаются), и для декодирования пакетов нам необходимо передать их конкретному AVCodec.
AVCodec декодирует их в AVFrame, в результате чего этот компонент выдает нам несжатый кадр. Отметим, что терминология и процесс одинаковы как для аудио- так и видео-потока.
Требования↑
Так как иногда возникают проблемы при компиляции или запуске примеров, мы будем использовать Docker в качестве среды разработки/выполнения. Также будем использовать видео с большим кроликом, поэтому, если у вас его нет на локальном компьютере, просто проведите в консоли команду make fetch_small_bunny_video.
Собственно, код↑
TLDR; покажи мне пример выполянемого кода, бро:
Мы опустим некоторые детали, но не волнуйтесь: исходный код доступен на github.
Мы собираемся выделить память для компонента AVFormatContext, который будет содержать информацию о формате (контейнере).
Теперь мы собираемся открыть файл, прочитать его заголовок и заполнить AVFormatContext минимальной информацией о формате (обратите внимание, что обычно кодеки не открываются). Для этого используется функция avformat_open_input. Он ожидает AVFormatContext, имя файла и два необязательных аргумента: AVInputFormat (если вы передадите NULL, FFmpeg определит формат) и AVDictionary (которые являются опциями демультиплексора).
Также можно напечатать название формата и длительность медиа:
Чтобы получить доступ к потокам, нам нужно прочитать данные с носителя. Это делает функция avformat_find_stream_info. Теперь pFormatContext-> nb_streams будет содержать количество потоков, а pFormatContext-> streams[i] даст нам i-й по счёту поток (AVStream).
Пройдемся в цикле по всем потокам:
Для каждого потока мы собираемся сохранить AVCodecParameters, описывающий свойства кодека, используемого i-м потоком:
Используя свойства кодеков можем найти соответствующий, запрашивая функцию avcodec_find_decoder, также можем найти зарегистрированный декодер для идентификатора кодека и вернуть AVCodec — компонент, который знает, как кодировать и декодировать поток:
Теперь мы можем распечатать информацию о кодеках:
С помощью кодека выделяем память для AVCodecContext, который будет содержать контекст для нашего процесса декодирования/кодирования. Но затем нужно заполнить этот контекст кодека параметрами CODEC — мы делаем это с помощью avcodec_parameters_to_context.
После того, как мы заполнили контекст кодека, необходимо открыть кодек. Вызываем функцию avcodec_open2 и затем можем ее использовать:
Теперь мы собираемся прочитать пакеты из потока и декодировать их в кадры, но сначала нам нужно выделить память для обоих компонентов (AVPacket и AVFrame).
Давайте скормим наши пакеты из потоков функции av_read_frame, пока у нее есть пакеты:
Теперь отправим пакет необработанных данных (сжатый кадр) в декодер через контекст кодека, используя функцию avcodec_send_packet:
И давайте получим кадр необработанных данных (несжатый кадр) от декодера через тот же контекст кодека, используя функцию avcodec_receive_frame:
Мы можем напечатать номер кадра, PTS, DTS, тип кадра и т.д.:
И напоследок, можем сохранить наш декодированный кадр в простое серое изображение. Процесс очень прост: мы будем использовать pFrame->data, где индекс связан с цветовыми пространствами Y, Cb и Cr. Просто выбираем 0 (Y), чтобы сохранить наше серое изображени:
И вуаля! Теперь у нас есть полутоновое изображение размером 2Мб:
Глава 1 — синхронизация аудио и видео↑
Быть в игре — это когда юный JS-разработчик пишет новый MSE-видеоплеер.
Прежде чем перейдем написанию кода транскодирования, давайте поговорим о синхронизации или о том, как видеоплеер узнаёт правильное время для воспроизведения кадра.
В предыдущем примере мы сохранили несколько кадров:
Когда мы проектируем видеоплеер, нам нужно воспроизводить каждый кадр в определенном темпе, иначе трудно получить удовольствие от видео либо из-за того, что оно воспроизводится слишком быстро, либо слишком медленно.
Поэтому нам нужно определить некую логику для плавного воспроизведения каждого кадра. В этом отношении каждый кадр имеет временнýю метку представления (PTS — от presentation timestamp), которая представляет собой увеличивающееся число, учитываемое в переменной timebase, которая представляет собой рациональное число (где знаменатель известен как временно́й масштаб — timescale), делимое на частоту кадров (fps).
Проще понять на примерах. Давайте смоделируем некоторые сценарии.
Для fps = 60/1 и timebase = 1/60000 каждый PTS будет увеличивать timescale / fps = 1000, поэтому реальное время PTS для каждого кадра может быть (при условии, что оно начинается с 0):
Почти по тому же сценарию, но с timescale, равной 1/60:
Для fps = 25/1 и timebase = 1/75 каждая PTS будет увеличивать timescale / fps = 3, и время PTS может быть:
Теперь с pts_time мы можем найти способ визуализировать это синхронизированным со звуком pts_time или с системными часами. FFmpeg libav предоставляет эту информацию через свой API:
Просто из любопытства, сохраненные нами кадры были отправлены в порядке DTS (кадры: 1, 6, 4, 2, 3, 5), но воспроизведены в порядке PTS (кадры: 1, 2, 3, 4, 5). Также обратите внимание, насколько дешевле обходятся B-кадры по сравнению с P или I-кадрами:
Глава 2 — ремультиплексирование↑
Ремультиплексирование (перекомпоновка, remuxing) — переход от одного формата (контейнера) к другому. Например, мы можем без особого труда заменить видео MPEG-4 на MPEG-TS с помощью FFmpeg:
MP4-файл будет демультиплексирован, при этом файл не будет декодирован или кодирован (-c copy), и, в конце концов, на выходет получим mpegts-файл. Если не указывать формат -f, ffmpeg попытается угадать его на основании расширения файла.
Общее использование FFmpeg или libav следует такому шаблону/архитектуре или рабочему процессу:
Теперь давайте создадим пример с использованием libav, чтобы обеспечить тот же эффект, что и при выполнении такой команды:
Мы собираемся читать из ввода (input_format_context) и изменять его на другой вывод (output_format_context):
Обычно начинаем с того, что выделяем память и открываем формат ввода. Для этого конкретного случая мы собираемся открыть входной файл и выделить память для выходного файла:
Будем ремультиплексировать только потоки видео, аудио и субтитров. Поэтому фиксируем, какие потоки будем использовать, в массив индексов:
Сразу после того, как выделим необходимую память, нужно выполнить цикл по всем потокам, и для каждого из которых надо создать новый выходной поток в нашем контексте выходного формата, используя функцию avformat_new_stream. Обратите внимание, что мы помечаем все потоки, которые не являются видео, аудио или субтитрами, чтобы была возможность пропустить их.
Теперь создаём выходной файл:
После этого можно копировать потоки, пакет за пакетом, из нашего ввода в наши выходные потоки. Это происходит в цикле, пока есть пакеты (av_read_frame), для каждого пакета нужно пересчитать PTS и DTS, чтобы наконец записать его (av_interleaved_write_frame) в наш контекст выходного формата.
Для завершения нам нужно записать трейлер потока в выходной медиафайл с помощью функции av_write_trailer:
Это работает! Не верите?! Проверьте с помощью ffprobe:
Подводя итог тому, что мы сделали, теперь можем вернуться к нашей первоначальной идее о том, как работает libav. Но мы пропустили часть кодека, что отображено на схеме.
Прежде чем закончим эту главу, хотелось бы показать такую важную часть процесса ремультиплексрования, где можно передавать параметры мультиплексору. Допустим, надо предоставить формат MPEG-DASH, поэтому нужно использовать фрагментированный mp4 (иногда называемый fmp4) вместо MPEG-TS или обычного MPEG-4.
С помощью командной строки это легко:
Почти так же просто это и в libav-версии, просто передаём опции при записи выходного заголовка, непосредственно перед копированием пакетов:
Теперь можем сгенерировать этот фрагментированный mp4-файл:
Чтобы убедиться, что тут всё по-честному, Вы можете использовать удивительный сайт-инструмент gpac/mp4box.js или сайт http://mp4parser.com/, дабы увидеть различия — сначала загрузите mp4.
Как видно, он имеет один неделимый блок mdat — это место, где находятся видео и аудио кадры. Теперь загрузите фрагментированный mp4, чтобы увидеть, как он расширяет блоки mdat:
Глава 3 — транскодирование↑
TLDR; покажи мне код и исполнение:
Мы пропустим некоторые детали, но не волнуйтесь: исходный код доступен на github.
В этой главе создадим минималистичннй транскодер, написанный на C, который может конвертировать видео из H264 в H265 с использованием библиотек FFmpeg libav, в частности libavcodec, libavformat и libavutil.
AVFormatContext — это абстракция для формата медиа-файла, т.е. для контейнера (MKV, MP4, Webm, TS)
AVStream представляет каждый тип данных для данного формата (например: аудио, видео, субтитры, метаданные)
AVPacket — это фрагмент сжатых данных, полученных из AVStream, которые могут быть декодированы с помощью AVCodec (например: av1, h264, vp9, hevc), генерирующих необработанные данные, называемые AVFrame.
Трансмультиплексирование↑
Начнем с простого преобразования, затем загрузим входной файл.
Теперь настроим декодер. AVFormatContext предоставит нам доступ ко всем компонентам AVStream, и для каждого из которых можем получить их AVCodec и создать конкретный AVCodecContext. И, наконец, можем открыть данный кодек, чтобы перейти к процессу декодирования.
AVCodecContext содержит данные о конфигурации мультимедиа, такие как скорость передачи данных, частота кадров, частота дискретизации, каналы, высота и многие другие.
Также нужно подготовить выходной медиа-файл для преобразования. Сначала выделим память для выходного AVFormatContext. Создадим каждый поток в выходном формате. Чтобы правильно упаковать поток, копируем параметры кодека из декодера.
Устанавливаем флаг AV_CODEC_FLAG_GLOBAL_HEADER, который сообщает кодировщику, что он может использовать глобальные заголовки, и, наконец, открываем выходной файл для записи и сохраняем заголовки:
Получаем AVPacket от декодера, корректируем метки времени и записываем пакет правильно в выходной файл. Несмотря на то, что функция av_interleaved_write_frame сообщает «write frame», сохраняем пакет. Заканчиваем процесс перестановки, записывая трейлер потока в файл.
Транскодирование↑
В предыдущем разделе была простая программа для преобразования, теперь добавим возможность кодировать файлы, в частности, перекодирование видео с h264 на h265.
После того, как подготовлен декодер, но перед тем, как организовать выходной медиафайл, настроим кодировщик.
Необходимо расширить цикл декодирования для транскодирования видеопотока:
Мы преобразовали поток мультимедиа из h264 в h265. Как и ожидалось, версия медиа-файла h265 меньше, чем h264, при этом у программы широкие возможности:
Положа руку на сердце, признаюсь, что было несколько посложнее, чем представлялось в начале. Пришлось ковыряться в исходном коде командной строки FFmpeg и много тестировать. Наверное, что-то где-то упустил, потому что пришлось применять force-cfr для h264, и всё ещё выскакивают некоторые предупреждающие сообщения, например о том, что тип кадра (5) принудительно был изменен на тип кадра (3).