index

2006年 12月
          1 2 3
  4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
  25 26 27 28 29 30 31
2007年 1月
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31        
2007年 2月
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28        

アレ

MP4Box,FreeBSD と Windows で挙動が異なる件   ▽20070104a #コンピュータ #動画圧縮

さてさて昨日は「ファイルを正常に抽出できないのは AVI ファイルが悪いのでは」 ってことでエンコ仕込んで寝たわけだが, 起きてみてパラメタ変更した AVI を食わせてもやっぱしダメだった. 昔作った DivX の AVI を食わせてもやっぱし正常に動かない, けどこれは本当に AVI がダメなのかもしれなくてあまり参考にならない.

それにしてもコケてるサイズが「だいたい 2GB くらい」なのが気になる. AVI1.0 は 2GB ファイル制限とかあるけど, 2GB 以上でも正常に抽出できる AVI もあるし, だいたい抽出後のファイルが 2GB ってことは AVI 的には 2GB を超えてるはずだから, MP4Box が AVI2.0 っつか OpenDML に対応してないってこたーあるまい.

で,試しに Windows の MP4Box でやってみたら……おいおい正常に抽出できるじゃんよー. Windows で動いて FreeBSD で動かない? なんでやー. とりあえず AVI 自体は問題ない,と思われる.

となると MP4Box が FreeBSD で 2GB まわりでバグってる? ということで検索してたら, なんかすげー似た症状を訴えてるひとを発見. AVI ファイルから H264 を抽出しようとしたら, 3.2GB あるはずなのに 2024MB しか出てきませんよーって,おおう全く同じ症状だ.

別のエンコーダだとどうよ? とか,そもそも AVI 使わなければいんじゃね? とか, 周囲の雑音に紛れて MP4Box 作者が登場. 結局「バグレポート登録してくんね?」「わーったよ作っとくよ」ってことになったようだ.

さて MP4Box というか GPAC のバグトラック. って,さっきの R!tman 氏のバグがまだ生きてる件w 登録されたの 3月とかだよ!?w で,そこには何やらヒントというか回答めいたものが.


 Can you try if it help if you 
 use "./configure --extra-cflags=-D_FILE_OFFSET_BITS=64 -D_LARGE_FILES
 -D_LARGEFILE_SOURCE=1" 
 should only be needed if you use a 32bit installation.

ファイルまわりの 64bit 対応をさせるコードなんですかね. さらに検索して調べると,Solaris とかある種のシステムの 32bit 版で, fseek()ftell() を 64bit 対応(というか 32bit 非依存化)させるのに使う定数らしい. そんでよくよく調べると,FreeBSD では fopen() とかは素で 64bit 対応なんだけど, fseek()ftell() だけは 64bit 版が別の関数( fseeko()ftello() )があるみたいだ. へぇー……生の C なんて 16bit の頃からこっち使ってなかったから全然知らなかったぜいw

となると,昨日ソースコードをごりごり解析していて見つけた中に怪しい箇所がある.


 src/util/os_divers.c
u64 gf_f64_tell(FILE *fp)
{
#if defined(_WIN32_WCE)
    return (u64) ftell(fp);
#elif defined(WIN32)
    fpos_t pos;
    if (fgetpos(fp, &pos))
        return (u64) -1;
    else
        return ((u64) pos);
#elif defined(CONFIG_LINUX)
    return (u64) ftello64(fp);
#elif defined(CONFIG_FREEBSD)
    return (u64) ftell(fp);
#else
    return (u64) ftell(fp);
#endif
}

ちょ…… CONFIG_FREEBSD とか名指ししといて ftello() 使ってないじゃん!ww さらにコードを grep してみると, せっかく gf_f64_tell() とか定義してるのに ftell() を直接使ってる箇所が山ほどあったりして, なんだかなぁもう……

そんなわけで,ftello() とか fseeko() を使うように os_divers.c を書換え. さらに MP4Box のコードで ftell() を直接使ってる箇所があったんでそこは gf_f64_tell() に書換え. さらにさらに,なぜか CONFIG_FREEBSD が認識されてなくて最後の else に来てるみたいなんで, ports の Makefile の CONFIGURE_ARGS--extra-cflags="-DCONFIG_FREEBSD=yes" を追加. そしたら改めて ports でコンパイルっと.

と! いうわけで! やっと期待通りに動いたー!!!!ヽ( ´∀`)ノ

さて次の問題は,HD 画質を H.264 でエンコードすると, 1280x720 サイズでもカクカクで再生できない件ですが. こればっかりはどうしようもないから CPU と GPU の進化を待とう……w

index