AMV4のサンプル動画を再生するときのDirect Showグラフ
図1.RGBサンプル動画(sample_amv4_rgb32_dr3.avi)を再生する場合の標準的なグラフ(x86)

図2.YUY2サンプル動画(sample_amv4_yuy2_dr3.avi)を再生する場合の標準的なグラフ(x86)

図3.AMV4デコーダーフィルタを使ったYUY2の再生グラフ(参考)

図2では2つ目のAVI Decompressorを使ってYUY2をRGBへ変換していたのが、AMV4デコーダーを使うとYUY2のままレンダラーへ接続できて余計な処理を省ける。
メディアプレイヤークラシック(MPC)でYUY2の動画が再生できない
同じ条件でもAMV2MTやAMV3では再生できるのにAMV4だと再生できません。
これには3つの要因が関係します
(1) MPCなどのメディアプレイヤーは画像サイズに制限があり、RGBは制限が緩いのに対し、YUY2では制限がきつい(特定の画像サイズしか扱えない?)
(2) AMV2MT/AMV3はYUY2の動画をRGBへ変換してMPCへ渡せるのに対し、AMV4はYUY2の動画はYUY2でしかMPCへ渡さないようになっている。
(3) MPCはYUY2の動画をRGBへ変換してくれない(WMPなどはYUY2の動画をRGBへ変換してくれる)。
このような事情からAMV4とMPCの組み合わでYUY2の動画を扱うと特定の画像サイズしか再生できない見たいです。
平たく言うと、対応できない画像サイズのYUY2動画はRGBへ変換して再生するけど、AMV4もMPCもRGBへ変換してくれないから再生できない。
と言った感じです。
具体例をあげると
1280x720 YUY2と言った一般的なフォーマットであればAMV4+MPCでも再生できますが、
1264x720 YUY2のように横サイズが16少ない画像サイズになると再生できません。
同じ画像サイズであってもRGB(1264x720 RGB32)であればAMV4+MPCで再生可能です。
ではどうするか?
手っ取り早い解決策はAMV4の方でRGBへ変換してあげればいい(変換する機能自体は実装済み)のですが、
画質面で不利になる可能性があるのでYUVの動画はYUVでのみ出力したいところです。
そこでAMV4デコーダーフィルターとなります。
コーデックの規格であるVCMにはおそらく画像サイズと言う概念しかないのでこのようなケースではどうにもならないのですが、Direct Show Filter(デコーダーフィルター)なら画像サイズとは別に表示エリアの概念があるため、YUY2における画像サイズの制限をなんとかできるかもしれません。
例えば、上記の1264x720の例であれば、画像サイズ(全体の大きさ)を1280x720とし、
表示エリアを1264x720とすることでYUY2のまま再生可能になるのではないかと思います。
もしくは、1264x720 YUY2のままネゴシエートできるかもしれません。
と言うことで、近々AMV4 Direct Show Decoder Filterを作って試してみようと思います。
GraphEditでみる1264x720 YUY2の再生グラフ
GraphEditで1264x720 YUY2の動画がどのように再生されるかを試したのが下図です。

1つ目のAVI DecompressorがAMV4ビデオコーデックを使ってYUY2形式でデコードして
2つ目のAVI Decompressor 0001がYUY2をRGB32へ変換しています。
カラースペースコンバーターは何だろう・・・1ラインのバイト数をレンダラーの仕様と合うよう調整しているのかな
このようにWindows Media Playerなどはプレイヤー側(Direct Show Graphのインテリジェンス機能)の働きによりRGBへ変換して再生できます。ただし、明らかに無駄な処理が含まれているのも解りますね。
理想は、一つ目のAVI Decompressorと同じ働きを持つAMV4デコーダーフィルタを用意して、ビデオレンダラーと直結することです。RGB変換やカラースペースコンバーターは排除したいところですね。
64bit版AMVビデオデコーダーを使って再生した場合のDirect Showグラフ
まず、ビデオレンダラーフィルターが複数ありどれが使われるかにより挙動が異なってくることがわかりました。
私のところでは下記の「(上側の)Video Renderer」のメリット値が一番高く、特に指定がない場合このレンダラーが使われます。ここでは便宜上、上側のビデオレンダラーを「レンダラー1」、下側を「レンダラー2」として記述します。
このほか、EVRがありますがメリット値が低いため明示的に使わない限り出番はありません(一応EVRでも正常に表示されます)。

レンダラー1の場合

「AVI Decompressor」が二つ入り、2つ目のデコンプレッサーによりカラーフォーマットが「YUY2 320x240」から「RGB 320x-240」へ変更されています。
レンダラー1の場合はRGBの座標軸をマイナスにすることで正常に表示されるようです。(スクリーンショットではプレビューがまっ黒ですが正常に表示されています)
自動的に2つ目のデコンプレッサーが入り調整されるため同様の環境であれば問題ないと思います。
レンダラー2の場合

