« WM同期リーダーでの負荷 | メイン | シーク処理 »

2005年10月28日

吉里吉里 ムービー拡張日誌2:: WM用カスタムアロケーター

    

まず、単純にIMemAllocatorをラップしたアロケーターを作ったが、それではまったく機能しなかった。
アロケーターがコールされるのはIWMSyncReader::GetNextSample内だが、このメソッドをコールする前にGetDeliveryBufferによってアロケーターからバッファを取得している。
アロケーターは、バッファのプールが空の時に確保しようとすると、バッファが使えるようになるまでブロックする。
つまり、GetDeliveryBufferで確保した後に、GetNextSample内で再度確保しようとしたらデッドロックする。
そこで、IMemAllocatorを使用してバッファを確保するのではなく、GetNextSample呼び出し前にカスタムアロケーターへバッファを設定し、カスタムアロケーターはそのバッファを返すようにした。
これでカスタムアロケーターを使用して再生できるようになった。

よくよく考えたら、GetDeliveryBufferを使わずに、GetNextSampleから返ってきたバッファからIMediaSampleを取り出して、そいつをDeliverでダウンストリームに送るような実装でも良かった。
こちらの方が構造的に良いかもしれない。
ただ、後述する問題を考えるとどちらがいいかは難しいところ。

カスタムアロケーターが出来たので、負荷を見てみようとAthlon XPのマシンで動かそうとしたが…… 最初のフレームだけを表示して動かない。
開発に使っているPen4では問題なく再生されるのだが。
さっぱり理由がわからないので、シークの処理を作ろうと四苦八苦していて気付いた。(シークの問題については後で書く予定)
GetNextSampleが1回しかコールされていないのにWM用カスタムアロケーターが2回コールされるタイミングがあるようだ。
2回コールされると、確保しようとした時にブロックされて止まってしまう。
そこで、内部にCMemAllocatorを持たせて、2回連続でコールされた時は、内部のCMemAllocatorからメモリを確保するようにした。
このようにしたら、Athlon XP 1600のマシンでも再生できるようになったが、音が出ない。
まだ何かあるようだ。
とりあえず、サウンドストリーム側は大したデータ量ではないだろうということで、カスタムアロケーターは使用しないことにしたら音が出るようになった。
で、CPU負荷はというと、40%~60%になった。
MPEG Iより少し重いが、これぐらいならいいかな。
ちなみにレイヤー描画の場合は、70%~90%。
レイヤー描画を使う場合、推奨 2.0GHz以上?

とりあえずは再生できるようになったが、なぜ2回連続でコールされるのか? など良くわからない部分がある。



投稿者 Takenori : 2005年10月28日 19:10




comments powered by Disqus
Total : Today : Yesterday : なかのひと