2012-04-09 95 views
1

我試圖提取從攝像機接收像素緩衝區的YUV數據,然後重新創建一個像素緩衝區,但我在CVOpenGLESTextureCacheCreateTextureFromImage得到-6683,文檔只是說,約CVOpenGLESTextureCacheCreateTextureFromImage問題

The pixel buffer is not compatible with OpenGL due to an unsupported buffer size, pixel format, or attribute.

哪些呢沒有太大的幫助。我該如何解決它?如下面的代碼:

- (void)Init 
{ 
    *****; 
    OSStatus err = CMBufferQueueCreate(kCFAllocatorDefault, 1, CMBufferQueueGetCallbacksForUnsortedSampleBuffers(), &previewBufferQueue); 

} 
- (void)captureOutput:(AVCaptureOutput *)captureOutput 
    didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer 
    fromConnection:(AVCaptureConnection *)connection 
{ 


    OSStatus err = CMBufferQueueEnqueue(previewBufferQueue, sampleBuffer); 
    if (!err) {   
    dispatch_async(dispatch_get_main_queue(), ^{ 
     CMSampleBufferRef sbuf = (CMSampleBufferRef)CMBufferQueueDequeueAndRetain(previewBufferQueue); 
     if (sbuf) { 
      CVImageBufferRef pixBuf = CMSampleBufferGetImageBuffer(sbuf); 
      [self.delegate displayPixelBuffer:pixBuf]; 
      CFRelease(sbuf); 
     } 
    }); 
    } 
} 

的displayPixelBuffer方法:

-(void)displayPixelBuffer:(CVImageBufferRef)pixelBuffer 
{ 
    CVPixelBufferLockBaseAddress(pixelBuffer, 0); 
    size_t planeWidth[2] = {CVPixelBufferGetWidthOfPlane(pixelBuffer, 0), width}; 
    size_t planeHeight[2] = {CVPixelBufferGetHeightOfPlane(pixelBuffer, 0), 
    CVPixelBufferGetHeightOfPlane(pixelBuffer, 1)}; 
    size_t planeBytesPerRow[2] = {CVPixelBufferGetBytesPerRowOfPlane(pixelBuffer, 0), width/2}; 

    unsigned char *YUV2[2] = {0}; 
    YUV2[0] = CVPixelBufferGetBaseAddressOfPlane(pixelBuffer, 0); 
    YUV2[1] = CVPixelBufferGetBaseAddressOfPlane(pixelBuffer, 1); 

    CVReturn renturn = CVPixelBufferCreateWithPlanarBytes(kCFAllocatorDefault, 
                 width, 
                 height, 
                 kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange, 
                 0, 
                 0, 
                 2, 
                 (void *)YUV2, 
                 planeWidth, 
                 planeHeight, 
                 planeBytesPerRow, 
                 nil, 
                 nil, nil, &imageBuffer); 


    glActiveTexture(GL_TEXTURE0); 
    CVOpenGLESTextureRef texture = NULL; 
    CVReturn err = CVOpenGLESTextureCacheCreateTextureFromImage(kCFAllocatorDefault, 
                  videoTextureCache, 
                  imageBuffer, 
                  NULL, 
                  GL_TEXTURE_2D, 
                  GL_LUMINANCE, 
                  width, 
                  height, 
                  GL_LUMINANCE, 
                  GL_UNSIGNED_BYTE, 
                  0, 
                  &texture); 

    if (!texture || err) { 
     NSLog(@"CVOpenGLESTextureCacheCreateTextureFromImage failed (error: %d)", err); 
     return; 
    } 
    glBindTexture(CVOpenGLESTextureGetTarget(texture), 0); 

    // Flush the CVOpenGLESTexture cache and release the texture 
    CVOpenGLESTextureCacheFlush(videoTextureCache, 0); 
    CVPixelBufferUnlockBaseAddress(pixelBuffer, 0); 
    CFRelease(texture); 

} 

結果CVOpenGLESTextureCacheCreateTextureFromImage失敗(錯誤:-6683),爲什麼呢?

+0

薩姆您好,我被卡住用相同的錯誤消息。你有沒有發現什麼是錯的?謝謝! – 2012-06-01 15:56:33

+1

同樣在這裏。如果你可以更新會很好。 – BlueVoodoo 2012-10-07 14:50:59

回答

1

我相信CVPixelBuffer需要成爲一個ioSurfaceBacked。

+0

確實:https://developer.apple.com/library/ios/qa/qa1781/_index.html – Tommy 2015-08-25 03:24:42

0

您從圖像緩衝區中錯誤地獲取了用於創建紋理的屬性值。這是它的方式

done: 

- (void)displayPixelBuffer:(CVPixelBufferRef)pixelBuffer 
{ 
    CVReturn err; 
    if (pixelBuffer != NULL) { 
     int frameWidth = (int)CVPixelBufferGetWidth(pixelBuffer); 
     int frameHeight = (int)CVPixelBufferGetHeight(pixelBuffer); 



     /* 
     CVOpenGLESTextureCacheCreateTextureFromImage will create GLES texture optimally from CVPixelBufferRef. 
     */ 

     /* 
     Create Y and UV textures from the pixel buffer. These textures will be drawn on the frame buffer Y-plane. 
     */ 
     glActiveTexture(GL_TEXTURE0); 
     err = CVOpenGLESTextureCacheCreateTextureFromImage(kCFAllocatorDefault, 
                  _videoTextureCache, 
                  pixelBuffer, 
                  NULL, 
                  GL_TEXTURE_2D, 
                  GL_RED_EXT, 
                  frameWidth, 
                  frameHeight, 
                  GL_RED_EXT, 
                  GL_UNSIGNED_BYTE, 
                  0, 
                  &_lumaTexture); 
     if (err) { 
      NSLog(@"Error at CVOpenGLESTextureCacheCreateTextureFromImage %d", err); 
     } 

     glBindTexture(CVOpenGLESTextureGetTarget(_lumaTexture), CVOpenGLESTextureGetName(_lumaTexture)); 
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 
     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 

     // UV-plane. 
     glActiveTexture(GL_TEXTURE1); 
     err = CVOpenGLESTextureCacheCreateTextureFromImage(kCFAllocatorDefault, 
                  _videoTextureCache, 
                  pixelBuffer, 
                  NULL, 
                  GL_TEXTURE_2D, 
                  GL_RG_EXT, 
                  frameWidth/2, 
                  frameHeight/2, 
                  GL_RG_EXT, 
                  GL_UNSIGNED_BYTE, 
                  1, 
                  &_chromaTexture); 
     if (err) { 
      NSLog(@"Error at CVOpenGLESTextureCacheCreateTextureFromImage %d", err); 
     } 

     glBindTexture(CVOpenGLESTextureGetTarget(_chromaTexture), CVOpenGLESTextureGetName(_chromaTexture)); 
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 
     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 

     glBindFramebuffer(GL_FRAMEBUFFER, _frameBufferHandle); 

    } 

這是從ADC站點上的AVBasicVideoOutput/APLEAGLView.m複製的。這是我使用的,以及公開發布他們的代碼的其他人(實際上是這樣)。如果有一千種方法可以做到這一點,我已經嘗試了所有的方法。這是方式。

注意|這是OpenGL 2.0;如果你對3.0已經準備好,我有AVBasicVideoOutput對我的博客的升級版:

http://demonicactivity.blogspot.com/2016/02/technology-apples-opengl-related-sample.html?m=1