レンダラー2でもデコンプレッサーが2つ入りカラーフォーマットが変更されますが、レンダラー2の場合RGBの座標軸は反転しません。(「RGB 320x240」となっています)
レンダラー2は座標軸を反転せずに正常に表示されます。
このようにレンダラーにより高さ方向の座標軸が反転するレンダラーと、反転しないレンダラーがあることがわかりました。ただし、基本的にはDirect Showの方で自動的に「反転する」、「反転しない」の調整を行ってくれるようなので利用者は意識しなくていいようになっているみたいです。
問題となるのはレンダラーが違ったり、異なるAVIデコンプレッサーが使われる場合、およびDirect Showを使わないメディアプレイヤーです。
Direct Showを使わないメディアプレイヤーでは上記フィルターによる自動調整が行われないためAMVビデオデコーダー側で座標軸を反転しないとどうにもならないケースがあるのかなと思います。
レンダラー1とレンダラー2について
レンダラー1は上記のスクリーンショットをみてわかる通り、プレビューの様子が真っ黒になり、オーバーレイレンダラーのように動画の画像をデスクトップ画像の一部に合成してディスプレイに表示されます(デスクトップコンポジションによる合成ではなく、ビデオカードによる合成と思われます)。と言うことは、デスクトップコンポジションが有効な状態でも遅延の少ないプレビュー表示が可能なのかもしれません。
現状アマレコTVはデスクトップコンポジションが有効な場合EVRを使うようになっていて、その性質上遅延が大きめですが、今回のレンダラー1を使うことで改善できるかもしれません(要調査)。
またレンダラー2はDirect Drawを使ったレンダラーのようで、こちらもいろいろなオプションが用意されていて興味深いです。設定次第ではレンダラー2でもオーバーレイ表示が可能なのでしょうか。


Enhanced Video Rendererのパフォーマンス
OS | Windows7 x86 評価版 |
MB | M3N78-EM |
CPU | Phenom x3 8750 2.4GHz |
MEMORY | DDR2 800 4GB(2GB*2 Dual channel) |
Video | Gefoce GT 240 Driver 191.07 |
フォーマット | 変換 | プレビューのFPS |
5760x3240、YUY2 | YUY2 | 53.1 |
■基本的なグラフの場合
DirectShowのインテリジェンス機能に任せてスマートティのプレビューピンとEVRを接続するとキャプチャ画像のカラーフォーマットにより次のようなグラフが作成されます。

YUV系をキャプチャすると「AVI Decompressor」によりRGB32かUYVYに変換されてEVRが接続されます。
RGB系は「Color Space Comverter」によりRGB32に変換されてEVRが接続されます。

この状態で5760x3240と大き目の映像(1920x1080を縦横に3つ並べたサイズ)を流しプレビューしたときのフレームレートを計測しパフォーマンスをチェックします。
フォーマット | 変換 | プレビューのFPS |
5760x3240、YUY2 | RGB32 | 4.3 |
5760x3240、UYVY | RGB32 | 2.7 |
5760x3240、HDYC | UYVY | 53.1 |
5760x3240、RGB24 | RGB32 | 17.1 |
5760x3240、RGB32 | RGB32 | 28.5 |
YUY2とUYVYをキャプチャした場合は「AVI Devompressor」によりRGB32への変換が行われその部分が極端に遅く使い物になりません。これはMonsterX-iなどのD3を入力した場合にデインターレースして60fpsでプレビューしようとしても40fps程度までしか処理できないなど非常に厳しい結果です。
一方HDYCをキャプチャした場合はUYVYに変換(FourCCやサブタイプを変えるだけっポイ)され最もいい結果がでています。これはVMR7と同等のパフォーマンスでありIntensity(HDYC)などはEVRを使っても基本的なグラフで快適にプレビューできました。
RGBに関してはあまり重要ではありませんが、こちらもRGB24をキャプチャした場合、「Color Space Converter」によりRGB32への変換が行われパフォーマンスは低下します。RGB32をキャプチャした場合は、元々HDYCの2倍の情報量なので変換等が行われなくても30フレーム前後となってしまうのは妥当な結果と言えます。
■アマレコTVの場合
続いてEVRと上手くネゴシエートできるようなフィルター「AmaRec Deinterlace」を用意してパフォーマンスを調べます。

YUY2、UYVY、HDYC、RGB32をキャプチャすると「AmaRec Deinterlace」によりネゴシエートされ変換系のフィルターなしでEVRが接続されます。

