IPカメラからの生のH.264ストリームがRTPフレームにパックされています。生のH.264データをファイルに取得して、ffmpeg
で変換できるようにしたいです。 。
したがって、生の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]
....
したがって、前のSPS
通信からSession Description Protocol
からPPS
とRTSP
を取得します。さらに、カメラは、ビデオストリーム自体を開始する前に、2つの単一メッセージでSPS
とPPS
を送信します。
したがって、メッセージを次の順序でキャプチャします。
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
次に、ペイロード付きのフレームがいくつかあり、ある時点でa RTP Marker Bit = 1
付きのフレーム。これは、(正しく理解できれば)完全なビデオフレームがあることを意味します。これ以降、プレフィックスを記述しますペイロードから(00 00 01
)とNAL
を再度シーケンスし、同じ手順を続行します。
これで、カメラは8つの完全なビデオフレームごとにSPS
とPPS
を再度送信します。 (上記の例に見られるように、2つのRTPフレームで)。特にPPS
はストリーミングの間に変更される可能性があることを知っていますが、それは問題ではありません。
私の質問は今です:
1.8番目のビデオフレームごとにSPS/PPSを書き込む必要がありますか?
SPS
とPPS
が変更されない場合は、ファイルの最初に書き込むだけで十分ですか?
2。SPS/PPSと通常のフレームを区別する方法RTPフレーム?
送信されたデータを解析する私のC++コードでは、RTP通常のペイロードのフレームとSPS/PPS
を運ぶフレームを区別する必要があります。どうすればそれらを区別できますか?さて、SPS/PPS
フレームは通常方法です小さいですが、これは信頼できる保存呼び出しではありません。無視する場合は、破棄できるデータを知る必要があるため、または書き込む必要がある場合は、その前に00 00 01
プレフィックスを付ける必要があります。それらは8番目のビデオフレームごとに発生するという固定ルールですか?
私が覚えているように、nal_unit_typeはフレームの最初のバイトの下位5ビットです。
nal_unit_type = frame[0] & 0x1f;
SPSとPPSは、ストリームの開始時に、ストリームの途中で変更された場合にのみ記述してください。
SPSおよびPPSフレームは、NALタイプ24(STAP-A)または25(STAP-B)のSTAP NALユニット(通常はSTAP-A)にパックされます。STAP形式は RFC-3984セクション5.7.1
マーカービットに依存せず、NALヘッダーの開始ビットと終了ビットを使用します。
フラグメント化されたビデオフレームの場合、ペイロードの最初のバイトの5つのNALタイプビットと組み合わせた最初のフラグメント(F、NRI)の3つのNALユニットビットを使用してNALユニットを再生成する必要があります(開始ビットが1に設定されたパケットの場合のみ)チェック RFC-3984セクション5.8 :
フラグメント化されたNALユニットのNALユニットタイプオクテットは、フラグメント化ユニットペイロードにそのまま含まれませんが、フラグメント化されたNALユニットのNALユニットタイプオクテットの情報は、FUインジケーターオクテットおよびFUヘッダーのタイプフィールド。
編集:フラグメンテーションユニットのNALユニット構築に関する詳細:
これは、FU-Aペイロードの最初の2バイトです(rtpヘッダーの直後)。
| 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 |
+---------------+---------------+
nALユニットを構築するには、「FUヘッダー」から「タイプ」を、「FUインジケーター」から「F」と「NRI」を取得する必要があります。
ここ は単純な実装です