オーディオとビデオの 8 部構成のエッセイ -- h264 AnnexB

NALU(ネットワーク抽象層ユニット)

オーディオとビデオのエンコードは、ストリーミング メディアとネットワークの分野で重要な位置を占めています。ストリーミング メディアのエンコードとデコードのプロセスは、次の図に大まかに示されています。

H264 はじめに

H.264 は 1999 年に開始され、2003 年に起草され、2007 年に検証のために最終的に完成されました。ITU 標準では、H.264 と呼ばれます。MPEG 標準では、MPEG-4 – MPEG-4 Part 10 のコンポーネントであり、Advanced Video Codec とも呼ばれます。そのため、多くの場合、MPEG-4 AVC または直接呼ばれます。 AVCと呼ばれます。

この記事の特典として、無料の C++ オーディオおよびビデオ学習教材パッケージ、技術ビデオ/コード (オーディオおよびビデオの開発、インタビューの質問、FFmpeg、webRTC、rtmp、hls、rtsp、ffplay、コーデック、プッシュなど) を受け取ることができます。プルストリーミング、srs)↓↓↓ ↓↓↓下記からご覧ください↓↓無料で入手するには記事下をクリック↓↓

H264 コーデック解析

画像のフレームが H.264 エンコーダを通過した後、1 つまたは複数のスライスにエンコードされ、これらのスライスを運ぶキャリアが NALU です。NALU とスライス (スライス) の関係を見てみましょう。

スライスの概念はフレームとは異なります。フレームはピクチャを記述するために使用され、フレームはピクチャに対応します。スライスは、H.264 で提案された新しい概念です。コンセプトは、H.264 に統合された概念です。ピクチャをエンコードしてからセグメント化することによる効率的な方法です。ピクチャには少なくとも 1 つ以上のスライスがあります。

上の図からわかるように、スライスは NALU にロードされ、ネットワーク経由で送信されます。ただし、これは NALU にスライスが存在する必要があることを意味するものではありません。NALU には他のスライスもロードされる可能性があるため、これは十分かつ不要な条件です。機能、ビデオを説明する情報。

スライスとは何ですか?

スライスの主な機能は、マクロブロックのキャリアとして機能することです (追記: マクロブロックの概念は以下で紹介します)。チップは主にビットエラーの拡散と伝送を制限するために作成されました。

ビットエラーの拡散と伝達を制限するにはどうすればよいでしょうか?

各スライス(slice)は互いに独立して送信される必要があり、あるスライスの予測(スライス(スライス)イントラ予測およびスライス(スライス)インター予測)は、他のスライス内のマクロブロック(Macroblock)を参照として使用することはできません。画像。

画像を使用して、スライスの具体的な構造を説明してみましょう。

ピクチャ/フレームには 1 つ以上のスライス (スライス) を含めることができ、各スライス (スライス) には整数のマクロブロック (マクロブロック) が含まれる、つまり、各スライス (スライス) には少なくとも 1 つのマクロブロック (マクロブロック) が含まれることがわかります。 )、各スライスには最大でも画像全体のマクロブロックが含まれます。

上記の構造では、各スライスにもヘッダーとデータの 2 つの部分が含まれていることを理解するのは難しくありません。 1. スライス ヘッダーには、スライス タイプ、スライス内のマクロブロック タイプ、スライス フレームの数、その画像に属するスライス情報が含まれます。対応するフレームの設定とパラメータ。2. 断片化されたデータにはマクロブロックが含まれており、ここにピクセル データを保存する必要があります。

マクロブロックとは何ですか?

マクロブロックには各ピクセルの輝度とクロミナンス情報が含まれているため、ビデオ情報の主なキャリアです。ビデオ デコードの主なタスクは、コード ストリームからマクロブロック内のピクセル配列を取得する効率的な方法を提供することです。

コンポーネント: マクロブロックは、16×16 輝度ピクセルと、追加の 8×8 Cb および 8×8 Cr カラー ピクセル ブロックで構成されます。各画像では、いくつかのマクロブロックがスライスに配置されます。

