2010年3月31日水曜日

Ubuntu奮戦記 その3 再生環境

動画のエンコード環境構築は、まず適切な再生環境を準備することから始まる。
適切な再生環境抜きでは、成果(エンコ後の動画)に対して評価を下すことが出来ない。
目的がiPhoneやPSP等向けの携帯動画なら実機を用意して再生確認をしなければならないし、ニコニコやzoomeへの投稿であるならば、投稿前の確認はFlashPlayerコンポーネントを使用するFLVPlayer(Flavie等)で行うべきである。
例えば「AviUtl+x264gui.auoでエンコードしています。投稿前にMPCで確認した時は大丈夫だったのに、ニコニコに投稿した動画はブラウザで見ると色が滲んで変に見えます。どうしてですか?」といった質問がたまにyoutube板のエンコードスレに来ることがある。
答えは「FlashPlayerはYUV420->RGB変換の際に色差情報の補間を一切行わないから」。
YUV420で圧縮された動画には、色差情報の不足のため、色が滲んでいたりエッジがギザギザになっているものがけっこうある。しかし、それではあんまりなので、一般的な再生環境はこれに補間処理を行って情報不足を目立たなくするようになっている。しかし、FlashPlayerは(おそらく処理量を低減し、少しでも再生を軽くするため)これをしない。言ってみれば安くあげるために手を抜いている。
このため、ある程度ニコニコ投稿経験をつんだAviUtlユーザーは、UVダウンサンプリングフィルタをYUV420-lanczos2(or lanczos3)で最後にかけることで対策を行う。これはある意味AviUtlの特徴であるYC48による高品質な処理を台無しにしてしまう行為になりかねないのだが、再生環境がFlashPlayerである場合はやむを得ないのである。

と、前置きがやたら長くなってしまったが、要はUbuntuで使うプレーヤーはどれにしようかというお話である。
結論から言えば、これは最初からmplayerに決まっていた。
#x264や#ffmpegにはたまに自分の環境で上手く再生できないと相談にやってくるLinuxユーザーやmacユーザーがいる。
「上手く再生できないんだけど、どうしたらええんかいな?」
「プレーヤーは何を使ってるんだ?」
「VLC(またはTotemとかQuickTimeとか)だよ」
「mplayer使えよ」
こういったやりとりが週に一度はあるような気がする。
特にVLCはデコード時に必要な参照フレームをすっ飛ばすために映像が崩壊するバグが数年間放置されており、また字幕周りもひどいということで甚だ評判が悪い。
Linuxならmplayerが一番と皆が口を揃えて言うのだから、やはりそれが正解なのだろう。

さて、さっそくmplayerを9.10にいれようと、synapticを開いて探してみたが…
「えーと、svn20090426…なにこれ?」
あらかじめ用意されているものは、たいへん古く、使い物にならないガラクタだった。
やはり、物事は簡単にはいかないものらしい。

次回に続く

2010年3月29日月曜日

Ubuntu奮戦記 その2 *nix使えよ!?

x264の公式フォーラムであるDoom10 Forumの特徴の一つは、登録メンバーにLinuxユーザーが多いことである。
以前の公式フォーラムに指定されていたDoom9(といっても今でもこっちの方が情報は多いけど)ではLinuxやmac関連の情報は少なく、一体彼らはどこで情報を手に入れているのか不思議に思っていた。(その後判明したが、彼らの情報交換は主にIRCや各ディストロの公式フォーラムで行われていた)
だからDoom10が出来たとき、それまでDoom9ではあまり見かけたことのない名前がいろいろ出てきてLinuxでのエンコードについて語っているのを見たときはちょっと驚いたものだった。

さて、このスレッドである。
http://doom10.org/index.php?topic=180.0
LinixやBSD(たぶんmacも含まれる)においてAviSynthを使うための簡単なガイドラインといったもので、とりあえず必要なツール類と簡単なスクリプトの例、そしてvimのsyntax fileがあげられていた。
「Windows以外のOSでは、こんなことせにゃならんのか…なんだか大変そうだねぇ、素直にWindows使えばいいのに」
とか思いながら読んでいたら、昔AviSynthBlogで読んだこの記事を思い出した。
自分では使ったこともないけど、なにかの役に立つかもしれないと思い、「vimならこんなのもあるみたいよ」と書き込んだ。
そしたらお礼の言葉とともに「お前も*nixを使うべきだよ」と返事が返ってきた。
まあ、せっかく勧めてくれたことだし、気が向いたら試してみるかななんて思っていたところで、前回のような状況になった。
かくして筆者はLinux体験をすることになったのである。

とりあえずディストロはUbuntuにした。
一番簡単で使いやすいとどこかで聞いた覚えがあったからだ。
Ubuntuの公式サイトから9.10のisoをDLしてimgburnでCDに焼いて、再起動。
言語設定とキーボードを日本語にして、あとは待つこと20分程度でインストールはとりあえず終了。
「再起動する」を選んで、CDを取り出してEnter。
なぜ「とりあえず」かというと、このあと初回のアップデートに結構時間がかかるからである。
アップデートが済んだらもう一度再起動。さらにハードウェアドライバの設定でビデオカード(GF8400M GS)のドライバーをNVIDIA製のもの(185)に変更してさらに再起動。
ここまででかかった時間は約1時間といったところだった。

