- 追加された行はこのように表示されます。
- 削除された行は
このように表示されます。
!!!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オプションを追加することも検討した(一度実装もした)のだが、修正範囲が広がるため既存のオプションを使用することにした。