トップ 検索 一覧 ヘルプ RSS ログイン

H.264/AVC(NAL)の変更点

  • 追加された行はこのように表示されます。
  • 削除された行はこのように表示されます。
このページの全ては誤っているかもしれません。[[x264関連の記事に関して]]を読んでください。

!!!H.264/AVC(NAL)

x264、というよりもH.264関連の文書を読む際に頻出の用語であるNALを概説してみる。

本当はx264の--nal-hrdオプションの説明を書きたかったのだが、そもそもNALとは何か、という説明が必要になってしまうため、まずはNALだけの説明をすることにした。

非常に端折っているため、厳密には正しくない記述があるが、ご了承願いたい。

!!大まかに理解する

Network Abstraction Layer(ネットワーク抽象化層)の略で、H.264の生のストリームを適当に区切る''処理階層''を指す。
この処理階層では、イメージ的には''「パケット」''に近い、''NALユニット''(NAL unit)を生成する。
NALはH.264のデータを多様なメディア(記憶媒体や伝送媒体)に乗せるために、アクセスしやすく整形することを目的としている。

x264で出力ファイルの拡張子に.264を指定した場合、このNALユニットの連続データ(より厳密にはAnnex Bのスタートコードを含む)として出力される。
つまり一般的に''「生(raw)のH.264ストリーム」と呼ばれるものは、NALレベルの出力データ''であり、
mp4やmkvなどのコンテナに含められる場合にも、NALレベルの整形データが使用される。

NALのフォーマットと中身の意味は規格書の"7 Syntax and semantics"で述べられている。
このタイトルにNALと冠されてはいないのは、H.264のストリームを読むということは、NALを読むということに他ならないからだ。

!!NALを読む際の用語

蛇足だが、NALの中身を語るときに使われる用語としてRBSP(raw byte sequence payload)とSODB(string of data bits)という用語がある。
RBSPはバイト単位で考えるNALユニットのペイロードで、SODBはビット単位で考えるRBSPの中身と考えればよい。
つまりSODBをバイト単位に切り上げるとRBSPになり、RBSPにヘッダをつけたものがNALユニットになる。
大まかに言えば、RBSPはバイト単位で考えるNALユニットのペイロードで、SODBはビット単位で考えるRBSPの中身と考えればよい。
つまりSODBに対してバイト単位に切り上げる処理を行うとRBSPになり、RBSPにヘッダをつけたものがNALユニットになる。

規格上、NALユニットの中身のフォーマットは、RBSPのシンタックスとして定義されている。
RBSPを構成するデータを、総称してsyntax elementと呼ぶ。

!!NALユニットの種類

NALユニットは様々なデータを含んでおり、概念的に、大きくVCLと非VCLに分類される。
VCL-NALユニットは、ざっくり言えば圧縮されたスライスデータそのものだ。
VCL(Video Coding Layer:映像符号化層)という用語は、NALよりも下位の処理階層を指している。

一方、非VCL-NALユニットはその他の補助的情報を含む物だ。
具体的には、以下のものが非VCL-NALユニットとして代表的だ。
*''SEI''(Supplemental Enhancement Information)
*''SPS''(Sequence Parameter Set)
*''PPS''(Picture Parameter Set)
*''AUD''(Access Unit Delimiter)
*Filler data(x264のr1480以降で''--nal-hrdでcbrを指定した場合に使用''される)
補助的とは言え、これらの名前も良く目にするので、中身は知らずともその重要さはなんとなくわかるだろう。
例えばSPSにはpic_width_in_mbs(_minus1)やbit_depth_luma(_minus8)等、非常に重要な情報が含まれている。

実際のデータとしては、NALユニットのヘッダ部にあるnal_unit_typeという数値データから、NALユニットの中身をある程度知ることができる。
例えばIDRピクチャのスライスデータには5が割り当てられており、これによって簡単にキーフレームを見つけることができる。
ただし、デコードに必要なデータが非VCL-NALユニットにあったりするので、単純にこのNALユニットからデコードを開始すればよいとは限らない。

nal_unit_typeの詳細は規格書の"7.4 Semantics"にある"Table 7-1 NAL unit type codes, syntax element categories, and NAL unit type classes"を参照のこと。

!!主な非VCL-NALユニットの紹介

紹介とは言っても、これらは1つ1つが規格書上で数ページ〜数十ページも割かれるほどのものだ。
ここでは大雑把な紹介に留め、詳細はいつか個別の記事として取り扱うことがあれば、その際に述べたい。

!SEI(Supplemental Enhancement Information)

SEIはピクセルデータの再現に必須ではないが、
表示やバッファ管理上有用な情報を提供するためにある。

SEI-NALユニットは、複数のSEIメッセージを含むことができる。
そのSEIメッセージには、以下のようなものがある。

*Buffering period(主にHRDに関連するバッファ管理情報)
*Picture timing(表示関連が主だがHRDにも絡む・pic_structを含む)
*User data registered by ITU-T Recommendation T.35(規定のユーザ情報)
*User data unregistered(自由なユーザ情報・x264ではエンコード設定を格納している)
*Recovery point(シーク後に表示を復帰するための情報・broken_link_flagを含む)

他にも色々あるがx264では使用されていないので省略。

!SPS(Sequence Parameter Set)

ストリームのデコードに必要な、基本的な情報。

*profile_idc(プロファイル)
*level_idc(レベル)
*num_ref_frames(参照フレーム数)
*pic_width_in_mbs_minus1(幅)
*pic_height_in_map_units_minus1(高さ)
*frame_mbs_only_flag(インターレース)
*mb_adaptive_frame_field_flag(MBAFF)
*direct_8x8_inference_flag
*frame_cropping_flag
*VUI(Video Usability Information)

他にも色々あるが省略。

!PPS(Picture Parameter Set)

個別のピクチャ(フレーム)をデコードする上で必要な情報。

*entropy_coding_mode_flag(CAVLC/CABAC)
*weighted_pred_flag(いわゆるweightp)
*weighted_bipred_flag(いわゆるweightb)
*pic_init_qp_minus26 (QP)
*chroma_qp_index_offset
*deblocking_filter_control_present_flag
*constrained_intra_pred_flag 
*スライスとピクチャの対応情報

他にも色々あるが省略。

!AUD(Access Unit Delimiter)

アクセスユニットの区切りを示すNALユニット。

アクセスユニットとは、1枚の実効的なピクチャ(フレーム)を生成できる、NALユニットの集まり。
1枚のピクチャ(フレーム)を得るためには複数のNALユニットが必要になるので、
その関連する複数のNALユニットを区切るために使用される。
素のH.264のストリームとしては必ずしも必要ではないが、デコーダの処理が楽になるため、
関連する規格では必須とされる場合があるようだ。

!!その他

NALユニットはその並び順も重要で、AUD, SPS, PPS, SEI…の優先順でアクセスユニットの開始と見なされる。
VCL-NALユニットの後でこれらが現れると新たなアクセスユニットの開始と見なされる。
SEI-NALユニットではSEIメッセージの順にも制限があり、Buffering periodを含む場合にはそれが最初でなければならなかったりもする。