次回に続く

2010年3月25日木曜日

Ubuntu奮戦記 その1:香港映画の悪夢

ここ数日間Ubuntu9.10をいじっている。
慣れないことだらけで、やたら苦労している。

「一体俺は何でこんなことをしているのだろうか?」

苦闘の果て、昨日やっと一段落ついたような感触を得たので振り返ってみた。
えーと、なんだったかなぁ...
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

すべての始まりは香港映画のDVDだった。

その日筆者は暇であった。
何もすることがないので、DVDを観ることにした。
20秒ほど本棚を眺め、手に取ったのはジャッキー・チェン監督/主演の「奇跡(miracle)」だった。
たしか数年前にTSUTAYAの安売りコーナーで500円くらいで買ったものである。
ドライブにディスクを突っ込んでMPCHCを起動した。
デコーダーはMS DTV-DVD Decoder、レンダラーはEVR-custom。
インターレース処理はビデオカードにおまかせ。
そして再生を開始すると…

DVDは4:3のレターボックスで収録されていた。
スクイーズでないことにまず腹が立った。
そして時々チラチラするような妙な違和感を覚えた。
訝しがりながらMPCHCの表示を見ると、60fpsで再生されていた。
Radeonのプルダウン検出が効いていない…だと…。
再生を中止し、調査を開始した。

DVDは60iで収録されていた。HD5870は間違っていなかった。
試しにYadif(mode=1)をかけた状態でコマ送りしてみると、同じフレームが1枚、2枚…そして前後のフレームが混ざりあったような残像のあるフレームが至るところに存在していた。
あきらかにPALソースをNTSCに無茶なやり方で変換したものである。
ひどい、ひどすぎる。
元々素材は24fpsなんだから、AssumeFPS(24000,1001,true)して、3:2プルダウンかければいいだけなのに、これを作った香港のオーサリング屋は、一旦PAL用に25p変換したものをブレンド処理して60iにしやがった。
ほんと映像業界って、どこの国でも…。
まあ最近はひどいDVDは少なくなったみたいだけど、かわりにひどいBDが増えているわけで。

こんなこと考える人間はあまりいない。
筆者も初めてこのDVDを観たときは、こんなことは少しも気にならなかった。
世の中、それで済んだほうがいいのである。
どうやらここ数年の経験は、あきらかに間違った方向に筆者を導いているらしい。
しかし、いまさらこの手の経験を‌リセットするのも無理である。
よせばいいのに、「修正してやる!」という気になってしまった。
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

さて、PAL->NTSCによるブレンドの修正は次のような処理を行う。

MPEG2Source("video.d2v")
#最初に上下左右の黒べたをフィールドオーダーが狂わないようにしながらcrop
Crop(left,top,right,bottom)
#次に60i->25pの修正
#なんらかの方法でBob(60fps化)
Bob()
#そしてSRestoreをかける
SRestore()
#これでブレンドはほぼ除去され、60iは25PのPALに戻される。
#今回の場合は素材は劇場用映画なのだから、これをさらに24fpsにしてやる
Audio=NicAC3Source("audio.ac3")
AudioDub(last,Audio)
AssumeFPS(24,1,true)
ResumpleAudio(48000)
return last

問題はBobになにを使うかである。
まずavisynth内蔵のBobではガタガタで論外。
Yadif(mode=1)を使ってみたが、どうにも汚い。
Yadifmod+NNEDI2でも汚い。
結局MCBobが一番よかったので、これでいくことにした。
avsをVirtualDubにセットし、ULY0で中間出力開始。
終了までにかかる時間は、えーと…約17時間ですと!?

さすがMCBob、SD未満のサイズですらこれであるorz

かくしてメインPCは占領され、筆者は再び暇になってしまった。
しかたがないのでサブノートを引っ張り出した。
半年ぶりくらいに電源を入れた。
起動したOSは、バンドルのXPsp2だった。
Windows7にすっかり慣れてしまった現在では、どうにも使う気になれなかった。
どうしたものかとしばらく天井を眺めていたら、このスレッドのことを思い出した。
http://doom10.org/index.php?topic=180.0

次回に続く

2010年3月9日火曜日

デザイン変更

ブログを書き始めて2ヶ月ほど(といっても更新はあまりしない)たって、初めてコメントが付いた。
まさか読む人がいるとは思わなかったのでびっくりした。
書いてる本人ですら三日に一度くらいしか開かないというのに...そもそもBarn(物置小屋)なんて、そんなもんでしょ。

とりあえず新着コメントの有無くらいはわかるようにしようとガジェットを追加してみた。
ついでにレイアウトもなんだか殺風景すぎる気がしたので変更(といってもBloggerのテンプレを別のものに変えただけ)。

やってみて改めて思ったが、我ながらこの手のことにはさっぱりセンスがないな...まあ、いいや。
物置小屋なんてこんなもんで十分でしょ。

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出力以上に使い道が思い浮かばないんだよなぁ…。