AWS Elemental MediaConvertでAV1を作ってみて画質とか見てみる

本記事は[DMMグループ Adovent Calender 2020](https://qiita.com/advent-calendar/2020/dmm)の最終日の投稿です。

どうもどうも。DMMで動画配信基盤をやっているチームのグループリーダーをやっている[yanoshi](https://twitter.com/yanoshi)です。
アドベントカレンダーが始まったと思ったら最終日が空いているじゃないですか！ってことで最終日をいただきました。メリクリ！ クリスマスですが、今年も特に予定はありません。えへへ。

昨年は1日目で今年は最終日です。空いているのはいつもこういう日。わかりやすくて良いですね。


さて、どんな記事を書こうかな？と思っていたのですが、もう12/24なんですよね。思ったよりも忙しくて何もできていない…

ってことで、昨年の記事に引き続きAV1の話をしていこうと思います。


注意(お約束):
本記事の内容は所属する組織との関係は一切ありません。全て筆者の個人による調査/私的見解であり個人利用の範疇による技術的検証となっています。
また本稿の内容を実施して発生したあらゆる損害を筆者は一切保証しません。


# AV1って何？

去年のアドカレ記事を参考にしてみてください。いっぱい色々書いています。(ほんとか？)

[AV1エンコーダーの速度と品質の比較 - ffmpeg(libaom) vs SVT-AV1 - Qiita](https://qiita.com/yanoshi/items/544a361baf76b8114067)

めっちゃ雑に説明すると、
**「ロイヤリティーフリー(ここはまだ議論の余地がありそうだけど)で利用できる動画コーデック。圧縮率が高いけど、めちゃくちゃエンコード時間がかかる」**
ってやつです。


# 2020年は更にAV1が身近になった1年だった

いよいよAV1のハードウェアデコーダーがGPUに搭載され始めました。

[NVIDIA RTX 30シリーズ](https://developer.nvidia.com/video-encode-and-decode-gpu-support-matrix-new)、Radeon RX 6000シリーズ、Intel Xeシリーズ辺りがAV1ハードウェアデコーダーを搭載しています。
詳しくは掘り下げていないですが、[4K動画でもデコードしてくれそう](https://videocardz.com/newz/microsoft-confirms-amd-radeon-rx-6000-series-support-av1-decoding)なので、いよいよ色々な動画に対して利用可能な域が近づいてきているような気がしますね。

さて、そんな中でクラウドエンコードソリューション周りも続々とAV1対応を発表してきました。
[AWS Elemental MediaConvert に AV1 エンコードを導入](https://aws.amazon.com/jp/about-aws/whats-new/2020/03/av1-encoding-now-available-with-aws-elemental-mediaconvert/)

**これは試さないと！って思っていたのですが、なかなか試せずにいたので、今回はMediaConvertでAV1エンコードをしてみます。**


# 入力ファイルの準備

昨年のエンコード結果がまだ手元に残っていたので、今回も[Sintel](https://durian.blender.org/news/sintel-4k-dcp/)です。BigBuckBunnyと同様にCC BY 3.0です。ありがとうありがとう。
[公式サイト](https://durian.blender.org/download/)より1080pのデータをダウンロードしてきました。

編集をMediaConvert側でやってもよいのですが、フレームレベルできれいに切り刻める自信がなかったので手元で事前にやっておきます。

```
ffmpeg -ss 00:00:00 -i input.mkv -c:v copy -c:a copy -t 00:00:30 "sintel_30s.mp4"
```

こちらのファイルをS3に適当にアップロードしておきます。

# IAMの準備

MediaConvert用のRoleを作っておきます。ユースケースとしてMediaConvert用の設定があるので、それを使いましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133666/c452a8f2-89b9-bd56-b04c-a9271e8cabb0.png)


# MediaConvertいじり

改めて説明するほどでも無いですが、AWS Elemental MediaConvertはファイルのエンコードやパッケージング等々を行ってくれるサービスです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133666/e156c869-dcfa-a972-2673-314c1e606be9.png)

ということでエンコードジョブを作成していきたいと思います｡

## 入力設定

事前にS3にアップロードしておいたMP4ファイルを指定しておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133666/d284948f-1dea-ccf4-eaf9-6b55067ae2ac.png)

## 出力設定

バケットの設定をして…
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133666/cc6cdf10-8a07-2da8-6858-96ddd4efc72c.png)

エンコード設定をやっていきます。
おっと。設定はQVBRしかないのですね。ってことでこの前作ったファイルとは単純比較できなさそうですね。とりあえず品質レベルは `7` 、最大ビットレートを `2000kbps` として設定してみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133666/10c2b56c-cc73-7341-d760-dbd214a1afbc.png)



## IAMと紐付け

さっき作っておいたRoleに紐付けます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133666/bb839cc2-cafa-43de-a15b-56ae87455d03.png)

## 実行！

所要時間は `2:51` でした。流石に速いですね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133666/c2dccaf2-d2c7-03ae-aad3-37fc208163e5.png)


# 完成したファイルのビットレート

`1671kbps` となりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133666/3faeb251-242b-fffb-c414-e5da91be1517.png)

