2012年5月2日水曜日

Core Video Task (4)

Core Video の役割は次の三つ.
1) Obtaing Frames Using the Display Link
2) Manipulationg Frames
3) Using Core Image Filtering With Core Video

今回は 1) - 3 Implementing the Display Link Output Callback Function です.

Implementing the Display Link Output Callback Function
display link が動作している間,フレームを準備する必要があるたびにアプリケーションに定期的にコールバックします.コールバック関数は OpenGL のテクスチャとして指定されたビデオソースからフレームを取得し,それをスクリーンへと表示する必要があります.

もしオブジェクト指向であれば,以下の Listing 2 - 4, Listing 2 - 5 のようなメソッドを呼び出すことになります.

Listing 2-4  Invoking a method from your callback
CVReturn MyDisplayLinkCallback (
    CVDisplayLinkRef displayLink,
    const CVTimeStamp *inNow,
    const CVTimeStamp *inOutputTime,
    CVOptionFlags flagsIn,
    CVOptionFlags *flagsOut,
    void *displayLinkContext)
{
 CVReturn error =
        [(MyVideoView*) displayLinkContext displayFrame:inOutputTime];
 return error;
}
この例では,コールバック関数は MyVideoView class に実装された displayFrame メソッドを単に呼び出します.このクラスのインスタンスは displayLinkContext parameter にあるコールバックに渡されます.ちなみに, MyVideoView class は NSOpenGLView class のサブクラスである必要があります.
Listing 2-5  Implementing the displayFrame method
- (CVReturn)displayFrame:(const CVTimeStamp *)timeStamp
{
    CVReturn rv = kCVReturnError;
    NSAutoreleasePool *pool;
 
    pool = [[NSAutoreleasePool alloc] init];
    if([self getFrameForTime:timeStamp])
    {
        [self drawRect:NSZeroRect];
        rv = kCVReturnSuccess;
    }
    else
    {
       rv = kCVReturnError;
    }
    [pool release];
    return rv;
}
 

Listing 2 - 6 では, QuickTime からビデオフレームを取得するときに,どのように getFrameForTime メソッドを実装するかを示しています.

Listing 2-6  Obtaining frames from QuickTime
- (BOOL)getFrameForTime:(const CVTimeStamp*)syncTimeStamp
{
    CVOpenGLTextureRef      newTextureRef = NULL;
 
    QTVisualContextTask(qtVisualContext);// 1
    if(QTVisualContextIsNewImageAvailable(qtVisualContext, syncTimeStamp))// 2
    {
        QTVisualContextCopyImageForTime(qtVisualContext, NULL, syncTimeStamp,// 3
                 &newTextureRef);
 
        CVOpenGLTextureRelease(currentFrame);// 4
        currentFrame = newTextureRef;
 
        CVOpenGLTextureGetCleanTexCoords (// 5
                    currentFrame, lowerLeft, lowerRight, upperRight, upperLeft);
        return YES; // we got a frame from QT
    }
    else
    {
        //NSLog(@"No Frame ready");
    }
    return NO;  // no frame available
}
以下のような処理になっています.

  1. 要求される管理維持が実行できるように,コンテキストに時間を与えます.各フレームを取得する前にこの関数を呼ばなければなりません.
  2. 与えられた時間に,新しいフレームが利用可能かどうかを確認します.要求された時間は現在の時間ではなく,フレームが表示されるであろう未来の時間を表します.
  3. もしフレームが利用可能であれば,それを OpenGL のテクスチャとして取得します.QuickTime 関数の QTVisualContextCopyImageForTime は QuickTime から任意の Core Video イメージバッファタイプとしてフレームを取得します.
  4. 現在のフレームを解放し,新しく取得したテクスチャをセットします.解放しなければメモリリーが起きてしまうようです.
  5. テクスチャの表示部の座標設定を行う.主に,テクスチャの境界 bounds を設定する.

0 件のコメント:

コメントを投稿