2012年4月19日木曜日

Core Video Task (2)

Core Video の役割として大きく三つあるといいました.今回はそのうちの,メインといっても過言ではない 1) Obtaing Frames Using the Display Link を見てみます.非圧縮のフレームを得るためには, display link を使うのが良いようです.

ここからは Apple の Programming Guide に沿って,NSOpenGLView class のサブクラス MyOpenGLView オブジェクトを使って話を進めます.MyOpenGLView の interface は以下の通りです(Programming Guide から引用).

Listing 2-1  The MyVideoView interface
@interface MyVideoView : NSOpenGLView
{
 
    NSRecursiveLock         *lock;
    QTMovie                 *qtMovie;
    QTTime                  movieDuration;
    QTVisualContextRef      qtVisualContext;
    CVDisplayLinkRef        displayLink;
    CVImageBufferRef        currentFrame;
    CIFilter                *effectFilter;
    CIContext               *ciContext;
 
    NSDictionary            *fontAttributes;
 
    int                     frameCount;
    int                     frameRate;
    CVTimeStamp             frameCountTimeStamp;
    double                  timebaseRatio;
    BOOL                    needsReshape;
    id                      delegate;
}
@end



そしてここから次の三つの処理.今日は一つ目だけ.
1. Setting Up the Display Link
2. Initializing Your Video Source
3. Implementing the Display Link Output Callback Function


Setting Up the Display Link

ステップが多いですが,ここでも以下のステップで display link を設定していきます.
- Create a display link thread.
- Bind the link to a specific display.
- Register a display output callback.
- Starting the display link thread.

このステップに関しては,すでに実装例として以下のコードがありますので確認してみましょう.


Listing 2-2  Setting up a display link
- (void)awakeFromNib
{
    CVReturn            error = kCVReturnSuccess;
    CGDirectDisplayID   displayID = CGMainDisplayID();// 1
 
    error = CVDisplayLinkCreateWithCGDisplay(displayID, &displayLink);// 2
    if(error)
    {
        NSLog(@"DisplayLink created with error:%d", error);
        displayLink = NULL;
        return;
    }
    error = CVDisplayLinkSetOutputCallback(displayLink,// 3
                                 MyDisplayLinkCallback, self);
 
}

さて,これらの処理を順(番号が既に振られています)をおってみていきます.
1. Display link に対応付けたい display に対して, Core Graphics display ID なるものを取得します.シンプルに, CGMainDisplayID の関数を使うとメインディスプレイの ID を取れます.

2. 1. で指定したディスプレイに対して display link を作成します.アクティブなディスプレイに対して display link を作成したいときには, CVDisplayLinkCreateWithActiveCGDisplays を使えばよいらしいです.そして,display link と特定のディスプレイを対応付けるために CVDisplayLinkSetCurrentCGDisplay を使うのだそうです.
ユーザがビデオコンテンツを含んだウィンドウを別のモニタに移動させたときには,適切に display link を更新する必要があります.Cocoa なら NSWindowDidMoveNotification を使えば対応できますね(ここは割愛).Carbon でも対応方法はあるそうですが,これも割愛します.

3. (エラー処理を挟んだ後)コールバックを設定します.


順を追って見てみればこんなものです.上記のように準備が整ったら, CVDisplayLinkStart を呼んで, display link のスレッドをアクティブにしましょう.このスレッドはアプリとは独立で動作します.アプリケーションを終了するときなどは, CVDisplayLinkStop を呼んでこのスレッドを止めましょう.

0 件のコメント:

コメントを投稿