CVOpenGLESTextureCacheCreateTextureFromImage returns error 6683

I'm currently trying to make an image in openGL using the YUV420 (biplanar) format. I get raw data and try to parse it into CVPixelBuffer and then pass the specified buffer using CVOpenGLESTextureCacheCreateTextureFromImage. Although I don't get parsing errors in CVPixelBuffer, I get an error (-6683) when I try to pass to CVOpenGLESTextureCacheCreateTextureFromImage. I try to follow the Apple GLCameraRipple code example - in addition, I use raw image data instead of camera data.

I hope someone can explain what it is that I don’t see here - I assume this is a missing attribute ...

FYI, plane 0 is the Y plane, and plane 1 is the UV plane β€” where the UV plane should be half the width and height of the Y plane.

size_t numPlanes = image->GetNumPlanes(); size_t planeWidth[numPlanes]; size_t planeHeight[numPlanes]; size_t scanWidth[numPlanes]; void *planeIndex[numPlanes]; for(int i = 0; i<numPlanes; i++){ i<1 ? planeWidth[i] = image->GetWidth() : planeWidth[i] = image->GetWidth()/2; i<1 ? planeHeight[i] = image->GetHeight() : planeWidth[i] = image->GetHeight()/2; scanWidth[i] = image->GetScanWidth(i); planeIndex[i] = image->GetPlanePointer(i); } CVPixelBufferRef pixelBuffer; CFDictionaryRef empty; CFMutableDictionaryRef attrs; empty = CFDictionaryCreate(kCFAllocatorDefault, NULL, NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); attrs = CFDictionaryCreateMutable(kCFAllocatorDefault, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFDictionarySetValue(attrs, kCVPixelBufferIOSurfacePropertiesKey, empty); CVReturn cvError = CVPixelBufferCreateWithPlanarBytes(kCFAllocatorDefault, image->GetWidth(), image->GetHeight(), kCVPixelFormatType_420YpCbCr8BiPlanarFullRange, nil, nil, numPlanes, planeIndex, planeWidth, planeHeight, scanWidth, nil, nil, attrs, &pixelBuffer); if(cvError) NSLog(@"Error at CVPixelBufferCreateWithPlanarBytes: %d", cvError); CVReturn err; size_t width = CVPixelBufferGetWidth(pixelBuffer); size_t height = CVPixelBufferGetHeight(pixelBuffer); if (!_videoTextureCache) { NSLog(@"No video texture cache"); return; } if (_bModel == nil || width != _textureWidth || height != _textureHeight) { _textureWidth = width; _textureHeight = height; _bModel = [[BufferModel alloc] initWithScreenWidth:_screenWidth screenHeight:_screenHeight meshFactor:_meshFactor textureWidth:_textureWidth textureHeight:_textureHeight]; [self setupBuffers]; } [self cleanUpTextures]; // CVOpenGLESTextureCacheCreateTextureFromImage will create GLES texture // optimally from CVImageBufferRef. // Y-plane glActiveTexture(GL_TEXTURE0); err = CVOpenGLESTextureCacheCreateTextureFromImage(kCFAllocatorDefault, _videoTextureCache, pixelBuffer, NULL, GL_TEXTURE_2D, GL_RED_EXT, _textureWidth, _textureHeight, GL_RED_EXT, GL_UNSIGNED_BYTE, 0, &_lumaTexture); if (err) { NSLog(@"Error at CVOpenGLESTextureCacheCreateTextureFromImage %d", err); } 

Thanks to everyone who can help. And although I know that the problem is similar (not quite the same), this problem is also quite old and never received any answers. I hope for greater happiness for my situation.

+6
source share
3 answers

The iosurface property is null in the generated CVPixelBuffer.

Created manually:

<CVPixelBuffer 0x1fd52790 width=1280 height=720 pixelFormat=420v iosurface=0x0 planes=2>

Created by CMSampleBufferGetImageBuffer:

<CVPixelBuffer 0x1fd521e0 width=1280 height=720 pixelFormat=420f iosurface=0x21621c54 planes=2>

As far as I know, there is no solution.

+4
source

Use CVPixelBufferCreate if you intend to use CVPixelBufferRef with OpenGL. This creates an iosurface for you, as opposed to WithBytes alternatives. The disadvantage is that you cannot reuse existing buffers. You will have to copy data from existing buffers to the new allocated buffers.

 // set pixel buffer attributes so we get an iosurface NSDictionary *pixelBufferAttributes = [NSDictionary dictionaryWithObjectsAndKeys: [NSDictionary dictionary], kCVPixelBufferIOSurfacePropertiesKey, nil]; // create planar pixel buffer CVPixelBufferRef pixelBuffer = nil; CVPixelBufferCreate(kCFAllocatorDefault, bufferYUV.width, bufferYUV.height, kCVPixelFormatType_420YpCbCr8BiPlanarFullRange, (CFDictionaryRef)pixelBufferAttributes, &pixelBuffer); // lock pixel buffer CVPixelBufferLockBaseAddress(pixelBuffer, 0); // get image details size_t width = CVPixelBufferGetWidth(pixelBuffer); size_t height = CVPixelBufferGetHeight(pixelBuffer); // get plane addresses unsigned char *baseAddressY = CVPixelBufferGetBaseAddressOfPlane(pixelBuffer, 0); unsigned char *baseAddressUV = CVPixelBufferGetBaseAddressOfPlane(pixelBuffer, 1); //TODO: copy your data buffers to the newly allocated memory locations // unlock pixel buffer address CVPixelBufferUnlockBaseAddress(pixelBuffer, 0); // intialize buffers if not already initialized (see GLCameraRipple example) if (!_buffersInitialized) { [self initializeBuffersWithTextureWidth:width textureHeight:height]; } // always clean up last textures CVReturn err; [self cleanUpTextures]; // Y-plane glActiveTexture(GL_TEXTURE0); err = CVOpenGLESTextureCacheCreateTextureFromImage(kCFAllocatorDefault, _videoTextureCache, pixelBuffer, NULL, GL_TEXTURE_2D, GL_RED_EXT, width, height, GL_RED_EXT, GL_UNSIGNED_BYTE, 0, &_lumaTexture); if (err) { NSLog(@"Could not create Y texture from image. %d", err); } glBindTexture(CVOpenGLESTextureGetTarget(_lumaTexture), CVOpenGLESTextureGetName(_lumaTexture)); 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, width / 2, height / 2, GL_RG_EXT, GL_UNSIGNED_BYTE, 1, &_chromaTexture); if (err) { NSLog(@"Could not create UV texture from image. %d", err); } glBindTexture(CVOpenGLESTextureGetTarget(_chromaTexture), CVOpenGLESTextureGetName(_chromaTexture)); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 
+1
source

I do not try the following approach to YUV, but it works on the case of RGB

https://developer.apple.com/library/ios/qa/qa1781/_index.html

add __bridge before CFDictionaryRef if ARC is enabled.

0
source

Source: https://habr.com/ru/post/926544/


All Articles