2013-05-14 30 views
13

Mam przechwycony strumień H264 w plikach PCAP i próbuję utworzyć pliki multimedialne z danych. Pojemnik nie jest ważny (avi, mp4, mkv, ...).
Kiedy używam videosnarf lub rtpbreak (w połączeniu z kodem Pythona, który dodaje 00 00 00 01 przed każdym pakietem), a następnie ffmpeg, wynik jest OK tylko wtedy, gdy wejściowa liczba klatek jest stała (lub bliska stała). Jednakże, gdy wejście jest vfr, wynik jest odtwarzany zbyt szybko (i w tych samych rzadkich przypadkach zbyt wolno).
Na przykład:Jak przekonwertować strumień H264 RTP z PCAP do odtwarzanego pliku wideo

videosnarf -i captured.pcap –c
ffmpeg -i H264-media-1.264 output.avi

Po jakiejś dochodzenie w kwestii wierzę teraz, że od videosnarf (i rtpbreak) wyjmujesz nagłówek RTP z pakietów, datownik jest stracone i ffmpeg odnosi się do wejścia dane jako cbr.

  1. chciałbym wiedzieć, czy istnieje sposób, aby przekazać (w osobnym pliku?) wektor znaczniki czasowe lub wszelkie inne informacje na FFmpeg więc wynik zostanie utworzony prawidłowo?
  2. Czy mogę w inny sposób pobrać dane z pliku PCAP i odtworzyć lub przekonwertować je, a następnie odtworzyć?
  3. Ponieważ wszystkie prace są wykonywane w języku Python, wszelkie sugestie bibliotek/modułów, które mogą pomóc w pracy (nawet jeśli wymaga to kodowania) są również mile widziane.

Uwaga: Wszystkie prace są wykonywane w trybie offline, bez ograniczeń na wyjściu. Może to być cbr/vbr, każdy możliwy do odtworzenia kontener i transkodowanie. Jedynym „ograniczeniem” mam: wszystko to powinno działać na Linuksie ...

Dzięki Y

Niektóre informacje dodatkowe:
Ponieważ nic nie daje FFMPEG z danymi czasowymi, postanowiłem spróbować innego podejścia : pomiń wideonarf i użyj kodu Pythona, aby przesłać pakiety bezpośrednio do ffmpeg (używając opcji "-f -i -"), ale potem odmawia ich zaakceptowania, chyba że udostępnię plik SDP ...
W jaki sposób udostępnić SDP plik? czy jest to dodatkowy plik wejściowy? („-i config.sdp”)

Poniższy kod jest nieudana próba robi powyżej:

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 

W ogóle to wola rura pakiety z pliku PCAP do następującego polecenia:

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

SDP: [RTP zawiera typ dynamiczny ładunku # 109, H264]

v=0
o=- 0 0 IN IP4 ::1
s=No Name
c=IN IP4 ::1
t=0 0
a=tool:libavformat 53.32.100
m=video 0 RTP/AVP 109
a=rtpmap:109 H264/90000
a=fmtp:109 packetization-mode=1;profile-level-id=64000c;sprop-parameter-sets=Z2QADKwkpAeCP6wEQAAAAwBAAAAFI8UKkg==,aMvMsiw=;
b=AS:200

Wyniki:

ffmpeg version 0.10.2 Copyright (c) 2000-2012 the FFmpeg developers
built on Mar 20 2012 04:34:50 with gcc 4.4.6 20110731 (Red Hat 4.4.6-3) configuration: --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] Format sdp probed with size=2048 and score=50 [sdp @ 0x15c0c00] video codec set to: h264 [NULL @ 0x15c7240] RTP Packetization Mode: 1 [NULL @ 0x15c7240] RTP Profile IDC: 64 Profile IOP: 0 Level: c [NULL @ 0x15c7240] Extradata set to 0x15c78e0 (size: 36)!err{or,}_recognition separate: 1; 1 [h264 @ 0x15c7240] err{or,}_recognition combined: 1; 10001 [sdp @ 0x15c0c00] decoding for stream 0 failed [sdp @ 0x15c0c00] Could not find codec parameters (Video: h264) [sdp @ 0x15c0c00] Estimating duration from bitrate, this may be inaccurate
109c.sdp: could not find codec parameters Traceback (most recent call last): File "./ffpipe.py", line 26, in
ffmpeg_proc.stdin.write(data[42:]) IOError: [Errno 32] Broken pipe

(wybacz masę powyżej, redaktor ciągle narzeka, że ​​kod nie jest wcięte OK ??)

pracuję w tej sprawie przez kilka dni ... Każda pomoc/sugestie/podpowiedź Będzie mile widziane.

+0

Masz szczęście? Szukasz tego samego – spicyramen

+0

Szukasz tego samego. – Rhys

+0

Jeśli możesz napisać c/C++, możesz zmodyfikować videonarf, aby przekazać dane h264 do libavformat. Jednakże, jeśli nigdy nie używałeś libavformat, to zajmie to trochę czasu, ale możesz uzyskać pomoc z listy mailingowej ffmpeg, jak to zrobić. – Pavel

Odpowiedz

1

Jestem pewien, że jedynym sposobem na (suto) byłoby odtworzenie strumienia rtp przy użyciu czasu sieciowego między pakietami jako opóźnienia.

Problem to zmienna liczba klatek na sekundę, ponieważ w h264 nie ma kontenera, który mógłby mu przekazać X ilość czasu, jaki upłynął między tą klatką, a ostatnią, w której nie ma pojęcia, jak wszystko zmierzyć.

Jeśli strumień h264 był stałą liczbą klatek na sekundę, możesz przesyłać dane rtp do ffmpeg bez ustawiania taktowania wejść fps, ale nie znam żadnych strumieni h264 rtp, które działają w ten sposób. Najprawdopodobniej zobaczysz, że strumień wideo gra w niektórych miejscach szybko, a w innych wolno.