上の図から、マクロブロックには、マクロブロック タイプ、予測タイプ、コード化ブロック パターン、量子化パラメータ、ピクセルの明るさと色差データ セットなどの情報が含まれていることがわかります。

H264 エンコード原理

オーディオとビデオの送信プロセスでは、ビデオ ファイルの送信が大きな問題になります。ビデオ ファイルの解像度は 1920*1080、各ピクセルは RGB で 3 バイトを占め、フレーム レートは 25 です。送信帯域幅の要件は次のとおりです。 :

1920 1080 3*25/1024/1024=148.315MB/s、bps に変更すると、1 秒あたりのビデオ帯域幅が 1186.523Mbps になることを意味しますが、これはネットワーク ストレージとしては許容できません。そこで、ビデオ圧縮およびエンコード技術が登場しました。

ビデオ ファイルの場合、ビデオは 1 つの画像フレーム (1 秒あたり 25 フレームなど) で構成されますが、画像フレームのピクセル ブロック間には類似性があるため、ビデオ フレームの画像を圧縮できます。H264 では、A ブロック サイズ 16 が採用されています。 ※16を選択し、同様にビデオフレーム画像を比較圧縮します。以下に示すように:

H264 の I フレーム、P フレーム、および B フレーム

H264 は、フレーム内圧縮とフレーム間圧縮を使用してエンコード圧縮率を向上させます。H264 は、独自の I フレーム、P フレーム、および B フレーム戦略を使用して、連続するフレーム間の圧縮を実現します。

図1に示すように、

圧縮比 B > P > I

H264 エンコーディング構造の分析

ビデオ圧縮の実装に加えて、H264 は、ネットワーク送信を容易にするために、対応するビデオ エンコードと断片化戦略も提供します。ネットワーク データを IP フレームにカプセル化するのと同様に、H264 ではグループ (GOP)、ピクチャのグループ、スライス、およびマクロブロックと呼ばれます。これらは一緒になって H264 のコード ストリームの階層構造を形成し、H264 はそれをシーケンス (GOP)、ピクチャ (pictrue)、スライス (Slice) に編成し、マクロブロックとサブブロックの 5 つのレベルがあります。GOP (Group of Pictures) は主に、1 つの IDR フレームと次の IDR フレームの間に何フレームあるかを記述するために使用されます。

H264 では、ビデオを連続したフレームに分割して送信し、連続したフレームの間に I フレーム、P フレーム、および B フレームを使用します。同時に、フレーム内音声については、画像をスライス、マクロブロック、ワードブロックに分割してセグメンテーションして送信し、このプロセスを通じてビデオファイルを圧縮してパッケージ化します。

IDR (インスタント デコーディング リフレッシュ、インスタント デコーディング リフレッシュ)

シーケンスの最初のイメージは IDR イメージ (即時にリフレッシュされたイメージ) と呼ばれ、IDR イメージはすべて I フレーム イメージです。

I フレームと IDR フレームは両方ともイントラ予測を使用します。I フレームは任意のフレームを参照する必要はありませんが、後続の P フレームおよび B フレームはこの I フレームより前のフレームを参照する場合があります。IDR はこれを許可しません。例 (デコード順序):

IDR1 P4 B2 B3 P7 B5 B6 I10 B8 B9 P13 B11 B12 P16 B14 B15 B8 は、I10 と交差して P7 の元のイメージを参照できます: IDR1 B2 B3 P4 B5 B6 P7 B8 B9 I10

ここでの IDR1 P4 B2 B3 P7 B5 B6 IDR8 P11 B9 B10 P14 B11 B12 B9 は IDR8 と P11 のみを参照でき、IDR8 より前のフレームを参照できません。

その中心的な機能はデコードを再同期することであり、デコーダが IDR イメージをデコードすると、直ちに参照フレーム キューをクリアし、すべてのデコードされたデータを出力または破棄し、パラメータ セットを再度検索して、新しいシーケンスを開始します。このようにして、前のシーケンスに重大なエラーがあった場合に、ここで再同期する機会を得ることができます。IDR イメージに続くイメージは、IDR より前のイメージのデータを使用してデコードされることはありません。

