SDP セッションの UDP ストリームをデコード可能な H.264 ストリームに変換する際に、いくつかの基本的なことが欠けています。H.264 対応のカメラでテストしており、プレーヤーでストリームを直接再生できます。翻訳されたストリームを再生しようとすると、プレーヤーによって認識されません (ヘッダーの欠落エラー)。ただし、これを Java アプリケーションに統合できるようにするには、UDP ストリームをデコードする必要があります。
私はすでに次の質問に対する非常に良い答えを見てきました:
- DirectShow ソース フィルターのデコーダー フィルターでデコードできるように生の UDP パケットを処理する方法
- ffmpeg (libavcodec) で H264 ビデオを RTP 経由でデコードする際の問題
どちらにもいくつかの小さな違いがあり、混乱を招きます (以下を参照)。
しかし、最初に簡単な部分を見てみましょう。カメラから見ると、SPS パケットと PPS パケットが送信されています。残りのすべてのパケットは、インデックス化されているかどうかにかかわらず、断片化されたフレームです。
フレームのないすべてのパケット (私の場合は NALUnitType 7 と 8 のみ) について、RTP ヘッダー (12 バイト) を取り除き、開始バイト 3 x 0 バイトと 1 x 1 を前に追加します (00 00 00 01)。
すべてのフラグメント化されたフレーム パケットについて、回答 1 の説明に従って再構築します。つまり、詳細には、RTP ヘッダーを削除します (これをデータ検証に使用します)。次に、ペイロードからフラグメント情報をデコードします。
最初のバイト: [ 3 NAL UNIT BITS | 5 FRAGMENT TYPE BITS]
2 番目のバイト: [ START BIT | エンドビット | 予約済みビット | 5 NALユニットビット]
開始ビットが設定されている場合、次のように構築された新しいペイロード ヘッダーがあります。[3 NAL UNIT BITS (最初のバイトから) | 5 NAL UNIT BITS (2 番目のバイトから)]
これにより、非 IDR スライスの NALUnitType 1 または IDR スライスの 5 が得られます。これは仕様によるものです。
この新しいペイロード ヘッダー (1 バイト) を取得し、2 バイトのヘッダーを除いたペイロードを新しいパッケージに添付します。エンド ビット情報が表示されるまで、すべての連続するフラグメントが同じ方法で追加されます (12 バイトの RTP ヘッダーのストリップ、ユニット タイプ情報の 2 バイトのストリップ)。最後が見えたら、このパケットの前に開始バイト (00 00 00 01) を置き、それをストリームに書き出します。
問題は、不明な理由でデコードできないことです。私が読んだ回答の回答 2 の違いは、ペイロード ヘッダーの 2 番目のバイトが変換されたパケットにも配置される可能性があることです。しかし、私は両方を試しましたが、まだ運がありません。
おそらく、新しく構築されたストリームには他に何か欠けているものがありますか? または、デフラグを間違えていますか?