ビデオコーデックの仕組みと VQ Analyzer の重要性

メディア・ソフトウェアの仕組みと重要性について理解している人はどれくらいいるでしょうか。この記事では、ビデオコーデックの概要と仕組みをもとに、現代のメディア業界において VQ Analyzer が重要である理由について説明します。

不明確な略語

AVCVP8VP9HEVCAV1VVC などの略語を目にすることがありますが、これらは具体的にはどのようなものでしょうか?なぜこのようにさまざまな種類があるのでしょうか?

これらの不明確とも思われる略語はコーデックとして知られており、以下のように主に 2 つのグループに分けられます。

  • MPEG Licensing Authority (MPEG-LA): AVC / HEVC / VVC
  • オープンソースおよびロイヤリティフリー: VP8 VP9 / AV1

コーデック間の比較は興味深いトピックではありますが、今回は本記事の執筆時点 (2020年前半) で知られているいくつかの重要な点についてのみ紹介します。

  • 現在人気のあるコーデックは AVC (H.264) および VP9 です (YouTube などの人気のストリーミング・サービスに使用されています)。
  • HEVC (H.265) は、2013 年にリリースされた効率的で優れたコーデックです。高評価されるほどの効率にもかかわらず、ライセンスポリシーの不備により、非常に人気が高まることはありませんでした。
  • AV1 は、現代の完全に無料で利用できるコーデックです。 最初の安定版は 2018年 3月 28日にリリースされ、YouTube、Netflix などのサービスで積極的に統合されています。
  • VVC (H.266) は、HEVC の後継コーデックになります。現在の市場において最も効率的なコーデックであり、2020年 7月に完成および承認される予定です。

ご覧の通り、コーデックにはさまざまな種類があり、そのすべてが継続的に進化するととのに、市場での競争を向上しています。

コーデックが開発された理由

まずはじめに、コーデックが必要な理由について理解する必要があります。

ビデオカメラで一般的な 2 時間の映画を特別な圧縮なしで撮影した場合、RGB ファイルが生成されます。それでは、以下のパラメーターをもとにサイズを計算してみましょう。

  • 映画の長さ: 2 時間
  • 毎秒ごとのフレーム数: 30
  • 解像度: 1920×1080
  • カラー形式: RGB

[su_quote]2 * 3600 * 30 * 1920 * 1080 * 3 = 1343692800000 バイト[/su_quote]

なんと、1.22TB に及ぶデータが含まれています。みなさんのコンピューターに内蔵されている HDD は何 TB までサポートしているでしょうか。

HEVC を使用して上記と同じ映画を圧縮した場合、サイズを 2.5GB まで縮小させることができます。つまり、解像度やフレームレートを変更せず、品質の低下を最小限に抑えている状態でも 500 倍も小さなサイズになるということです。

上記の問題に対する解決策

さて、上記の段階で何が問題であるかをご理解いただけたかと思います。生のストリームは非常に大きく、解像度、フレームレート、長さ、エフェクト (HDR など) の増加などにより、年々さらに大きくなっています。

これで圧縮技術が必要であることが分かりますが、何ができるのか考えてみましょう。基本的な理論から、圧縮には 2 種類あることが分かります。

  • ロスレス圧縮
  • 非可逆圧縮

また、異なるカラー形式を使用することができます。

カラー形式

ほとんどの場合、RGB 形式の代わりに輝度をエンコードする YUV 形式が使用されます。

それはなぜでしょうか?科学的研究では、人間の目は色の変化よりも輝度の変化に敏感であると証明されています。これにより、色度を抑えて輝度にフォーカスすることで 1 ピクセルごとのバイト数を抑えることができます。例えば、一般的なエンコード形式は 4:2:0 (1 ピクセルあたり 1.5 バイト) です。色差信号は、輝度信号の水平および垂直解像度の半分です (Richardson 2010)。この形式は、保存専用であることにご注意ください。映画を見るときに、ビデオカードが YUV を RGB に変換します。

ロスレス圧縮

ロスレス圧縮 (可変長符号を参照) をエミュレートし、どのような結果を得ることができるか見てみましょう。

入力:

  • YUV カラー形式の生ビデオファイル: vicue_test_1920x1080_420_8_500.yuv
  • サイズ: 1.44GB (1,555,200,000 バイト)
  • フレーム数: 500

以下の設定を行った 7zip を使用します。

  • 形式: 7z
  • 圧縮レベル: 中間
  • 圧縮メソッド: LZMA2
  • 辞書サイズ: 16 MB
  • ワードサイズ: 32

出力:

  • vicue_test_1920x1080_420_8_500.7z
  • サイズ: 301MB (316,626,856 バイト)
  • 圧縮率: おおよそ 5:1 (※理想的ではありません)

結果: 上記の例では圧縮率が 5:1 と悪くありませんが、さらなる向上の余地があります。

非可逆圧縮: 参照テスト

