CVOpenGLESTextureCacheCreateTextureFromImage возвращает ошибку 6683

В настоящее время я пытаюсь нарисовать изображение в openGL, используя формат YUV420 (двухплоскостной). Я получаю необработанные данные и пытаюсь проанализировать их в CVPixelBuffer, а затем передать указанный буфер с помощью CVOpenGLESTextureCacheCreateTextureFromImage. Хотя я не получаю ошибок при разборе в CVPixelBuffer, я получаю ошибку (-6683) при попытке перейти в CVOpenGLESTextureCacheCreateTextureFromImage. Я стараюсь изо всех сил следовать примеру кода GLCameraRipple от Apple - за исключением того, что опять же я использую необработанные данные изображения вместо данных с камеры.

Надеюсь, кто-то может объяснить, что мне здесь не хватает - я предполагаю, что это недостающий атрибут ...

К вашему сведению, плоскость 0 - это плоскость Y, а плоскость 1 - это плоскость UV, где плоскость UV должна составлять половину ширины и высоты плоскости Y.

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);
}

Спасибо всем, кто может предложить помощь. И хотя я знаю, что существует похожая проблема (не совсем та же), эта проблема также довольно старая и никогда не получала никаких ответов. Я надеюсь, что мне повезет больше.

7 голосов | спросил Doc 28 thEurope/Moscowp30Europe/Moscow09bEurope/MoscowFri, 28 Sep 2012 23:35:46 +0400 2012, 23:35:46

3 ответа


0

Свойство iosurface равно нулю в созданном вами CVPixelBuffer.

Создано вручную:

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

Создано CMSampleBufferGetImageBuffer:

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

Насколько мне известно, нет решения.

ответил junglecat 1 +04002012-10-01T10:40:24+04:00312012bEurope/MoscowMon, 01 Oct 2012 10:40:24 +0400 2012, 10:40:24
0

Используйте CVPixelBufferCreate, если собираетесь использовать CVPixelBufferRef с OpenGL. Он создает iosurface для вас, в отличие от альтернатив WithBytes. Недостатком является то, что вы не можете повторно использовать существующие буферы. Вам нужно будет скопировать данные из существующих буферов во вновь распределенные буферы.

// 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);
ответил Anton 25 Jam1000000amFri, 25 Jan 2013 05:49:29 +040013 2013, 05:49:29
0

Я не пробую следующий подход на YUV, но он работает в случае RGB

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

добавьте __bridge перед CFDictionaryRef, если ARC включен.

ответил willSapgreen 25 FebruaryEurope/MoscowbWed, 25 Feb 2015 09:44:37 +0300000000amWed, 25 Feb 2015 09:44:37 +030015 2015, 09:44:37

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132