我有一个视频应用程序,可以在预览运行时同时进行实时预览以及静态图像捕获。我使用的是应用程序加载时预先生成的4个纹理。我正在访问三个线程的纹理。在线程间共享帧缓冲区
为了使实时预览工作,我必须创建一个Sharegroup(见下文),以便captureOutput
方法可以将结果存储在名为FBO_OUT
的帧缓冲区中。然后,为了显示到屏幕我需要访问FBO_OUT
拨打电话presentRenderbuffer
。如果我没有使用Sharegroup,我只是得到了一堆乱码。
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;
}
定期,captureOutput
里面我需要调用此代码:
#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
这工作得很好,问题是,我现在要做的拍摄静止图像后,同样的事情通过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应用程序中消耗了很多性能,所以这可能会加起来。此外,您可以考虑使用单个范围的调度队列,并将访问单个资源(如上下文)的所有操作分派到该队列中。这是一种保证安全访问此共享资源的无锁方法,并且一直是我最近的首选方法。 –