跨线程共享帧缓冲区

时间:2011-11-24 09:33:54

标签: iphone opengl-es

我有一个视频应用,可以在预览运行时同时进行实时预览和静态图像捕捉。我正在使用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 */
     }

这似乎是上下文和线程的问题。

1 个答案:

答案 0 :(得分:1)

我找到了答案。您需要确保@synchronized块在两种方法中。这花了我很长时间才找到,因为我的着色器发生了一些非常奇怪的事情。当XCode认为它们都是大写的时,其中一个文件名在磁盘上是小写的。这使得着色器在实时预览中工作,但在静止图像捕获部分中给了我一个白色屏幕。不知道为什么。

相关问题