ルギア君の戯言

雑多な記事。

リアルタイムエンコード可能な動画形式を漁る

実測値はパソコンのスペックやグラフィックボードなどにはかなり左右されるはずなので、目安として見てください。


ここでいうリアルタイムエンコードとは ディスクI/O も含める。

環境

決してこのようなことを行うのに向いた環境ではない。(むしろ劣悪?)

CPU Intel Core 2 Duo T5500 1.66 GHz
GPU Intel Mobile 945GM xorg-x11-drv-intel-2.16.0-1m.mo8.x86_64
HDD WDC WD6400BPVT SATA 1.5Gbps (?)
KDE OpenGL 使用 kdebase-4.7.0-1m.mo8.x86_64
ffmpeg 右に --enable-x11grab を付けてビルドしたもの ffmpeg-0.7.0-0.20110803.3m.mo8.x86_64
SuperTuxKart supertuxkart-0.7.2-1m.mo8.x86_64
irrlicht irrlicht-1.8.0-0.svn3843.1m.mo8.x86_64

supertuxkart と irrlicht はビルドしたもののコミットしてない。理由は

  • supertuxkart はこの irrlicht のリビジョンのものでしかビルドできないため、(特に irrlicht の) バグやセキュリティ的に不安だから。
  • irrlicht の 1.8.0 の stable はまだリリースされていない。
  • supertuxkart 側では irrlicht の 1.8.0 を使うようにという指示になっているが、これより新しいリビジョンのものではやはりビルドできない。
  • irrlicht のソースのうち一部のファイルで supertuxkart がビルド出来るように別のリビジョンのファイルを使った。

などによる。こんなんでも良ければコミットするけど。


あとどうでも良い理由として

  • 0.6.x と 0.7.x のゲームの難易度が全然違う
    • AI が発達したり、システムが新しくなったりして異常に難しくなった
    • カメラワークがすこし違う…気がする
  • ネットワーク対戦のオプションがあるが実装されていない

…から昔のままでも良いかなって。グラフィックや音楽は一新された。

# hdparm -Tt /dev/sda

/dev/sda:
 Timing cached reads:   1648 MB in  2.00 seconds = 824.68 MB/sec
 Timing buffered disk reads: 250 MB in  3.01 seconds =  82.97 MB/sec

$ LANG=C dd if=/dev/zero of=/tmp/image (ext4 on LV)
^C
1270587+0 records in
1270587+0 records out
650540544 bytes (651 MB) copied, 8.44583 s, 77.0 MB/s

$ LANG=C dd if=/dev/zero of=image      (xfs on LV)
^C
1373934+0 records in
1373934+0 records out
703454208 bytes (703 MB) copied, 10.2321 s, 68.7 MB/s

$ uname -a
Linux arpa-castle.site 3.0.0-2m.mo8.x86_64 #1 SMP Thu Jul 28 19:51:51 JST 2011 x86_64 x86_64 x86_64 GNU/Linux

調べ方

SuperTuxKart を解像度 800×600*1 においてレースを ffmpeg の x11grab 機能で撮影する。このエンコード速度を調べる。

台数 4 台 (自分含む) Hexley (PC)、Beagle、Adiumy、Pidgin
難易度 Novice (簡単)
ルール Normal Race (普通)
コース Secret Garden
周回 2 周

撮影時間はおよそ 2 分ぐらい。なお、撮影してないときの SuperTuxKart の FPS は 16〜20 ぐらい。かなり重いみたい。
撮影を行う。例えば、

$ ffmpeg -f x11grab -s 800x600 -r 30 -i :0+2,22 -f alsa -ar 44100 -ac 2 -i hw:0 -vcodec mpeg2video  -b 4.9M -acodec libfaac -ar 44100 -ac 2 -ab 128k a.mp4

のように。制約がある場合にはそれに変換させる (例えば DV は画素サイズが 720×480 (NTSC の場合))。


音声のコーデックはそれに見合うもの、とする。例えば、H.264 には AAC、MPEG2 には MPEG2、可逆圧縮 (zlib) なものには可逆圧縮 (flac) のものを、生 (rawvideo) には生 (pcm_u16le) を。ソースは bgra であるが、大半の動画形式は yuv となる。bgra で格納できない形式の場合にはカラー変換も行われる。そのままを尊重し、-pix_fmt は指定しない。サウンドデバイスはループバックを指定しておく。

メモ

  • libx264 のハックは Core i7 2600(K) のみ(らしい) ので対象外。
    • それでも Intel 補正があるらしく相当速いみたい。
  • グラボでエンコードできるわけねーだろ、この環境で!!

評価の方法

ffmpeg のオプションに指定する rate 値に対して、達成出来たエンコードFPS の割合を表す。例えば上の例なら 30 fpsエンコード出来れば 100%、25 fps でしかエンコード出来なければ 83% となる。安定しなければ「不安定」と記すことにする。

結果

