LINUX.ORG.RU

Формат mp4 потока. Ткните носом.

 , , ,


0

1

Всем привет, встала задача: работать «на лету» с потоком данных, являющихся стримом mp4 video.

Приложение (внешнее, исходники недоступны) динамически подгружает мою библиотеку, из библиотеки торчит наружу функция:

void doSmthUseful(unsigned char *buf, size_t size, off_t len);

Где: buf - данные, size - размер данных, len - смещение от начала файла. Это всё, что мне может быть известно о входных данных.

Файл читается приложением с самого начала и отдаёт данные библиотеке кусками, например по 20 килобайт. То есть среди этих данных с самого начала будет и «хедер» файла со служебной информацией (то есть это можно внутри либы «сохранить» на будущее).

Как я понял, немного покурив исходники ffmpeg, после служебного заголовка с метаданными, данные в потоке идут «кадрами», в начале каждого из которых по идее должна идти структура с информацией о длине кадра, времени и тд. В с этой структурой мне и надо doSmthUseful.

Я видел

typedef struct MOVFragmentInfo {
    int64_t offset;
    int64_t time;
    int64_t duration;
    int64_t tfrf_offset;
} MOVFragmentInfo;

в libavformat/movenc.h.

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

Вопрос: как происходит декодирование mp4, есть ли аналогичная структура, каков формат этой структуры, как её распознать в потоке «сырых» байт? Если кто с этим работал, ткните, пожалуйста, носом в исходники ffmpeg, где оно описано и используется.

Дело в том, что я с видео никогда не работал, а сделать надо достаточно срочно.

☆☆☆☆☆

Последнее исправление: DELIRIUM (всего исправлений: 1)

Смотри муксер и демуксер MP4 в FFmpeg: libavformat/movenc*, libavformat/mov*. Конкретнее не подскажу.

А использовать сам FFmpeg на уровне API не катит?

Krieger_Od ★★
()

Исходник - QuickTime File Format Specification. Никаких «аналогичных структур» нет. Данные разбирают по байтам (а для потоковых форматов даже побитово).

Файл читается приложением с самого начала и отдаёт данные библиотеке кусками, например по 20 килобайт. То есть среди этих данных с самого начала будет и «хедер» файла со служебной информацией (то есть это можно внутри либы «сохранить» на будущее).

Т. е. тебе отдают поток данных, а mp4 не предназначен для этого. Заголовок может оказаться в конце файла, а без него разобрать начало не реально. И «сохранить» на будущее придется все содержимое файла, пока не доберешься до заголовка.

В ffmpeg декодирование в libavformat/mov.c, функции mov_read_header, mov_read_packet. Без возможности сделать seek они не работают.

fopen ★★
()

Если сильно упростить mp4 данные о всех кадрах в файле (местоположение, размер, является ли опорным) хранятся в этом самом «хедере». Опять же это не «хедер», не заголовок, по сути...

Эх. ладно по порядку. mp4 это набор «атомов», каждый атом может иметь в своем составе другие атомы или некую информацию. Информация о разбивке файла на кадры в отдельном атоме (и да, он может быть даже после данных в файле). Все кадры (просто подряд друг за другом) - другой, отдельный атом (или иногда несколько).

Надеюсь понятно объяснил.

mov это... а не помню уже, врать не буду,.. но скорее всего будет не совсем релевантен настоящему mpeg4.

Да, есть «пакетные» форматы, пригодные для упомянутого в треде стриминга, это (помянутый к ночи) asf, mpeg-ts. Они разработаны так, что можно выцепить кадр из середины потока. Впрочем, копая глубже, кадры можно выцеплять без служебной информации контейнера, если знать формат. Для h264 например достаточно парсить потом по NAL юнитам, они начинаются всегда одинаково, поймать sps/pps (прочитать всю служебную информацию), потом поймать idr (он будет за ними) и можно декодировать. :-)

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