2012-03-08 46 views
10

を識別します。生のH.264データをファイルに入れて、ffmpegと変換できるようにしたい。H.264 - 私はRTPフレームにパックIPカメラからの生のH.264ストリームを持っているSPSとPPSフレーム

私は私の生のH.264ファイルにデータを書き込みたいときに、私はそれがこのように見えるように持って出た:

00 00 01 [SPS] 
00 00 01 [PPS] 
00 00 01 [NALByte] 
[PAYLOAD RTP Frame 1]  // Payload always without the first 2 Bytes -> NAL 
[PAYLOAD RTP Frame 2] 
[... until PAYLOAD Frame with Mark Bit received] // From here its a new Video Frame 
00 00 01 [NAL BYTE] 
[PAYLOAD RTP Frame 1] 
.... 

だから私は私の外にSession Description ProtocolからSPSPPSを取得先にRTSPと通信します。さらに、カメラは、ビデオストリーム自体を開始する前に2つのメッセージにSPSPPSを送信します。

だから私はこの順序でメッセージをキャプチャ:

1. Preceding RTSP Communication here (including SDP with SPS and PPS) 
2. RTP Frame with Payload: 67 42 80 28 DA 01 40 16 C4 // This is the SPS 
3. RTP Frame with Payload: 68 CE 3C 80     // This is the PPS 
4. RTP Frame with Payload: ... // Video Data 

は、その後、いくつかのフレームはMarker Bit = 1でRTPフレームペイロードとし、いくつかの時点で存在しています。これは私が完全にビデオフレームを持っていることを意味します。これのafer私は再びプレフィックスシーケンス(00 00 01)とペイロードからNALを書き、同じ手順で上に行きます。すべての8の完全なビデオが再びSPSPPSをフレーム後

今、私のカメラは私を送信します。 (上記の例のように、2つのRTPフレームでも同様です)。私は特にPPSがストリーミングの間で変更できることを知っていますが、それは問題ではありません。

私の質問は次のようになります。

1.私はSPS/PPSごとに8ビデオフレームを記述する必要がありますか?私のSPSと私のPPSが、彼らが私のファイルと、何よりもの非常に最初に書かれているために十分であるべき変化しないのですか?もし

2. SPS/PPSと通常のRTPフレームを区別するには?

送信データを解析する私のC++コードでは、普通のペイロードを持つRTPフレームと、SPS/PPSを持っているRTPフレームの違いを作る必要があります。どのように私はそれらを区別することができますか?さて、SPS/PPSのフレームは通常は小さいですが、これは依存するセーブコールではありません。私はそれらを無視した場合ので、私は、私は捨てることのできるデータを知る必要があり、または私はそれらを記述する必要がある場合、私は彼らの前に00 00 01プレフィックスを配置する必要があります。 ?それとも、8番目のビデオフレームごとに発生するという固定ルールですか?

+0

ありがとうございます。私はあなたと同じ質問をしています。私はlive555のソースコードを読んで、そのような各パケット/フレームを保存する理由を知らない。このスレッドを読んだら、事は私にはっきりと分かります。 live555の実装に基づく提案として、マーカビットは他のコーデックでのみ使用され、H264にはフレームの開始/終了を表すstart_bitとend_bitがあり、H264ではマーカービットは使用されません。 – user534498

答えて

10
  1. SPSとPPSが変更されない場合は、最初のものを除いて省略することができます。
  2. SPSの場合、各NALのnal_unit_typeフィールドを解析する必要があります(nal_unit_type == 7)。 PPSの場合、nal_unit_type == 8。

nal_unit_typeは、フレームの1バイト目の下位5ビットです。

nal_unit_type = frame[0] & 0x1f; 
+0

これは、 'SPS'フレームと' PPS'フレームの最初の2バイトが他のすべてのRTPフレームの最初の2バイトのような何らかの "NALステータス"ですか?つまり、nal_unit_typeフィールドには、SPSとPPSの7または8が、ビデオデータを意味する28のフィールドと同じフィールドになりますか? – Toby

+2

nal_unit_typeの詳細な定義については、H.264ドキュメントを参照することができます。 btw、(payload [0]&0x1f)== 28はこれが断片化されたビデオフレームであることを意味し、この場合、実際のnal_unit_typeは(payload [1]&0x1f)でなければなりません。これはRFC3984で定義されています。 – ciphor

+0

ええと読みましたが、それを得ました...しかし、あなたはnal_unit_type = 28が断片化したビデオフレームであることをどのように知っていますか? RFC 3984は、http://www-ee.uta.edu/dip/courses/ee5356/H264systems.pdfを参照しています。表7.1(ページ63) - コード28は「未指定」になります。 – Toby

10
  1. あなたは、ストリームの開始時にSPS及びPPSを書くべき、と彼らは、ストリームの途中で変更する場合のみです。

  2. SPS及びPPSフレームはRFC-3984 section 5.7.1

  3. ドンに記載されているNALタイプ24(STAP-A)または25(STAP-B)STAPフォーマットにSTAP NALユニット(一般STAP-A)に充填されていますマーカービットに依存せず、NALヘッダーの開始ビットと終了ビットを使用します。

  4. フラグメント化されたビデオフレームの場合、ペイロード内の最初のバイトの5つのNALタイプビット(開始ビットが1に設定されたパケットのみ)と組み合わせた3つのNALユニットビットの最初のフラグメント(F、NRI) RFC-3984 section 5.8

    断片化 NALユニットのNALユニットタイプオクテットペイロード、 むしろ 断片化されたNALユニットのNALユニットタイプオクテットの情報が搬送される断片化ユニットでそのように含まれていない

    FとNRIのフィールドは、フラグメンテーションユニットのFU インジケータオクテットとのタイプフィールドはFUヘッダーです。

EDIT:フラグメンテーションユニットのNALユニットの構成について以上説明:

| FU indicator | FU header | 
+---------------+---------------+ 
|0|1|2|3|4|5|6|7|0|1|2|3|4|5|6|7| 
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 
|F|NRI| Type |S|E|R| Type | 
+---------------+---------------+ 

これは(右のRTPヘッダの後)FU-ペイロードの最初の2バイトであります

NALユニットを構築するには、「FUヘッダ」から「タイプ」を、「FUインジケータ」から「F」と「NRI」を選択してください。

hereは簡単な実装です

+0

アイテム4を説明できますか?私はスペックのそのセクションを読んだことがあります。あなたが何回引用したのか、私はそれが何を記述しているのか分かりません。これは、これらのルールに基づいてFUインジケータを再構築し、FUヘッダーを破棄し、ペイロードの最初の5ビットを破棄し、再構築されたFUインジケータをペイロードと連結することを意味しますか?ありがとうございます – Joshua

+1

@ジョシュア:もう少し説明を追加しました –

+0

ありがとう、コード例は非常にエレガントで、私はあなたの簡略化した説明に感謝します。後で、あなたが引用した宣言は簡単ですが、項目4の説明はペイロードのビットを使用することを示唆しています。私は今あなたが意味することを理解しています。 – Joshua

関連する問題