ffmpeg の nvenc を動かすときに苦労したことメモ

More than 3 years have passed since last update.

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 としたらうまくいった。