2011-11-24 24 views
1

プレビューの実行中に、ライブプレビューと静止画キャプチャの両方を行うビデオアプリがあります。私はアプリが読み込まれるときに事前に生成される4つのテクスチャを使用しています。私は3つのスレッドを介してテクスチャにアクセスしています。スレッド間でフレームバッファを共有

ライブプレビュー作業を行うために、というフレームバッファに結果を保存できるように、私は共有グループ(下記参照)を作成しなければなりませんでした。次に、画面に表示するために、私はpresentRenderbufferへの呼び出しのためにFBO_OUTにアクセスする必要がありました。 Sharegroupを使用しなかった場合、ちょっとばかばかしいことがあります。

#define SHAREGROUP_CONTEXT [[[appDelegate mainViewController] oglView] offscreenContext] 

if ([EAGLContext currentContext] != SHAREGROUP_CONTEXT) { 
    NSLog(@"setting context"); 
    glFlush(); 
    [EAGLContext setCurrentContext:SHAREGROUP_CONTEXT]; 
} 

@synchronized(SHAREGROUP_CONTEXT) 
{ 
    /* process pixels */ 
} 

glFlush(); // at end of method 

これは正常に動作し、問題は、私は今、静止画撮影後に同じことをやろうとしているということです。私はこのコードを呼び出す必要がcaptureOutput

定期
CAEAGLLayer* eaglLayer = (CAEAGLLayer *)self.layer; 
eaglLayer.opaque = YES; 
eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys: 
           [NSNumber numberWithBool:NO], kEAGLDrawablePropertyRetainedBacking, 
           kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, 
           nil]; 
oglContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; 
offscreenContext = [[EAGLContext alloc] initWithAPI:[oglContext API] sharegroup:oglContext.sharegroup]; 
if (!oglContext || ![EAGLContext setCurrentContext:oglContext]) { 
    NSLog(@"Problem with OpenGL context."); 
    [self release]; 

    return nil; 
} 

、しかし、私はこれをやってみましたにも関わらず、再びちんぷんかんぷんを取得しています、captureStillImageAsynchronouslyFromConnectionブロックを経由して(プレビューがまだ実行されている間):

AVCaptureConnection *sic = [AVCamUtilities connectionWithMediaType:AVMediaTypeVideo fromConnections:[[self stillImageOutput] connections]]; 

[[self stillImageOutput] captureStillImageAsynchronouslyFromConnection:sic 
                completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) 
{ 

    @synchronized(SHAREGROUP_CONTEXT) 
    { 

     /* generate new textures to process the imageDataSampleBuffer and cry */ 
    } 

これは、問題のウィットのようですhコンテキストとスレッディング。

答えて

1

私は答えを見つけました。 @synchronizedブロックが、どちらもの方法になっていることを確認する必要があります。これは私のシェイダーでは非常に奇妙なことが起こっていたので、私は見つけ出すのにずっと時間がかかりました。ファイル名の1つは、XCodeがすべて大文字であると思ったときにディスク上の小文字でした。これにより、ライブプレビューでシェーダが動作するようになりましたが、静止画キャプチャ部分に白い画面が表示されました。理由は分かりません。

+0

ここでアクセスをロックするために '@synchronized'を使用すると、少しのパフォーマンスを犠牲にするかもしれません:http://perpendiculo.us/?p=133。 NSLockのオーバーヘッドは非常に少なく、pthreadミューテックスはさらに安価です。私は過去にOpenGLアプリケーションで多くのパフォーマンスを消費していたロックを見てきました。また、単一ワイドディスパッチキューを使用して、単一のリソース(コンテキストなど)にアクセスするすべてのアクションをそのキューにディスパッチすることもできます。これは、この共有されたリソースへの安全なアクセスを保証するロックフリーの方法であり、最近私の好ましいアプローチでした。 –