やっと正常に make 成功
まぁ何が間違っていたかというと、入力の出力を取り違えるというなんともアホなミスでした。
正しいパッチはこれ。
--- libavcodec/x86/dsputil_mmx.c.orig 2009-03-14 23:19:05.000000000 +0900 +++ libavcodec/x86/dsputil_mmx.c 2009-03-15 19:02:16.000000000 +0900 @@ -679,10 +679,17 @@ static inline void transpose4x4(uint8_t *dst, uint8_t *src, int dst_stride, int src_stride){ __asm__ volatile( //FIXME could save 1 instruction if done as 8x4 ... - "movd %4, %%mm0 \n\t" - "movd %5, %%mm1 \n\t" - "movd %6, %%mm2 \n\t" - "movd %7, %%mm3 \n\t" + "movd %0, %%mm0 \n\t" + "movd %1, %%mm1 \n\t" + "movd %2, %%mm2 \n\t" + "movd %3, %%mm3 \n\t" + : + : "m" (*(uint32_t*)(src + 0*src_stride)), + "m" (*(uint32_t*)(src + 1*src_stride)), + "m" (*(uint32_t*)(src + 2*src_stride)), + "m" (*(uint32_t*)(src + 3*src_stride)) + ); + __asm__ volatile( "punpcklbw %%mm1, %%mm0 \n\t" "punpcklbw %%mm3, %%mm2 \n\t" "movq %%mm0, %%mm1 \n\t" @@ -699,10 +706,6 @@ "=m" (*(uint32_t*)(dst + 1*dst_stride)), "=m" (*(uint32_t*)(dst + 2*dst_stride)), "=m" (*(uint32_t*)(dst + 3*dst_stride)) - : "m" (*(uint32_t*)(src + 0*src_stride)), - "m" (*(uint32_t*)(src + 1*src_stride)), - "m" (*(uint32_t*)(src + 2*src_stride)), - "m" (*(uint32_t*)(src + 3*src_stride)) ); }
libswscale/rgb2rgb_template.c と libavcodec/x86/flacdsp_mmx.c のパッチは また FFmpeg の make が通らない - EAGLE 雑記 のでOKのはず。
例のエラーメッセージ
can't find a register in class 'GENERAL_REGS' while reloading 'asm'
は、ようするに「汎用レジスタが足りないよ!」ってことだったのか。
これは GCC のバグ、、、なのかなぁ。
レジスタが足りないんだったら、一気にアドレスをレジスタに置かずにわければいいと思うんだけど。
いやしかしインラインアセンブリで書いてある以上、これはプログラマの責任なのかなぁ。
というか、x86 で MMX を有効化してコンパイルすればここのコードが使われるわけで、MMX のある x86 CPU って今どきかなり普通だと思うんだけど、FFmpeg のデベロッパはこれに気づいていないんだろうか。
gcc のバージョンが悪い?手元にある gcc-4.0.1, gcc-4.2.1, gcc-4.3.2 はすべて5個以上の変数を突っぱねるんだけど。
それとも俺の configure オプションが悪い?
おまけ
こんな記事を見つけた。まだ読んでいない。
http://www.phoronix.com/scan.php?page=article&item=ffmpeg_05_interview