眠い中数時間デバッグさせられた怒りに任せて書いています。
起こったこと :
3DSの自作ソフトのソースコード中で、かの有名なFFmpegのlibavfilterを初めて使ったところフィルターグラフ構築した後のavfilter_graph_config()が失敗を返す。
調べたところFFmpegのデバッグログを見るといいとか書いてあったからログのコールバック関数設定してエラーを見たら"Duplicated sample format"とのこと。このエラーがGoogleで微塵も引っ掛からない。
仕方がないのでFFmpegの中に潜り込んでいろいろデバッグ表示させたら以下のようなコードが原因なことが判明 :
※以下のコードにある2つの関数は本来別々のファイルにあります。
enum AVSampleFormat {
AV_SAMPLE_FMT_NONE = -1,
<省略>
};
static int query_formats(<省略>)
{
<省略>
static const enum AVSampleFormat sample_fmts[] = {
AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_S32P,
AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_DBLP,
AV_SAMPLE_FMT_NONE
};
<省略>
formats = ff_make_format_list(sample_fmts);
<省略>
}
AVFilterFormats *ff_make_format_list(const int *fmts)
{
<省略>
int count = 0;
if (fmts)
for (count = 0; fmts[count] != -1; count++);
<省略>
}
AV_SAMPLE_FMT_NONE
が-1に等しいので番兵の役割をしています。
ところがデバッグ表示していると ff_make_format_list
の方では count
が620にもなっているではないですか。
嫌な予感がしながら sample_fmts
の要素の型を enum AVSampleFormat
から int
に変えると直ってしまいました。
つまりenum AVSampleFormat
が4バイトではなかったようです。
実際この環境で
enum X {
ABC = -1,
DEF,
GHI,
JKL
};
に対して sizeof (enum X)
は1になりました。
普通の環境のGCCだとenum
はデフォルトではint
でコンパイル時に-fshort-enums
を付けると必要最小限のバイト数になるらしいですが今回-fshort-enums
は付けていないつもりです。
余裕があったら本家にちょっとissueっぽいの立てるかもしれないけどあっちがどこまで変な環境をサポートするつもりなのかは調べてから行かないとダメそうですね。
しかしライブラリの中いじることになったのは初めてだ