[FFmpeg] FFmpegにAviSynthスクリプトを読みこませる

## 背景

``Windows``で音声ファイルや映像ファイルを扱うときに必需品ともいえる``AviSynth``を
``Linux``で音声ファイルや映像ファイルを扱うときの必需品である``FFmpeg``で利用できるようにしましょう

### 環境

 * Windows 7 64bit
 * CentOS 6.7


## ダウンロード

各種アプリケーションの説明は割愛させていただきます。

[AviSynth](http://www.avisynth.info/)
ダウンロードは[こちら](https://sourceforge.net/projects/avisynth2/)
バージョンは**2.6**（2016年2月現在）をインストールします。


[VirtualDub](http://www.virtualdub.org/)
ダウンロードは[こちら](http://virtualdub.sourceforge.net/)
バージョンは**1.10.4**（2016年2月現在）をインストールします。
32bit(x86)版がよいです。


[FFmpeg](https://www.ffmpeg.org//)
ダウンロードは[こちら](https://www.ffmpeg.org/download.html)
バージョンは**3.0**（2016年2月現在）ですね。


## 下準備

 1. VirtualDubをインストールしておく。zipなので適当に解凍してね。
 2. メモ帳でAviSynthスクリプトを書く。
 3. VirtualDubにAviSynthスクリプトを読みこませる。

### AviSynthスクリプト

```ColorBars.avs
ColorBars().Trim(0, 1799)
```

### VirtualDubに読み込ませる
![demo2.png](https://qiita-image-store.s3.amazonaws.com/0/31085/7bc4a01d-47ee-a100-e27d-1c5650214c52.png)

（VirtualDubで読めないAVSファイルは記述が間違っていますので、適宜確認してください。）

これで下準備はOK


## FFmpegをWindows用にビルドする

### 1. Mingw32のインストール
```shell-session
# yum install mingw32-*
```

### 2. FFmpegのダウンロードとビルド
```shell-session
$ git clone git://source.ffmpeg.org/ffmpeg.git ffmpeg
$ cd ffmpeg
$ vi _x86.sh
$ sh _x86.sh
$ make
```

```shell-session:_x86.sh
#!/bin/bash
export PKG_CONFIG_PATH=/usr/i686-w64-mingw32/lib/pkgconfig

./configure \
--prefix=/usr/i686-w64-mingw32 \
--enable-gpl \
--enable-version3 \
--enable-nonfree \
--disable-ffserver \
--disable-doc \
--disable-htmlpages \
--disable-manpages \
--disable-podpages \
--disable-txtpages \
--enable-memalign-hack \
--enable-static \
--disable-shared \
--disable-ffprobe \
--disable-ffplay \
--disable-ffserver \
--arch=x86_64 \
--cpu=x86_64 \
--cross-prefix=/usr/bin/i686-w64-mingw32- \
--enable-cross-compile \
--target-os=mingw32 \
--extra-cflags='-I/usr/i686-w64-mingw32/include' \
--extra-ldlibflags='-L/usr/i686-w64-mingw32/lib' \
--enable-avisynth
```

注意点ですが
``AviSynth``が``32bit``なので、``i686-w64-mingw32``を利用します。
動かす``Windows``が``64bit``の場合は、``arch``と``cpu``を``x86_64``にします。

``make install``は必要ないです。

無事ビルドが終わったら、Windows側に``ffmpeg.exe``と``/usr/i686-w64-mingw32/sys-root/mingw/bin/libwinpthread-1.dll``をダウンロードしてきましょう。``dll``は``ffmpeg.exe``と同じディレクトリにいれておいてください。


## エンコード

さぁお待ちかねのエンコードです。
が、ライブラリをいれないと、汎用的なコーデックがあんまりないですね。。。
ここでは、Windows上でApple ProResを作ってみましょう。

```shell-session
> ffmpeg.exe -f avisynth -i ColorBars.avs -c:v prores -c:a aac -f mov ColorBars.mov

ffmpeg version N-78756-g6aac43f Copyright (c) 2000-2016 the FFmpeg developers
  built with gcc 4.9.2 (GCC) 20141030 (Fedora MinGW 4.9.2-1.el6)
  configuration: --prefix=/usr/i686-w64-mingw32 --enable-gpl --enable-version3 --enable-nonfree --disable-ffserver --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --enable-memalign-hack --enable-static --disable-shared --arch=x86_64 --cpu=x86_64 --cross-prefix=/usr/bin/i686-w64-mingw32- --enable-cross-compile --target-os=mingw32 --extra-cflags=-I/usr/i686-w64-mingw32/include --extra-ldlibflags=-L/usr/i686-w64-mingw32/lib --enable-avisynth
  libavutil      55. 19.100 / 55. 19.100
  libavcodec     57. 27.100 / 57. 27.100
  libavformat    57. 26.100 / 57. 26.100
  libavdevice    57.  0.101 / 57.  0.101
  libavfilter     6. 37.100 /  6. 37.100
  libswscale      4.  0.100 /  4.  0.100
  libswresample   2.  0.101 /  2.  0.101
  libpostproc    54.  0.100 / 54.  0.100
Guessed Channel Layout for  Input Stream #0.1 : stereo
Input #0, avisynth, from 'ColorBars.avs':
  Duration: 00:01:00.06, start: 0.000000, bitrate: 0 kb/s
    Stream #0:0: Video: rawvideo (BGRA / 0x41524742), bgra, 640x480, 29.97 fps, 29.97 tbr, 29.97 tbn, 29.97 tbc
    Stream #0:1: Audio: pcm_f32le, 48000 Hz, 2 channels, flt, 3072 kb/s
File 'ColorBars.mov' already exists. Overwrite ? [y/N] y
[prores @ 03ae4b40] encoding with ProRes standard (apcn) profile
[prores @ 03b288a0] encoding with ProRes standard (apcn) profile
[prores @ 03b2ace0] encoding with ProRes standard (apcn) profile
[prores @ 03b2d120] encoding with ProRes standard (apcn) profile
[prores @ 00769b20] encoding with ProRes standard (apcn) profile
Output #0, mov, to 'ColorBars.mov':
  Metadata:
    encoder         : Lavf57.26.100
    Stream #0:0: Video: prores (apcn / 0x6E637061), yuv422p10le, 640x480, q=2-31, 200 kb/s, 29.97 fps, 30k tbn, 29.97 tbc
    Metadata:
      encoder         : Lavc57.27.100 prores
    Stream #0:1: Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 128 kb/s
    Metadata:
      encoder         : Lavc57.27.100 aac
Stream mapping:
  Stream #0:0 -> #0:0 (rawvideo (native) -> prores (native))
  Stream #0:1 -> #0:1 (pcm_f32le (native) -> aac (native))
Press [q] to stop, [?] for help
frame= 1800 fps=137 q=-0.0 Lsize=   40465kB time=00:01:00.07 bitrate=5518.0kbits/s speed=4.58x
video:39475kB audio:945kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.110743%
[aac @ 03ac8920] Qavg: 10026.263
```

## エピローグ

こんな感じでAviSynthがFFmpegで使えるようになりました。

``FFmpeg``と``AviSynth``のコンビネーションを本領発揮させるためには

 1. ``FFmpeg``で``YUY2/LPCM``の``AVI``にデコード
 2. ``AviSynth``スクリプトを記述
 3. そのスクリプトを``FFmpeg``に読み込ませ、各種フォーマットにエンコード

という流れが典型的な手法かと思います。

ただし、実際は``FFmpeg``で``AVI``を作成すると、時間とHDD容量を大量に消費しますので
``AviSynth``側であらゆるフォーマットを読み込めるような工夫が必要になります。
（例） DirectShowSource(), DGDecode_MPEG2Source(), QTSource_QTInput(), ...

以上です。