「AmaRec Deinterlace」フィルターではカラーフォーマットの変換は一切行わず、ピッチやアロケータをEVRの都合にあわせるだけです(HDYCはFourCCとサブタイプだけUYVYに変更)。
フォーマット | 変換 | プレビューのFPS |
5760x3240、YUY2 | YUY2 | 53.7 |
5760x3240、UYVY | UYVY | 53.7 |
5760x3240、HDYC | UYVY | 53.7 |
5760x3240、RGB24 | RGB32 | 11.9 |
5760x3240、RGB32 | RGB32 | 28.5 |
RGB24を除いてフォーマットの変換を一切行わない為、VMR7と比べパフォーマンスの低下はありません。RGB24は「Color Space Converter」により変換される為パフォーマンスが低下します。また、「AmaRec Deinterlace」のコピー処理もある為、結果1よりさらに遅くなっています。
■まとめ
EVRはVMR7に比べて重い(処理が遅い)と言われているのは、EVR自体の処理ではなくその手前に入る変換フィルターが足を引っ張っている事が原因と思われます。アマレコTVはその部分を「AmaRec Deinterlace」フィルターで調整し、EVRでも多くのケースでVMR7と同等のパフォーマンスを発揮できるようになっています。
グラフ構成 | フォーマット | 変換 | プレビューのFPS |
VMR7 (オーバーレイ) | 5760x3240、YUY2 | なし | 53.1 |
EVR + AVI Decompressor | 5760x3240、YUY2 | RGB32 | 4.3 |
5760x3240、UYVY | RGB32 | 2.7 | |
5760x3240、HDYC | なし | 53.1 | |
EVR + Color Space Converter | 5760x3240、RGB24 | RGB32 | 17.1 |
5760x3240、RGB32 | なし | 28.5 | |
EVR + AmaRec Deinterlace | 5760x3240、YUY2 | なし | 53.7 |
5760x3240、UYVY | なし | 53.7 | |
5760x3240、HDYC | なし | 53.7 | |
5760x3240、RGB32 | なし | 28.5 | |
EVR + Color Space Converter + AmaRec Deinterlace | 5760x3240、RGB24 | RGB32 | 11.9 |
DirectShowオーディオレンダリングの累積遅延
どうやらスマートティーフィルターはビデオでもオーディオでも同じように働き、遅延した分のデータを破棄してくれるようです。なのでオーディオレンダラーにどんどんデータが溜まっていくという状況を回避できる。
DirectShowのドキュメントにはオーディオデータを複数に分ける部分でインフィニットピンティーフィルターを使って説明がなされているのでちょっと気が付きませんでした。なんでスマートティーフィルターで説明されてないんだろう?オーディオでスマートティーフィルターを使っちゃ不味いとかあるのでしょうか。
自作レンダラーも完成したので両方を比べてみましたが音質や遅延具合に大きな差異は感じられませんでした。なのでどっちをメインにするか迷うところですが、せっかくなので何かしらのデメリットが出るまでは自作レンダラーをメインにして行こうと思います。
Direct Show
で、いくつかDirectShow標準のフィルタでは上手く行かないケースがありました。
1.録画処理とプレビュー処理の両立ができない。
キャプチャピンとプレビューピンのそれぞれで録画処理とプレビュー用のレンダリングを行いますが、録画処理の方が何らかの理由で一時的に止まると(HDDのアクセス待ちが主)その間プレビューもとまってしまう。そのため録画中はプレビューのご機嫌がナナめになります。
録画処理に関しては一時的に止まっても賢くバッファリングされているため、出来上がるビデオファイルへの影響は出にくく素晴らしいのですが、何分プレビューが犠牲になるのが痛い。
ここは録画処理が止まってもグラフ処理を止めない工夫が必要で、キャプチャツールの定番である「ふぬああ」ではそのあたりにも配慮されていて、独自のマルチプレクサにより録画処理が止まってもプレビューに影響がでにくくなっているようです。
2.オーディオ再生の遅延。
映像はプレビューピンをレンダリングする事で遅れた分のデータに関しては自動的に破棄されるので表示される画像は遅延し難くなっています。
また、キャプチャピンにビデオレンダラを接続する事でも表示出来ますが、この場合は遅れた分のデータが破棄されず表示されてしまうため遅延が起こる度に遅延時間が累積されどんどん遅れていくことになります。
一方、オーディオの方は元々録音してから再生するという仕組みのため録音時間分の遅延がどうしても発生してしまいます。このあたりはDirectShowのドキュメントにも書いてありますが、これに加えレンダリング時の累積遅延が発生します。オーディオに関しては丁度映像のキャプチャピンをレンダリングするのと同じような動作になるようで、累積した遅延を回復する術がみつかりませんでした。結局この部分は遅延が累積しない自前のオーディオレンダラを作る事で改善することになります。
オーディオ処理に関してはファンタジーリモートでやった音声転送の概念がそのまま適用できるので出来るだけ遅延を抑えたリアルタイム処理と再生品質の両立は可能かな。
という事で、次のアマレコはビデオキャプチャをやります!
1の問題に関しては元々録画処理をDirectShowではなくアマレコ秘伝のライブラリで行うのでDirectShowはプレビューに専念でき、録画とプレビューの両立が可能となります。