以下は H264 コード ストリームの例です (コード ストリームのフレーム分析から、B フレームを参照フレームとして使用できないことがわかります)

I0 B40 B80 B120 P160I0 B160

SPS: シーケンス パラメータ セット SPS は、符号化ビデオ シーケンス (符号化ビデオ シーケンス) のグローバル パラメータのセットを格納します。

PPS: 画像パラメータ セット。シーケンス内の特定の画像または複数の画像のパラメータに対応します。

I フレーム: 独立してデコードして完全な画像を生成できるイントラコード化フレーム。

P フレーム: 前方予測コーディング フレーム。完全なピクチャを生成するには、その前の I または B を参照する必要があります。

B フレーム: 双方向予測内挿コーディング フレームは、前の I または P フレームと次の P フレームを参照して完全な画像を生成します。

I フレームを送信する前に、SPS と PPS を少なくとも 1 回送信する必要があります。

この記事の特典として、無料の C++ オーディオおよびビデオ学習教材パッケージ、技術ビデオ/コード (オーディオおよびビデオの開発、インタビューの質問、FFmpeg、webRTC、rtmp、hls、rtsp、ffplay、コーデック、プッシュなど) を受け取ることができます。プルストリーミング、srs)↓↓↓ ↓↓↓下記からご覧ください↓↓無料で入手するには記事下をクリック↓↓

NALUの構造

H.264のオリジナルコードストリーム(ネイキッドストリーム)はNALUを次々と構成しており、その機能はVCL(Videocoding Layer)とNAL(Network Extraction Layer)の2層に分かれています。

VCL: コア圧縮エンジンと、ブロック、マクロブロック、スライスの構文レベルの定義が含まれており、設計目標は、ネットワークから可能な限り独立して効率的なエンコードを可能にすることです。

NAL: VCL によって生成されたビット文字列をさまざまなネットワークやさまざまな環境に適応させる責任を負い、映画レベルを超えるすべての構文レベルをカバーします。

VCL がデータの送信または保存を実行する前に、これらのエンコードされた VCL データは NAL ユニットにマッピングまたはカプセル化されます。

(波)

NALU 構造単位の主な構造は次のとおりです。元の H.264 NALU 単位は通常、[StartCode] [NALU Header] [NALU Payload] の 3 つの部分で構成されます。Start Code は、これがデータの始まりであることを示すために使用されます。 NALU ユニット。「00 00 00 01」または「00 00 01」である必要があります。それ以外の場合は、基本的に NAL ヘッダー + RBSP と同等です。

(FFmpeg 逆多重化後、MP4 ファイルから読み取られたパケットにはスタートコードがありませんが、TS ファイルから読み取られたパケットにはスタートコードがあります)

NALUを解析する

各 NAL ユニットは、1 バイトのヘッダー情報 (データ タイプを示すために使用) やペイロード データの数バイトの整数バイトなど、特定の構文要素を含む可変長のバイト文字列です。

NALUヘッダ情報(1バイト):

で:

T はロード データ タイプで、5 を占めます。 bitnal_unit_type: この NALU ユニットのタイプ、1 ~ 12 は H.264 で使用され、24 ~ 31 は H.264 以外のアプリケーションで使用されます。

R は重要度インジケーター ビットで、2 ビット snal_ref_idc を占めます。 00 ~ 11 は、この NALU の重要性を示すようです。たとえば、00 NALU デコーダーは画像の再生に影響を与えずにこの NALU を破棄できます。0 ~ 3、値が大きいほど、 value は、現在の NAL がより重要であり、最初に保護する必要があることを示します。現在の NAL が参照フレーム、シーケンス パラメータ セット、またはイメージ パラメータ セット、これらの重要な単位に属するスライスである場合、この構文要素は 0 より大きくなければなりません。

最後の F は禁止ビットで、1bitforbidden_​​zero_bit を占めます。H.264 仕様では、このビットは 0 でなければならないと規定されています。

