環境:
H.264 エンコード形式で RTP 経由でデータをストリーミングできる IP カメラがあります。この raw ストリームは、イーサネットから記録されます。そのデータで、私は働かなければなりません。
ゴール:
最後に、一般的なメディア プレーヤー (VLC や Windows MP など) で再生できる *.mp4 ファイルが必要です。
私はこれまでに何をしましたか:
持っている生のストリーム データを取得して解析します。データは RTP 経由で送信されたので、NAL バイト、SPS、および PPS を処理する必要があります。
1.生ファイルの書き込み
最初に、イーサネット経由で受信した各フレームのタイプを判別します。そのために、すべての RTP ペイロードの最初の 2 バイトを解析して、8 NAL ユニット ビット、フラグメント タイプ ビット、開始ビット、予約ビット、終了ビットを取得します。ペイロードでは、次のように配置されています。
Byte 1: [ 3 NAL Unit Bits | 5 Fragment Type Bits]
Byte 2: [Start Bit | Reserved Bit | End Bit | 5 NAL Unit Bits]
これから私は決定することができます:
- ビデオ フレームの開始と終了 -> 開始ビットと終了ビット
- ペイロードのタイプ -> 5 フラグメント タイプ ビット
- NAL ユニットバイト
私の場合に必要なフラグメントタイプは次のとおりです。
Fragment Type 7 = SPS
Fragment Type 8 = PPS
Fragment Type 28 = Video Fragment
NAL バイトは、バイト 1 と 2 の NAL ユニット ビットを組み合わせて作成されます。
断片化のタイプに応じて、次のことを行います。
SPS/PPS:
- NAL プレフィックス (
0x00 0x00 0x01
) を書き込み、次に SPS または PPS データを書き込みます。
スタートビットによるフラグメンテーション
- NAL プレフィックスを書き込む
- NAL ユニット バイトの書き込み
- 残りの生データを書き込む
スタート ビットなしのフラグメンテーション
- 生データの書き込み
これは、生のファイルが次のようになることを意味します。
[NAL Prefix][SPS][NAL Prefix][PPS][NAL Prefix][NAL Unit Byte][Raw Video Data][Raw Video Data]....[NAL Prefix][NAL Unit Byte][Raw Video Data]...
ストリーム データで見つけたすべての PPS と SPS に対して、NAL プレフィックス ( 0x00 0x00 0x01 ) を書き込んでから、SPS/PPS 自体を書きます。
現在、このデータを一部のメディアプレーヤーで再生できないため、次のようになります。
2.ファイルを変換する
コーデックをあまり使用しないようにしたかったので、既存のアプリケーション -> FFmpeg を使用することにしました。これは、これらのパラメーターを使用して呼び出しています。
ffmpeg.exe -f h264 -i <RawInputFile> -vcodec copy -r 25 <OutPutFilename>.mp4
-f h264
:これは、h264コード化されたストリームがあることをffmpegに伝えるはずです
-vcodec copy
: マンページからの引用:
Force video codec to codec. Use the "copy" special value to tell that the raw codec data must be copied as is.
-r 25
: フレームレートを 25 FPS に設定します。
これらのパラメーターを使用して ffmpeg を呼び出すと、VLC と Windows MP で再生できる .mp4 ファイルが取得されるため、実際に機能します。しかし、ファイルは私の生のファイルとは少し異なって見えます。
これは私の質問につながります:
私は実際に何をしましたか?
私の問題は、それが機能していないということではありません。ffmpeg を呼び出して実際に何をしたかを知りたい/知りたいだけです。再生できない未加工の H264 ファイルがありました。FFmpegを使用した後、再生できます。
元の raw ファイル (私が作成したもの) と FFmpeg によって作成されたファイルとの間には、次の違いがあります。
- ヘッダー: FFmpeg ファイルには約 0x30 バイトのヘッダーがあります
- フッター: FFmpeg ファイルにもフッターがあります
- 変更されたプレフィックスと 2 つの新しいバイト:
Raw ファイルからの新しいビデオ フレームは
[NAL Prefix][NAL Unit Byte][Raw Video Data]
、新しいファイルのように開始されますが、次のようになります。
[0x00 0x00][2 "Random" Bytes][NAL Unit Byte][Raw Video Data].....[0x00 0x00[2 other "Random" Bytes][NAL Unit Byte][Raw Video Data]...
Video Stream にはコンテナ形式が必要であることを理解しています (間違っていたら訂正してください。ただし、新しいヘッダーとフッターが原因であると思います)。しかし、実際に生データの一部のバイトが変更されるのはなぜですか? ストリーム自体はffmpegではなくプレーヤーによってデコードされる必要があるため、デコードすることはできません。
ご覧のとおり、私の問題には説明以上の新しい解決策は必要ありません (したがって、自分で説明できます)。ffmpeg は実際に何をしますか? また、ビデオ データ内の一部のバイトが変更されるのはなぜですか?