【问题标题】:CVPixelBufferRef as a GPU TextureCVPixelBufferRef 作为 GPU 纹理
【发布时间】:2014-06-13 06:57:35
【问题描述】:

我有一个(或可能两个)我正在 CPU 上处理的 CVPixelBufferRef 对象,然后将结果放到最终的 CVPixelBufferRef 上。我想使用 GLSL 在 GPU 上进行此处理,因为 CPU 几乎无法跟上(这些是实时视频帧)。我知道这是可能的“直接”(即编写我自己的开放式 gl 代码),但是从(绝对难以理解的)示例代码中,我看到这是一个疯狂的工作量。

两个选项似乎是:

1) GPUImage:这是一个很棒的库,但我有点不清楚我是否可以轻松地做我想做的事。我尝试的第一件事是使用以下代码请求与 OpenGLES 兼容的像素缓冲区:

@{ (NSString *)kCVPixelBufferPixelFormatTypeKey : [NSNumber numberWithUnsignedInt:kCVPixelFormatType_32BGRA],
          (NSString*)kCVPixelBufferOpenGLESCompatibilityKey : [NSNumber numberWithBool:YES]};

然后将数据从 CVPixelBufferRef 传输到 GPUImageRawDataInput 如下:

// setup:
_foreground = [[GPUImageRawDataInput alloc] initWithBytes:nil size:CGSizeMake(0,0)pixelFormat:GPUPixelFormatBGRA type:GPUPixelTypeUByte];

// call for each frame:
[_foreground updateDataFromBytes:CVPixelBufferGetBaseAddress(foregroundPixelBuffer)
                            size:CGSizeMake(CVPixelBufferGetWidth(foregroundPixelBuffer), CVPixelBufferGetHeight(foregroundPixelBuffer))];

但是,我的 CPU 使用率在 iPhone 5S 上从 7% 上升到 27%,仅使用那条线(没有处理或任何东西)。这表明 CPU 上正在进行一些复制,或者有其他问题。我错过了什么吗?

2) OpenFrameworks:OF 通常用于这种类型的事情,并且 OF 项目可以很容易地设置为使用 GLSL。然而,关于这个解决方案还有两个问题:1. 我可以使用 openframeworks 作为库,还是我必须重新调整我的整个应用程序才能使用 OpenGL 功能?我没有看到任何教程或文档显示我如何在不从头开始并创建 OF 应用程序的情况下做到这一点。 2. 是否可以使用 CVPixelBufferRef 作为纹理。

我的目标是 iOS 7+。

【问题讨论】:

    标签: ios avfoundation gpu gpuimage openframeworks


    【解决方案1】:

    我能够使用GPUImageMovie 类来实现它。如果你查看这个类,你会看到有一个 private method 叫做:

    - (void)processMovieFrame:(CVPixelBufferRef)movieFrame withSampleTime:(CMTime)currentSampleTime
    

    此方法将CVPixelBufferRef 作为输入。

    要访问此方法,请声明一个在您的类中公开它的类扩展

    @interface GPUImageMovie ()
    -(void) processMovieFrame:(CVPixelBufferRef)movieFrame withSampleTime:(CMTime)currentSampleTime;
    @end
    

    然后初始化类,设置过滤器,并将视频帧传递给它:

    GPUImageMovie *gpuMovie = [[GPUImageMovie alloc] initWithAsset:nil];      // <- call initWithAsset even though there's no asset
                                                                              //  to initialize internal data structures
    
    // connect filters...
    
    // Call the method we exposed
    [gpuMovie processMovieFrame:myCVPixelBufferRef withSampleTime:kCMTimeZero];
    

    有一件事:您需要使用kCVPixelFormatType_420YpCbCr8BiPlanarFullRange 请求您的像素缓冲区,以匹配library expects 的内容。

    【讨论】:

    • 我在一年前发布了这个问题,不记得细节了。我将继续并将您的答案标记为正确,因为您似乎已经让它起作用了!
    猜你喜欢
    • 2013-05-18
    • 2015-01-13
    • 1970-01-01
    • 1970-01-01
    • 2013-04-18
    • 2010-09-30
    • 2014-05-31
    • 2012-07-29
    • 1970-01-01
    相关资源
    最近更新 更多