Raspberry Pi 4 Model B 8GB と FFmpeg 4.4 でハードウェアエンコードを行ってみます。
OS
OS は Raspberry Pi OS (旧 Raspbian) ではなく Ubuntu 20.04 を使用しました。2021 年 5 月の時点では Raspberry Pi OS は 32bit 版しか提供されておらず、 64bit 版はベータのテストバージョンです。一方、Ubuntu は公式に Raspberry Pi 4 向けの 64bit 版が提供されています。また、私は自作 PC でも Ubuntu を使用しているため、そこでのノウハウを横展開できる利点もあります。
Raspberry Pi 4 Model B 8GB にインストールした Ubuntu のバージョンは 20.04 です。インストールについは下記の通り、別途投稿しています。
FFmpeg のビルドオプション
数年前に Raspberry Pi 3 で FFmpeg を使用したハードウェアエンコードを行っていた時はビルドオプションとして
--enable-omx-rpi --enable-mmal
を設定していたのですが、Raspberry Pi 4 + 64bit OS ではサポートされていませんでした(ビルドに失敗してしまう)。
下記は FFmpeg の wiki の HWAccelI 情報です。
https://trac.ffmpeg.org/wiki/HWAccelIntro
また、下記は Raspberry Pi のフォーラムの Video acceleration on the Raspberry Pi 4 というスレッドです。
結論としては、Raspberry Pi 4 + 64bit OS + FFmpeg では v4l2_m2m を使用するようです。FFmpeg をビルドする際には何もオプションを付ける必要はありません。configure を実行するのみでデフォルトで下記の設定がされます。
External libraries providing hardware acceleration:
v4l2_m2m
FFmpeg のビルドとインストール
まず、必要と思われるパッケージを APT でインストールします。私にとって必要なパッケージをインストールしており、他者にとっては過剰なインストールになっているかもしれません。
sudo apt install -y build-essential git wget libasound2-dev \
autoconf libtool pcsc-tools pkg-config libpcsclite-dev pcscd \
cmake yasm curl ssh dkms unzip
FFmpeg をダウンロードしてビルドしてインストールします。前述の通り configure には何もオプションを付けません。Raspberry Pi 上でビルドすると 20 分くらいかかりました。
cd ~/working_directory && \
wget http://ffmpeg.org/releases/ffmpeg-4.4.tar.gz && \
tar zxvf ffmpeg-4.4.tar.gz && \
cd ffmpeg-4.4 && \
./configure && \
make -j$(nproc) && \
sudo make install
バージョン情報です。
$ ffmpeg -version
ffmpeg version 4.4 Copyright (c) 2000-2021 the FFmpeg developers
built with gcc 9 (Ubuntu 9.3.0-17ubuntu1~20.04)
configuration:
libavutil 56. 70.100 / 56. 70.100
libavcodec 58.134.100 / 58.134.100
libavformat 58. 76.100 / 58. 76.100
libavdevice 58. 13.100 / 58. 13.100
libavfilter 7.110.100 / 7.110.100
libswscale 5. 9.100 / 5. 9.100
libswresample 3. 9.100 / 3. 9.100
動作確認
Sintel の Trailer を変換してみました。ビットレートは 5Mbps 程度に設定してみました。
https://durian.blender.org/download/
なんと変換速度は 2.2 倍でした。つまり、Raspberry Pi 4 で、H.264 のリアルタイムエンコードも可能ということになります。すごいですね。
$ ffmpeg -i sintel_trailer-1080p.mp4 -c:v h264_v4l2m2m -b:v 5000k test.mp4
Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1920x1080, 2108 kb/s, 24 fps, 24 tbr, 24 tbn, 48 tbc (default)
Metadata:
creation_time : 1970-01-01T00:00:00.000000Z
handler_name : VideoHandler
vendor_id : [0][0][0][0]
Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 126 kb/s (default)
Metadata:
creation_time : 1970-01-01T00:00:00.000000Z
handler_name : SoundHandler
vendor_id : [0][0][0][0]
Stream mapping:
Stream #0:0 -> #0:0 (h264 (native) -> h264 (h264_v4l2m2m))
Stream #0:1 -> #0:1 (aac (native) -> aac (native))
Press [q] to stop, [?] for help
[h264_v4l2m2m @ 0xaaab00f9e040] Using device /dev/video11
[h264_v4l2m2m @ 0xaaab00f9e040] driver 'bcm2835-codec' on card 'bcm2835-codec-encode' in mplane mode
[h264_v4l2m2m @ 0xaaab00f9e040] requesting formats: output=YU12 capture=H264
...
frame= 1253 fps= 53 q=-0.0 Lsize= 20391kB time=00:00:52.04 bitrate=3209.8kbits/s speed= 2.2x