« ゲームキャスティング? | メイン | 返ってこなくなる »

2005年12月26日

吉里吉里 ムービー拡張日誌2:: EAccessViolationに悩む

    

再生できるようになって、メニューの問題もクリアしたと思ったら、EAccessViolationに悩まされた。
ムービーを1個だけ再生した場合は発生せず、簡易ムービープレーヤーで2つ目のムービーファイルをドロップした時に発生する。

初めデストラクタが2回コールされている?と思ったが、そんなことはなく、どうも2回目の初期化が失敗してすぐに破棄されているようだった。
2回目の初期化が失敗しているとわかった後は比較的早く原因がわかった。
2回目に失敗していた直接の原因はRegisterClassExでのウィンドウクラスの登録だった。
VMRのアロケーター&プレゼンターは子ウィンドウを持っていて、最初に子ウィンドウを作る時にウィンドウクラスを登録し、アロケーター&プレゼンターが削除される時にウィンドウクラスの登録を解除していた。
ムービープレーヤーでは、破棄した直後に生成しているので、この作りでも問題ないはずだが、なぜか登録解除が間に合っていなかった。(同時再生を考えるとこの作りではまずい)
アロケーター&プレゼンターは、VideoOverlayの実体となるtTVPDSMixerVideoOverlayが保持しているCOMオブジェクトになっている。
初めtTVPDSMixerVideoOverlayが削除される時にReleaseを呼ぶようにしていたが、参照カウントが4も残っていて消えないので、deleteするようにしたが、それではまずいようなのでReleaseに戻した。
アロケーター&プレゼンターは、VMRにも保持されているので、削除時に参照カウントが残っていても不思議ではない。
そして、どうやらこの参照カウントが0になるタイミングがtTVPDSMixerVideoOverlayが削除された少し後のようだ。
DirectShowのグラフは複数のスレッドで構成されているのでRelese()がコールされた瞬間には消えないのだろう。

そこで、ウィンドウクラスを登録したアトムを持つ変数をクラス属性にして、実行時に1回だけ登録されるようにした。
こうすることでEAccessViolationはなくなり、初期化の失敗もなくなった。

フルスクリーンとウィンドウの切り替えは何度もやったが、生成&破棄などはあまりやっていない。
もっといろいろとテストしたほうが良さそうだ。



投稿者 Takenori : 2005年12月26日 22:33




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