プレビューの実行中に、ライブプレビューと静止画キャプチャの両方を行うビデオアプリがあります。私はアプリが読み込まれるときに事前に生成される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コンテキストとスレッディング。
ここでアクセスをロックするために '@synchronized'を使用すると、少しのパフォーマンスを犠牲にするかもしれません:http://perpendiculo.us/?p=133。 NSLockのオーバーヘッドは非常に少なく、pthreadミューテックスはさらに安価です。私は過去にOpenGLアプリケーションで多くのパフォーマンスを消費していたロックを見てきました。また、単一ワイドディスパッチキューを使用して、単一のリソース(コンテキストなど)にアクセスするすべてのアクションをそのキューにディスパッチすることもできます。これは、この共有されたリソースへの安全なアクセスを保証するロックフリーの方法であり、最近私の好ましいアプローチでした。 –