H.264 標準では、データ ストリームがメディアに保存されるときに、NALU の開始位置と終了位置を示すために、各 NALU の前に開始コード 0x000001 または 0x00000001 が追加されると規定されています。

このような仕組みにより、コードストリーム中からNALUの開始識別子としてスタートコードが検出され、次のスタートコードが検出された時点で現在のNALUが終了する。

3 バイトの 0x000001 は 1 回だけ使用されます。つまり、完全なフレームが複数のスライス (スライス) にコンパイルされるとき、これらのスライスを含む NALU は 3 バイトの開始コードを使用します。それ以外の場合は、4 バイトの 0x00000001 です。

例: 0x00 00 00 01 67 …0x00 00 00 01 68 …0x00 00 00 01 65 …67: バイナリ: 0110 011100111 = 7 (10 進数)

NALU 分析では、このレッスンでは主に 5/6/7/8 の 4 つのタイプに焦点を当てます。

H264 annexb モード

H264 には 2 つのパッケージがあります

1 つは annexb モードで、ES の startcode、SPS、および PPS を使用する従来のモードです。

1 つは mp4 モードです。一般的に mp4 mkv は mp4 モードです。スタートコードはありません。SPS と PPS およびその他の情報はコンテナーにカプセル化されます。各フレームの最初の 4 バイトがフレームの長さです。

多くのデコーダは annexb モードのみをサポートしているため、mp4 を変換する必要があります。変換するには、ffmpeg で h264_mp4toannexb_filter を使用します。

成し遂げる:

const AVBitStreamFilter *bsfilter = av_bsf_get_by_name("h264_mp4toannexb");
AVBSFContext *bsf_ctx = NULL;
// 2 初始化过滤器上下⽂
av_bsf_alloc(bsfilter, &bsf_ctx); //AVBSFContext;
// 3 添加解码器属性
avcodec_parameters_copy(bsf_ctx->par_in, ifmt_ctx>streams[videoindex]->codecpar);
av_bsf_init(bsf_ctx);

補足説明

GOP グループの写真

GOP は 2 つの I フレーム間の間隔を指します。比較のために、GOP は 120 です。720 p60 の場合、2 秒ごとの I フレームです。ビデオ エンコード シーケンスでは、エンコードされたフレームには主に 3 つのタイプがあります: I フレーム、以下に示すように、P フレーム フレーム、B フレーム:

  1. I フレームは、イントラ符号化されたピクチャ (イントラ符号化された画像フレーム) であり、他の画像フレームを参照せず、このフレームの情報のみを符号化に使用します。
  2. PフレームはPredictive-codedPicture(予測符号化ピクチャフレーム)であり、前のIフレームまたはPフレームを利用して、動き予測を用いたフレーム間予測符号化を行う。
  3. B フレームは、最も圧縮率の高い双方向予測ピクチャ (双方向予測符号化画像フレーム) で、前の画像フレーム (I フレームまたは P フレーム) と後続の画像フレーム (P フレーム) の両方に動き予測を使用する必要がある方式です。フレーム間の双方向予測符号化を実行します。

ビデオコーディングシーケンスでは、GOP はグループオブピクチャであり、2 つの I フレーム間の距離を指し、リファレンスは 2 つの P フレーム間の距離を指します。I フレームは P フレームよりも多くのバイトを占有し、P フレームは B フレームよりも多くのバイトを占有します。

したがって、コードレートが変わらないという前提の下では、GOP 値が大きいほど P および B フレームの数が多くなり、I、P、B の各フレームが平均して占めるバイト数が多くなり、取得が容易になります。画質が良くなります。Reference が大きいほど、B フレームの数が多くなり、同様に、より良い画質が得られやすくなります。

