2012-02-03 30 views
3

我試圖修改Apple的GLCameraRipple示例應用程序以在後臺線程上處理視頻幀。在這個例子中,它處理使用下面的代碼在主線程的每個幀:如何修改GLCameraRipple示例以在後臺線程上處理?

// Set dispatch to be on the main thread so OpenGL can do things with the data 
[dataOutput setSampleBufferDelegate:self queue:dispatch_get_main_queue()]; 

如果我改變了代碼在後臺線程來處理:

dispatch_queue_t videoQueue = dispatch_queue_create("com.test.queue", NULL); 
[dataOutput setSampleBufferDelegate:self queue:videoQueue]; 

然後程序崩潰。

當我嘗試創建第二個EAGLContext與蘋果的文檔中指定的共享,然後我只看到一個綠色或黑色的屏幕。

如何修改此示例應用程序以在後臺線程上運行?

+0

當你的應用程序崩潰時,你得到的錯誤是什麼? – 2012-02-03 14:59:40

+0

圖像通過什麼方式進入屏幕?你是否遵循了規則(即,之前刷新,傳遞,刷新),以便在同一共享組中的不同上下文之間傳遞已命名的GL資源? – Tommy 2012-02-03 16:58:28

回答

2

這實際上是相當有趣的,我修了樣品後。這裏的問題是CVOpenGLESTextureCacheCreateTextureFromImage()函數。如果你看一下控制檯,當你得到綠色的質地,你會看到類似下面的被記錄:在

CVOpenGLESTextureCacheCreateTextureFromImage -6661

-6661

錯誤,根據頭文件(即只有當前我可以找到有關這些新功能的文檔),是一個kCVReturnInvalidArgument錯誤。這個函數的其中一個參數顯然是錯誤的。原來這是CVImageBufferRef這是問題。它看起來像是正在解除分配或以其他方式更改,而處理此紋理高速緩存更新的塊正在發生。

我嘗試了一些方法來解決這個問題,並最終使用了一個調度隊列和調度信號,就像我在this answer中描述的那樣,委託仍然在主線程上回調,並且在委託內執行如下操作:

- (void)captureOutput:(AVCaptureOutput *)captureOutput 
didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer 
     fromConnection:(AVCaptureConnection *)connection 
{ 
    if (dispatch_semaphore_wait(frameRenderingSemaphore, DISPATCH_TIME_NOW) != 0) 
    { 
     return; 
    } 

    CVImageBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); 
    CVPixelBufferLockBaseAddress(pixelBuffer, 0); 
    CFRetain(pixelBuffer); 

    dispatch_async(openGLESContextQueue, ^{ 
     [EAGLContext setCurrentContext:_context]; 

     // Rest of your processing 

     CVPixelBufferUnlockBaseAddress(pixelBuffer, 0); 
     CFRelease(pixelBuffer); 

     dispatch_semaphore_signal(frameRenderingSemaphore); 
    }); 
} 

通過在主線程創建CVImageBufferRef,鎖定它指向的字節,並保留它,然後交給受異步塊,這似乎是解決這個問題的錯誤。顯示此修改的完整項目可從here下載。

我應該在這裏說一件事:這似乎沒有給你帶來任何好處。如果您查看GLCameraRipple示例的設置方式,應用程序中最重的操作(即連續波紋效果的計算)已被分派到後臺隊列。這也是使用新的快速上傳路徑向OpenGL ES提供攝像機數據,所以在主線程上運行時這不是瓶頸。

在我的儀器上分析了雙核iPhone 4S,我發現在這個示例應用程序的股票版本和我在後臺隊列上運行幀上傳的修改版本之間,渲染速度或CPU使用率沒有顯着差異。不過,這是一個有趣的問題來診斷。

+0

謝謝,布拉德。你是最棒的。 – dimaxyu 2012-02-08 10:39:21

+0

你好布拉德,我有一個關於這個解決方案的問題。如果我不僅要將相機用作opengl對象的紋理,而且要使用相同的樣本緩衝區來執行一些OpenCV操作,這種方法是否有用?你會推薦使用紋理嗎?理想情況下,我認爲使用OpenGL做一些圖像跟蹤將是最好的,但在着色器上進行編程超出了我的經驗。謝謝 – Pochi 2012-08-20 09:38:10

相關問題