2013-05-14 127 views
13

PCAPファイルにH264のストリームをキャプチャし、データからメディアファイルを作成しようとしました。コンテナは重要ではありません(avi、mp4、mkv、...)。
またはrtpbreak(各パケットの前に00 00 00 01を追加するPythonコードと組み合わせて)とffmpegを使用すると、入力フレームレートが一定(またはほぼ一定)の場合のみ結果がOKになります。しかし、入力がvfrの場合、結果は非常に速く再生されます(同じまれなケースでは遅すぎます)。たとえば
H264 RTPストリームをPCAPから再生可能なビデオファイルに変換する方法

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

videosnarf(およびrtpbreak)パケットからRTPヘッダを削除しているので、今では、私は信じている問題のいくつかの調査を行った後、タイムスタンプが失われ、ffmpegの入力を参照していますデータはcbrです。

  1. 私が合格する方法があるかどうかを知りたいと思います(別のファイルには?) 結果が正しく作成されますので、ffmpegのためのタイムスタンプベクトルやその他の情報?
  2. PCAPファイルからデータを取り出して再生したり、変換して再生する方法はありますか?
  3. すべての作業はPythonで行われるので、作業に役立つライブラリ/モジュールの提案(コード化が必要な場合でも)は歓迎です。

注:すべての作業はオフラインで行われ、出力に制限はありません。それは、cbr/vbr、任意の再生可能なコンテナ、トランスコードすることができます。唯一の「限界」私が持っている:それはすべてのLinux上で実行する必要があります...

おかげ Yを

いくつかの追加情報が

:何がタイムスタンプデータとFFMPEGを提供していないので
は、私は別のアプローチをとることに決めた :videosnarfをスキップし、パケットを直接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ファイル:

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

結果[RTPダイナミックペイロードタイプ#109、H264を含む]:

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

(エディタがインデントOK ??ないコード不満に保つ、上記の質量を許す)

私は日のために、この問題に取り組んでいます...任意のヘルプ/提案/ヒント感謝されます。

+0

これで運がいいですか?同じものを探す – spicyramen

+0

同じものを探す – Rhys

+0

c/C++を書くことができれば、videosnarfを修正してh264データをlibavformatに渡すことができます。しかし、あなたがlibavformatを使ったことがないなら、それに慣れるまでに時間がかかりますが、ffmpegメーリングリストの助けを借りてそれを行うことができます。 – Pavel

答えて

1

パケット間のネットワーク時間を遅延として使用して、rtpストリームを再生するには、(sanely)するしかありません。

問題は可変フレームレートです。h264の周りにコンテナがないので、このフレームと最後のフレームとの間に経過した時間Xは、どのようにすべて時間を計るか分かりません。

h264ストリームが一定のフレームレートだった場合、入力fpsを設定するタイミングを外してrtpデータをffmpegにプッシュすることができますが、そのように動作するh264 rtpストリームはわかりません。最もよく見られるのは、ビデオストリームが一部のパートでは高速で、他のパートでは遅く再生する方法です。

関連する問題