なお、GOP値を大きくしても画質向上には限界があり、シーンの切り替わり時にH.264エンコーダが自動的にIフレームを挿入するため、実際のGOP値は短くなります。一方、GOP では I フレームから P フレームと B フレームを予測しますが、I フレームの画質が比較的悪い場合、GOP 内の後続の P フレームと B フレームの画質に影響を与えることはできません。次の GOP が始まるまで回復するため、GOP 値をあまり大きく設定しないでください。同時に、P フレームと B フレームの複雑さは I フレームの複雑さよりも大きいため、P フレームと B フレームが多すぎると符号化効率に影響し、符号化効率が低下します。また、GOP が長すぎるとシーク動作の応答速度にも影響しますが、P フレームと B フレームは前の I フレームまたは P フレームから予測されるため、シーク動作を直接配置する必要があります。 , まず、この GOP の I フレームと前の N 個の予測フレームをデコードする必要があります。GOP の値が長いほど、デコードする必要がある予測フレームの数が多くなり、シークの応答時間も長くなります。

H.264 の I フレーム、B フレーム、および P フレーム

H264 の画像は、I フレームから始まり次の I フレームで終わる、画像符号化後のデータ ストリームであるシーケンスという単位で構成されます。

IDR イメージ: シーケンスの最初のイメージは IDR イメージ (即時リフレッシュ イメージ) と呼ばれ、IDR イメージはすべて I フレーム イメージです。

H.264 では、デコードの再同期のために IDR イメージが導入されており、デコーダが IDR イメージをデコードすると、直ちに参照フレーム キューをクリアし、すべてのデコードされたデータを出力または破棄し、パラメータ セットを再度検索して、新しいシーケンスを開始します。そうすることで、前のシーケンスで何か重大な問題が発生した場合に、再同期する機会が得られます。IDR イメージの後のイメージは、IDR より前のイメージ データを使用してデコードされることはありません。

シーケンスとは、内容がそれほど変わらない画像をエンコードした後に生成される一連のデータ ストリームです。モーションの変化が比較的小さい場合、シーケンスは非常に長くなる可能性があります。モーションの変化が小さいということは、イメージ スクリーンのコンテンツの変化がほとんどないことを意味するため、I フレームを編集し、P フレームと B フレームを保持することができます。モーションの変化が多い場合、シーケンスは比較的短くなります。たとえば、1 つの I フレームと 3 つまたは 4 つの P フレームが含まれます。

3 種類の IPB フレームの説明

1. I フレーム I フレーム: フレーム内エンコード フレーム。I フレームはキー フレームを表し、このフレームの完全な保持として理解できます。デコード時にはこのフレームのデータのみが必要です (完全なフレームが含まれているため)。

I フレームの特徴:

  1. フルフレーム圧縮でエンコードされたフレームです。JPEG 圧縮エンコードとフルフレーム画像情報の送信を実行します。
  2. デコード中に、I フレームのデータのみを使用して完全な画像を再構築できます。
  3. I フレームは、画像の背景と動く被写体の詳細を記述します。
  4. I フレームは他のフレームを参照して生成する必要はありません。
  5. I フレームは、P フレームと B フレームの参照フレームです (その品質は、同じグループ内の後続のフレームの品質に直接影響します)。
  6. I フレームはフレーム グループ GOP の基本フレームです (IDR の場合は最初のフレームです)。グループ内には IDR フレームが 1 つだけあり、I フレーム (IDR フレームを含む) が 1 つ以上あります。
  7. I フレームでは動きの量を考慮する必要はありません。
  8. I フレームが占めるデータに含まれる情報量は比較的多くなります。

2.Pフレーム

P フレーム: 前方予測符号化フレーム。P フレームは、このフレームと 1 つ前のキー フレーム (または P フレーム) との差分を表し、デコード時には、このフレームで定義された差分を、以前にキャッシュされたピクチャと重ね合わせて、最終的なピクチャを生成する必要があります。(つまり、差分フレーム、P フレームには完全な画像データはなく、前のフレームの画像と異なるデータのみが含まれます)

P フレームの予測と再構成: P フレームは、I フレームを参照フレームとして使用し、I フレーム内の P フレームの「ある点」の予測値と動きベクトルを求め、予測差分を取得して動きベクトルを送信します。一緒に。受信側では、Iフレームから動きベクトルに基づいてPフレームの「ある点」の予測値を求め、その差分を加算してPフレームの「ある点」のサンプル値を求め、これにより、完全な P フレームが得られます。

