{{{#!gfm # MMA Advent Calendar 2016/12/21 これは[MMA Advent Calendar 2016](http://www.adventar.org/calendars/1414)の21日目の記事です ## ffmpeg filterとは https://trac.ffmpeg.org/wiki/FancyFilteringExamples 標準でffmpegにはマンデルブロ集合とかライフゲームなどの面白いfilter機能がついています。今回はそのfilterの作り方を説明します。[Libavfilter](https://ffmpeg.org/libavfilter.html)から直接作ることもできるのですが今回は[Frei0r](https://frei0r.dyne.org/)で作る方法を記述します。実際の動画編集はノンリニア編集するほうが便利ですが生配信などにはもしかして自作フィルターが使えるかもしれません(?) ## Frei0r [Frei0r](https://frei0r.dyne.org/)というのはクロスプラットフォームのvideo effect pluginです。最近の新しいffmpegはfrei0rに対応しています。ffmpeg -versionして--enable-frei0rと表示されていれば対応しています。 ```cpp #include "frei0r.hpp" #include "frei0r_math.h" #include // frei0r::filterを継承して作っていきます class Mat33 : public frei0r::filter { public: Mat33(unsigned int width, unsigned int height) { // register_paramで引数を登録することができます register_param(m11, "m11", "matrix element m11"); register_param(m12, "m12", "matrix element m12"); register_param(m13, "m13", "matrix element m13"); register_param(m21, "m21", "matrix element m21"); register_param(m22, "m22", "matrix element m22"); register_param(m23, "m23", "matrix element m23"); register_param(m31, "m31", "matrix element m31"); register_param(m32, "m32", "matrix element m32"); register_param(m33, "m33", "matrix element m33"); } // updateで一フレームごとの処理を書いていきます // inに編集前ピクセルデータがあり、outに編集後のピクセルデータを入れます virtual void update(double time, uint32_t* out, const uint32_t* in) { std::copy(in, in + width*height, out); for (unsigned int y=1; y plugin("Mat33", "3*3 Matrix filter", "su_zu", 0,1, F0R_COLOR_MODEL_RGBA8888); ``` 上の例は3×3行列のフィルター処理を行えるフィルターを書いてみました。なんかフィルターフィルター言っててわかりづらい。。。 ### How to Use ```sh # buildしたfilter DLLのmat33.dllをC:\Program Files (x86)\frei0r\lib\frei0r-1に置いたとしましょう #FREI0R_PATH環境変数を設定 $ export FREI0R_PATH="C:\Program Files (x86)\frei0r\lib\frei0r-1" $ ffmpeg -i INPUT.mp4 -vf "frei0r=hogefugafilter" OUTPUT.mp4 ``` ちなみにdllは https://www.mma.club.uec.ac.jp/~su_zu/public/mat33.dll に置いておきました。信用できない人はソースはgithubに上げたので自分でビルドしてみてください。 https://github.com/suzusuzu/frei0r/blob/mat33/src/filter/mat33/mat33.cpp ### sobel filter sobel filterとは空間1次微分を計算してedgeを抽出するfilterです。 ![上から下へのsobel filter](https://wiki.mma.club.uec.ac.jp/su_zu/ffmpeg%20filter%E3%81%AE%E4%BD%9C%E3%82%8A%E6%96%B9?action=AttachFile&do=get&target=up2down.png) 上から下へのsobel filter ![左から右へのsobel filter](https://wiki.mma.club.uec.ac.jp/su_zu/ffmpeg%20filter%E3%81%AE%E4%BD%9C%E3%82%8A%E6%96%B9?action=AttachFile&do=get&target=letft2right.png) 左から右へのsobel filter ちなみにfilterは","で処理を繋げることができる。今回はsobelフィルターをかけるまえにグレースケールを行う 元動画 http://download.blender.org/peach/bigbuckbunny_movies/big_buck_bunny_480p_surround-fix.avi ``` $ ffmpeg -t 30 -i http://download.blender.org/peach/bigbuckbunny_movies/big_buck_bunny_480p_surround-fix.avi -vf "format=gray,frei0r=mat33:1|2|1|0|0|0|-1|-2|-1" -pix_fmt yuv420p sobel.mp4 ``` }}} <)>> {{{#!gfm ### 平滑化 filter 平均化 filterとも言います。 名前の通り平らに滑らかにするfilterです。 ![](https://wiki.mma.club.uec.ac.jp/su_zu/ffmpeg%20filter%E3%81%AE%E4%BD%9C%E3%82%8A%E6%96%B9?action=AttachFile&do=get&target=ave.png) ``` $ ffmpeg -t 30 -i http://download.blender.org/peach/bigbuckbunny_movies/big_buck_bunny_480p_surround-fix.avi -vf "frei0r=mat33:0.111|0.111|0.111|0.111|0.111|0.111|0.111|0.111|0.111" -pix_fmt yuv420p ave.mp4 ``` }}} <)>>