2012年4月23日月曜日

Core Video Task (3)

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

1) では,次の三つの処理が待ち受けていました.
1. Setting Up the Display Link
2. Initializing Your Video Source
3. Implementing the Display Link Output Callback Function

今回は 1) - 2 Initializing Your Video Source を見ていきますね.


Initializing Your Video Source

まず,ビデオソースを用意しなければなりません. OpenGL のテクスチャとして非圧縮なビデオデータを渡せるものであれば何でも構いません.例えば,Quicktime や OpenGL や独自のフレームジェネレータなどなど...

それぞれの場合において,生成されたビデオを表示するための OpenGL context を作る必要があります.つまりは,ビデオを表示させたいところはここだというのを示すためにビデオソースを渡すことになります.

では, QuickTime での例を示します(Programming Guide から引用).
Listing 2-3  Initializing a QuickTime video source
- (id)initWithFilePath:(NSString*)theFilePath // 1
{
    self = [super init];
 
    OSStatus        theError = noErr;
    Boolean         active = TRUE;
    UInt32          trackCount = 0;
    OSType          theTrackType;
    Track           theTrack = NULL;
    Media           theMedia = NULL;
 
    QTNewMoviePropertyElement newMovieProperties[] = // 2
        {
        {kQTPropertyClass_DataLocation,
            kQTDataLocationPropertyID_CFStringNativePath,
            sizeof(theFilePath), &theFilePath, 0},
        {kQTPropertyClass_NewMovieProperty, kQTNewMoviePropertyID_Active,
            sizeof(active), &active, 0},
        {kQTPropertyClass_Context, kQTContextPropertyID_VisualContext,
            sizeof(qtVisualContext), &qtVisualContext, 0},
        };
 
    theError = QTOpenGLTextureContextCreate( NULL, NULL, // 3
        [[NSOpenGLView defaultPixelFormat]
         CGLPixelFormatObj], NULL, &qtVisualContext);
 
    if(qtVisualContext == NULL)
     {
        NSLog(@"QTVisualContext creation failed with error:%d", theError);
        return NULL;
    }
 
    theError = NewMovieFromProperties(
        sizeof(newMovieProperties) / sizeof(newMovieProperties[0]),// 4
        newMovieProperties, 0, NULL, &channelMovie);
 
    if(theError)
    {
        NSLog(@"NewMovieFromProperties failed with %d", theError);
        return NULL;
    }
 
    // setup the movie
    GoToBeginningOfMovie(channelMovie);// 5
    SetMovieRate(channelMovie, 1 << 16);
    SetTimeBaseFlags(GetMovieTimeBase(channelMovie), loopTimeBase);
    trackCount = GetMovieTrackCount(channelMovie);
    while(trackCount > 0)
    {
        theTrack = GetMovieIndTrack(channelMovie, trackCount);
        if(theTrack != NULL)
        {
            theMedia = GetTrackMedia(theTrack);
            if(theMedia != NULL)
            {
                GetMediaHandlerDescription(theMedia, &theTrackType, 0, 0);
                if(theTrackType != VideoMediaType)
                {
                    SetTrackEnabled(theTrack, false);
                }
            }
        }
        trackCount--;
    }
 
    return self;
}

では,以下はコードの説明を書いておきます.
  1. 引数に QuickTime movie のパスを持ってます.
  2. movie のプロパティを設定します.これらのプロパティは,後で出てくる  NewMovieFromProperties 関数に渡されます.
    • ファイルのパス
    • アクティブにするかどうか,YES/NO
    • この movie と関連付ける visual context,ここではクラスのインスタンス変数である QTVisualContextRef qtVisualContext を使っています
  3. 続いて OpenGL texture context を作成します.この QuickTime 関数 QTOpenGLTextureContextCreate は, CGLContext と CGLPixelFormat を要求してくるので,Cocoa の場合,初期化の際に生成した NSOpenGLContext と NSOpenGLPixelFormat から取得します. この context は qtVisualContext に含まれ,その後 NewMovieFromProperties に渡されます.
  4. 動画を生成します.インスタンス化するのに NewMovieFromProperties (available in Mac OS X v10.4 and later, or QuickTime 7.0 and later) を使います.Cocoa を使っているなら, QTKit のメソッドである movieFromFile を代用することもできます.また, movie 生成後に visual context を更新する必要があれば, SetMovieVisualContext を使いましょう.
  5. 動画の初期化処理を実行します.上の例では,通常フレームレートやループ処理を扱う上で,常用的なコードになっています.また,このコードでは,音声等の非ビデオトラックはオフにし,ビデオトラックだけをループします.



次回は, 1) - 3. Implementing the Display Link Output Callback Function をみていきます.

0 件のコメント:

コメントを投稿