トップ 検索 一覧 ヘルプ RSS ログイン

MinGW+ffmpeg(8)改造の変更点

  • 追加された行はこのように表示されます。
  • 削除された行はこのように表示されます。
!!!MinGW+ffmpeg(8)改造
当初の方針より、x264のMBAFF(インターレース)に対応し、携帯動画変換君で使用可能なffmpegに改造する。なお、ここでは'''Revision9726(2007/07/18)'''のffmpegに対し修正を施す。最新版でない理由は[[MinGW+ffmpeg(1)準備]]を参照。
当初の方針より、x264のMBAFF(インターレース)に対応し、携帯動画変換君で使用可能なffmpegに改造する。なお、ここでは''Revision9726(2007/07/18)''のffmpegに対し修正を施す。最新版でない理由は[[MinGW+ffmpeg(1)準備]]を参照。

!!携帯動画変換君対応
まずは、携帯動画変換君でエンコードを中断する場合の対応を含める。
この対応を行わないと、中断ボタンを押してもffmpegが終了せず、中止するには携帯動画変換君ごと強制終了するしかなくなる。
修正するのはffmpeg.cの以下の関数だ。
 static int read_key(void)
これの後半で、
 #elif defined(HAVE_CONIO_H)
     if(kbhit())
         return(getch());
 #endif
という箇所がある。
ここを
 #elif defined(HAVE_CONIO_H)
 // felidlabo: this is hack and is not smart way, but useful.
 #if defined(__MINGW32__)
     unsigned char ch;
     int n = filelength(0);
     if (n > 0) {
         n = read(0, &ch, 1);
         if (n == 1)
             return ch;
         return n;
     }
 #endif
     if(kbhit())
         return(getch());
 #endif
と、標準入力に対して低レベルなread関数での対応を含める。

あくまでhackであり賢明な方法ではないかも知れないが、ひとまずこれで中断ボタンに対応出来る。

!!x264のMBAFF(インターレース)対応
H.264/AVCにはPIFFとMBAFFというインターレース方式があるが、x264が対応するのはMBAFFの方だ。詳細は後々研究するとして、この対応がffmpegにはないので修正する。

libavcodec/libx264.cを開き、
 static int
 X264_init(AVCodecContext *avctx)
という関数を修正する。修正場所はどこでもよいのだが、ここでは
     x4->params.analyse.inter = 0;
という行の直前に挿入する。
     // felidlabo: interlace
     x4->params.b_interlaced = (avctx->flags & CODEC_FLAG_INTERLACED_DCT) ? 1 : 0;
     x4->params.analyse.inter = 0;
この修正行は、b_interlacedが単なる二値フラグ(ゼロ・非ゼロ)なので、
     x4->params.b_interlaced = avctx->flags & CODEC_FLAG_INTERLACED_DCT);
という形式でもよいのだが、個人的な好みと後の研究のしやすさのため、上記のようにした。

こうして作成したffmpeg.exeは、x264でのエンコード(-vcodec libx264)時に、-flags ildctとすることでMBAFFを指定できる。例えば
 ffmpeg.exe -i input.mpg -vcodec libx264 -flags +ildct -acodec libfaac -f mp4 out.mp4
と言った具合に。

!余談
ffmpegには他にもインターレース関連のオプション(例えばilmeフラグ)があり、「どのオプションでインターレースONとすべきか」は迷うところだ。ここではMBAFFが「ジグザグスキャンを1ライン飛びにする」ように動作することから、意味的に最も近そうなildctフラグにマップした。実際にはx264内部ではilme的な動作も行っているだろうが、ffmpegが多数のコーデックに対応している以上、オプションと動作が一対一で対応しないのは仕方のないところだ。

当初は新規に-interlacedオプションを追加することも検討した(一度実装もした)のだが、修正範囲が広がるため既存のオプションを使用することにした。