Raspberry Pi 4 64ビット環境でffmpegをビルドしてハードウェアエンコードしてみました

Raspberry Pi地デジ関連記事


以前、Raspberry Pi 4の64ビット環境で、動画のハードウェアエンコードが可能かどうか検証しましたが、動画が緑色になり、うまくいかない状況でした。

先日Oさんからコメントを頂き、動画が緑色になるのは、ffmpeg 4.2.xのバグという情報を頂きました。

ということは、ffmpegをなんとかすれば、Raspberry Pi 4の64ビット環境で、ハードウェアエンコードが可能ということですか?本当ですか?

というわけで。背中を押して頂いた勢いで、Raspberry Pi 4でffmpegをビルドして再度検証してみました。


Raspberry pi 4 64ビット版Ubuntu 20.04.1のカスタムffmpegビルド手順

使用するRaspberry PiとOS

メモリー容量4GB版のRaspbery Piを使用しましたが。64ビットということで、8GB版でも問題ないかと思います。私は8GBでは試してませんが、むしろメモリー容量8GBが本気を出すときが来たのではないかと。ぜひ試してみたいです!

OSは、Ubuntu 20.04.1 LTS 64ビットServer版を使用しました。microSDカードは使用せずに、USB接続した1TBのHDDから起動しました。

USB接続したHDDから起動する場合、容量が大きすぎると起動できないようです。3TBは起動できたという情報もありますが、環境によって異なるようです。

各種ライブラリはUbuntu 20.04.1標準を使用

最新バージョンのffmpegをビルド(ソースコードをコンパイルしてオブジェクトファイルを生成、リンクして実行バイナリを作成)しますが、使用するライブラリはUbuntu 20.04.1標準のものを使用しました。

具体的な意味ですが、configureのオプションを既存のUbuntu 20.04.1同梱のffmpeg 4.2.4に合わせて新しいffmpeg 4.3.xをビルドすることで、機能的に同じではあるもののバグが少ないffmpegにしましょう、という考え方になります。

新しいライブラリを取り入れれば機能が増えますが、作業が大変になりますので、そこは別の機会に致します。

既存のffmpeg 4.2.4のconfigureオプションは下記のようです。

configuration: 
--prefix=/usr 
--extra-version=1ubuntu0.1 
--toolchain=hardened 
--libdir=/usr/lib/aarch64-linux-gnu 
--incdir=/usr/include/aarch64-linux-gnu 
--arch=arm64 
--enable-gpl 
--disable-stripping 
--enable-avresample 
--disable-filter=resample 
--enable-avisynth 
--enable-gnutls 
--enable-ladspa 
--enable-libaom 
--enable-libass 
--enable-libbluray 
--enable-libbs2b 
--enable-libcaca 
--enable-libcdio 
--enable-libcodec2 
--enable-libflite 
--enable-libfontconfig 
--enable-libfreetype 
--enable-libfribidi 
--enable-libgme 
--enable-libgsm 
--enable-libjack 
--enable-libmp3lame 
--enable-libmysofa 
--enable-libopenjpeg 
--enable-libopenmpt 
--enable-libopus 
--enable-libpulse 
--enable-librsvg 
--enable-librubberband 
--enable-libshine 
--enable-libsnappy 
--enable-libsoxr 
--enable-libspeex 
--enable-libssh 
--enable-libtheora 
--enable-libtwolame 
--enable-libvidstab 
--enable-libvorbis 
--enable-libvpx 
--enable-libwavpack 
--enable-libwebp 
--enable-libx265 
--enable-libxml2 
--enable-libxvid 
--enable-libzmq 
--enable-libzvbi 
--enable-lv2 
--enable-omx 
--enable-openal 
--enable-opencl 
--enable-opengl 
--enable-sdl2 
--enable-libdc1394 
--enable-libdrm 
--enable-libiec61883 
--enable-chromaprint 
--enable-frei0r 
--enable-libx264 
--enable-shared

こちらのconfigureオプションでビルドが可能になるように、各種パッケージのインストールを行いたいと思います。

ビルド関連ツールのインストール

「Raspberry Pi 4 Ubuntu 20.04.1 64ビット版で動画が緑色になるのはffmpegのバグ」というエビデンスはもう1つあります。次の記事になります。

こちらの記事のffmpegビルド手順を参考にさせて頂こうと思ったのですが、使用するライブラリが少なすぎる感じがしました。Ubuntu添付のffmpegの機能がずいぶん削られてしまいます。

