2010年3月8日月曜日

ffmpegsourceのmpegsource入力

ffmpegsourceは、myrsloik氏をリーダーとして#darkholdのメンバーが開発しているffmpegのwrapperである。
lavfでdemuxし、lavcでデコードして,swscaleで色空間変換やリサイズを扱い、lavfilterでその他のフィルタを掛けることが出来るAviSynth用ソースフィルターであり、最近ではx264の入力にも使われるようになった。
ffmpegが使われているだけあって非常に多くのフォーマットやコーデックに対応しており便利なことこの上ないのだが、弱点も幾つかある。なんでもlavfのmpeg parserは問題があるのでかわりにHaali氏のparser(HaaliMediaSplitterで使われているもの)を利用することにしたのだが、これはこれでやはり問題があるらしく、しかもHaaliはソースが公開されていないため、不具合に対処しようがないというのである。

一方、AviSynthでmpeg入力とくれば、真っ先にあげられるのはneuron2氏のDGMPGDecである。
こちらのほうもしょっちゅうヘマをするが、そのたびにneuron2氏はソースに手を入れ何とかしてきたので、AviSynthユーザーは特に理由がない限り、普通はmpegソースにはこちらを使う。

これは#darkholdメンバーにしてみれば、非常に面白くない事態であろう。
なんせ、世にあふれる動画ソースは殆どがPS(DVD)かTS(放送)かm2ts(BD)であるのに、あのneuron2のツールを使わねばならないのである。
くっ、悔しい...で(ry
(なんで#darkholdがneuron2氏を嫌うのか分からない人は、#darkholdがなんなのかとか、neuron2氏の過去の言動を、CCCPのサイトやDoom9等で調べてみればいい)

てな感じのことがあって、このたび#darkholdの重鎮の一人であるTheFluff氏が自前のmpeg parserをスクラッチで書く気になったみたいだ、とJEEB氏から聞いた。
以下、某IRCのログより適当に抜粋

(JEEB) そういや、TheFluff氏は夕べdgindexのソースのTSパーサーなど読んでた
(JEEB) 結局諦めたのかwww
(JEEB) <Lord> anyway are you really sure you want to steal that code? :P
(JEEB) <TheFluff> no, it seems way too annoying
(JEEB) <TheFluff> I'd rather write a ts parsing library instead
(JEEB) <TheFluff> from scratch
(JEEB) <TheFluff> I mean, how hard can it be!?!!?!111
(JEEB) dgindexのソースを読んでみたら色々面白いものが見つかったけど、再利用出来る部分があまりなかったw
(JEEB) <TheFluff> rather than check how much data he has read and deciding to stop parsing after not encountering any headers after a certain amount of data, he gets the current time in milliseconds and aborts parsing if headers have been found for more than 5 wallclock seconds
(JEEB) ↑dgindexから
(JEEB) 5秒内でTSヘッダが見つからない→止まるw
(JEEB) どれぐらいデータが読み込めたかに関わらずw
(chikuzen_) TSならまるもプラグインのほうが速いよ
(chikuzen_) ソースも公開してるから見てみるのもいいかもね
(JEEB) ほほぉ
(JEEB) あと、日本専用のソースならねぇ・・・ 他にATSCなどなTSファイルがあるからねぇ
(JEEB) まぁ、何もないよりマシかとw
(chikuzen_) http://www.marumo.ne.jp/mpeg2/
(chikuzen_) GPLみたいなケチくさいこと言わないのがまるもさんのいいところ
(JEEB) ライセンスは?
(JEEB) 再配布の禁止
(JEEB) ↑これがあるけどねぇ
(chikuzen_) そのままではね
(JEEB) ふむ
(chikuzen_) つまりいじったものに関しては一切関知しない
(JEEB) おぉー、readme.enでちゃんと書いてある
(JEEB) まぁ、ちゃんとライセンスを書いてくれる人は嬉しいわ
(JEEB) 書いてない人は「書いてないなら、何も出きない」という法律的な理屈を理解してないかなw
(chikuzen_) LanczosResizeのオリジナルは彼だけど、うやむやのうちにavisynthオリジナルみたいになっちゃったりして
(chikuzen_) 結構腹が立ったこともあるんじゃないかな
(JEEB) ほほぉ
(chikuzen_) まあ、120fpsAVIの生みの親でもあるんだけどね
(JEEB) それは言わないことにしようw
(chikuzen_) 本職のコーデックプログラマだから、フリーのエンコーダーは書けないって前に日記に書いてたな
(JEEB) ほほぉ
(JEEB) まぁ、TheFluff氏は今他のことをやってるけど、とりあえず#darkholdで貼ってみた

数時間後

(JEEB) chikuzen_, あのMPEG-2プラグインを紹介してくれてありがとうw ソースはこんな初心者の目で見る限りでも、かなりdgindexより再利用できそうw
(chikuzen_) まあそのままは使えないだろうけど、parserなりdemuxerなりの‭参考くらいにはなるかも
(JEEB) うん

さて、どうなることやら

それにしても、草を生やすのが好きなフィンランド人である。

2010年3月2日火曜日

JM Reference Software

JM Reference Softwareが更新されたと小耳に挟んだので見に行ってみた。
http://iphome.hhi.de/suehring/tml/

おお、本当に更新されてるじゃんってことで早速DLしてビルド。

用意するもの
Microsoft VisualC++2008 ExpressEdision
WindowsSDK for Windows7 and .NET Framework3.5SP1 

手順
・JMのzipを解凍する
・中にあるjm_vc9.slnをVC++2008で開く
・"ソリューション構成"を"Release"にする
・ldecodとlencodのプロジェクトをそれぞれ”ビルド"する

これでbinフォルダの中にldecod.exeとlencod.exeができるので、あとはbinフォルダをまるごとコピーして、好きな場所に保存すればおしまい。

2010年3月1日月曜日

x264vfwの復活

前回の記事を書いた後にDoom9に行ってみたら、x264vfwのスレッドが何故か賑わっていた。
何事だろうと訝しがりつつ新着投稿を読んでみると、あらびっくり。死んだと思われていたvfwが華麗なる復活を遂げているではないですか。
これはすごいと言うしかない。

そもそもvfwの何が悪かったかといえば、いわゆる"one frame in, one frame out"の原則である。
vfwはその仕組み上、エンコード前のフレームを1枚入力すると、そのフレームをエンコードして1枚出力しない限り、次のフレームを入力することが出来ない様になっている。これでは、Bフレームのように未来を参照するフレームのエンコードが原則的に出来ないし、処理速度をあげるためにマルチスレッド化を行おうにも、1枚のフレームを複数に分割して処理することしか許されない。複数枚のフレームを一度に処理するのと違って、圧縮率が低下するは、処理速度の大幅な向上は望めないはで問題がありすぎた。
xvidやDivX5等が主流の頃は、これを何とかしようとPackedBitStreamなる、なんともややこしいハックが行われたりしていたが、それはそれで問題が合ったりして、そうこうするうちにvfwは可逆圧縮コーデック専用のような扱いになりかけていた。

今回のx264vfw-r1471は今までとは明らかに一線を画す改造である。
vfwはまず1枚のフレームをエンコーダーに渡す。
エンコーダーは入力フレームを1枚受け取ると、エンコードしないでそのフレームをキャッシュしておき、かわりに真っ黒なフレームをエンコード済のフレームとして出力する。vfwは入力したフレームが無事に出力されたと騙されて、次のフレームをエンコーダーに渡し、受け取った真っ黒なフレームをAVIとして出力する。
これを繰り返すとエンコーダーには複数枚のフレームがキャッシュされていくが、ある程度のフレーム(x264ならrc-lookaheadによるだろう)が貯まった時点で、初めてエンコーダーはエンコードを始める。複数のフレームを同時に扱えるので、Bフレームの使用もまったく問題ないし、マルチスレッドによる高速な処理も行える。そしてエンコードされたフレームは、vfwによって作られた偽物のAVIとは別の場所に、mp4やmkvとして保存される。
この仕組だと、ACMによってエンコードされた音声は偽物のAVIのほうに格納されてしまうので、従来のものよりは少し扱いづらいことにはなるが、そもそも音声は別処理して後で改めて結合するのが今時の常識であるから、それほど大した問題ではない。
バッチ処理すると複数のダミーが出来るのがウザイと思う人もいるかも知れないが、それにしたって映像だけのAVIならどんどん上書きすればいいだけだから、出来上がるダミーは結局一つで済む。

そして今回の改造の一番すごいところは、他のエンコーダーにも応用可能な点である。
この仕組みを使えばmpeg2だろうがmpeg4だろうがtheoraだろうが、すべてvfwで実装出来る。極端な話、ffmpeg vfw codec(ffdshowではない)すら可能であろうと言うことだ。

VirtualDubはすでにPhaeron(Avery Lee)氏がCLIエンコーダーとの連携機能実装に動いているため、今回のx264vfw-r1471の恩恵を受けることはそれほど大きくはないだろう。
しかし他のソフト(TMPGEnc、Premiere、Vegas、Nive、紙芝居クリエーター、CrystelEngine等)のユーザーにとってはこれは非常に素晴らしい前進と言えるのではないかな。

x264.exeでavi出力

komisar氏のサイトを眺めていたら、なにやら見たことのないnewパッチがあった。
x264_avi_out.v2.diff
名前から察するに、x264.exeでAVI出力出来るようになるパッチらしい。
面白そうなので、さっそくビルドに挑戦してみた。

パッチ自体は問題もなく当てることが出来たが、いざ出来上がったバイナリでAVI出力を試してみると、エラーが出て上手くいかない。
他のMKVやMP4は普通に出力できるのに、なんでだろうと思いながらパッチの中身を覗いてみたらなんとなく理由がわかった。
このパッチはどうやらlavfのavimuxerを使用するものらしい。
そういや自分のビルドに使ってるffmpegは、configureで--disable-muxersにしているんだった。これでは駄目なはずだわな。

つーことで、ffmpegからビルドし直してみることにした。
いままでの設定は
./configure --prefix=/mingw/x86_64-pc-mingw32 --cross-prefix=x86_64-pc-mingw32- --enable-cross-compile --target-os=mingw32 --host-cc=gcc --enable-gpl --enable-postproc --enable-memalign-hack --enable-runtime-cpudetect --disable-devices --disable-filters --disable-encoders --disable-network --disable-muxers --disable-decoder=aac,ac3,adpcm_*,alac,als,ape,atrac?,cook,dca,dsicinaudio,dxa,eac3,flac,interplay_dpcm,mlp,mp1,mp2,mp3,mp3*,mpc?,pcm_*,qcelp,ra_*,sipr,truehd,truespeech,tta,vorbis,wavpack,wma*,twinvq --disable-demuxer=aac,ac3,pcm_*,ape,amr,ass,au,avs,dts,eac3,flac,mp3,mpc,mpc8,truehd,tta,w64,wav,wv --disable-parser=aac,ac3,dca,mlp,mpegaudio
これが
./configure --prefix=/mingw/x86_64-pc-mingw32 --cross-prefix=x86_64-pc-mingw32- --enable-cross-compile --target-os=mingw32 --host-cc=gcc --enable-gpl --enable-postproc --enable-memalign-hack --enable-runtime-cpudetect --disable-devices --disable-filters --disable-encoders --disable-network --disable-decoder=aac,ac3,adpcm_*,alac,als,ape,atrac?,cook,dca,dsicinaudio,dxa,eac3,flac,interplay_dpcm,mlp,mp1,mp2,mp3,mp3*,mpc?,pcm_*,qcelp,ra_*,sipr,truehd,truespeech,tta,vorbis,wavpack,wma*,twinvq --disable-demuxer=aac,ac3,pcm_*,ape,amr,ass,au,avs,dts,eac3,flac,mp3,mpc,mpc8,truehd,tta,w64,wav,wv --disable-parser=aac,ac3,dca,mlp,mpegaudio --disable-muxer=ac3,adts,aiff,amr,as*,au,avm2,c*,d*,e*,f*,g*,h*,i*,m*,n*,o*,p*,r*,s*,t*,v*,w*,y*
に変った。
ただでさえ長ったらしいconfigureが、さらに長くなっちゃったよ… 。

さて、enable-muxer aviになってることを確認して、ffmpegをビルド。
お次はx264をもう一度ビルドし直し。
再度AVI出力を試してみたら、今度は無事にAVIで出力出来ました!

しかし、こんなもん、一体何に使えばいいんでしょうかね?
FLV出力以上に使い道が思い浮かばないんだよなぁ…。

2010年2月16日火曜日

SWF用DirectShowFilter その2

前回の記事に書いたSWF用DirectShowFilter(以下DSF)に、新たなる欠点を発見した。
どうもDirectShow使ってるせいか、動きが止まっている部分で、本来表示されなければいけないフレーム数よりも少ないフレーム数になってしまうことがある。

つまり、本当は全く同じ絵が5回連続で表示されるべきところが、1回だけ表示して、すぐ次の絵になってしまう、といったことが起こるのである。
一方、swf_vfpだとそのようなことは起こらない。
5フレーム同じ絵が続く場面では、きっちり5フレーム表示され、4フレームすっ飛ばしたりはしないのだ。

フレームをすっ飛ばしてしまうということは、音ズレとしてはっきりわかってしまうので、非常にまずい。特に止め絵を多用するものだと、終りのほうは悲惨なものになってしまう。

やはり信頼性はswf_vfpの方が高い。
DSFはスプライトが使われている部分の差し替え用AVI作成以外には使えないと思った方がいいようだ。

2010年2月14日日曜日

SWF用DirectShowFilter

Doom9のこのスレでSWF用DirectShowFilterなるものが紹介されていた。
SWFでDirectShowといえばMPCを思い浮かべるが、あれはただIE用FlashPlayerをそのまま使っているだけで、ブラウザ以上のことは特に何もできない。

これが本当ならすげえやってことで、さっそくDL。
http://www.medialooks.com/products/directshow_filters/flash_source.html
どうやらフリーのようだが、要登録らしい。
あと、IE用FlashPlayerを利用しているようで、こちらも必須とのこと。

さて、インストールしてみて、まずはWMP12でSWFを再生出来るか試してみた…が再生出来ない。
どうもActiveXでセキュリティに引っかかっているようだね。
IE同様、WMPでもSWFの再生はブロックがかかるのか…はじめて知ったよ。
ではこれならってことで、QonohaPlayerで試してみると…上手くいきました!
特にコマ落ちしてる様子もなく、なによりもスプライトを使っている部分もちゃんと動いてる! すごい!(何がすごいか分からない人は、SWFをAVIやMP4に変換しようとしたことのない人でしょう。経験者ならみんな驚くと思います)

さて、再生出来るなら、当然変換にも使えるはずってことで、AviUtlのDirectShowFileReaderで読み込めるか試してみると…クラッシュしたやんけ、オイ…。
ではVirtualDubならどうかとDirectShow input driverで試してみると…これもだめ。
AviSynthならどうかとDirectShowSource使って…orz
ならばこれはどうかとDSS2を使ってみると…やったぁ、読み込めた!
さっそくVirtualDubでAVIに変換…順調に行きました。

でも、なんでDSS2以外はダメなのかしら? ってことでしばらく試行錯誤してみると…どうやら音声を同時に読み込もうとするとクラッシュすることが判明。DirectShowSourceでもaudio=falseにしたら読み込めた(DSS2はもともと音声は読めないから無問題なわけね)。
そういえば、swf_vfpの履歴にmp3音声がどうこうってあったなぁ…あれと同じでPCMを使ってれば読めるのかもしれないけど、手元にPCM音源のSWFがみつからなかったので、調査は保留。
まあ、音声はいままでも別処理だったし、状況は好転したと言えますね。

さて、スプライト関連も上手く再現出来ることだし、これはswf_vfpもいよいよお役御免かなぁ…なんて思ってたところで、一つ不具合を見つけた。
どうやらレイヤーの重ね方だかアルファチャンネルの透過度の具合のせいか、色がおかしくなることがある。同じ現象はswfdrop.exeを使った場合も起こったことを思い出した。
うーん、swf_vfpなら、これは起こらないんだよなぁ…やっぱりすごいよ、まるもさん。

とりあえず、基本はやはりswf_vfp、スプライトの部分はこのDSF、どちらでもダメな場合はデスクトップキャプチャでAVIを作って、切り貼りするってことになるかな。

*今回の実験に使用したSWFは、過去に筆者がニコニコ投稿用エンコードを代理したものを使わせて頂きました。作った人、勝手に使ってごめんね。

2010年2月5日金曜日

lavf/ffms付きx264_x64ビルド

ちょっとサボっていたら、前回の更新から一週間以上経っていた。
誰も読まないチラシの裏替わりとはいえ、やはりサボるのはあまり良くないだろう。

ここ数日はx264.exe(x64)の自ビルドでlavf/ffms入力を有効にするために四苦八苦していた。
Windows&AviSynthユーザーとしては、全く要らないといってもいい機能ではあるが、やはり出来る事ならば有効にしておきたいのが人情というもの。

以下にその手順を書いておく
なお、これはr1416現在の情報なので、あとあと使えなくなっても知らない。

クロスコンパイルできるビルド環境構築は各自でやってるものとする。
参考:
http://komisar.gin.by/mingw/add/MinGW%20cross-compile%20toolchain%20(EN)/
http://zoome.jp/VFR_maniac/diary/89/
ちなみに筆者はkomisar氏のcross-mingw.gcc443.generic.20100124を使用している。
fstabは
e:/msys/mingw /mingw
e:/msys/local/ /usr/local
e:/msys/tmp /tmp1

まずpthread、zlib、bzip2はkomisar氏の配布しているものをそのまま使用しているので省略。

 yasm(0.8.0):
$ wget -c http://www.tortall.net/projects/yasm/releases/yasm-0.8.0.tar.gz
$ tar zxvf yasm-0.8.0.tar.gz
$ cd yasm-0.8.0
$ ./configure --prefix=/mingw
$ make
$ make install
$ cd ~

GPAC:
$ cvs -d:pserver:anonymous@gpac.cvs.sourceforge.net:/cvsroot/gpac login
passwordはなし
$ cvs -z3 -d:pserver:anonymous@gpac.cvs.sourceforge.net:/cvsroot/gpac co -P gpac
$ cd gpac
$ cvs update -D "2010-01-23 UTC"
$ wget -c http://pastebin.php?dl=m59b9d49c
$ mv pastebin.php@dl=m59b9d49c muken_20100123.diff
$ patch -uNp0 < muken_20100123.diff
$ ./configure --prefix=/mingw/x86_64-pc-mingw32 --cross-prefix=x86_64-pc-mingw32- --cpu=x86_64 --static- mp4box
$ make lib apps
$ make install-lib
$ cp -p ./bin/gcc/MP4Box.exe /e/mp4tools/mp4box.exe
$ cd ~
ちなみに途中であてているパッチはVFR maniac氏の最新パッチ(どうやら現在、非公開の様子)
/e/mp4toolsは各自適当に変更して欲しい。

FFMPEG(今回は2010-02-01のスナップショット):
$ wget -c http://ffmpeg.org/releases/ffmpeg-checkout-snapshot.tar.bz2
$ tar jxvf ffmpeg-checkout-snapshot.tar.bz2
$ cd ffmpeg-checkout-snapshot
ここで./libswscale/swscale_template.cの2500行目あたりを次のように書き換え
#if ARCH_X86_64 && AV_GCC_VERSION_AT_LEAST(3,4)
:: "m" (src1), "m" (dst), "g" (dstWidth), "m" (xInc_shr16), "m" (xInc_mask),
#else

#if ARCH_X86_64 && AV_GCC_VERSION_AT_LEAST(3,4)
:: "m" (src1), "m" (dst), "g" ((x86_reg)dstWidth), "m" (xInc_shr16), "m" (xInc_mask),
#else
にする(1行だけ)。
$ ./configure --prefix=/mingw/x86_64-pc-mingw32 --cross-prefix="x86_64-pc-mingw32-" --enable-cross-compile --target-os=mingw32 --host-cc=gcc --enable-gpl --enable-postproc --enable-memalign-hack --enable-runtime-cpudetect --disable-devices --disable-filters --disable-encoders --disable-muxers --disable-network --disable-decoder=aac,ac3,adpcm_*,alac,als,ape,atrac?,cook,dca,dsicinaudio,dxa,eac3,flac,interplay_dpcm,mlp,mp1,mp2,mp3,mp3*,mpc?,pcm_*,qcelp,ra_*,sipr,truehd,truespeech,tta,vorbis,wavpack,wma*,twinvq --disable-demuxer=aac,ac3,pcm_*,ape,amr,ass,au,avs,dts,eac3,flac,mp3,mpc,mpc8,truehd,tta,w64,wav,wv --disable-parser=aac,ac3,dca,mlp,mpegaudio
$ make
$ make install
$ cd ~
configure長すぎる...でもバイナリが小さくなるし、無効にしても影響のない機能はなるべく切るべきだと思う。
なお、pthreadをautostaticでビルドしておけば、--enable-pthreadsもいけるそうだが、今回はパス。

ffms(現時点では275):
$ svn checkout http://ffmpegsource.googlecode.com/svn/trunk/ ffms2
$ cd ffms2
$ PKG-CONFIG="/mingw/x86_64-pc-mingw32/bin/pkg-config.exe" ./configure --prefix=/mingw/x86_64-pc-mingw32 --host=x86_64-pc-mingw32
$ make
$ make install
$ cd ~
なおpkg-config.exeは
http://ftp.gnome.org/pub/gnome/binaries/win32/dependencies/pkg-config_0.23-3_win32.zip
glibは
http://ftp.gnome.org/pub/gnome/binaries/win32/glib/2.22/glib_2.22.3-1_win32.zip
からDLして、あらかじめ/mingw/x86_64-PC-mingw32以下にまとめてぶちこんでおくこと

x264:
$ git clone git://git.videolan.org/x264.git x264
$ cd x264
$ ./configure --cross-prefix=x86_64-pc-mingw32- --host=x86_64-pc-mingw32
$ make fprofiled VIDS="/g/for_test/soccer_4cif.y4m"
$ make install
$ cp -p /usr/local/bin/x264.exe /e/x264/mine/x264_r1416.exe
$ exit
なんか-march=core2はあまり速くならないようなので、最近はあまりつけていない
fprofiledの動画はなんでもいいらしいが、とりあえずhttp://media.xiph.org/video/derf/y4m/soccer_4cif.y4mを使っている。
mp4box同様、/e/x264/mineのあたりは各自で適当に変えること
上には書いてないが、NAL-HRDパッチとkomisar氏のlog_fileパッチはいつも当てている。

以上で終了。
筆者にIRCで丁寧に教えてくれたVFR maniac氏とJEEB氏に感謝します。