Ubuntuでターミナルエミュレータにtmux-256colorを使う

TL;DR

ncurses-termパッケージをaptでインストールしろ。

Ubuntuはtmuxパッケージのdependsにncurses-termを設定しろ。

環境

  • Linux : 4.10.0(x86_64)
  • Ubuntu : 17.04(Zesty Zapus)
  • tmux : 2.3
  • ncurses : 6.0+20160625-1ubuntu1

メモ

ターミナルを複数画面に分割して利用できるターミナルマルチプレクサとして tmuxを愛用している。 tmuxは起動時に~/.tmux.confを参照して、内部で起動するターミナルエミュレータの種類を変更できる。

256色カラーを有効化するときにはscreen-256colorを指定しろという記述はあちらこちらに見つかるが、 tmux - ArchWiki によればtmux-256colorというtmux向けのターミナルエミュレータの利用が推奨されている。

しかし、Ubuntuにおいてtmuxをインストールしたあとにinfocmp tmux-256colorをしても、tmux-256colorというターミナルエミュレータの設定は見当たらない。 ということをTwitterで愚痴っていたら次のアドバイスをもらった。

どうやらncurses>=20150502ならばtmux-256colorはすでにインストールされているという。 矛盾した事象が起きているので色々探してみると次の記事が見つかった。

chakku.hatenablog.com

この記事の内容に従ってncurses-termをインストールするとtmux-256colorが現れた。

Raspberry Pi2 + FFmpegでMPEG2TSをハードウェアエンコード

TL;DR

  • Raspberry Pi2にハードウェアアクセラレーションを有効化したFFmpegを導入した
  • ハードウェアエンコードのみで20fpsを、ハードウェアデコード及びエンコードの有効化で26fpsの処理速度が得られた
  • ハードウェアでコード及びエンコードを用いれば、30fpsの動画をほぼ等速で処理可能になる

はじめに

Raspberry Piにはカメラ接続端子が搭載されていることはよく知られている。 そして、カメラの入力を取り扱うためにハードウェアエンコーダが搭載されている事もまた知られている。 ところでこのハードウェアエンコーダはMPEG2をネイティブで取り扱うことができるので、これを転用してMPEG2TSをハードウェアエンコードしたいという考えが生まれる。

少し前までであればこのようなハードウェアエンコードにはgstreamerを使うのが定番だったが、 gstreamerは動画エンコードを目的としたツールではないため、大量のオプションが必要だったりとやや不便なツールだった。 ここ最近になって、FFmpegRaspberry Piのハードウェアエンコードに対応したので、ビルドしてこれを利用する。 また、ハードウェアエンコードによる処理速度の向上を他の環境と比較する。

準備編

はじめにMPEG2用のライセンスを手に入れておく。

これについては、すでに複数の参考文献があるためここでは割愛する 基本的には購入ページに書いてある指示と、ライセンスキーが記載されたメールに書いてある指示に従えば有効化できる。 有効になっていると、次のコマンドを実行した時に結果がenabledとなる。

vcgencmd codec_enabled MPG2

次にビルド環境を整える。 Raspberry Piをセットアップした直後であれば、様々なツールが揃っていないと思われるが、とりあえず下記のコマンドを実行すると良い。

apt install build-essential raspberrypi-kernel-headers libomxil-bellagio-dev git

build-essentialは基本的なビルドツール(makegcc)がインストールできる。 raspberrypi-kernel-headersはMMALを利用するためのヘッダーファイルmmal.hをインストールする。 *1 libomxil-bellagio-devはハードウェアエンコードに必要なOpenMAX ILのライブラリを提供している。

また、今回はFFmpegのgitリポジトリからソースコードを取ってくるためgitをインストールする。