ちなみに、前回libaomを使って作ったファイルは `649kbps` だったみたいです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133666/3815b9e1-93b6-10e7-b91a-cc0ecc29f88d.png)

これは雰囲気半分くらいのビットレートにしても問題なさそうですね。リトライしてみます。

# `1000kbps` で設定してエンコードしてみた

2分34秒でエンコードできました。出力されたビットレートは `892kbps` となりました。libaomの値に近くなりました。 1.374倍程度のファイルサイズになりましたね。
画質を比較して、このファイルサイズ差と画質差がどうなっているか見てみましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133666/2dc9f48c-f628-0840-2470-7de85476420f.png)



# 画質を見てみます

こんな感じでガッと数値を取ってみます。

```
ffmpeg -i sintel_30s_av1.mp4 -t 00:00:30 -r 24 -i sintel_30s.mp4 -t 00:00:30 -r 24 -filter_complex "[0:v]settb=1/AVTB,setpts=PTS-STARTPTS[main];[1:v]settb=1/AVTB,setpts=PTS-STARTPTS[ref];[main][ref]libvmaf=vmaf_v0.6.1.pkl" -repor t -f null -
```

結果なのですが `95.264100` でした。悪くはない。
昨年の ffmpeg(libaom) `-cpu-used 1` で取得した値は `97.248482` だったので、まぁそれと比較する画質が低いですね。



