4

私はopengl esを使用してiPadでbgr24データを表示します.opengl esについては初めてなので、ビデオの表示部分ではRosyWriterのAPPLEサンプルのコードを使用します. 動作しますが、CVOpenGLESTextureCacheCreateTextureFromImage 関数のコストは 30 ミリ秒を超えていますが、RosyWriter ではそのコストは無視できます。まず BGR24 を BGRA ピクセル形式に変換し、次に CVPixelBufferCreateWithBytes 関数を使用して CVPixelBufferRef を作成し、次に CVOpenGLESTextureCacheCreateTextureFromImage で CVOpenGLESTextureRef を取得します。次のような私のコード、

- (void)transformBGRToBGRA:(const UInt8 *)pict width:(int)width height:(int)height
{
rgb.data = (void *)pict;

vImage_Error error = vImageConvert_RGB888toARGB8888(&rgb,NULL,0,&argb,NO,kvImageNoFlags);
if (error != kvImageNoError) {
    NSLog(@"vImageConvert_RGB888toARGB8888 error");
}

const uint8_t permuteMap[4] = {1,2,3,0};

error = vImagePermuteChannels_ARGB8888(&argb,&bgra,permuteMap,kvImageNoFlags);
if (error != kvImageNoError) {
    NSLog(@"vImagePermuteChannels_ARGB8888 error");
}

free((void *)pict);
}

変換後、CVPixelBufferRef が生成され、次のコードが生成されます。

[self transformBGRToBGRA:pict width:width height:height];

CVPixelBufferRef pixelBuffer;
CVReturn err = CVPixelBufferCreateWithBytes(NULL,
                             width,
                             height,
                             kCVPixelFormatType_32BGRA, 
                             (void*)bgraData, 
                             bytesByRow, 
                             NULL, 
                             0,
                             NULL, 
                             &pixelBuffer);

if(!pixelBuffer || err)
{
    NSLog(@"CVPixelBufferCreateWithBytes failed (error: %d)", err);  
    return;
}

CVOpenGLESTextureRef texture = NULL;
err = CVOpenGLESTextureCacheCreateTextureFromImage(kCFAllocatorDefault, 
                                                            videoTextureCache,
                                                            pixelBuffer,
                                                            NULL,
                                                            GL_TEXTURE_2D,
                                                            GL_RGBA,
                                                            width,
                                                            height,
                                                            GL_BGRA,
                                                            GL_UNSIGNED_BYTE,
                                                            0,
                                                            &texture);


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

他のコードは RosyWriter のサンプルとほぼ同じで、シェーダーが含まれています。だから私は理由を知りたい、この問題を解決する方法。

4

1 に答える 1

5

最近の私の調査ではCVOpenGLESTextureCacheCreateTextureFromImage、データが大きい場合になぜ多くの時間がかかるのかがわかります。ここでは 3Mです。かなりのコストがかかる割り当て、コピー、および移動操作、特にコピー操作です。次に、ピクセル バッファー プールを使用すると、パフォーマンスが 30ms から 5ms に大幅に向上しますCVOpenGLESTextureCacheCreateTextureFromImage。これは、glTexImage2D() と同じレベルです。次のような私の解決策:

NSMutableDictionary*     attributes;
attributes = [NSMutableDictionary dictionary];


[attributes setObject:[NSNumber numberWithInt:kCVPixelFormatType_32BGRA] forKey:(NSString*)kCVPixelBufferPixelFormatTypeKey];
[attributes setObject:[NSNumber numberWithInt:videoWidth] forKey: (NSString*)kCVPixelBufferWidthKey];
[attributes setObject:[NSNumber numberWithInt:videoHeight] forKey: (NSString*)kCVPixelBufferHeightKey];

CVPixelBufferPoolCreate(kCFAllocatorDefault, NULL, (CFDictionaryRef) attributes, &bufferPool);

CVPixelBufferPoolCreatePixelBuffer (NULL,bufferPool,&pixelBuffer);

CVPixelBufferLockBaseAddress(pixelBuffer,0);

UInt8 * baseAddress = CVPixelBufferGetBaseAddress(pixelBuffer);

memcpy(baseAddress, bgraData, bytesByRow * videoHeight);

CVPixelBufferUnlockBaseAddress(pixelBuffer,0);

この新しく作成されたpixelBufferを使用すると、高速化できます。

次の構成を属性に追加すると、パフォーマンスが最高になり、1 ミリ秒未満になります。

 NSDictionary *IOSurfaceProperties = [NSDictionary dictionaryWithObjectsAndKeys:
                                                                        [NSNumber numberWithBool:YES], @"IOSurfaceOpenGLESFBOCompatibility",[NSNumber numberWithBool:YES], @"IOSurfaceOpenGLESTextureCompatibility",nil];

[attributes setObject:IOSurfaceProperties forKey:(NSString*)kCVPixelBufferIOSurfacePropertiesKey];
于 2012-07-30T05:32:04.423 に答える