ffmpegの比較的新しい機能で、NVIDIAのGPUパワーを利用して高速にMP4に変換できるnvencというものを使ってみたが、いろいろ苦労したのでメモ。
ちなみに、今回はCentOSにインストールしています。
基本的なインストール手順はこちらを参考にさせていただきました
http://nico-lab.net/installing_cuda_with_ffmpeg/
また、NVIDIA関連のダウンロードはこちらから行いました
https://developer.nvidia.com/nvidia-video-codec-sdk
ffmpegをコンパイルできない
CUDA ToolkitとNVIDIA Driverをインストールした上で
./configure --enable-nonfree --enable-nvenc
make
sudo make install
を実行したところ、なぜか make の途中でエラーになる。
エラーの起きた libavcodec/nvenc.c を見てみると、どうやら
typedef struct NvencData
{
union {
int64_t timestamp;
NvencOutputSurface *surface;
};
} NvencData;
のところでシンタックスエラーになっているらしい。
C言語のコンパイラの系統とかバージョンとかに詳しくないのだが、自分の環境のコンパイラで扱えない文法なのだろうか...
とりあえず、動作に悪影響があるか不安ではあるが、上の箇所を
typedef union NvencData
{
int64_t timestamp;
NvencOutputSurface *surface;
} NvencData;
のようにしてみたところ、コンパイルが通り、最終的には動いてくれた。
当時、ffmpeg 2.6.1のコードでこのエラーが起きたが、現在、ffmpeg 2.6.3でも上の箇所は変更されていないようだった。
H.264のProfileを指定できない
H.264のMainProfileでエンコードされる必要があったので、libx264を使っていたときのオプション -profile:v main をそのまま指定してみたが、nvencではエラーになる。
エラーメッセージを見ると、
Undefined constant or missing '(' in 'main'
Unable to parse option value "main"
Error setting option profile to value main.
-profile:v main はパースできない不正な書式らしいが、適当に-foobar:vとか指定したときとメッセージが違うので、-profile:vは理解されているらしい。
ソースをがんばってたどったところ、そもそも -profile:v に指定する値が整数値であることがわかり、 libavcodec/avcodec.h に答えを見つけた。
libavcodec/nvenc.c のswitch文によると、使用できる値は下のようになっているらしい。
| Profile | Value |
|---|---|
| Baseline | 66 |
| Main | 77 |
| High | 100 |
今回はMainProfileにしたかったので、 -profile:v 77 としたらうまくいった。