現代のエンコーダーによるビデオファイルの圧縮の品質はどうでしょうか。

ffmpeg を使用して、HEVC によって先程の .yuv ファイルをエンコードします。

ffmpeg -f rawvideo -pix_fmt yuv420p -s:v 1920x1080 -r 25 -i vicue_test_1920x1080_420_8_500.yuv -c:v libx265 output.mp4

結果:

  • 出力: .mp4
  • サイズ: 12.5MB (13,168,899 バイト)
  • 圧縮率: 118:1
  • fffmpeg の生ログ
Input #0, rawvideo, from 'vicue_test_1920x1080_420_8_500.yuv':
  Duration: 00:00:20.00, start: 0.000000, bitrate: 622080 kb/s
    Stream #0:0: Video: rawvideo (I420 / 0x30323449), yuv420p, 1920x1080, 622080 kb/s, 25 tbr, 25 tbn, 25 tbc
Stream mapping:
  Stream #0:0 -> #0:0 (rawvideo (native) -> hevc (libx265))
Press [q] to stop, [?] for help
x265 [info]: HEVC encoder version 3.0_Au+7-cb3e172a5f51
x265 [info]: build info [Windows][GCC 8.2.1][64 bit] 8bit+10bit
x265 [info]: using cpu capabilities: MMX2 SSE2Fast LZCNT SSSE3 SSE4.2 AVX FMA3 BMI2 AVX2
x265 [info]: Main profile, Level-4 (Main tier)
x265 [info]: Thread pool created using 8 threads
x265 [info]: Slices                              : 1
x265 [info]: frame threads / pool features       : 3 / wpp(17 rows)
x265 [info]: Coding QT: max CU size, min CU size : 64 / 8
x265 [info]: Residual QT: max TU size, max depth : 32 / 1 inter / 1 intra
x265 [info]: ME / range / subpel / merge         : hex / 57 / 2 / 2
x265 [info]: Keyframe min / max / scenecut / bias: 25 / 250 / 40 / 5.00
x265 [info]: Lookahead / bframes / badapt        : 20 / 4 / 2
x265 [info]: b-pyramid / weightp / weightb       : 1 / 1 / 0
x265 [info]: References / ref-limit  cu / depth  : 3 / on / on
x265 [info]: AQ: mode / str / qg-size / cu-tree  : 2 / 1.0 / 32 / 1
x265 [info]: Rate Control / qCompress            : CRF-28.0 / 0.60
x265 [info]: tools: rd=3 psy-rd=2.00 rskip signhide tmvp strong-intra-smoothing
x265 [info]: tools: lslices=6 deblock sao
Output #0, mp4, to 'output.mp4':
  Metadata:
    encoder         : Lavf58.26.101
    Stream #0:0: Video: hevc (libx265) (hev1 / 0x31766568), yuv420p, 1920x1080, q=2-31, 25 fps, 12800 tbn, 25 tbc
    Metadata:
      encoder         : Lavc58.47.102 libx265
frame=  500 fps=5.4 q=-0.0 Lsize=   12860kB time=00:00:19.88 bitrate=5299.3kbits/s speed=0.217x
video:12854kB audio:0kB subtitle:0kB other streams:0kB global headers:2kB muxing overhead: 0.049566%
x265 [info]: frame I:      4, Avg QP:27.84  kb/s: 6871.70
x265 [info]: frame P:    456, Avg QP:30.31  kb/s: 5370.48
x265 [info]: frame B:     40, Avg QP:33.20  kb/s: 3891.26
x265 [info]: Weighted P-Frames: Y:4.8% UV:4.2%
x265 [info]: consecutive B-frames: 91.7% 7.8% 0.4% 0.0% 0.0%
encoded 500 frames in 91.77s (5.45 fps), 5264.15 kb/s, Avg QP:30.52

オリジナルの YUV のフレームのスクリーンショット

図 1: オリジナルの YUV のフレームのスクリーンショット

HEVC ストリームのフレームのスクリーンショット

図 2: HEVC ストリームのフレームのスクリーンショット

図 1 と図 2 の間にはわずかな違いはあるものの、品質はほとんど同じであり、ファイルサイズは 12.5MB まで抑えられています。コーデックの重要性と効果は、このような場面で大いに発揮されます。

非可逆圧縮: 説明

[su_quote]非可逆圧縮を行う場合、品質が損なわれてしまいます。[/su_quote]

これは事実ですが、現代の技術を利用して品質の低下を最小限に抑えることができます。

主な技術は以下の通りです。

  • イントラ予測 – フレームに同じ要素が存在する場合、同じフレームの異なる場所からその要素を「継承」できます。
  • インター予測 – 異なるフレーム間で要素を「継承」できます。
  • 量子化

Git のバージョン・コントロール・システム (VCS) と同様に、ファイル全体ではなく、ファイルの差分のみを保存します。

