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 ホームページの説明)。
参照文書
- ITU(国際電気通信連合)によって開発された文書: H.264:一般的な視聴覚サービスのための高度なビデオコーディング 。許容可能 ここに ダウンロード先(2017年4月版をダウンロードしました)
- ウィキペディア: 高度なビデオコーディング
- RFC6184:H.264ビデオのRTPペイロード形式
典型的なプロファイルレベル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つの条件が満たされた場合に、デコーダーがすべてのビットストリームをデコードできることを意味します。
- profile_idcが66またはconstraint_set0_flag = 1、OK、確立済み(profile_idcは0x42、10進数で66、constraint_set0_flagは1に等しい)
- Contract_set1_flag = 1、OK、確立済み(constraint_set1_flagは1に等しい)
- これは特にわかりません。 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を理解するのにも役立ちます。