FFmpegソースコードは次のコマンドで取得する。 今回はgithubに上がっているミラー(https://github.com/FFmpeg/FFmpeg)を利用することにした。

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

取得に成功したらディレクトリを移動してビルドを進めていく

cd ~/FFmpeg
./configure --arch=armel --target-os=linux --enable-mmal --enable-gpl --enable-omx --enable-omx-rpi --enable-nonfree --prefix=$HOME/usr/local

最小限でビルドするとこの形になる。--prefixは標準のインストール先にインストールしても良いなら指定しなくて構わない。 --enable-omx-rpi--enable-mmalを指定することで、Raspberry Piでのハードウェアアクセラレーションを有効にする。 この設定ではlibx264libmp3lameなどは利用できないので、必要ならば別途用意してビルド時に指定をする。

make -j4 #ここは実コア数に応じて変更する。

を実行し、生成されたバイナリでハードウェアエンコーディングが有効になっているか確かめる。 有効になっていれば、次のコマンドを実行した時にそれぞれハードウェアアクセラレーションを利用するデコーダ・エンコーダが表示される。

# デコーダの表示
./ffmpeg -decoders 2> /dev/null | grep mmal
 V..... h264_mmal            h264 (mmal) (codec h264)
 V..... mpeg2_mmal           mpeg2 (mmal) (codec mpeg2video)
 V..... mpeg4_mmal           mpeg4 (mmal) (codec mpeg4)
 V..... vc1_mmal             vc1 (mmal) (codec vc1)
# エンコーダの表示
./ffmpeg -encoders 2> /dev/null | grep omx
 V..... h264_omx             OpenMAX IL H.264 video encoder (codec h264)

これらが表示されていれば、ハードウェアアクセラレーションが有効になっているので、あとはインストールすれば簡単に利用できる。

make install

テスト

実際にビルドしたFFmpegを使って、適当なMPEG2TSファイルをH.264/AACのmp4ファイルにエンコードする。 また、ハードウェアアクセラレーションの効果を確認するために、幾つかの設定を変更してエンコードを試みる。

入力ファイルとして、今回はERBラボが提供しているサンプルストリームisdbt18.tsを利用する。 isdbt18.tsは1分間の実写動画であり、ストリームの形式はMPEG2/AACとなっている。 ffprobeを用いて表示したストリーム情報を以下に示す。

Input #0, mpegts, from 'isdbt188.ts':
  Duration: 00:01:00.87, start: 109.851700, bitrate: 17304 kb/s
  Program 23664
    Metadata:
      service_name    : ?ERB?|ニ・1
      service_provider:
    Stream #0:0[0x200]: Video: mpeg2video (Main) ([2][0][0][0] / 0x0002), yuv420p(tv, top first), 1440x1080 [SAR 4:3 DAR 16:9], 16712 kb/s, 29.97 fps, 29.97 tbr, 90k tbn, 59.94 tbc
    Stream #0:1[0x201]: Audio: aac (LC) ([15][0][0][0] / 0x000F), 48000 Hz, stereo, fltp, 186 kb/s

まずはハードウェアエンコーディングだけを利用してエンコードする。オプションは次の形になる。

ffmpeg -fflags +discardcorrupt -i isdbt18.ts -c:a copy -bsf:a aac_adtstoasc -c:v h264_omx -b:v 5000k -y out.mp4

-bsf:a aac_adtstoasc-fflags +discardcorruptの指定はオーディオストリームをコピーするときに発生するエラーを抑止するために指定する。 これがないとmp4への変換時にaac bitstream errorが発生する。

そして、出力のビデオコーデックとしてh264_omxを指定する。これによってエンコード時にハードウェアを利用する。

また、ビットレートを指定しておかないと非常に低いビットレートで変換されることになり、出力結果が目も当てられなくなるのでそれなりの値を指定しておくと良い。

この時、ストリームの入出力間での対応は次のようになる。

Stream mapping:
  Stream #0:0 -> #0:0 (mpeg2video (native) -> h264 (h264_omx))
  Stream #0:1 -> #0:1 (copy)

これを見ればわかるようにデコード時にハードウェアが利用されておらず、エンコード時にのみハードウェアが利用されている。 この時のCPU使用率は100%手前から150%程度となる。また、処理速度は20fpsとなり、ファイル実時間に対しておおよそ3/2倍の時間でエンコードが完了する。

次にデコード・エンコードともにハードウェアアクセラレーションを有効化する。

ffmpeg -fflags +discardcorrupt -c:v mpeg2_mmal -i isdbt.ts -c:a copy -bsf:a aac_adtstoasc -c:v h264_omx -b:v 5000k -y out.mp4

先ほどとの違いはオプションに-c:v mpeg2_mmalが追加されている点で、これでハードウェアデコードが行われる。 *2

この時のCPU使用率はおおよそ50%程度となり、ハードウェアエンコードのみの場合に比べるとかなりCPU負荷が軽減されていることがわかる。 処理速度は26fpsとなり、先程に比べるとやや処理速度が向上していることがわかる。 これならば、ほぼ等速といって差し支えない程度になるため、かなり実用的ではないだろうか。

おまけ

どれくらいの速度が出ているのか実際他の環境でも比較してみる

その1

の場合

実行コマンドは

ffmpeg -fflags +discardcorrupt -i isdbt18.ts -c:a copy -bsf:a aac_adtstoasc -c:v h264 -b:v 5000k -y out.mp4

この時の処理速度は92fpsということは、ファイル実時間に対して約1/3倍の時間でエンコードできる。 さすが現行のAMDハイエンドCPUの面目躍如といったところ。

その2

実行コマンドはその1と同様。 この時の処理速度は13fpsで、ファイル実時間に対しておおよそ2倍の時間でエンコードすることになる。 ハードウェアアクセラレーションを有効化したRaspberry Pi2であれば、Sandy Bridge世代のCeleronよりも高速に動画処理ができるという結果になった。

まとめ

Raspberry PiのハードウェアエンコーダとMMALを用いた支援によって、30fps程度のエンコード能力を得られることがわかった。 これによって、地上デジタル放送などの録画ファイルを適当にRaspberry Piエンコードするという目論見が、時間に対してもそこまで辛くなさそうということがわかってきた。 今回はGPUメモリを128MB割り当てた設定で行っているので、割当を増やした場合の処理についてもテストする必要があると感じる。

また、言うまでもないことだが

等を試すと、CPU処理が挟まる形になるため、処理速度が大幅に低下する。 あくまでも、MPEG2TSをH.264形式に変換するだけに使えると思っておいたほうが良いだろう。

参考資料

orumin.blogspot.jp

qiita.com

www.reddit.com

stackoverflow.com

superuser.com

*1:なくてもビルドできるかもしれない。[要出典]

*2:この時、入力のストリームを見ると解像度が320 * 240とワンセグ相当に見えるが、エンコードが終わると1440 * 1080の動画を得ることができる