7

現在、YUV420形式(バイプラナー)を使用してopenGLで画像を描画しようとしています。生データを受け取り、それをCVPixelBufferに解析しようとしています。次に、CVOpenGLESTextureCacheCreateTextureFromImageを使用してそのバッファーを渡します。CVPixelBufferに解析するときにエラーは発生しませんが、CVOpenGLESTextureCacheCreateTextureFromImageに渡そうとするとエラー(-6683)が発生します。私はアップルのGLCameraRippleサンプルコードに従うように最善を尽くしています-ここでも、カメラからのデータの代わりに生の画像データを使用しています。

うまくいけば、誰かが私がここで欠落していることが何であるかを説明することができます-私はそれが欠落している属性であると思います...

参考までに、平面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);
}

支援を提供できる人に感謝します。同様の問題があることは承知していますが(まったく同じではありません)、この問題も非常に古く、応答がありません。私は自分の状況にもっと幸運を祈っています。

4

3 に答える 3

4

作成したCVPixelBufferのiosurfaceプロパティはnullです。

手動で作成:

<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>

私の知る限り、解決策はありません。

于 2012-10-01T06:40:24.333 に答える
1

OpenGLでを使用するCVPixelBufferCreate場合に使用します。CVPixelBufferRef代替案とは異なり、それはあなたのために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);
于 2013-01-25T01:49:29.490 に答える
0

私はYUVで次のアプローチを試しませんが、RGBの場合は機能します

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

ARCが有効になっている場合は、CFDictionaryRefの前に__bridgeを追加します。

于 2015-02-25T06:44:37.887 に答える