このため、ビルドツールのインストール等のスクリプトを参考にさせて頂きつつ、不足していると感じたところは独自に補わせて頂きました。

最初に、上記の記事で紹介されているビルドツールとライブラリをインストールします。

sudo apt-get update -qq && sudo apt-get -y install \
  autoconf \
  automake \
  build-essential \
  cmake \
  git-core \
  libass-dev \
  libfreetype6-dev \
  libgnutls28-dev \
  libsdl2-dev \
  libtool \
  libva-dev \
  libvdpau-dev \
  libvorbis-dev \
  libxcb1-dev \
  libxcb-shm0-dev \
  libxcb-xfixes0-dev \
  pkg-config \
  texinfo \
  wget \
  yasm \
  zlib1g-dev

続いて、不足している各種ライブラリ(-dev付き)をインストールします。

sudo apt install \
libavresample-dev libavresample4 \
nasm \
libx264-dev \
libx265-dev libnuma-dev \
libvpx-dev \
libfdk-aac-dev \
libmp3lame-dev \
libopus-dev

こちらはffmpegのコンパイルガイドに基づきます。

ソースコードの取得

ビルドに必要なツールとライブラリのインストールが終わったところで。続いてffmpegのソースコードを取得します。

gitコマンドで最新バージョンを取得しました。

git clone --depth 1 git://github.com/FFmpeg/FFmpeg.git

