3.5万円のミニPCでハードウェアエンコードして6倍時間短縮した話
経緯
動画が沢山あるけどストレージの容量は限られてる!
H.265でエンコードしたかったわけですが、4コア8スレッドとかだと0.7倍速くらいでしかエンコードできない... これではいつまで経っても終わらない!!
ということで、ハードウェアエンコードしまくればいいじゃないか!と思い立ったわけです。
環境
PC
Lenovo M75q-1 tiny
CPU: Ryzen 5 PRO 3400GE 4C8T
RAM: 16GB DDR4
GPU: Radeon Vega 11
OS : Ubuntu 18.04.4 LTS Desktop
Lenovo M75q-1 tinyについて
今回の隠れたテーマはこの激安Ryzen搭載小型デスクトップです。
週末特価を狙うとおよそ3.5万円で NVMeのSSD, 8GB RAM, Ryzen 5 PRO 3400GEの小型デスクトップが手に入って最高なシロモノですね。
なんとWindows 10 Proも入っています。※ 今回は吹き飛ばしてOSはUbuntuを入れてます。
あまりに安くそこそこの性能でめちゃくちゃ静かなので、我が家ではテレビのそばに付けっぱなしで設置して、NAS, VPNサーバー, リモート開発サーバーなどとして使ってます。
多少手間はかかりますが、そのへんの激安NASキットよりも100倍いいです。(当社比です)
Ryzen 5 PRO 3400GEは性能としてはまったくRyzen 5 3400GEと同じで、Ryzen 5 3400Gの35W版です。
RyzenシリーズのG付きモデルは所謂APUというやつで、内蔵グラフィックスとしてRadeon Vegaが載っているものになります。
このPCに付属するACアダプタが65Wなので問題なさそうなのですが、さすがにカツカツらしく、より大容量のACアダプタに交換すると主にGPU性能が爆アゲするらしいです(未確認)
ヤフオクで本物かわからない135WのACアダプタを買ったので、届いたら交換してレビューします。
Amazonで買うなら↓がよさそう。
本当はM75q-1 tinyのレビュー記事も書きたかったのですが、面倒なので↓を参考に。 little-beans.net
調査
ffmpegを利用したLinuxでのハードウェアエンコード事情
今回のキモは「Linuxでの」というところになります。
Windowsで使う場合は、Linux上でクロスコンパイルしたffmpegのバイナリをWindowsに持ってきて使ったりするらしいです。
参考: AMD VCE 対応の ffmpeg をつくる | ニコラボ
Linux上では、VA-API経由でのハードウェアエンコードにしか対応していないみたいなので、こいつを使います。
HWAccelIntro – FFmpeg
手順
1. ffmpeg 4系を入れる
ちょっと古いですが↓の資料をみると、VA-APIを使ったハードウェアエンコードはffmpeg 4.0で大幅な最適化が入ったそうです。
今時のLinuxにおけるGPUエンコード事情2018
ところがUbuntu 18.04.4 LTSで標準で入るffmpegは本記事の執筆時点で 3.4.6
です。
そのため、まずは野良aptリポジトリを使って4系を入れます。
野良リポジトリ追加
sudo add-apt-repository ppa:savoury1/ffmpeg4 sudo add-apt-repository ppa:savoury1/graphics sudo add-apt-repository ppa:savoury1/multimedia sudo apt-get update
ffmpegインストール
sudo apt-get install ffmpeg
ffmpeg -version
$ ffmpeg -version ffmpeg version 4.2.2-1ubuntu1~18.04.sav0 Copyright (c) 2000-2019 the FFmpeg developers built with gcc 7 (Ubuntu 7.5.0-3ubuntu1~18.04) configuration: --prefix=/usr --extra-version='1ubuntu1~18.04.sav0' --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --arch=amd64 --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-nvenc --enable-chromaprint --enable-frei0r --enable-libx264 --enable-shared libavutil 56. 31.100 / 56. 31.100 libavcodec 58. 54.100 / 58. 54.100 libavformat 58. 29.100 / 58. 29.100 libavdevice 58. 8.100 / 58. 8.100 libavfilter 7. 57.100 / 7. 57.100 libavresample 4. 0. 0 / 4. 0. 0 libswscale 5. 5.100 / 5. 5.100 libswresample 3. 5.100 / 3. 5.100 libpostproc 55. 5.100 / 55. 5.100
無事 4.2.2
が入ったようです。
$ ffmpeg -h encoder=hevc_vaapi (0)[~] ffmpeg version 4.2.2-1ubuntu1~18.04.sav0 Copyright (c) 2000-2019 the FFmpeg developers built with gcc 7 (Ubuntu 7.5.0-3ubuntu1~18.04) configuration: --prefix=/usr --extra-version='1ubuntu1~18.04.sav0' --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --arch=amd64 --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-nvenc --enable-chromaprint --enable-frei0r --enable-libx264 --enable-shared libavutil 56. 31.100 / 56. 31.100 libavcodec 58. 54.100 / 58. 54.100 libavformat 58. 29.100 / 58. 29.100 libavdevice 58. 8.100 / 58. 8.100 libavfilter 7. 57.100 / 7. 57.100 libavresample 4. 0. 0 / 4. 0. 0 libswscale 5. 5.100 / 5. 5.100 libswresample 3. 5.100 / 3. 5.100 libpostproc 55. 5.100 / 55. 5.100 Encoder hevc_vaapi [H.265/HEVC (VAAPI)]: General capabilities: delay hardware Threading capabilities: none Supported pixel formats: vaapi_vld h265_vaapi AVOptions: -low_power <boolean> E..V..... Use low-power encoding mode (only available on some platforms; may not support all encoding features) (default false) -idr_interval <int> E..V..... Distance (in I-frames) between IDR frames (from 0 to INT_MAX) (default 0) -b_depth <int> E..V..... Maximum B-frame reference depth (from 1 to INT_MAX) (default 1) -rc_mode <int> E..V..... Set rate control mode (from 0 to 6) (default auto) auto E..V..... Choose mode automatically based on other parameters CQP E..V..... Constant-quality CBR E..V..... Constant-bitrate VBR E..V..... Variable-bitrate ICQ E..V..... Intelligent constant-quality QVBR E..V..... Quality-defined variable-bitrate AVBR E..V..... Average variable-bitrate -qp <int> E..V..... Constant QP (for P-frames; scaled by qfactor/qoffset for I/B) (from 0 to 52) (default 0) -aud <boolean> E..V..... Include AUD (default false) -profile <int> E..V..... Set profile (general_profile_idc) (from -99 to 255) (default -99) main E..V..... main10 E..V..... rext E..V..... -tier <int> E..V..... Set tier (general_tier_flag) (from 0 to 1) (default main) main E..V..... high E..V..... -level <int> E..V..... Set level (general_level_idc) (from -99 to 255) (default -99) 1 E..V..... 2 E..V..... 2.1 E..V..... 3 E..V..... 3.1 E..V..... 4 E..V..... 4.1 E..V..... 5 E..V..... 5.1 E..V..... 5.2 E..V..... 6 E..V..... 6.1 E..V..... 6.2 E..V..... -sei <flags> E..V..... Set SEI to include (default hdr) hdr E..V..... Include HDR metadata for mastering display colour volume and content light level information
よくわからないけどどうやら使えそうです。()
2. VA-APIの準備
確認ツールのインストール
VA-APIの対応状況を確認しておくため、確認ツールを入れます。
sudo apt-get install vainfo
$ vainfo (0)[~] error: can't connect to X server! libva info: VA-API version 1.7.0 libva info: Trying to open /usr/lib/x86_64-linux-gnu/dri/radeonsi_drv_video.so libva info: Found init function __vaDriverInit_1_1 libva info: va_openDriver() returns 0 vainfo: VA-API version: 1.7 (libva 2.1.0) vainfo: Driver version: Mesa Gallium driver 19.2.8 for AMD RAVEN (DRM 3.33.0, 5.3.0-53-generic, LLVM 9.0.0) vainfo: Supported profile and entrypoints VAProfileMPEG2Simple : VAEntrypointVLD VAProfileMPEG2Main : VAEntrypointVLD VAProfileVC1Simple : VAEntrypointVLD VAProfileVC1Main : VAEntrypointVLD VAProfileVC1Advanced : VAEntrypointVLD VAProfileH264ConstrainedBaseline: VAEntrypointVLD VAProfileH264ConstrainedBaseline: VAEntrypointEncSlice VAProfileH264Main : VAEntrypointVLD VAProfileH264Main : VAEntrypointEncSlice VAProfileH264High : VAEntrypointVLD VAProfileH264High : VAEntrypointEncSlice VAProfileHEVCMain : VAEntrypointVLD VAProfileHEVCMain : VAEntrypointEncSlice VAProfileHEVCMain10 : VAEntrypointVLD VAProfileJPEGBaseline : VAEntrypointVLD VAProfileVP9Profile0 : VAEntrypointVLD VAProfileVP9Profile2 : VAEntrypointVLD VAProfileNone : VAEntrypointVideoProc
リモートからつないでいるのでX serverにつながらん!といわれますが、 VAProfileHEVCMain
の VAEntrypointVLD
と VAEntrypointEnvcSlice
があるので、対応していそうですね。
ドライバは /usr/lib/x86_64-linux-gnu/dri/radeonsi_drv_video.so
となっていて、これはRadeonの標準ドライバだそうです。
利用するドライバを明示
今回はVGAデバイスが一つしか無くてドライバが一つしかロードされていないので指定しなくても問題ない気がしますが、ねんのためVA-APIで利用するドライバを指定しておきます。
export LIBVA_DRIVER_NAME=radeonsi
3. エンコード実行
では実際にエンコードしていきましょう。テストとして今回はH.264の動画を、音声はそのままでH.265に変換してみます。
ffmpeg -vaapi_device /dev/dri/renderD128 -hwaccel vaapi -hwaccel_output_format vaapi -i hoge.mp4 -vf 'format=p010|vaapi,hwupload' -c:v hevc_vaapi -qp 28 -c:a copy -tag:v hvc1 hoge_hw.mp4
詳しいオプションは説明しませんが、vaapiと書いてある部分のオプションが重要です。
動画の品質は -qp
オプションで決定できます。
H.264の場合は以下のような感じです。
ffmpeg -vaapi_device /dev/dri/renderD128 -hwaccel vaapi -hwaccel_output_format vaapi -i hoge.mp4 -vf 'format=nv12|vaapi,hwupload' -c:v h264_vaapi -qp 28 -c:a copy -tag:v hvc1 hoge_hw.mp4
4. 結論
実行したときの変換速度を比較してみます。
ソフトウェアエンコードの場合
$ ffmpeg -i hoge.mp4 -c:v libx265 -qp 28 -c:a copy -tag:v hvc1 hoge_hw.mp4 frame= 456 fps= 42 q=-0.0 size= 1280kB time=00:00:16.32 bitrate= 642.5kbits/s speed= 1.5x
ハードウェアエンコードの場合
$ ffmpeg -vaapi_device /dev/dri/renderD128 -hwaccel vaapi -hwaccel_output_format vaapi -i hoge.mp4 -vf 'format=p010|vaapi,hwupload' -c:v hevc_vaapi -qp 28 -c:a copy -tag:v hvc1 hoge_hw.mp4 frame= 1148 fps=228 q=-0.0 size= 6912kB time=00:00:39.33 bitrate=1439.4kbits/s speed=7.83x
およそ6倍くらいのスピードが出ていますね。すごい。
Ryzen 5のG付きはAPUなので、GPUもCPUも大体同じくらいの温度になるのですが、
ソフトウェアエンコードのときは80℃近く、ハードウェアエンコードのときは50℃前後で落ち着いていました。
まとめ
h.265の変換で、およそ6倍程度の変換速度の差が出ました。
ただし、実際の変換結果は載せませんが傾向としてソフトウェアエンコードのほうが画質がよく、 -qp
でのクオリティ設定ではよりビットレートが低く、つまり容量が小さくなる傾向にあります。
容量をめちゃくちゃ重視するならソフトウェアエンコードでじっくり、現実的にはハードウェアエンコードで丁度いい画質設定を探してがっつりエンコードするのがよいのではないでしょうか。
参考
Ubuntu – bionic の ffmpeg パッケージに関する詳細
How to Install FFmpeg 4.2 in Ubuntu 18.04 / Linux Mint 19.x | UbuntuHandbook
www.sunmattu.net
MacでPostgreSQLが使えなくなったのを解決した話
背景
Homebrewでインストールしたpostgresqlに、突如入れなくなったので、対応をまとめておいた。
結論から言うと、 brew upgrade
で気づいたらpostgresqlのメジャーバージョンが上がっていた、という罠。
経緯
入れない
$ psql psql: error: could not connect to server: could not connect to server: No such file or directory Is the server running locally and accepting connections on Unix domain socket "/tmp/.s.PGSQL.5432"?
サービスは起動してた
$ brew services start postgresql Service `postgresql` already started, use `brew services restart postgresql` to restart.
再インストールしてみたがだめだった
$ brew reinstall postgresql ==> Reinstalling postgresql ==> Downloading https://homebrew.bintray.com/bottles/postgresql-12.1.catalina.bottle.tar.gz Already downloaded: /Users/yu.kobayashi/Library/Caches/Homebrew/downloads/9c1e9459a75290edc60c44b88a078c693b6a5ebfb2f2af7ddbb13f7e76914399--postgresql-12.1.catalina.bottle.tar.gz ==> Pouring postgresql-12.1.catalina.bottle.tar.gz ==> Caveats To migrate existing data from a previous major version of PostgreSQL run: brew postgresql-upgrade-database To have launchd start postgresql now and restart at login: brew services start postgresql Or, if you don't want/need a background service you can just run: pg_ctl -D /usr/local/var/postgres start ==> Summary 🍺 /usr/local/Cellar/postgresql/12.1: 3,217 files, 37.7MB $ psql psql: error: could not connect to server: could not connect to server: No such file or directory Is the server running locally and accepting connections on Unix domain socket "/tmp/.s.PGSQL.5432"?
気づき
再インストールのとき、よく見ると、
==> Downloading https://homebrew.bintray.com/bottles/postgresql-12.1.catalina.bottle.tar.gz
お?? 12?To migrate existing data from a previous major version of PostgreSQL run: brew postgresql-upgrade-database
お??
解決策
postgresが11から12にバージョン上がって、DBやら設定やらをアップデートかけなきゃいけなかったらしい、という話。いわれたとおりにコマンドをたたく。
$ brew postgresql-upgrade-database ==> brew install postgresql@11 ==> Downloading https://homebrew.bintray.com/bottles/postgresql@11-11.6.catalina.bottle.tar.gz ==> Downloading from https://akamai.bintray.com/c9/c91e358723fd5f700f059a0a1beff478d3e4aaa2ec40a3a166e946ff130d9fd0?__gda__=exp=1574911628~hmac=574662 ######################################################################## 100.0% ==> Pouring postgresql@11-11.6.catalina.bottle.tar.gz ==> /usr/local/Cellar/postgresql@11/11.6/bin/initdb --locale=C -E UTF-8 /usr/local/var/postgresql@11 ==> Caveats To migrate existing data from a previous major version of PostgreSQL run: brew postgresql-upgrade-database postgresql@11 is keg-only, which means it was not symlinked into /usr/local, because this is an alternate version of another formula. If you need to have postgresql@11 first in your PATH run: echo 'export PATH="/usr/local/opt/postgresql@11/bin:$PATH"' >> ~/.zshrc For compilers to find postgresql@11 you may need to set: export LDFLAGS="-L/usr/local/opt/postgresql@11/lib" export CPPFLAGS="-I/usr/local/opt/postgresql@11/include" For pkg-config to find postgresql@11 you may need to set: export PKG_CONFIG_PATH="/usr/local/opt/postgresql@11/lib/pkgconfig" To have launchd start postgresql@11 now and restart at login: brew services start postgresql@11 Or, if you don't want/need a background service you can just run: pg_ctl -D /usr/local/var/postgresql@11 start ==> Summary 🍺 /usr/local/Cellar/postgresql@11/11.6: 3,191 files, 36.4MB ==> Upgrading postgresql data from 11 to 12... Stopping `postgresql`... (might take a while) ==> Successfully stopped `postgresql` (label: homebrew.mxcl.postgresql) waiting for server to start....2019-11-28 12:15:33.884 JST [7885] LOG: listening on IPv6 address "::1", port 5432 2019-11-28 12:15:33.884 JST [7885] LOG: listening on IPv4 address "127.0.0.1", port 5432 2019-11-28 12:15:33.886 JST [7885] LOG: listening on Unix socket "/tmp/.s.PGSQL.5432" 2019-11-28 12:15:33.908 JST [7886] LOG: database system was interrupted; last known up at 2019-11-22 10:49:27 JST ...2019-11-28 12:15:37.323 JST [7886] LOG: database system was not properly shut down; automatic recovery in progress 2019-11-28 12:15:37.326 JST [7886] LOG: redo starts at 0/206DDC0 2019-11-28 12:15:37.326 JST [7886] LOG: invalid record length at 0/206DEA0: wanted 24, got 0 2019-11-28 12:15:37.326 JST [7886] LOG: redo done at 0/206DE68 2019-11-28 12:15:37.337 JST [7885] LOG: database system is ready to accept connections done server started waiting for server to shut down...2019-11-28 12:15:37.720 JST [7885] LOG: received fast shutdown request .2019-11-28 12:15:37.720 JST [7885] LOG: aborting any active transactions 2019-11-28 12:15:37.721 JST [7885] LOG: background worker "logical replication launcher" (PID 7892) exited with exit code 1 2019-11-28 12:15:37.721 JST [7887] LOG: shutting down 2019-11-28 12:15:37.728 JST [7885] LOG: database system is shut down done server stopped ==> Moving postgresql data from /usr/local/var/postgres to /usr/local/var/postgres.old... ==> Creating database... The files belonging to this database system will be owned by user "yu.kobayashi". This user must also own the server process. The database cluster will be initialized with locale "C". The default text search configuration will be set to "english". Data page checksums are disabled. fixing permissions on existing directory /usr/local/var/postgres ... ok creating subdirectories ... ok selecting dynamic shared memory implementation ... posix selecting default max_connections ... 100 selecting default shared_buffers ... 128MB selecting default time zone ... Asia/Tokyo creating configuration files ... ok running bootstrap script ... ok performing post-bootstrap initialization ... ok syncing data to disk ... ok initdb: warning: enabling "trust" authentication for local connections You can change this by editing pg_hba.conf or using the option -A, or --auth-local and --auth-host, the next time you run initdb. Success. You can now start the database server using: /usr/local/opt/postgresql/bin/pg_ctl -D /usr/local/var/postgres -l logfile start ==> Migrating and upgrading data... Performing Consistency Checks ----------------------------- Checking cluster versions ok Checking database user is the install user ok Checking database connection settings ok Checking for prepared transactions ok Checking for reg* data types in user tables ok Checking for contrib/isn with bigint-passing mismatch ok Checking for tables WITH OIDS ok Checking for invalid "sql_identifier" user columns ok Creating dump of global objects ok Creating dump of database schemas ok Checking for presence of required libraries ok Checking database user is the install user ok Checking for prepared transactions ok If pg_upgrade fails after this point, you must re-initdb the new cluster before continuing. Performing Upgrade ------------------ Analyzing all rows in the new cluster ok Freezing all rows in the new cluster ok Deleting files from new pg_xact ok Copying old pg_xact to new server ok Setting next transaction ID and epoch for new cluster ok Deleting files from new pg_multixact/offsets ok Copying old pg_multixact/offsets to new server ok Deleting files from new pg_multixact/members ok Copying old pg_multixact/members to new server ok Setting next multixact ID and offset for new cluster ok Resetting WAL archives ok Setting frozenxid and minmxid counters in new cluster ok Restoring global objects in the new cluster ok Restoring database schemas in the new cluster ok Copying user relation files ok Setting next OID for new cluster ok Sync data directory to disk ok Creating script to analyze new cluster ok Creating script to delete old cluster ok Upgrade Complete ---------------- Optimizer statistics are not transferred by pg_upgrade so, once you start the new server, consider running: ./analyze_new_cluster.sh Running this script will delete the old cluster's data files: ./delete_old_cluster.sh ==> Upgraded postgresql data from 11 to 12! ==> Your postgresql 11 data remains at /usr/local/var/postgres.old ==> Successfully started `postgresql` (label: homebrew.mxcl.postgresql)
解決した
$ psql postgres psql (12.1) Type "help" for help. postgres=# \q
macのごみ箱の挙動がおかしくなったら
未だに頑張ってMacBook Pro 13-inch Late 2013を使い続けていますが、先日ゴム足が取れてしまって悲しみにくれていた@sweep3092です。
6年めに入りつつあるMacですが、なんとかごまかしごまかし使っていたものの、とうとうガタが来たのか、ごみ箱を空にするのに非常に時間がかかるようになってしまいました。
SSDの寿命かなーなんて思っていましたが、SMARTを見る限りだと寿命って感じでもなく、ごみ箱を空にする以外はすこぶる快調なので悩んでいました。
日本語では全然情報がありませんでしたが、調べてみるとどうやらごみ箱を再構成するといいらしい。
というわけで手順です。
1. セーフモードで再起動する
Macをセーフモードで再起動します。
やり方は↑に書いてあるとおりですが、電源を入れたらShiftキーをログイン画面が表示されるまで押し続ける、これだけです。
2. ごみ箱を削除する
ややこしいですが、ごみ箱そのものを削除します。
sudo rm -rf ~/.Trash
3. ごみ箱を作る
ごみ箱を亡き者にしてしまったので、もう一度作ります。
mkdir ~/.Trash sudo chown $UID ~/.Trash chmod u+rwx ~/.Trash
4. 再起動
再起動して、セーフモードではなく通常のモードでmacを起動してください。 ゴミをごみ箱に入れて、正常にごみ箱を空にすることができたら、これで手順はすべて完了です。