rawvideo 30 fps + pcm_s16le
ffmpeg -f x11grab -s 800x600 -r 30 -i :0+2,22 -f alsa -ar 44100 -ac 2 -i hw:0 -vcodec rawvideo -acodec pcm_s16le -ar 44100 -ac 2 -ab 128k a.avi
frame= 5659 fps= 27 q=0.0 Lsize=10643380kB time=00:03:08.58 bitrate=462343.8kbits/s dup=0 drop=334
  • カラー変換なし。
  • なんとまあ、3分の動画でファイルサイズが 10G…。
  • 90% - ディスク I/O 面がかなりきつい。HDD の LED が付きっぱなし。
  • SuperTuxKart 処理落ち。
  • なお、上の関係上、再生も辛い。
  • 画質に関しては非圧縮なのでもちろん文句無し。
  • Min: 4 fps / Max: 20 fps
zlib 30 fps + flac
ffmpeg -f x11grab -s 800x600 -r 30 -i :0+2,22 -f alsa -ar 44100 -ac 2 -i hw:0 -vcodec zlib -acodec flac -ar 44100 -ac 2 -ab 128k a.avi
frame=  829 fps=  5 q=0.0 Lsize=  643766kB time=00:02:31.30 bitrate=34855.8kbits/s
  • カラー変換なし。
  • 17%
  • かなり重いらしい…。他の撮った時はそうでもなかったような気もしたんだけどなぁ。
  • 音は絶対に一致しない。(組み合わせの問題)
    • キーフレームがないから、一致させようとすることすらできない。
    • 別の形式にトランスコードすると改善する場合がある
  • Min: 8 fps / Max: 30 fps
mpeg2video 5M 30 fps + mp2 128k
ffmpeg -f x11grab -s 800x600 -r 30 -i :0+2,22 -f alsa -ar 44100 -ac 2 -i hw:0 -vcodec mpeg2video  -b 5M -acodec mp2 -ar 44100 -ac 2 -ab 128k a.mpg
frame= 5486 fps= 30 q=4.0 Lsize=  115136kB time=00:03:02.09 bitrate=5179.6kbits/s dup=766 drop=0
  • 100%
  • 動画は綺麗。
  • Min: 10 fps / Max: 25 fps
mpeg2video 10M 30fps + mp2 128k
$ ffmpeg -f x11grab -s 800x600 -r 30 -i :0+2,22 -f alsa -ar 44100 -ac 2 -i hw:0 -vcodec mpeg2video  -b 10M -acodec mp2 -ar 44100 -ac 2 -ab 128k a.mpg
frame= 5167 fps= 30 q=2.0 Lsize=  213588kB time=00:02:49.79 bitrate=10304.8kbits/s dup=1055 drop=0
  • 100% − サイズは倍だが、まだいけるらしい。さすが軽い形式。
  • 絵は綺麗だが音声に対して動画の一定の遅延があった。
  • Min: 8 fps / Max: 31 fps
H.264 slow 2M 30 fps + faac 128k
ffmpeg -f x11grab -s 800x600 -r 30 -i :0+2,22 -f alsa -ar 44100 -ac 2 -i hw:0 -vcodec libx264 -b 2M -vpre lossless_slow -acodec libfaac -ar 44100 -ac 2 -ab 128k a.mp4
frame= 4738 fps= 30 q=0.0 Lsize=   43644kB time=00:00:55.07 bitrate=6491.4kbits/s dup=4534 drop=0
  • 100% - 速い…?
  • 画像は綺麗だが再生するとカクカク。(大量の dup がそれを物語る)
  • 音が飛んだ動画になった。(長さが 55 秒しかないから?)
  • Min: 10 fps / Max: 25 fps
H.264 medium 2M 30 fps + faac 128k
ffmpeg -f x11grab -s 800x600 -r 30 -i :0+2,22 -f alsa -ar 44100 -ac 2 -i hw:0 -vcodec libx264 -b 2M -vpre lossless_medium -acodec libfaac -ar 44100 -ac 2 -ab 128k a.mp4
frame= 4651 fps= 30 q=0.0 Lsize=   43313kB time=00:01:00.09 bitrate=5904.5kbits/s dup=4457 drop=0
  • 100%
  • やはりカクカクで音が飛んでいる。
    • 原因がスペック不足では無いことがわかる。
  • Min: 11 fps / Max: 25 fps
H.264 fast 2M 30 fps + faac 128k
ffmpeg -f x11grab -s 800x600 -r 30 -i :0+2,22 -f alsa -ar 44100 -ac 2 -i hw:0 -vcodec libx264 -b 2M -vpre lossless_fast -acodec libfaac -ar 44100 -ac 2 -ab 128k a.mp4
frame= 4574 fps= 30 q=0.0 Lsize=  158919kB time=00:02:26.49 bitrate=8886.8kbits/s dup=3914 drop=0
  • 100%
  • 大量の dup のせいでやはりカクカク。
  • サイズは増加。
  • Min: 13 fps / Max: 26 fps
