Как преобразовать поток RTP H264 из PCAP в воспроизводимый видеофайл

Я захватил поток H264 в файлах PCAP и пытался создать медиафайлы из данных. Контейнер не важен (avi, mp4, mkv,...).
Когда я использую videosnarf или rtpbreak (в сочетании с кодом python, который добавляет 00 00 00 01 перед каждым пакетом), а затем ffmpeg, результат нормально, только если частота входного кадра постоянна (или почти постоянна). Однако, когда вход vfr, результат играет слишком быстро (и в тех же редких случаях слишком медленно).
Например:

videonarf -i capt.pcap -c
ffmpeg -i H264-media-1.264 output.avi

После некоторого исследования проблемы я верю, что, поскольку videosnarf (и rtpbreak) удаляет заголовок RTP из пакетов, метка времени теряется, а ffmpeg ссылается на входные данные как cbr.

  • Я хотел бы знать, есть ли способ пройти (в отдельном файле?) вектор временной метки или любую другую информацию в ffmpeg, чтобы результат будет создан правильно?
  • Есть ли какой-либо другой способ, который я могу извлечь из файла PCAP, воспроизвести его или преобразовать, а затем воспроизвести?
  • Поскольку вся работа выполняется на Python, любое предложение библиотек/модулей, которые могут помочь в работе (даже если требуется некоторая кодировка), также приветствуется.

Примечание. Вся работа выполняется в автономном режиме, без ограничений на выход. Это может быть cbr/vbr, любой воспроизводимый контейнер и транскодирование. Единственное "ограничение", которое у меня есть: все должно работать на linux...

Спасибо У

Дополнительная информация:
Поскольку ничто не дает FFMPEG данным временной метки, я решил попробовать другой подход: skip videosnarf и использовать код Python для прямого подключения пакетов к ffmpeg (используя опции "-f -i -" ), но затем он отказывается принимать это, если я не предоставил файл SDP...
Как предоставить файл SDP? это дополнительный входной файл? ( "-i config.sdp" )

Следующий код - неудачная попытка сделать следующее:

import time  
import sys  
import shutil  
import subprocess  
import os  
import dpkt  

if len(sys.argv) < 2:  
    print "argument required!"  
    print "txpcap <pcap file>"  
    sys.exit(2)  
pcap_full_path = sys.argv[1]  

ffmp_cmd = ['ffmpeg','-loglevel','debug','-y','-i','109c.sdp','-f','rtp','-i','-','-na','-vcodec','copy','p.mp4']  

ffmpeg_proc = subprocess.Popen(ffmp_cmd,stdout = subprocess.PIPE,stdin = subprocess.PIPE)  

with open(pcap_full_path, "rb") as pcap_file:  
    pcapReader = dpkt.pcap.Reader(pcap_file)  
    for ts, data in pcapReader:  
        if len(data) < 49:  
            continue  
        ffmpeg_proc.stdin.write(data[42:])

sout, err = ffmpeg_proc.communicate()  
print "stdout ---------------------------------------"  
print sout  
print "stderr ---------------------------------------"  
print err  

В общем случае это приведет к передаче пакетов из файла PCAP в следующую команду:

ffmpeg -loglevel debug -y -i 109c.sdp -f rtp -i - -na -vcodec copy p.mp4

Файл SDP: [RTP включает динамический тип полезной нагрузки # 109, H264]

v = 0
o = - 0 0 IN IP4:: 1
s = Нет имени
c = IN IP4:: 1
t = 0 0
a = инструмент: libavformat 53.32.100
m = видео 0 RTP/AVP 109
a = rtpmap: 109 H264/90000
а = fmtp: 109 пакетирование режим = 1; профиль уровня-ID = 64000c; sprop-наборы параметров = Z2QADKwkpAeCP6wEQAAAAwBAAAAFI8UKkg ==, aMvMsiw =;
б = АС: 200

Результаты:

версия ffmpeg 0.10.2 Copyright (c) 2000-2012 разработчики FFmpeg
построено 20 марта 2012 года 04:34:50 с gcc 4.4.6 20110731 (Red Hat 4.4.6-3): --prefix =/usr --libdir =/usr/lib64 --shlibdir =/usr/lib64 --mandir =/usr/share/man --enable-shared --enable-runtime -cpudetect --enable-gpl --enable-version3 --enable-postproc --enable-avfilter --enable-pthreads --enable-x11grab --enable-vdpau --disable-avisynth --enable-frei0r --enable -libopencv --enable-libdc1394 --enable-libdirac --enable-libgsm --enable-libmp3lame --enable-libnut --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable- librtmp --enable-libschroedinger --enable-libspeex --enable-libtheora --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libxavs --enable-libxvid --extra-cflags = '- O2 -g -pipe -Wall -Wp, -D_FORTIFY_SOURCE = 2 -fexceptions -fstack-protector -param = ssp-buffer-size = 4 -m64 -mtune = generic -fPIC '-disable-stripping libavutil 51. 35.100/51 35.100 libavcodec 53. 61.100/53. 61.100 libavformat 53. 32.100 /53. 32.100 libavdevice 53. 4.100/53. 4.100
libavfilter 2. 61.100/2. 61.100 libswscale 2. 1.100 /2. 1.100 libswresample 0. 6.100/0. 6.100
libpostproc 52. 0.100/52. 0.100 [sdp @0x15c0c00] Формат sdp с размером = 2048 и счетом = 50 [sdp @0x15c0c00] набор видеокодеков to: h264 [NULL @0x15c7240] Режим пакетной передачи RTP: 1 [NULL @ 0x15c7240] Профиль RTP IDC: 64 Профиль IOP: 0 Уровень: c [NULL @ 0x15c7240] Extradata установлен в 0x15c78e0 (размер: 36)! Err {или,} _ распознавание отдельный: 1; 1 [h264 @0x15c7240] err (или,} _ распознавание: 1; 10001 [sdp @0x15c0c00] для потока 0 не удалось [sdp @ 0x15c0c00] Не удалось найти параметры кодека (видео: h264) [sdp @ 0x15c0c00] Оценка продолжительности от битрейта, это может быть неточно
109c.sdp: не удалось найти параметры кодека Traceback (последнее call last): Файл "./ffpipe.py", строка 26, в
ffmpeg_proc.stdin.write(данные [42:]) IOError: [Errno 32] Broken pipe

(простите массу выше, редактор продолжает жаловаться на код, который не имеет отступов OK?)

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

Ответы

Ответ 1

Я уверен, что единственным способом (разумным) было бы воспроизвести поток rtp, используя время сети между пакетами как задержку.

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

Если поток h264 был постоянной частотой кадров, вы могли бы вывести данные rtp в ffmpeg с отключением таймингов, устанавливающих входы fps, но я не знаю ни одного h264 rtp-потока, которые работают так. То, что вы, скорее всего, увидите, это видеопоток, способный быстро двигаться в некоторых местах и ​​замедляться в других.