L.Entisの日記: ソフトウェア動画プレイ
って言うか、メディアプレイヤーで MPEG を再生しようとすると例外が発生するってどうなの?
(まだ、エラー返して再生できないだけならいいんだけど…)
以前にも、ゲームじゃないけど、ムービー再生するのに MCI を使ったことがあるんだけど、色々泣かされたんだよね~
MCI レイヤのバグかと思って DirectShow 使っても全く同じ。(少なくとも DirectShow 以下のレイヤの問題らしい)
で、自前 CODEC 使う場合にはそれはそれで問題がないわけじゃなかったりするんだけどね…
例えば、MMX Pentium 200MHz 位がターゲットの時代だと、解像度は320x240 とかでいいんで、CPU 上の処理が問題だったんだけど、今だと 640x480 が普通だったりするんだよね。
そうすると何が問題って、FSB、要するにメモリの速度。
Pentium4 以上なら何も問題ないんだけど、PentiumIII 550MHz 位までが対象なんで、最低でも PentiumIII 800MHz FSB 100MHz で、640x480 30fps のムービーをほぼコマ落ち無しで再生させたいところ。
で、FSB 100MHz をベースに考えると
1フレームの容量=640*480*4 bytes
1フレームの理想的転送時間=2*(1フレームの容量)/4/100M=2*3.072[ms]
※リード+ライトなので2倍
30fpsの1フレームあたりの時間=33[ms]
実際に許される1フレームあたりの展開時間=25[ms]以下
デコードに要するステップ;(1) エントロピー符号の復号
(2) 逆量子化・データの再配列
(3) 直行変換
(4) リサンプリング(4:2:0 の変換)
(5) 色空間変換
(6) 動き補償・画像のリストア
(7) システムメモリ→VRAM 転送
で、(3) が DCT なら、(1)~(6) を1マクロブロック毎に処理できるので、データに関しては L1 キャッシュにほぼ収まるんだけど、命令キャッシュも含めてややキャッシュから外れるんだよね。
しかも、大いなる問題として、(6) の時に、16x16 のメモリアクセスになるんだけど、ラインとラインの間のアドレスが飛ぶのでストリーミングメモリアクセス(バースト転送)の性能を十分に発揮できないので、理論値よりも圧倒的に低い性能しか出ないんだよね。
なので、実際には1マクロブロックライン(640x16 pixel)単位で L2 キャッシュにデータをおいておくことを考慮して、連続メモリアクセスになるように考慮してる。
Pentium4 みたいに FSB が異様に速いマシンだと速度的な違いを見出すことはほとんどできないんだけど、PentiumIII だと明白な違いが…
(6) の動き補償なんて、前フレーム、後フレーム、現在の差分の3つを使って画像を作るんだけど、半画素単位での動きにも対応してるので…(ブツブツ…)
まあ、(7) で少なくとも 6[ms] 使うし、(6) では(メモリアクセス速度だけで)少なくとも 12[ms] は必要になるんだよね…
あと、(1) の処理でメモリライトの際に L2 キャッシュにヒットしない可能性が結構あるので(リードは確実にヒットしないんだけど)、それを考慮するとそのメモリアクセス時間だけで 3[ms] 位(下手すると…というか、実際には 6[ms])
というわけで、全部足すと 24[ms]。
CPU で行う処理は可能な限りメモリアクセスにオーバーラップさせないと実現不可能ってことなんだけどね…(いやまあ、それなりに近い数字が出てるからいいんだけど、それでも一杯一杯なのがなぁ~~~)
-- 追記
因みに、DivX とかでみんなテレビ番組を録画してるのをソフトウェア再生してるのを見て、どうして再生できるのかと思ったら、解像度が 448x336 だったり…。それでも、700MHz くらいだと処理落ちすることもあるらしいと聞くとまあ、がんばってるほうなのかなぁ~?と自分を落ち着かせてみる(^^;
せめて 640x480 でなく、640x368 位にしてくれるとずいぶん楽なんだけど…。
それにしても、WMV デコーダーとかはどうなってるんだろう…いや、いくらかはハードウェアアクセラレーションが使えるのかもしれないけど…
ソフトウェア動画プレイ More ログイン