[MPEG-DASH] パフォーマンスチューニングを行う

# はじめに
- 映像/音声の品質
- ダウンロードからの再生速度
- シーク操作（再生位置の変更）の精度

アダプティブストリーミングにおいて、映像の画質や音声の音質は、[ビットレート](https://ja.wikipedia.org/wiki/ビットレート)が関係しています。[ビットレート](https://ja.wikipedia.org/wiki/ビットレート)が低くなると映像に[ブロックノイズ](https://ja.wikipedia.org/wiki/ブロックノイズ)が発生したり、音が割れたりします。映像の滑らかさは、[フレームレート](https://ja.wikipedia.org/wiki/フレームレート)が関係しています。[フレームレート](https://ja.wikipedia.org/wiki/フレームレート)が低くなるとコマ落ちが発生します。
ダウンロードからの再生速度は、帯域幅やファイルサイズが関係しています。帯域幅が小さくなったり、ファイルサイズが大きくなるとバッファリング時間（再生までの待ち時間）が発生します。
シーク操作の精度は、セグメントファイルの再生時間が関係しています。セグメントの再生時間が長くなると、指定した再生位置からズレて再生される可能性があります。

今回は「ダウンロードからの再生速度」と「シーク操作」の2つのパフォーマンスチューニングを紹介します。

# パフォーマンスチューニング
## コーデック
コーデックとは、映像や音声を圧縮する方式です。ここでは映像コーデックを説明します。

### 映像コーデック
- [H.264](#h264)
- [H.265](#h265)

#### H.264
[H.264（MPEG-4 AVC）](https://ja.wikipedia.org/wiki/H.264)では、フレーム（静止画像の1コマ）間で似たような部分を圧縮してファイルサイズを小さくしています。前フレームと後フレーム画像の一部または全体で変化が少ない箇所を予測してファイルサイズを圧縮しています。H.264は、この動き予測のアルゴリズムが優れています。画面全体を細かくブロックに分割して、そのままフレーム間の変化量を送っています。

#### H.265
[H.265（HEVC）](https://ja.wikipedia.org/wiki/H.265)では、フレーム間の変化量からブロックサイズを最適化して送っています。H.264に比べると約2倍の圧縮率になりますが、圧縮にかける時間が数倍～10数倍くらいになります。

## フレームの種類
- Iフレーム
- Bフレーム
- Pフレーム

H.264, H.265では、フレームの種類が3つあります。Iフレームは、キーフレームとも呼ばれます。圧縮率は他のフレームに比べると最小です。動画のシークを行う場合、シークした位置にキーフレームがある必要があります。そのため、キーフレームが多いほどシークの精度があがります。（ただし、その分ファイルサイズが大きくなります。）BフレームやPフレームの圧縮率は高いです。

## GOP
GOP（Group of Picture）は、Iフレームを含むフレームの集合体を指します。特定の順序(IBBPBB,IBBPBB..)で編成されています。

## GOPサイズ
- GOPサイズが小さい
    - シーク精度が上がる
- GOPサイズが大きい
    - シーク精度が下がる

GOPサイズは、値が小さいほどキーフレームが頻繁に作成されます。GOPサイズを小さくするとシーク精度が上がりますが、ファイルサイズが大きくなります。

## GOPサイズの求め方
- `GOPサイズ`=`フラグメントサイズ`×`フレームレート`

## GOPサイズの出力方法

```bash:実行
mp4dump Bullfinch.mp4
```
[Bento4](https://www.bento4.com/)というソフトウェアに同梱されている`mp4dump`でGOPサイズを取得することができます。

## ClosedGOP
ClosedGOPは、1つのGOPをClosedに設定することで1つのGOPを切り出しても前後のGOPに干渉が起きないようにする仕組みです。ClosedGOPにすることで1つのGOPで映像を完結することができるため、映像編集が容易になります。[Fragmented MP4](https://qiita.com/yun_bow/items/a33266b78d5aab807c71)ではClosedGOPであることを推奨しています。
「BB,IBBPBBPBBPBB」のようなGOPがあった場合、先頭の2つBフレームはPフレームの差分で作成されているため、OpenGOPでこの部分を切り出してしまうと2つのBフレームは参照できなくなります。

## フラグメントサイズ
- フラグメントサイズが小さい
    - シーク精度が上がる
    - メディアのファイルサイズが大きくなる
- フラグメントサイズが大きい
    - シーク精度が下がる
    - メディアのファイルサイズが小さくなる

フラグメントサイズは、[Fragmented MP4](https://qiita.com/yun_bow/items/a33266b78d5aab807c71)で分割したサイズです。

## セグメントサイズ
- セグメントサイズが小さい
    - リクエスト遅延の影響を受けやすい。
- セグメントサイズが大きい
    - 帯域不安定なワイヤレスネットワークで失速の影響を受けやすい。

セグメントサイズは、MPEG-DASHで使用されているメディアファイルを分割したサイズです。

# おわりに
フラグメントサイズを小さくするとシーク精度が上がります。しかし、ファイルサイズが大きくなりバッファリングが発生する可能性があります。トレードオフの関係にあります。再生するデバイスやアプリケーションを明確にしてそれに合うようにチューニングする必要があります。

最後までご覧いただき、ありがとうございました。

# 関連リンク
- [[MPEG-DASH] 初心者のためのWEBストリーミング入門](https://qiita.com/yun_bow/items/a97ad78615c6ca3a75bb)
- [[MPEG-DASH] Fragmented MP4のファイル構造](https://qiita.com/yun_bow/items/a33266b78d5aab807c71)
- [[MPEG-DASH] MPDのファイル構造](https://qiita.com/yun_bow/items/780e49531174272e7c44)
- [[MPEG-DASH] DRMシステムの概要と種類](https://qiita.com/yun_bow/items/e573f4754579d1627a13)
- [[MPEG-DASH] Bento4でDRMパッケージを行う](https://qiita.com/yun_bow/items/77b86d75e15f245f265b)
- [[MPEG-DASH] dashJSでアダプティブストリーミングを再生する](https://qiita.com/yun_bow/items/88582964c113c8499742)
- [[MPEG-DASH] videoJSでアダプティブストリーミングを再生する](https://qiita.com/yun_bow/items/3cdcb0a4f961d6e1e06d)
- [MPEG-DASH] パフォーマンスチューニングを行う（本稿）

以上です。