Windows Media Video 2 2M + Windows Media Audio v2 128k
ffmpeg -f x11grab -s 800x600 -r 30 -i :0+2,22 -f alsa -ar 44100 -ac 2 -i hw:0 -vcodec wmv2 -acodec wmav2 -b 2M -ar 44100 -ac 2 -ab 128k a.wmv
frame= 5167 fps= 30 q=13.8 Lsize=   45839kB time=00:02:52.19 bitrate=2180.7kbits/s dup=514 drop=0
  • 100%
  • 画質はやや悪。“アレ”のせいだろうか。
  • Min: 10 fps / Max: 21 fps
Windows Media Video 2 10M + Windows Media Audio v2 128k
ffmpeg -f x11grab -s 800x600 -r 30 -i :0+2,22 -f alsa -ar 44100 -ac 2 -i hw:0 -vcodec wmv2 -acodec wmav2 -b 10M -ar 44100 -ac 2 -ab 128k a.wmv
frame= 4709 fps= 30 q=2.0 Lsize=  195264kB time=00:02:35.06 bitrate=10315.8kbits/s dup=1284 drop=3
  • 100%
  • 画質は上に比べれば良いが、ややカクカク気味。複製されたフレームが倍以上になった。
  • Min: 10 fps / Max: 24 fps
Theora 5M + Vorbis 128k
ffmpeg -f x11grab -s 800x600 -r 30 -i :0+2,22 -f alsa -ar 44100 -ac 2 -i hw:0 -vcodec libtheora -acodec libvorbis -b 5M -ar 44100 -ac 2 -ab 128k a.ogv
frame= 3476 fps= 14 q=0.0 Lsize=   36798kB time=00:00:00.09 bitrate=3245596.5kbits/s dup=3468 drop=0
  • 46%
  • なぜかとてつもなく重く、外から kill してようやく落ちる。
  • みてわかるようにたったの 8 フレームしかキャプチャされていない。
  • どおりで recordMyDesktop が重いわけだ。
  • Min: 8 fps / Max: 28 fps
DV Video 12M + pcm_s16le
ffmpeg -f x11grab -s 800x600 -r 29.97 -i :0+2,22 -f alsa -ar 48000 -ac 2 -i hw:0 -vcodec dvvideo -b 12M -s 720x480 -acodec pcm_s16le a.dv
frame= 5199 fps= 30 q=0.0 Lsize=  588281kB time=00:02:47.52 bitrate=28766.8kbits/s dup=1122 drop=2
  • 100%
  • フォーマットの制約が非常に厳しいことで有名な形式。
  • 動画のリサイズは ffmpeg でやったが、音声のリサンプルはサウンドカード (カードじゃないが…) にお任せ。
  • 遅れ気味。
  • Min: 7 fps / Max: 28 fps
DV Video 6M + pcm_s16le
ffmpeg -f x11grab -s 800x600 -r 29.97 -i :0+2,22 -f alsa -ar 48000 -ac 2 -i hw:0 -vcodec dvvideo -b 6M -s 720x480 -acodec pcm_s16le a.dv
frame= 5173 fps= 30 q=0.0 Lsize=  578438kB time=00:02:44.70 bitrate=28769.6kbits/s dup=1095 drop=0
  • 100%
  • サイズが減って画質が悪くなっただけだった。
  • Min: 11 fps / Max: 21 fps
Motion JPEG 6M + libmp3lame 64k
ffmpeg -f x11grab -s 800x600 -r 29.97 -i :0+2,22 -f alsa -ar 44100 -ac 2 -i hw:0 -vcodec mjpeg -b 6M -acodec libmp3lame a.avi
frame= 4482 fps= 26 q=18.9 Lsize=  129259kB time=00:02:53.97 bitrate=6086.4kbits/s dup=0 drop=63
  • 86%
  • 画像の JPEG と同じぐらいには画質は悪い。テロップのある動画だとそこの回りに滲みができる。
  • Min: 10 fps / Max: 23 fps
BitMap 連写

こうやると同時に同じ分の音声も録音できる。

ffmpeg -f x11grab -s 800x600 -r 29.97 -i :0+2,22 -vcodec bmp tmp/a%05d.bmp -f alsa -ar 44100 -ac 2 -i hw:0 -acodec pcm_s16le out.wav
frame= 5608 fps= 30 q=0.0 Lsize=      -0kB time=00:02:54.86 bitrate=  -0.0kbits/s dup=715 drop=107
  • 100%
  • 画質は最高に良い動画が出来そう。
  • 音合わせは難しそう。
  • Min: 9 fps / Max: 19 fps

まとめ

  • やっぱり実用的なのは mpeg2video あたりだねー。
  • recordMyDesktop に付いては“昔はよかった”ので libtheora の何かのせいだろう。
  • 画質に拘るならがんばって音あわせするといって BitMap 連写もいいかもねー。


*1:本当は 640×480 が良かったけど、0.7.x で削除されてしまった…