« iPhone でも Flash でも再生できる mp4 を ffmpeg で作る方法 | メイン | Joker Racer サービスの一時休止についての説明 »

2010年03月24日

[iPhone] TwitCastingの不具合の詳細メモ あとで読む

猛烈にディープな話しなので、その手の方以外はスルーの方向で。

先日リリースした TwitCasting に不具合があったので、一旦アプリを AppStore から削除したのですが、不具合の原因を書いておきます。

原因の根底は音声配信。iPhone の場合、音声の録音には AudioQueue を使う方法しかなくて(OpenALでは録音できない)、これを使います。


AudioQueueNewInput(&recordState.dataFormat, HandleInputBuffer, &recordState, CFRunLoopGetCurrent(), kCFRunLoopCommonModes, 0, &recordState.queue);

まぁこんな感じで、サウンドの入力イベントを RunLoop に割りつけます。

で、問題は、この関数の第4引数、CFRunLoopGetCurrent() にあります。

RunLoop は他のイベントも処理しているので、処理時間のかかるイベントが起こると音声の録音イベントが間に合わず「音飛び」が起こります。
これは処理速度の問題から iPhone 3G (3GSじゃないほう) で特に顕著に発生します。

そのため、この第4引数に NULL を指定することで、デバイスからの処理を特別な RunLoop にて実行させることが可能になっています。

で、NULL にするのはいいのですが、じゃぁ、今度は受け取った音声データをストリーム配信するときにどのスレッドにまかせればいいのか、という問題になります。

NULL指定で動く RunLoop は強烈に優先度が高いので、ここでそのまま処理を続行するわけにはいかない。
が、音声は何者にも優先して配信したい。ということで、元の RunLoop に戻すときに

NSRunLoop performSelector:target:argument:order:modes

この order という優先度に 0 とかを使ったのが不具合の原因。プライオリティ指定して RunLoop に戻したとき、他に待イベントが無い、または同プライオリティのイベントのみがある場合はいいのですが、その他のプライオリティのイベント待ちが混ざっていた場合、なんとプライオリティゼロのイベントの順序が入れ替わるという・・・

これにより、配信待ちの音声パケットの順序が入れ替わり、音声がくちゃくちゃになる、という状態になります。

で、このやり方で RunLoop に戻すのはまずい、ということで改修したのがこちら

NSThread performSelector:onThread:withObject:waitUntilDone:

これも猛烈に便利なスレッド処理関数で、これによりスレッドにイベントを戻しつつ、順序は最後尾、ということができるようになります。
(しかも最後の引数で同期/非同期も選べるという・・・なんて便利)


で、この処理に変更したものが現在の最新版となります。が。が。


問題はここでおしまい、といきたかったのですが、残念ながらそうはいかなかったようで・・・


実は、もともとの NULL 指定して割り込み処理されるサウンドのイベントなのですが、この優先度が高いためかどうなのか、通信状態が厳しくなってくると割り込みイベントがデッドロック状態になるようなのです(もちろん、ソフトウェアの制御にも問題があるのでしょうが・・)。

通信イベントとサウンドの録音イベントががっしり組合って動かない状態・・・が 20 ~ 30秒という長い時間継続します。

その間、すべての Runloop が微動だにしないので、ソフトウェア側で制御する余地がまったくありません・・・

ということで、現行の TwitCasting では、通信状態が悪くなり、このデッドロックが発生すると画面が固まったように見えるという状態になります。30秒ほど放置すれば(デバイス側でタイムアウトがかかるのか)処理が戻ってきて録画終了ダイアログが表示される、という状態です。


ということで、これまた近々に修正版をリリースしようと思います。すいません・・・

以上、ちょい細かすぎるメモ書き、でした。

Follow yoski on Twitter

ワード

投稿者 aka : 2010年03月24日 10:51  / 2010年03月 / iPhone

トラックバック

人気ブログランキング - a++ My RSS 管理人ブログ

このエントリーのトラックバックURL:
http://210.188.206.194/mt-tb-sf.cgi/825

コメント

コメントしてください

あわせて読みたい




保存しますか?


あとで読む | to read | フレッシュリーダー | フレッシュミーティング | RSSフィード.cc | あわせて読みたい | track feed MyRSS管理人