19

環境:

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:

  1. NAL プレフィックス ( 0x00 0x00 0x01) を書き込み、次に SPS または PPS データを書き込みます。

スタートビットによるフラグメンテーション

  1. NAL プレフィックスを書き込む
  2. NAL ユニット バイトの書き込み
  3. 残りの生データを書き込む

スタート ビットなしのフラグメンテーション

  1. 生データの書き込み

これは、生のファイルが次のようになることを意味します。

[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 によって作成されたファイルとの間には、次の違いがあります。

  1. ヘッダー: FFmpeg ファイルには約 0x30 バイトのヘッダーがあります
  2. フッター: FFmpeg ファイルにもフッターがあります
  3. 変更されたプレフィックスと 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 は実際に何をしますか? また、ビデオ データ内の一部のバイトが変更されるのはなぜですか?

4

3 に答える 3

0

ストリームがパケット化されたようです。多くのコンテナ形式は、ビットストリームをパケットに分割し、タイムスタンプやパケットの長さなどの情報を少し追加します。これにより、すべてをデコードせずにファイルをスキップし、パケットが失われたときに再同期し、オーディオ/ビデオ、複数のストリームの結合など

詳細については、MP4 ファイル形式の情報を参照してください:
http://en.wikipedia.org/wiki/MPEG-4_Part_14

于 2012-07-26T21:09:07.827 に答える
-2

変更の詳細については、オープンh264 仕様を参照してください。章附属書 B.

于 2014-04-10T15:28:38.707 に答える