2013年4月2日火曜日

AVGreenScreenPlayer 4

前回に引き続き,GSPlayerView.m の中身を見て行きましょう.

GSPlayerView クラスにはプライベートなインスタンス変数 _displayLink がありました.これは CVDisplayLinkRef 型で,Core Video が提供する Display Link を表す変数でした.

Display Link は平たく言えばディスプレイのリフレッシュに連動した割り込みでした.

さて,GSPlayerView.m のソースコード上で CVDisplayLinkRef を検索してみましょう.早速

static CVReturn displayLinkCallBack(...);

というプロトタイプ宣言が見つかります.関数定義はソースコードの終わりの方にあります.

displayLinkCallBackの関数定義を見てみると,最後の引数としてvoidポインタdisplayLinkContextを受け取っていますが,これは任意のオブジェクトを渡す効率的な方法がvoidポインタしか無いため仕方なくvoidポインタになっているものです.(そもそもC言語スタイルのコールバックにするためこのような仕様になっているのでしょう.)

関数定義の冒頭で displayLinkContext は GSPlayerView ポインタへキャストされています.つまり,C++で言うところのthisポインタがわたってくるのですね.また,この「thisポインタ」経由で AVPlayerItemVideoOutput ポインタである _playerItemVideoOutput インスタンス変数を取り出しています.

で,関数の中で何をしているのかと見てみると,単に新しい画像があれば適切なタイミングで描画し(キューに入れ),無ければしばらく待つだけです.

つまり,displayLinkCallBack は単にタイミングをとっているだけなんですね.

では実際の描画処理はどこで行われているかというと,displayLinkCallBack 関数から呼び出されている displayPixelBuffer メソッドなのですが,ほとんどの仕事は AVSampleBufferDisplayLayer クラス(の変数 videoLayer)で行われています.

この AVSampleBufferDisplayLayer クラスは OS X 10.8 から追加されたクラスで,Core Animation レイヤーにビデオを流す機能を持っています.かつては QTMovieLayer という QTMovie を再生する Core Animation レイヤーがあったのですが,QuickTime Kit のフェードアウトとともに,こちらも AVFoundation への移行が進んでいます.単にムービーを再生するだけなら AVPlayerLayer を,Core Image フィルタを使うなら AVSampleBufferDisplayLayer を使います.ただし,AVSampleBufferDisplayLayer は新しいクラスのせいか,まだドキュメントが整備されていないようです.

次回はこのあたりのメカニズムを見て行きましょう.

0 件のコメント:

コメントを投稿