SSブログ

Magiquand (10.6+ Beta 0.9)のバグ解決?? [OpenCV関係]

こないだまで悩んでいた「魔法の杖」アプリのバグの原因がわかったかもしれない。

問題はたぶんタイミングの問題だろうと思っていた。

KTKit Captureを使ったカメラ入力はデリゲートのcaptureOutput:didOutputVideoFrame:withSampleBuffer:fromConnection:という長い名前のメソッドを呼ぶことでフレームのピクセルデータがデリゲートの手に入る。ところがこれが呼ばれるスレッドがメインスレッドとは限らない。CALayerを使った表示はメインスレッドでないと正常に表示されないので、どこかでデータをスレッド越しに渡さないといけない。カメラのデリゲートメソッドが呼ばれるスレッドにはどうやらNSRunLoopは動いていないらしくて、カメラからのフレームデータが揃った時点でデリゲートメソッドが呼ばれる。一方メインスレッドではNSRunLoopがまわっていて、ループが一回りしてはじめて制御がわたってくる。

こういう非同期の処理に対する対応はQTKit Captureを使う上ではちゃんとやらないといけないんだけど、どうやらCALayerを使ってNSViewで表示を始めるとき、メインスレッドはかなり長い間ストールするらしい。おそらく何らかのリソースをロードしてるんだろう。その間にたくさんフレーム落ちして、そのせいで初期化がうまくいかないらしい。ちなみにAVFoundationではデリゲートメソッドが呼ばれるスレッドを転送前であれば指定できる。

前書いたようにカメラの画素数はフレーム転送が始まらないとわからないのでそのあと初期化になるのに、転送が始まるときはメインスレッドがストールしている、ということみたい。

カメラ画像はCALayerをNSViewの上に直接表示していて僕のコードは何もしていないので問題なく表示されるんだけど、パーティクルの方はピクセルデータから計算しているので、初期化に失敗してると表示されない。また、立ち上げ直すとNSViewがロードするリソースがキャッシュされているので初期化が成功する、ということなんだろうと思う。

転送開始とストール(NSViewのCALayerへの初期化)のタイミングをずらすか、たくさんフレーム落ちしても問題ないようにすればいいんだろうと思う。その路線でコーディングしてデバグしてみよう。


nice!(0)  コメント(0)  トラックバック(0) 

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

トラックバック 0

献立09/29献立09/30 ブログトップ

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。