P フレームの特徴:

  1. P フレームは、I フレームの 1 ~ 2 フレーム遅れの符号化フレームです。
  2. P フレームは、動き補償の方法を使用して、前の I または P フレームとの差分および動きベクトル (予測誤差) を送信します。
  3. デコード時には、I フレームの予測値と予測誤差を加算して、完全な P フレーム画像を再構成する必要があります。
  4. P フレームは、前方予測フレーム間コーディングです。これは、それに最も近い前の I フレームまたは P フレームのみを参照します。
  5. P フレームは、その後ろの P フレームの参照フレーム、またはその前後の B フレームの参照フレームにすることができます。
  6. P フレームは参照フレームであるため、復号エラーが拡散する可能性があります。
  7. 差動伝送なのでPフレームの方が圧縮率が高くなります。

3.Bフレーム

B フレーム: 双方向予測補間符号化フレーム。B フレームは双方向の差分フレームです。つまり、B フレームはこのフレームと前後のフレームの差分を記録します (詳細はさらに複雑で、4 つの状況がありますが、わかりやすくするためにこのようにしました)つまり、B フレームをデコードするには、キャッシュされた前のピクチャを取得するだけでなく、後続のピクチャもデコードし、前後のピクチャとこのフレームのデータを重ね合わせて最終的なピクチャを取得する必要があります。Bフレームは圧縮率が高いですが、デコード時にCPUが疲れてしまいます。

B フレームの予測と再構成

B フレームは、前の I または P フレームと次の P フレームを参照フレームとして、B フレーム内の「ある点」の予測値と 2 つの動きベクトルを「見つけ出し」、予測差分と動きベクトルを取得します。送信用。受信側は、動きベクトルに基づいて 2 つの参照フレームの予測値を「見つけて (計算し)」、その差分と合計して B フレームの「ある点」のサンプル値を取得し、完全な B フレームを取得します。

Bフレームの特徴

1) B フレームは、前の I または P フレームと次の P フレームによって予測されます。

2) B フレームは、前の I または P フレームおよび次の P フレームとの間の予測誤差および動きベクトルを送信します。

3)Bフレームは双方向予測符号化フレームである。

4) B フレームは 2 つの参照フレーム間の動被写体の変化のみを反映し、予測がより正確であるため、圧縮率が最も高くなります。

5) B フレームは参照フレームではないため、復号エラーの拡散を引き起こしません。

注: I、B、および P フレームは、圧縮アルゴリズムのニーズに従って人為的に定義されており、すべて実際の物理フレームです。一般的に、I フレームの圧縮率は 7 (JPG と同様)、P フレームの圧縮率は 20、B フレームの圧縮率は 50 に達することがあります。B フレームを使用すると多くのスペースを節約でき、節約されたスペースをより多くの I フレームの保存に使用でき、同じビット レートでより良い画質を提供できることがわかります。

H264 コードストリームの 6 層構造は非常に重要です

この絵は自分で描きたかったのですが、ネット上にある絵と互換性がなく、拡散には好ましくないので、そのまま引用させていただきました。

以下の図の 1 番目、2 番目、および 3 番目の層は非常に重要であり、開発中に遭遇します。

H.264 エンコードされたビデオの各画像グループ (GOP、画像グループ) には、送信シーケンス (PPS) とフレーム自体の画像パラメーター (SPS) が与えられるため、全体的な構造は次のようになります。

H.264 では、構文要素はシーケンス、イメージ、スライス、マクロブロック、サブマクロブロックの 5 つのレベルに編成されます。

この記事の特典として、無料の C++ オーディオおよびビデオ学習教材パッケージ、技術ビデオ/コード (オーディオおよびビデオの開発、インタビューの質問、FFmpeg、webRTC、rtmp、hls、rtsp、ffplay、コーデック、プッシュなど) を受け取ることができます。プルストリーミング、srs)↓↓↓ ↓↓↓下記からご覧ください↓↓無料で入手するには記事下をクリック↓↓

おすすめ

転載: blog.csdn.net/m0_60259116/article/details/132741804