Как я могу узнать продолжительность любого файла h264?

У меня есть один файл, в котором есть только кадры h264 в виде блока NAL. Итак, есть ли какой-нибудь метод, чтобы я мог подсчитать продолжительность этого файла?

Я не знаю, сколько кадров в файле. У меня есть только размер файла.

PS: Все, что я хочу сделать, это на языке C и на платформе Linux.


person Jeegar Patel    schedule 15.09.2011    source источник


Ответы (3)


Ваш вопрос бессмыслен, поэтому кто-то проголосовал за вас.

Файл-контейнер

Во-первых, нет такого понятия, как H264 file. Может быть файл-контейнер (MP4, AVI, MKV), содержащий видео в кодировке H264. Этот формат контейнера обычно также содержит данные о длительности видео. Поэтому вам нужно разобрать этот файл, проверить документацию по формату, чтобы увидеть, где сохраняется продолжительность, а затем извлечь его.

Самый простой способ - использовать FFMPEG, как предложил Аугусто.

Байтовый поток NAL

Если ваш файл состоит только из блоков NAL, сохраненных один за другим, например, в потоке байтов NAL, НЕТ СПОСОБНОСТИ получить продолжительность видео! Поскольку изображение, закодированное в формате H264, не содержит информации о времени.

Если это так, вы все равно можете сделать приближение, если знаете FPS видео... Вам нужно подсчитать все кадры в файле, за исключением:

  • Наборы параметров последовательности
  • Наборы параметров изображения
  • Конец потока
  • Конец последовательности
  • Данные фильтра
  • Разделитель единиц доступа

А потом посчитай: NUMBER_OF_FRAMES / FPS = DURATION_IN_SECONDS

Поток RTP

Если вы ошибаетесь и над каждым блоком NAL есть заголовок RTP, вы можете легко получить продолжительность видео, проверив время RTP каждого заголовка RTP. Что означают байты в заголовке RTP, вы можете узнать здесь: http://www.networksorcery.com/enp/protocol/rtp.htm. Вы хотите получить часть TIMESTAMP (целое число 4 байта) из каждого. Код должен сделать это:

int last_timestamp = GetNextTimestamp();
double duration_in_ms = 0;

while(true)
{
    int next = GetNextTimestamp();
    duration_in_ms += (next - last_timestamp)/90000.0;
    last_timestamp = next;
}
person Cipi    schedule 26.09.2011
comment
эй, это то, что я искал NUMBER_OF_FRAMES / FPS = DURATION_IN_SECONDS, мне просто нужно приблизительное значение - person Jeegar Patel; 26.09.2011

h.264 содержит информацию о времени.

Необработанные данные приложенияb h.264 в той или иной форме (в памяти или в файле) будут содержать некоторые «наборы параметров последовательности» или кадры SPS. Обычно они содержат информацию о времени, в частности «time_scale» и «num_units_in_tick». В большинстве сценариев частота кадров является фиксированной, что указывается флагом «fixed_frame_rate_flag» в SPS. Длительность для каждого кадра будет равна 2 * num_units_in_tick / time_scale (2 == 1 + nuit_field_based_flag). Кадры обычно разделяются «разделителем единиц доступа».

Количество кадров, умноженное на продолжительность кадра, даст вам общую продолжительность.

person Fredrik Widlund    schedule 12.07.2017

Грязный способ получения длительности, который используют многие разработчики, заключается в запуске ffmpeg для получения информации из файла и анализе того, что ffmpeg выводит на стандартный вывод. Я знаю, что это не идеально, но это работает.

Если вы запустите ffmpeg -i Sintel.2010.1080p.mkv (вы можете загрузить Sintel с здесь), одна из выходных строк будет Duration: 00:14:48.03, start: 0.000000, bitrate: 640 kb/s. Вы можете проанализировать строку и извлечь продолжительность.

Возможно, вы сможете получить ту же информацию, вызвав какую-нибудь функцию C из ffmpeg напрямую, но мне это неизвестно.

person Augusto    schedule 15.09.2011
comment
битрейт что значит в видео? - person Jeegar Patel; 15.09.2011
comment
h.264 содержит информацию о времени, см. альтернативный ответ. - person Fredrik Widlund; 13.07.2017