```
$ ./ffmpeg.exe -i sintel_30s_av1.mp4 -t 00:00:30 -r 24 -i sintel_30s.mp4 -t 00:00:30 -r 24 -filter_complex "[0:v]settb=1/AVTB,setpts=PTS-STARTPTS[main];[1:v]settb=1/AVTB,setpts=PTS-STARTPTS[ref];[main][ref]libvmaf=vmaf_v0.6.1.pkl" -repor t -f null -
ffmpeg started on 2020-12-24 at 23:53:20
Report written to "ffmpeg-20201224-235320.log"
Log level: 48
ffmpeg version N-95652-gd1d627fafd-gc54268ce02+1 Copyright (c) 2000-2019 the FFmpeg developers
  built with gcc 9.2.0 (Rev2, Built by MSYS2 project)
  configuration: --prefix=/local32 --bindir=/local32/bin-video --pkg-config-flags=--static --disable-autodetect --enable-amf --enable-bzlib --enable-cuda --enable-cuvid --enable-d3d11va --enable-dxva2 --enable-iconv --enable-lzma --enable-nvenc --enable-zlib --enable-sdl2 --enable-ffnvcodec --enable-nvdec --enable-cuda-llvm --enable-libmp3lame --enable-libopus --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libx265 --enable-libdav1d --disable-debug --enable-fontconfig --enable-libass --enable-libbluray --enable-libfreetype --enable-libmfx --enable-libmysofa --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvo-amrwbenc --enable-libwavpack --enable-libwebp --enable-libxml2 --enable-libzimg --enable-libshine --enable-gpl --enable-avisynth --enable-libxvid --enable-libaom --enable-libopenmpt --enable-version3 --enable-chromaprint --enable-frei0r --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libflite --enable-libfribidi --enable-libgme --enable-libgsm --enable-libilbc --enable-libkvazaar --enable-libmodplug --enable-librtmp --enable-librubberband --enable-libssh --enable-libtesseract --enable-libxavs --enable-libzmq --enable-libzvbi --enable-openal --enable-libvmaf --enable-libcodec2 --enable-libsrt --enable-ladspa --enable-opencl --enable-opengl --enable-libopenh264 --enable-mbedtls --extra-cflags=-fopenmp --extra-libs=-lgomp --extra-cflags=-DLIBTWOLAME_STATIC --extra-libs=-lstdc++ --extra-cflags=-DLIBSSH_STATIC --extra-ldflags='-Wl,--allow-multiple-definition' --extra-cflags=-DCACA_STATIC --extra-cflags=-DMODPLUG_STATIC --extra-cflags=-DCHROMAPRINT_NODLL --extra-libs=-lstdc++ --extra-cflags=-DZMQ_STATIC --extra-libs=-lpsapi --extra-cflags=-DLIBXML_STATIC --extra-libs=-liconv --disable-w32threads --extra-cflags=-DKVZ_STATIC_LIB --extra-version=gc54268ce02+1
  libavutil      56. 35.101 / 56. 35.101
  libavcodec     58. 60.100 / 58. 60.100
  libavformat    58. 34.101 / 58. 34.101
  libavdevice    58.  9.100 / 58.  9.100
  libavfilter     7. 66.100 /  7. 66.100
  libswscale      5.  6.100 /  5.  6.100
  libswresample   3.  6.100 /  3.  6.100
  libpostproc    55.  6.100 / 55.  6.100
[libdav1d @ 08e117c0] libdav1d 0.5.1
[libdav1d @ 08e117c0] Frame size limit reduced from 2147483647 to 67108864.
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'sintel_30s_av1.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 1
    compatible_brands: isomav01
    creation_time   : 2020-12-24T14:19:18.000000Z
  Duration: 00:00:30.04, start: -0.041667, bitrate: 994 kb/s
    Stream #0:0(und): Video: av1 (Main) (av01 / 0x31307661), yuv420p(tv, bt709/unknown/unknown), 1920x818, 891 kb/s, 24 fps, 24 tbr, 24k tbn, 24k tbc (default)
    Metadata:
      creation_time   : 2020-12-24T14:19:18.000000Z
      handler_name    : ETI ISO Video Media Handler
      encoder         :
                      : AOM Coding
    Stream #0:1(eng): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 96 kb/s (default)
    Metadata:
      creation_time   : 2020-12-24T14:19:18.000000Z
      handler_name    : ETI ISO Audio Media Handler
Input #1, mov,mp4,m4a,3gp,3g2,mj2, from 'sintel_30s.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf57.83.100
  Duration: 00:00:30.08, start: 0.000000, bitrate: 16240 kb/s
    Chapter #1:0: start 0.000000, end 30.000000
    Metadata:
      title           : Chapter 01
    Stream #1:0(eng): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709/unknown/unknown), 1920x818, 15595 kb/s, SAR 1:1 DAR 960:409, 24 fps, 24 tbr, 16k tbn, 48 tbc (default)
    Metadata:
      handler_name    : VideoHandler
    Stream #1:1(eng): Audio: ac3 (ac-3 / 0x332D6361), 48000 Hz, 5.1(side), fltp, 640 kb/s (default)
    Metadata:
      handler_name    : SoundHandler
    Side data:
      audio service type: main
    Stream #1:2(eng): Data: bin_data (text / 0x74786574), 0 kb/s
    Metadata:
      handler_name    : SubtitleHandler
[libdav1d @ 08e28a40] libdav1d 0.5.1
[libdav1d @ 08e28a40] Frame size limit reduced from 2147483647 to 67108864.
Stream mapping:
  Stream #0:0 (libdav1d) -> settb (graph 0)
  Stream #1:0 (h264) -> settb (graph 0)
  libvmaf (graph 0) -> Stream #0:0 (wrapped_avframe)
  Stream #1:1 -> #0:1 (ac3 (native) -> pcm_s16le (native))
Press [q] to stop, [?] for help
Output #0, null, to 'pipe:':
  Metadata:
    major_brand     : isom
    minor_version   : 1
    compatible_brands: isomav01
    encoder         : Lavf58.34.101
    Chapter #0:0: start 0.000000, end 30.000000
    Metadata:
      title           : Chapter 01
    Stream #0:0: Video: wrapped_avframe, yuv420p, 1920x818, q=2-31, 200 kb/s, 24 fps, 24 tbn, 24 tbc (default)
    Metadata:
      encoder         : Lavc58.60.100 wrapped_avframe
    Stream #0:1(eng): Audio: pcm_s16le, 48000 Hz, 5.1(side), s16, 4608 kb/s (default)
    Metadata:
      handler_name    : SoundHandler
      encoder         : Lavc58.60.100 pcm_s16le
    Side data:
      audio service type: main
frame=  721 fps= 46 q=-0.0 Lsize=N/A time=00:00:30.00 bitrate=N/A speed=1.92x
video:287kB audio:16875kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
[libvmaf @ 09c58780] VMAF score: 95.264100
```

# 過去のエンコード結果と比較

