H.264についてprofile-level-id



About H 264 Profile Level Id



WebRTC開発では、ビデオストリームのエンコードタイプとしてH.264を使用すると、問題が発生します。つまり、エンコーダーとデコーダーが独自のエンコードおよびデコード機能をネゴシエートする必要があります。たとえば、エンコーダーが高レベルのプロファイルとレベルを使用している場合、またはデコーダーがサポートしていないエンコード機能を使用している場合、デコーダーにとっては災害になります。

ご存知のとおり、H.264のプロファイルとレベルにはさまざまな種類があり、すべてのエンコーダーまたはデコーダーがすべてのプロファイルとレベルをサポートしているわけではありません。実際のアプリケーションでは、H.264のプロファイルとレベルを識別するために3バイトの値(42801fなど)がよく見られます。この記事は、H.264のプロファイルレベルを簡単に記録して説明するためのものです。 IDの見方。



H.264のプロファイルとレベルは何ですか?

ここでは詳しく説明しません。次の2つのリンクに詳細なリストがあります。
https://en.wikipedia.org/wiki/Advanced_Video_Coding#Profiles
https://en.wikipedia.org/wiki/Advanced_Video_Coding#Levels
プロファイルとレベルには非常に多くの種類がありますが、WebRTCまたはリアルタイムストリーミングメディア処理で一般的なものはごくわずかです。たとえば、WebRTCはデフォルトでOpenH264を使用し、そのエンコーダーは制約付きベースライン+レベル5.2のみをサポートします(を参照) OpenH264 github ホームページの説明)。

参照文書

典型的なプロファイルレベルIDの例

Profile-level-idはsdpで一般的です。たとえば、chrome:// webrtc-internalsで、H.264でエンコードされたビデオストリームをプッシュすると、ローカルsdpでこのprofile-level-idを確認できます。
画像
このprofile-level-idは、上記のリファレンスにあります RFC6184 8.1メディアタイプ登録セクションに詳細な説明があります。



見方を説明するために例を挙げましょう。上の図に示されている値を取ります。次の4つを含みます。

42001f 42e01f 4d0032 640032

これらの3バイトはすべて16進数で表されます。最初のバイトはprofile_idc(0x42、0x4d、0x64)を表し、2番目のバイトはprofile-iopを表し、3番目のバイトはレベルを表します。最初のバイトと3番目のバイトは、たとえば次のように理解しやすくなっています。

  • 42001f :最初のバイト0x42 = 10進数66、参照ウィキペディアのページによると、66はに対応します ベースラインプロファイル (BP、66)。 3番目のバイト0x1f = 10進数31、対応するレベルは3.1です
  • 42e01f :最初のバイトと3番目のバイトは上記と同じで、中央に0xe0があります。これについては、後で説明します。
  • 4d0032 :最初のバイト0x4d = 10進数77 = メインプロファイル (MP、77)。 3番目のバイト0x32 = 10進数の50、レベルは5.0
  • 640032 :最初のバイト0x64 =小数100 = 人目を引く (HiP、100)。 3番目のバイトは上記と同じです
    したがって、1バイト目と3バイト目は非常に単純で、一目で理解できます。

真ん中のバイトを見てみましょう。



RFC6184で導入され、2番目のバイトは プロファイル-iop 、その各ビットは次に対応します:constraint_set {0,1,2,3,4,5} _flag、合計6ビット、最後の2ビットは予約ビットであり、常に0です。

それでは、上の1つを振り返ってみましょう 42e01f 。最初から最初のバイトと3番目のバイトまで、それがベースラインプロファイル+レベル3.1であることがわかりますが、42001fと42e01fの違いは何ですか? 2番目のバイト0xe0に依存し、そのバイナリは次のとおりです。

1 1 1 0 0 0 00

参考資料のITUドキュメントのA.2.1.1制約付きベースラインプロファイルセクションを照会すると、次の説明が表示されます。

特定のレベルで制約付きベースラインプロファイルに準拠するデコーダーは、次のすべてが当てはまるすべてのビットストリームをデコードできる必要があります。
– profile_idcが66に等しいか、constraint_set0_flagが1に等しい
–constraint_set1_flagが1に等しい
– level_idcおよびconstraint_set3_flagは、指定されたレベル以下のレベルを表します。

これは、次の3つの条件が満たされた場合に、デコーダーがすべてのビットストリームをデコードできることを意味します。

  1. profile_idcが66またはconstraint_set0_flag = 1、OK、確立済み(profile_idcは0x42、10進数で66、constraint_set0_flagは1に等しい)
  2. Contract_set1_flag = 1、OK、確立済み(constraint_set1_flagは1に等しい)
  3. これは特にわかりません。 Level_idc(3.1)およびconstraint_set3_flag(0)は、指定されたレベル以下のレベルを意味しますか?

したがって、推測すると、42001fは少なくとも上記の条件1と2を満たさないため、42e01fは制約付きベースラインプロファイルであり、42001fはベースラインプロファイルです。

さらに、2種類のプロファイルとレベルの定義がWebRTCモバイル端末のネイティブSDKソースコードにもあります。ソースコードは次の場所にあります。

sdk android api org webrtc VideoCodecInfo.java (AndroidネイティブSDK)
sdk objc components video_codec RTCH264ProfileLevelId.mm (iOSネイティブSDK)

コードでわかるように、2つのプロファイルとレベルの組み合わせのみを定義します。

42e01f:制約付きベースラインプロファイル+レベル3.1
640c1f:制約付きハイプロファイル+レベル3.1

ちなみに、640c1fの0x0cを見てみましょう。そのバイナリは次のとおりです。

0 0 0 0 1 1 00

ITUドキュメント(セクションA.2.4.2制約付きハイプロファイル)を確認し、説明を参照してください。

profile_idcは100に等しく、constraint_set4_flagは1に等しく、constraint_set5_flagは1に等しく、level_idcは指定されたレベル以下のレベルを表します。

profile_idcは100(つまり、0x64)に等しく、constraint_set4_flagとconstraint_set5_flagは1(満たされている)に等しくなければならないため、640cは制約付きハイプロファイルを表します。

さらに、以下に示すように、上記の参照のWikipediaページからプロファイルを簡単に判断することもできます。
画像
制約セットx(x = 1,3,4、4&5 ...)は、constraint_set {0,1,2,3,4,5} _flagに対応します。対応するビット値は1である必要があります。

OK、この時点で、将来的にprofile-level-idが表示され、それが何を意味するのかすぐにわかります。

さらにいくつかあります:
64001f(ハイプロファイル+レベル3.1)
640016(ハイプロファイル+レベル2.2)
640c34(制約付きハイプロファイル+レベル5.2)
42801e(ベースラインプロファイル+レベル3.0)

最後に、githubの誰かが、jsを使用してプロファイルレベルIDの解析ツールを作成しました。 https://github.com/ibc/h264-profile-level-id 、profile-level-idを理解するのにも役立ちます。