このページの全ては誤っているかもしれません。x264関連の記事に関してを読んでください。
CBRの幻想
多くの人々が誤解しているであろう、CBRの実態を書いてみる。
記事を書くきっかけがx264のr1244でのCBRの説明削除にあるため、x264を説明する意図が多分に含まれているが、一般的なCBRの理解にも十分資するはず。また、CBRという言葉・概念が一般に浸透したのはMP3が大きく関わっていると思われるため、多く引き合いに出している。
最近のx264におけるCBRという用語についての注意
x264はr1480でnal-hrdパッチを取り込み、Filler NALユニットが使用可能になった。このため、x264には現在、CBRという用語は2つのポイントで存在する。
- --bitrate == --vbv-maxrateとするCBRモード。
- --nal-hrd cbrで指定し、出力にFiller NALユニットを加える指定。
この両者とも、広い意味でのCBRに寄与するのだが、その働きは異なる。本記事で扱うのは前者のCBRモードの方だ。そして、先に断ってしまうが、本記事は最終的に「CBRモードはVBRデータを出力する」という結論に達する。「どうしてもCBRが得られなければ困る」という場合には、本記事を読んでCBRの正体を知った後に、後者の--nal-hrd cbrに関してx264(nal-hrd),H.264/AVC(HRD),MPEG-1/2(VBV)を参照するとよいだろう。
デジタル映像圧縮技術におけるCBR
そもそもフレーム間の参照によるデータ量の圧縮を行う、現在の殆どのデジタル映像圧縮方式においては、真のCBRの意味は曖昧だ。一定時間量に対し一定データ量であることがCBRの定義だが、この「一定時間」の取り方で大きく意味が異なる。
厳密にアトミックな時間(最小の時間単位)を基準とする絶対的CBRならば1フレーム単位になるが、フレームタイプに関係なく全フレームを同じデータ量にすればIフレームの画質は酷いものになるだろう。
これを緩和して1GOP単位とすれば画質はマシになるが、GOP内はVBRであり、この時点で相対的なCBRになる。そしてOpenGOPでは「1GOP」が独立に切り離せない(時間に対するデータ量を割り出せない)ので、CBRの定義から揺らいでくる。
そしてそれ以上の時間単位では、もはやCBRと呼ぶよりもVBRであり、変動するが大体平均的なビットレートという意味でABRという言葉があるに過ぎない。
ABR
CBRは人間の感覚的にデータ量を見積もる上で便利であり、実装側もシーク処理を単純化できる。初期のMP3の実装などでVBRの取り扱いに問題があったことも手伝って、未だにCBR絶対主義的な人々は多い。
ABRという言葉はCBRではないがCBR的なものとして、そのような人々のアレルギー反応を緩和する目的で導入された感がある。ABRはVBRの一種であり、決してCBRでは有り得ない。ABRを相対的なCBRと捉えるならば人間の感覚的には便利かもしれないが、実装側の処理は基本的にVBRだ。
しかし、それでもABRという言葉は重要である。なぜなら、現代のデジタル圧縮技術でCBRと呼ばれているものが、実際には殆どABR、特にCapped ABRと呼ばれるものの一種であるからだ。しかし、ABR・CBRと言われてその中身を正しくイメージするためには、レートコントロールやVBVの充足という概念を知らなければならない。
その為に、まずは「一般にCBRと呼ばれているもの」の実際の中身から暴いていこう。
CBRの中身
元々CBRという概念は、例えば古い通信系のシステムのように、変動するデータ量(VBR)を扱えないシステムとの整合から生まれたものだ。むしろ、最初期のデジタル圧縮技術(G.711等)にはCBRしかなかったのでCBRが当然だったとも言える。当時の圧縮技術は素のPCMに対する直接的な単純加工によって成り立っており、真の絶対的CBRが簡単に実現出来ていたし、その方が通信系にとっても都合が良かった。
しかしそれらの圧縮技術は現代に比べると圧縮率が小さく、品質もあまり良くはなかった。この状況を打破するのが音声系のMP3やMD(MiniDisc)に代表される、直交変換(主にDCT)系の圧縮技術だ。これらは人間の感覚精度の隙を利用し、効率的にデータを削ることで圧倒的な圧縮率と品質を実現したが、同時に一つの問題があった。その原理的に、PCMの1サンプルと出力データ量が固定的に対応しないのだ。
これでは既存の通信インフラ、記録装置などを流用できない事態になりかねず、せっかくの素晴らしい技術も活かされなくなってしまう。つまりMP3等の新興技術は、既存のシステムとの整合性上、例えそれが擬製的であっても、CBRを実現する必要があった。そしてその方法として利用されたのはパディングだった。
パディングとは詰め物の事だ。ダンボール箱に中身が合わなければ新聞紙や緩衝材で詰め物をするように、本当のデータに無意味なデータを足すことで、見かけ上一定データ量であるように見せている。以降、現代的なデジタル圧縮技術で実現するCBRは実際にはVBR・ABRであるものをCBRに見せる擬製的システムであり、1bitの無駄もなく本当にCBRであることはまずない。
原理的な問題
では、なぜ現代のデジタル圧縮技術は真の意味で固定的なデータ量を出力できないのだろうか。
これは、デジタル圧縮の最終段で行われるエントロピー圧縮に起因している。ハフマンや算術圧縮などが有名で、H.264ではCAVLCやCABACと呼ばれる処理部分が該当する。そしてこれらの圧縮技術は、「最終的に出力されるデータサイズを事前に知ることができない」という点で共通している。つまり、エンコードしてみてデータサイズに不都合があったら、入力データを変更してやり直すしかないのであり、固定的なデータサイズを必要とするCBRには根本的にそぐわない。
全てはVBR
この問題のエントロピー圧縮は、何も映像・音声に固有のものではない。
考えて見て欲しいが、例えばJPEG、PNG、ZIP、LZH等々、動画や音声に限らず、「圧縮」と名の付くものの殆ど、特に高圧縮なものは全てと言って良いほど、事前に出力サイズを完全に予測することはできない。JPEGの出力サイズを調整できるツールはあるが、これも上記の通りエンコードを何度もやり直し、偶然目的の範囲に収まったものを結果としているだけだ。
つまり、ほぼ全ての現代的な圧縮はVBR的だ。
擬制的CBR
上記の例からも分かるように、例えVBR的であってもエントロピー圧縮は強力であり、これ無しには現在のような圧縮率は望めないと言ってよい。当然の欲求として、何とかしてCBRの世界にも取り込みたいものだ。これを解決するため、エンコーダは過去の実績や経験則からCBRで指定されるデータ量より僅かに少なめになると予測されるデータをエントロピー圧縮にかけ、出力データ量が短ければパディングし、長ければ入力データを変更してやり直すということをする。
もちろん、ものすごく頑張れば1bitの無駄もないデータが偶然算出されるかもしれない。そのために、例えばMP3ならカットオフフィルタを1Hzずつ変えてみるとか、H.264なら全マクロブロックのパーティション割りを1つずつ変えてみるとかして、偶然望みのサイズになるまで試すことはできるかもしれない。が、当然、時間とのトレードオフで現実的ではなく、それで望みのサイズが出力される保証もない。それでいて、品質の改善は微々たるものだろう。
このようにして、全てのVBRはCBR的に見せかけることもできる。最大ビットレート部分のデータ量と同じになるよう、他の部分にパディングを行えばよいからだ。無駄な部分の量(割合)が異なるだけで、MP3のCBRが行うこととの違いはない。
しかし、これでは保存メディアへの格納時に無駄が大きすぎる。例えば固定品質VBRでは、最大ビットレート部分と最小ビットレート部分が倍以上異なる事など珍しくもなんともない。「CBRにするためにはVBRの倍のファイルサイズになりますが品質は同じです」と言われたら、あなたはどう思うだろうか。
このために、潮流はVBRになっている。
VBRの技術的障壁
ここまでVBRが善でありCBRが悪であるかのような扱いをしているが、これは価値観の問題であり、必ずしもVBRが最良な訳ではない。VBRを実際に運用するためには、CBRでは不要な処理が必要であり、一般に実装はより複雑で難しい。簡便さを求めるなら、擬製的でもCBRの方が楽ではある。
シーク
VBR採用時の技術的課題の最たるものは、前述のとおりシークである。CBRではビットレートに時間をかければ特定時刻のデータの位置を得ることができるが、VBRでは時間とデータ量が比例しないため、そういった方法でデータの位置を得ることができない。
これを解決するために、殆どのマルチメディアコンテナ(.mp4や.mkv、.asfなどのファイル)ではインデックス(目次)が作成される。多くの映像コーデックでは元々キーフレームにしかシークができないため、これらの位置をインデックスにし、シークの際にはこのインデックスからデータの位置を割り出してアクセスしている。
なお、若干余談だが、放送の場合には、そもそも放送そのものをシークすることはできないため、このインデックスは存在しない。このため、放送用のコンテナ(例えば.ts:MPEG-2 Transport Stream)のデータをそのまま記録し、後ほど再生する場合には、シークの基準は時間ではなく、データ量になる。つまり1時間の動画の50%部分にシークをしても、30分の部分に当たるとは限らない。これが30分に当たることがあるとすれば、それは擬製的なCBR(ヌルパケットやパディングなどの無駄なデータが含まれる)であるか、偶然前半も後半も平均すれば同じビットレートであったというだけである。このため、放送用のコンテナを再生可能なプレーヤでも、動画の合計時間やシーク後の現在再生している位置の時刻を表示しない(できない)ものがある。
ではその表示を行えているプレーヤはどうやっているのか。実は、放送データにはインデックスはないものの、フレームレート制御などの目的で現在の再生位置がどの時刻であるかというデータは存在している。現在再生している位置の時刻は、シーク後にそこの時刻情報を先頭の時刻情報と比較して算出可能だ。動画の合計時間に関しても同様で、先頭と末尾の時刻情報を比較して算出することが可能だ。
ただし、コンテナの時刻情報の格納方法によっては、この手段が使用できないケースがある。例えば時刻情報が0.01秒単位で32bitで格納されている場合、約497日で32bitがオーバーフローする(MPEG-2ではSTC/SCR/PCRが48bitで27MHzらしいので約120日になる)。すると、先頭より末尾の時刻が若いケースが発生し、この場合には正しい時間を計算することができなくなる。筆者は実際の放送データを見たことはないが、実際の放送では1日に1度といった頻度で、オーバーフローする前に時刻情報がゼロにリセットされていたりするらしい。この場合でも、そこを跨いだ放送データでは同じ問題が発生するため、問題解決にはならない。むしろ、単純なオーバーフローであればオーバーフローを見越して計算する事が可能だが、途中でゼロリセットされる場合にはいつの時点でリセットが発生したかを簡単に得られないため、却って対応を難しくすることになる。
レートコントロールとVBV
VBRは完成品の品質と、トータルのデータサイズのバランスを考えればよい選択肢ではある。だが、圧縮しづらくデータ量がふくらんでしまう部分だからといって、際限なく大きなデータを受け取るわけにもいかない。エンコード・デコードを行うにはバッファが必要であり、そのバッファを置くメモリは有限だからだ。特に、家電レベルで使用する規格であれば、必要なバッファ量は規格で定めなければならない。
しかし前述のように、現代のデジタル圧縮方式では事前に出力サイズを知ることはできない。このため、エンコーダの設計者は経験則を適用したり、圧縮中の情報から動的に品質を調整したりして、何とか規格で定めるバッファに収まるように努力する。その努力がレートコントロールであり、その確認手段がVBV(Video Buffer Verifier)だ。しかしそれらを駆使したとしても、あるとき突然、極度に圧縮しにくいフレーム(音声のフレームでも映像のフレームでも)に出会うと、バッファスペースに困窮し、その品質を極端に落としてエンコードすることになってしまう。
この問題の解決方法として一般に有効なのが、いわゆる2パスエンコードだ。実際にエンコードをしてみなければ分からないのだから、1度エンコードをしてしまい、その時の情報を元にエンコードをやり直すのが2パスになる。突発的な圧縮しにくいフレームが来る前に、それ以前のフレームの品質を少しずつ落としてバッファに空きを作り、問題のフレームの品質を酷く落とすことなく対処できるようになる。もちろん逆に、エンコーダがそのフレームが視覚・聴覚心理的に重要でないと判断すれば、より重要なフレームにビット(バッファ)を割り当てることもできる。
VBV・レートコントロールはVBR固有の課題ではなく、CBRでも課題(むしろ歴史的にはCBRにこそ使われていた)ではあるのだが、CBRの場合には他のフレームやGOPとのビット配分(バッファ配分)を調整することは基本的にできない。つまり、CBRの場合には、決まったビットレートを守るために、強制的にそのフレームの質を落とすしかなく、品質的に問題ではあるものの、選択肢がないので実装上の難しさはない。VBRでは配分ができるだけに、自由度が高く、この部分の実装はエンコーダの性格と性能を如実に表すものになる。
ちなみに、1つのフレームでのみVBVを考えることを、x264のchangelogの用語ではsingle frame VBVと呼んでいる。恐らく一般的にも通じる用語だろう。
なお、ここではレートコントロールとバッファ要件に関する事柄(VBV)をまとめて大雑把に扱っているが、本来は各論でもっと大きく扱われるべきものだ。これらだけで特許がいくつも成立するほど、その奥は深い。
再びABR
閑話休題。
ところで、ABRはVBRの一種でしかないと先に書いた。ABRの正確な定義がどこかにあるのか筆者は知らないが、上記のようなレートコントロールが入っているVBRは、全体でのビットレートをある程度狙えるという意味でABRと考えることができるだろう。ある一定区間(平均化区間と呼ぶことが多い)で大体同じビットレートになるよう、データ量を配分することができるのがABRと定義して良さそうだ。
一方、VBRとVBVの関係からは何が生まれるだろうか。規格で定めるバッファ量は、そこにある一定時間分のデータが入ることを想定しており、その時間の範囲でバッファ量を超えるデータを作成できない。つまりVBVの制限付きのVBRで作成されるデータは、ある時間単位に対して常に一定以下である。
レートコントロールの行われるABRに対し、さらにこのようなVBVによる「最大ビットレート制限」を行う方式を、Capped ABRと呼ぶ。ゲームやコンピュータにある程度詳しい人なら、「キャップ」という言葉は目にしたことがあるだろう。Capped ABRは、VBRの品質対データ量の良好な特性を活かしつつも、再生互換性を確保できる、ハイブリッドな方式だ。
ここで、レートコントロールで目標とするビットレートと、VBVによる制限ビットレートを同じに設定するとどうなるだろうか?レートコントロールはバッファを柔軟に活用して、なるべく劣化の少ないデータを作成しようとするが、VBVによってバッファから溢れるような困ったデータは作成しないことが保証される。つまり、レートコントロールとVBVが有効に働いていれば、指定されるビットレートに限りなく近づくが、超えないことになる。
この状態は、何かに似てないだろうか?
そこに、僅かな詰め物を足せば。
x264のCBRモード
やっと本来書きたかった部分に到達した。
x264のエンコードは、基本的にはVBRだ。もう、答えを言ってしまおう。x264のCBRモードの定義は、ソースのdoc/ratecontrol.txtに書いてある。若干古くなっているので読み替えるべきだが、VBVの指定付きであるCapped ABRモードの事をCBRモードと呼んでいる。そして、x264的な(CBRモードではない)ABRモードの定義は、厳密なVBVを充足しないが、大体指定のビットレートに落ち着くようにレートコントロールを行うものとなっている。
このCBRモードに関して、補足説明が付いている。その内容は、「CBRモードは要求されたものより若干小さいビットレートを使うことがある」ということだ。これはまさに擬製的で完全なCBRを出力するわけではないことを明示している。このCBRモードの出力は結局VBRではあるが、あと僅かな詰め物(後のr1272で言及され、r1480で実装された"filler")を足せばCBRに見せることもできる。「CBRモード」という名前自体が嘘なわけではない。
x264に限らず、現在の一般的なCBRの定義は、必ずしもMP3のような擬製的で完全なCBRを指していない。このページでは無駄に長々と解説したが、ffmpegのFAQ(日本語訳)では「あなたはCBRが何であるか理解していません、MPEGの仕様書を読んでください。Video Buffer VerifierとConstant Bitrateについて読んでください。」と一蹴されている。
まとめ
x264におけるCBRモードとは、なるべく厳密なレートコントロールを行いバッファ要件を満たすようなVBR、つまり条件付きABRである。そしてレートコントロールは行うが、バッファ要件たるVBVがない場合を単にABRモードと呼ぶ。
このCBRモードはバッファをなるべく無駄にしないようにはするが、MP3のような無駄なパディングは行わない。このため、x264ではqcomp=0にしても、MP3のように一見ビット・バイト単位で完璧に見えるCBRを出力するわけではない。それは別の部分の仕事だからだ。CBRモードはCBRを標榜してはいるが、殆どの場合で指定ビットレートより僅かに少ないビットレートを上下しながら進行し、出力データは結局VBRである。
そしてエントロピー圧縮を伴なう現代的な圧縮技術にとって、真の意味で完全なCBRは幻想であり、存在しない。また現代的なMP4やmkvといったコンテナはVBRを扱えるように設計されており、今では完全なCBRに大きなアドバンテージはない。
MP3から脈々と続くCBRへの幻想を捨て、現代的な意味でのCBRを理解して使おう。
最終更新時間:2009年10月25日 02時20分28秒