おそらくなのですが、MediaConvertはシャーディングエンコードしていると思うので、こんな短いファイルで比較してあげるのは酷な気がするんですよね…
とは言うものの一応比較していました。速度もそうですが、あんまり圧縮効率はよくなさそうですね。見る限りVP9で良くない？って感じが若干。

| エンコーダー                         | エンコード時間(秒) | VMAF(ソースとの比較) | ビットレート |
|:-----------------------------------:|:------------------:|:--------------------:|:------------:|
| **AWS Elemental MediaConvert**      | 154                | 95.264100            | 892 kbps     |
|             x264:   ffmpeg(libx264) | 5.719              | 87.969659            | 790 kbps     |
|               VP9:   ffmpeg(libvpx) | 75.16              | 96.28681             | 894 kbps     |
| AV1:   ffmpeg(libaom) `-cpu-used 1` | 2,834.16           | 97.248482            | 649 kbps     |
| AV1:   ffmpeg(libaom) `-cpu-used 5` | 795.297            | 96.868897            | 696 kbps     |
|        AV1:   SVT-AV1 `-enc-mode 1` | 501.466            | 96.962693            | 721 kbps     |
|        AV1:   SVT-AV1 `-enc-mode 5` | 54.261             | 95.945126            | 741 kbps     |


# 総評

時間がなかったのでかなりざっくりな検証になってしまいました。
が、なんとなく雰囲気を察することができたのでよきよき。

もしかしたらAWS Elemental的にはVP9に対応する代わりにAV1に対応したのかもしれませんね。
VP9さん、未だにバージョン1.0が来ないし…まぁVP9に対応するよりはAV1に対応したほうが将来性ありそうな気はしますもんね…

2020年も着々とAV1が普及した気もしますが、割と特許周りで暗雲が立ち込め始めた年だったようにも感じます。
さっさと諸々解決してほしいなという気持ちになりますね。

ただ、ビジネス面で考えると、特許プールがx265レベルの混沌にならなければ別に特許料を払っても良いのでは？とも思うので、案外[VVC](https://ja.wikipedia.org/wiki/Versatile_Video_Coding)が最終的な落ち着きどころになったりするのかも？？とか思う今日このごろだったりします。


# 宣伝

今回のお遊びも、弊社のエンジニア支援制度のおかげで私のお財布を傷めずに行うことができました。ありがとう弊社！
[DMM Tech Empowerment -エンジニア・デザイナーのためのサポート制度パッケージを公開！- - DMM inside](https://inside.dmm.com/entry/2019/01/15/dmm-tech-empowerment)
[AWS トレーニング活用事例：DMM.com](https://aws.amazon.com/jp/training/case-studies/dmm-training/)

2020年の個人的な振り返りなのですが、今年はいっぱい会社のオウンドメディアに記事をチームで書きました。
弊社内で作っているシャーディングエンコーダーシステムの話にも少し触れていたりするので、興味がある方はぜひ。
[連載、始めます ～進化する動画配信基盤～ - DMM inside](https://inside.dmm.com/entry/2020/02/04/evolving_content_delivery_platform_00)

で、上記のエンコーダーが頑張ってくれた成果として4Kの配信が始まっていたりします。話題のゲーム機PS5でも見れたりするよ。みんな見てね。わいわい！
[DMM初4K対応動画を期間限定で無料公開！](https://www.dmm.com/digital/4k/freevideo)

あとAWSさんにお声がけいただいてInterBEEでも登壇しました。
「あのInterBEEでお話できるとは…！」って感じです。結構デカめのライブ配信の案件紹介とかもしていたりするので、ご興味のある方はぜひ見てみてください(まだ見れるはず？)
[AWSを活用した配信事例とAmazon CloudFrontの最新アップデート | 映像・音響、放送・通信業界の情報発信サイト INTER BEE ONLINE](https://www.inter-bee.com/ja/online/conference/session/?event_id=15&conference_id=1551)
[[レポート] AWSを活用した配信事例とAmazon CloudFrontの最新アップデート #interbee2020 | Developers.IO](https://dev.classmethod.jp/articles/report-interbee2020-cloudfront-media/)

色々とあった1年間でしたね。しかしながらその中でもなかなか頑張ったのかな？と個人的には思っていたりします。来年も頑張っていきたいですね。良い年になると良いなぁ。

がんばるぞい！

**来年も弊社DMMを何卒よろしくおねがいします！(最終日らしい締め)**

[![DMM.com 2020 HIGHLIGHTS](http://img.youtube.com/vi/6HGbNA9SyMc/0.jpg)<br>DMM.com 2020 HIGHLIGHTS - YouTube](http://www.youtube.com/watch?v=6HGbNA9SyMc)