エンコードのプロセス

次に、高度なエンコードプロセスを示す以下のダイアグラムを見てみましょう。

抽象エンコーダーの高度なエンコードのプロセス

図 3: 抽象エンコーダーの高度なエンコードのプロセス

エンコードプロセスの説明

  1. 拡張子 .yuv など、ソースとなる動画ファイルを入力します。エンコードプロセスを開始するには、動画から1 フレーム取得します。それぞれのフレームをブロック分けする必要があります。それぞれのブロックにおいて並列計算を行います。
  2. インター予測: モーション推定 (ME) – エンコーダーは、他のフレームにあるブロックから、「継承可能」 なブロックを探します。
    VQ Analyzer 4.2.0 (AV1 ストリーム) で視覚化されたエンコード済みのストリームでの ME の表示

    図 4: VQ Analyzer 4.2.0 (AV1 ストリーム) で視覚化されたエンコード済みのストリームでの ME の表示

  3. イントラ予測 – エンコーダーは、同じフレーム内のブロックから「継承可能」なブロックを探します。
    VQ Analyzer 4.2.0 (VVC/H.266 ストリーム) で視覚化されたエンコード済みのストリームでのイントラ予測の表示

    図 5: VQ Analyzer 4.2.0 (VVC/H.266 ストリーム) で視覚化されたエンコード済みのストリームでのイントラ予測の表示

  4. モーション推定とイントラ予測を計算後、エンコーダーは削減可能なバイト数と品質をもとにより効率的な予測を選択します。
  5. 本ステップ以降、ソース画像ではなく予測をもとに作業を進めていきます。予測とはつまり、プロセスの結果、最小限の残差でアーティファクトを提供します。
  6. 残差とは、すべての予測ができないデータを示します。残差の条件式は、次の通りです。
    source_block — prediction_block = residual_block
  7. 本ステップでのゴールは、残差を極力減らすことです。エンコーダーは、離散コサイン変換 (DCT) のようなアルゴリズムを使用して残差を減らします。DCT の原理は、最小の係数で画像の特性を最大化することです。強力なエネルギー圧縮という特性があり、信号情報のほとんどはいくつかの低周波成分に集中する傾向があります。ほとんどの場合、品質の低下が抑えられて圧縮率が向上し、後続の量子化プロセスの効率が向上します。

    離散コサイン変換後の行列の視覚化の例は以下の通りです。

    離散コサイン変換

    図 6: 離散コサイン変換 (http://www.pcs-ip.eu/index.php/main/edu/5)

  8. 量子化 – 離散コサイン変換などの変換を適用した後、画像データの精度を下げたり、ゼロに近い離散コサイン変換の値を削除するために利用できます。つまり、これは単純な値の削減 (matrix_of_coefficients/matrix_of_constants) になります。このステップにおいて、動画ストリームは非可逆圧縮の最大の効果を得ることができます (疑似 C++ 言語)。

    quantized_coefficient[i] = round(coefficents[i]/q_step[i])

    説明:

    • quantized_coefficient – 量子化後の係数のベクトル
    • coefficents – 離散コサイン変換後の係数のベクトル
    • q_step – コーデック仕様の一部である定数 (または最新のコーデックでは動的な値) のベクトル
  9. これでエンコーダーの中にデコーダーを用意する事ができました。それぞれのエンコーダーの中にはデコーダーがあります。これは、次に続くフレームを予測するために必要となります。フレームはエンコード済みのブロックから取得した予測します。
  10. エンコーダーは、次の計算を行います: 残差*(5) + 予測*(9) = reconstructed_frame
  11. これにより、エンコーダーは Decoder Picture Buffer (DPB) にほとんどのソースファイルを取り入れます。DPB は、ステップ 2 のモーション推定 (ME) で使用される参照フレームを格納する固定最大サイズのバッファーです。
  12. フレーム/ブロックの準備ができたら、エントロピー・コーディング・アルゴリズム (CABAC など) を使用します。

まとめ

ご覧の通り、ご覧のとおり、コーデックとは幅広い技術を使用する複雑なソフトウェアです。VVC のような最新のコーデックでは、機械学習の分野から得られたいくつかの要素も使用されています。これらの開発は、幅広い改善余地と進化する技術によって常に進められています。また、現在ではより高い解像度 (FullHD > 4K > 8K)、より高いフレームレート (30 > 60)、より小さな帯域幅コスト、特殊効果 (HDR など)、 360 度効果などのさらなる技術を求めるコンテンツ提供者とユーザーにより成り立つ成熟した市場も存在します。

VQ Analyzer 製品に関する詳細は、弊社の概要ページをご確認ください。
無償評価版をご希望の方は、こちらのフォームからお申込みください。


この記事は、ViCue Soft 社の Technology Blog に公開されている「What is a Video Codec and How Does It Work?」の日本語参考訳です。

タイトルとURLをコピーしました