LINUX.ORG.RU

[ffmpeg] - Сохранение видеопотока h264 в контейнер


0

0

Есть необходимость сохранять поток данных в конкретном контейнере (mp4, avi, mkv). У меня есть набор файлов, каждый из которых соответствует одному фрейму h264 (могут быть и другие форматы, например, mjpeg, divx). В первую очередь мне необходимо знать, правильно ли я понимаю как можно решить эту задачу средствами ffmpeg.

Последовательность действий:
1) Подготовка контейнера (создание AVFormatContext; создание, добавление и настройка параметров видео потока; создание файла (контейнера))
2) Чтение пакетов из каждого файла, отвечающего за один фрейм.
3) Запись прочитанных пакетов в контейнер.

Есть ли какие этапы, которые я пропустил? Например, декодирование и кодирование.

Я попытался реализовать вышеуказанную схему, основываясь на немногочисленных примерах, которые есть в нете. Но у меня постоянно валится приложение (Segmentation fault) при попытке записать в выходной поток первый пакет (функция av_interleaved_write_frame).

Подскажите, пожалуйста, может я неверно пытаюсь реализовать эту задачу? Я имею ввиду сам подход к ее реализации.

[ffmpeg] - Сохранение видеопотока h264 в контейнер

Примерно правильная последовательность. Кодировать-декодировать нет необходимости.
В output_exmaple.c довольно неплохой код для примера.
А почему валится, тоже не так сложно узнать, благо код открыт.

P.S. я когда-то дня четыре убил, пытаясь понять, почему кодирование в ffmpeg не работает. Оказалось, просто забыл вызвать av_register_all().

Dead ★★★★ ()

[ffmpeg] - Сохранение видеопотока h264 в контейнер

Тебе девайс какой-то сразу в h264 отдаёт? Можешь свой пример в архиве с десятком фреймов куда-нибудь выложить? Я года три назад записью видео через avcodec/avformat занимался.

mv ★★★★★ ()

[ffmpeg] - Сохранение видеопотока h264 в контейнер

а из cli нельзя разве несколько input в один output? И всё ffmpeg сделает.

true_admin ★★★★★ ()

[ffmpeg] - Сохранение видеопотока h264 в контейнер

Код открыт и, наверное, это было бы лучшим решением посмотреть, что же происходит внутри. Но я не могу даже скомпилить код ffmpeg в эклипсе, так как очень много ошибок. В нете тоже нет готового решения, как это сделать (по крайней мере я не нашел).

scandinaf ()

[ffmpeg] - Сохранение видеопотока h264 в контейнер

Проблема решена. Надо было делать так:

1) создание AVFormatContext - avformat_alloc_context()
2) открытие файла - url_fopen()
3) создание видео потока - av_new_stream()
4) настройка параметров потока - stream->codec->codec_type, stream->codec->width, stream->codec->height, stream->time_base и т.д.
5) запись заголовка файла - av_write_header()
6) последовательная запись фреймов
7) запись трейлера - av_write_trailer()
8) освобождение использованных ресурсов.

Моя проблема заключалась в том, что пункты 5 и 6 были в обратной последовательности ( то есть, сначала 6, а потом 5), что и приводило к исключениям.

Да, кадры я получал от камеры. Но мне их предоставили в виде последовательности файлов. Запись в выходной поток я производил приблизительно так:

1) Открытие файла. Стандартное, через fopen().
2) Чтение содержимого файла в буфер (uint8_t* buf);
3) Дальше так
packet.data = buf;
packet.size = buf_size;
...
4)Запись пакета - av_interleaved_write_frame()
5)Освобождение ресурсов.

P.S. Может то, что я описал, не совсем правильно, но мне помогло. Может кому-то еще будет полезно. А вдруг? :)

scandinaf ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.