ちなみにブランチからリリースバージョン4.3を取得する場合は下記のコマンドのようです。(自分用覚書

git clone --depth 1 --branch release/4.3 git://github.com/FFmp
eg/FFmpeg.git

今回は最新のソースをビルドしてみましたが、バージョンはgit-2021-01-03-6c24f2bでした。

configure実行

先ほど、Ubuntu 20.04.1標準のffmpeg configureオプションを記載致しましたが、そのままではビルドできませんでした。オプションを2つ削り、「–enable-avisynth」と「–enable-libwavpack」オプションはつけずにconfigureを実行しました。

またインストール先のprefixは既存のffmpegとぶつからないように「/opt/usr」に変更しました。

# git cloneで取得したソースディレクトリに移動
cd FFmpeg
# configure実行
./configure \
--prefix=/opt/usr \
--extra-version=1ubuntu0.1 \
--toolchain=hardened \
--libdir=/usr/lib/aarch64-linux-gnu \
--incdir=/usr/include/aarch64-linux-gnu \
--arch=arm64 \
--enable-gpl \
--disable-stripping \
--enable-avresample \
--disable-filter=resample \
--enable-gnutls \
--enable-ladspa \
--enable-libaom \
--enable-libass \
--enable-libbluray \
--enable-libbs2b \
--enable-libcaca \
--enable-libcdio \
--enable-libcodec2 \
--enable-libflite \
--enable-libfontconfig \
--enable-libfreetype \
--enable-libfribidi \
--enable-libgme \
--enable-libgsm \
--enable-libjack \
--enable-libmp3lame \
--enable-libmysofa \
--enable-libopenjpeg \
--enable-libopenmpt \
--enable-libopus \
--enable-libpulse \
--enable-librsvg \
--enable-librubberband \
--enable-libshine \
--enable-libsnappy \
--enable-libsoxr \
--enable-libspeex \
--enable-libssh \
--enable-libtheora \
--enable-libtwolame \
--enable-libvidstab \
--enable-libvorbis \
--enable-libvpx \
--enable-libwebp \
--enable-libx265 \
--enable-libxml2 \
--enable-libxvid \
--enable-libzmq \
--enable-libzvbi \
--enable-lv2 \
--enable-omx \
--enable-openal \
--enable-opencl \
--enable-opengl \
--enable-sdl2 \
--enable-libdc1394 \
--enable-libdrm \
--enable-libiec61883 \
--enable-chromaprint \
--enable-frei0r \
--enable-libx264 \
--enable-shared
# 次の2行はコメント化
# --enable-avisynth \
# --enable-libwavpack \

しばらく待つとconfigureが完了し、Makefileが出力されます。ではいよいよmakeコマンドでビルドします。マルチコア最適化オプション付きでビルドしました。

make -j4

ビルドは30分弱で完了しました。コンパイル中に警告がちらほら表示されましたが、リンクエラーもなく無事にビルドできました。

既存のffmpegと共存できるように/optにインストール

インストール先はconfigureのprefixオプションで予め/optを指定しておきました。make installコマンドでインストールします。

sudo make install

このような感じで、ffmpeg,ffplayffprobeコマンドが/opt/usr/binにインストールされました。自力でビルド・インストールしたffmpegコマンドを実行してみましょう。ふむふむ。特に問題なく動きそうです。

以上で最新バージョンのffmpegのビルド・インストールが完了しました。

うまくビルドできたようですので、エンコードもうまくいく予感がしますが・・・どうでしょうか?実際に試してみました。


Raspberry Pi 4 64ビット版Ubuntu 20.04.1 LTS Serverでffmpegハードウェアエンコード成功

結論から申し上げます。ビルドしたffmpegでエンコードしたところ。

Ubuntu 20.04.1添付のffmpegと異なり、次の2つのポイントがありました。

  1. 映像は正しい色で出力されました。緑色ではありません。
  2. エンコード時、ビットレートを指定する必要があります。指定しないと400kbpsの低ビットレートでエンコードされるため、ファイルサイズが小さく画質が低くなります。適切なビットレートを指定することで、良好な画質が得られました。

短い動画ですが、これは1分20秒程度のtsファイルを実際にハードウェア・エンコードして出力されたファイルになります。

上述の通り、-b:v オプションでビットレートを指定しないと、低品質の映像が出力されてしまいます。5Mbpsでハードウェアエンコードしてみました。

time /opt/usr/bin/ffmpeg -i test.ts -c:v h264_v4l2m2m -b:v 5M -y test_v4l2m2m_5M.mp4
# -b:vオプションでビットレートを指定しないと低画質になります

エンコード中のフレームレートは65fps出ており、ハードウェアエンコーダが有効であることがわかります。エンコードにかかった実時間は43秒・・・動画の長さの1分20秒の半分で出力されています。ユーザ時間が1分かかっていますが、このあたりは動画が短すぎて計算の誤差が出ているようですが、動画の再生時間よりも短い時間でエンコードできているのは確かなようです。

生成されたtest_v4l2m2m_5M.mp4は問題なく再生できました。

ハードウェアエンコード時の負荷は最大4.0程度で、4コアのRaspberry Pi 4の負荷としてはバランスが良い状態です。ソフトウェアエンコードした場合は、ロードアベレージが8.0に達して、エンコード以外の処理に遅延が発生する状況でしたので、ハードウェアエンコードはソフトウェアエンコードよりも負荷がずっと小さいことが確認できました。

これで実際に、64ビットのUbuntu 20.04.1環境でも、ffmpegでハードウェアエンコードが可能であることがわかりました。


EPGStationの設定変更

EPGStationの設定を変更して、ハードウェアエンコードが可能なffmpegを使用するようにしました。

vi EPGStation/config/config.json
# ffpmegのパスを/opt/usr/bin/ffmpegに変更
"ffmpeg": "/opt/usr/bin/ffmpeg",
"ffprobe": "/opt/usr/bin/ffprobe",
# libx264をh264_v4l2m2mに置換
# vimの場合、:(コロン)→%s/libx264/h264_v4l2m2m/g→エンターで一括置換

変更が終わりましたら、EPGStationを再起動しました。

# EPGStationのidを確認
sudo pm2 status
# idを指定して再起動
sudo pm2 restart 1


Raspberry Piの録画環境を、いろいろと整えてきましたが。

ffmpegのビルドは、最後の難関だった感じがします。

苦労の甲斐があり、これでRaspberry Pi録画環境が完成!・・・というわけでも無さそうです。

libx264をh264_v4l2m2mに置換したものの、実用に耐えるエンコードオプションを、いろいろと調整する必要があるかと思います。

32ビット環境と64ビット環境では、調整~チューニングが異なるかと思いますので、64ビット環境での最適解を探す苦労があるかもしれません。

楽しみながら、いろいろと実験してみてください!(私は力尽きました


Raspberry Pi地デジ関連記事

スポンサーリンク

フォローする

スポンサーリンク

コメント

  1. Oさん より:

    Raspberry Pi64bit環境でのハードウェアエンコードうまくいったようでよかったです!
    自分も最初はffmpegをソースコードからビルドしようとしたのですが、何故かうまくいかず最終的にはffmpeg公式サイトからビルド済みのものを使うという形になってしまいました。
    最新版のビルド方法まで書いていただいているということで、参考にしてもう一度やってみたいと思います。

    • hide より:

      Oさん こんにちは。
      コメント頂きありがとうございます。

      情報を頂き、検証がうまく行きまして良かったです。
      ありがとうございました。

      なるほど、バイナリ版をダウンロードされたのですね。
      ビルドが無事うまく進みますよう願っております。