Aero有効時におけるデスクトップキャプチャについて
しかし、Windows7になったからか、それとも最近のPCの性能の御蔭か今ではAeroが有効なままでも著しくパフォーマンスが低下することは無く、それなりのパフォーマンスでデスクトップキャプチャできるようです。今回私が調査した結果を書きます。なお、以下のドキュメントは私がとったデータから推測したもので完全に憶測です。事実と異なる可能性がある点にご注意下さい。
■Windows7におけるAero有効時のデスクトップキャプチャの特性
(1) 取得する画像サイズの大小にかかわらず2フレーム分待たされる。
例えばモニターのリフレッシュレートが60Hz(昨今の大抵の液晶モニターが60Hzです)の場合どんなに頑張っても秒間30コマまでしかキャプチャすることができません。キャプチャ範囲が320x240と小さくても、最大30fpsだし、1920x1080と大きくても最大30fpsが限界となります。ちなみに120Hzモニターであればキャプチャfpsの限界は60fpsとなります。リフレッシュレートの半分がキャプチャfpsの限界と考えればわかりやすいかと思います。
(2) 複数のアプリケーションがデスクトップキャプチャをする場合、協調的な動作となる。
例えば60Hzモニターの場合にアマレココを2つ同時に起動すると、それぞれ30fpsに設定しても個々のアマレココの動作は15fpsが限界となります。2つのアプリケーションの合計が30fpsを超えることはありません。
同様に3つのアマレココを同時に起動するとそれぞれ10fps前後での動作となります。
このようにAero有効時は他のアプリケーションの影響を受けてしまいますので、もし、キャプチャfpsが30で安定しない場合は他のアプリケーションがデスクトップにアクセスしていないか確認するといいでしょう(どうやってかくにんする?)。
(3) APIによる違い
基本的にはデスクトップのハンドルからデバイスコンテキストを取得して、そこからBitBlt()関数で画像をキャプチャします。
これはアマレココも今回のアマレコTVのデスクトップキャプチャ機能も同じです。
昨今では2D画像を扱うためのAPIが多々マイクロソフトから提供されており、その中にデスクトップ画像を取得できるものもあります。BitBlt()なんて古臭いので新しいAPIを一通り試してみましたが、いずれも期待外れに終わり、おそらく新しいAPIにしろBitBlt()にしろデスクトップから画像を取得する処理はOSにより一元管理されていて、その部分がネックなので改善の見込みはありませんでした。
■Windows8では・・・
この状況を打開すると思われるのがWindows8で導入されたDesktop Duplication APIです。
しかし、サンプルプログラムを作ってみましたが残念ながらWindows7では利用できませんでした。Windows8も持っていないので具体的にどのような動作になるのか確認も取れていません。将来的にはこれがWindows7で使えるようになってデスクトップキャプチャのこの閉塞感を打破してくれることを期待します。
■そして「ウィンドウ・キャプチャ」
結局アマレココから何も変わらないじゃんってことになりますが、ひとつ進展したのが「ウインドウ・キャプチャ」機能です。
ウインドウキャプチャはAeroが有効な場合にのみ利用可能で、指定したウインドウの画像のみをキャプチャします。指定したウインドウは他のウインドウの下に隠れていても隠れた部分を含めキャプチャすることができます。
一番の特徴は画像をデスクトップからキャプチャするのではなく、指定したアプリケーションのオフスクリーンメモリーからキャプチャすることでパフォーマンスを向上させることができることです(30fpsに制限されない)。
■「ウインドウ・キャプチャ」の概要
Aero有効時は各アプリケーションの画像を管理するためのオフスクリーンメモリーをOSが用意するらしく、デスクトップコンポジションはそのオフスクリーンの画像を元にDirectXの機能を使って半透明や拡大・縮小、3D変換といった処理を施し最終的にデスクトップ用の画像として合成(レンダリング)します。
デスクトップ・キャプチャはレンダリングされた後の画像をキャプチャするのに対し、ウインドウ・キャプチャはレンダリングの元となるオフスクリーンをキャプチャする点が異なります。
そして、その違いはパフォーマンスに大きく影響し、デスクトップ・キャプチャはレンダリングが終わるのを待つ必要があるのに対し、オフスクリーンキャプチャ(ウインドウ・キャプチャ)では基本的に待たされません(アプリケーション自体が画像を更新している間は待たされると思う)。なのでAeroが有効でもサクサク動き、高fpsで録画することが可能となります。
弱点は、レンダリングされる前の不完全な画像なので、DirectXなどの処理が反映されないことです。キャプション部などのAeroガラスであったり、DirectXを使ったゲーム、EVRなどを使って表示している動画などもキャプチャできません。
■「Aero有効時にデスクトップキャプチャのパフォーマンスが低下する」について
(1) BitBlt()などのデスクトップキャプチャ処理がアプリケーションで実行されると、OSはキャプチャ処理を奪い取る。
(AeroはDirectXのフルスクリーンモードで動作するためBitBlt()などでは正常にキャプチャできない、アマレココがフルスクリーンのゲームを正常にキャプチャできないのと同じ。その対策としてOSが特別にキャプチャ処理を代行してくれるものと思われる)
(2) OSのキャプチャ処理はデスクトップコンポジションに対しデスクトップ画像をキャプチャ用に欲しいとリクエストを出す。
(3) デスクトップコンポジションはリクエストがあると表示用とキャプチャ用の2つのデスクトップ画像をレンダリングする。
しかし、いまレンダリング中の処理には新しいリクエストは間に合わないので反映されない。
キャプチャ用の画像がレンダリングされるのは最短で次のフレームとなる。
(これが今のフレームと次のフレームの2フレーム分待たされる原因と思われる)
(4) 次のフレームがレンダリングされ、リクエストに応じキャプチャ用の画像がOSのキャプチャ処理へ渡される。
(5) OSのキャプチャ処理はデスクトップコンポジションから取得した画像をBitBlt()などを実行したアプリケーションへ送る。
ポイントはOSのリクエストが次のレンダリングでないと反映されないことと、OSのキャプチャ処理がシングルタスクで窓口が一つしかなく、複数のアプリケーションがBitBlt()を使うと行列ができてしまう点です。
行列ができる状況でも合理的にリクエストを発行することは無く、リクエスト→1フレーム以上待つ→レンダリング結果取得→ひととおり終わってから次のリクエストのサイクルをマイペースでこなすためパフォーマンスが低下してしまいます。

- 関連記事
-
- アマレコTV FAQ オーディオレンダラーの再生プロパティが表示されない
- アマレコTV FAQ 分配ケーブルを使うと画面が暗くなる
- アマレコTV FAQ アマステを使うとエラーになる
- Core Audio Dll Ver2.30c 多チャネルスピーカー対応ベータ版
- アマレコTV FAQ コンポジットとS端子が勝手に切り替わる
- デインターレースフィルタ FPS低下対応ベータ版
- アマレコTV Ver3.00 デスクトップキャプチャ機能
- Aero有効時におけるデスクトップキャプチャについて
- アマレコTV デスクトップキャプチャ機能 簡易ヘルプ 使い方編
- アマレコTV デスクトップキャプチャ機能 簡易ヘルプ ヒントとFAQ編
- アマレコTV Ver3.00a 不具合修正版と再生音の話
- アマレコTV Ver3.00a 不具合修正版とMP3
- アマレコTV デスクトップキャプチャに関するFAQ
- アマレコTVスレについて
- アマレコTVスレについて その2 予約録画
trackback
コメントの投稿