创建一个RGB的CVPixelBufferRef

iOS的编码器仅仅支持CVPixelBufferRef的输入,常规的做法是从编码器Session的PixelBufferPool拿到一个CVPixelBufferRef,不过它的格式NV12(kCVPixelFormatType_420YpCbCr8BiPlanarFullRange或者kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange)这两种形式。我们的业务场景是可以直接拿到OpenGLES的Texture的,如果采用这种方案那么我需要在shader中把RGB转为NV12。所以这个不是最优的方案,最优的方案应该是直接创建一个RGB的CVPixelBufferRef然后再把OpenGLES的Texture画上去。我是参考GPUImage的做法,不过它也是参考这里,在GPUImage的代码中有说明。

The H.264 encoder natively supports kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange and 
kCVPixelFormatType_420YpCbCr8BiPlanarFullRange, which should be used with video and full range 
input respectively. The JPEG encoder on iOS natively supports 
kCVPixelFormatType_422YpCbCr8FullRange. For other video codecs on OSX, 
kCVPixelFormatType_422YpCbCr8 is the preferred pixel format for video and is generally the most 
performant when encoding. If you need to work in the RGB domain then kCVPixelFormatType_32BGRA is 
recommended on iOS and kCVPixelFormatType_32ARGB is recommended on OSX.
  • 创建CVPixelBufferRef
    仅仅支持创建kCVPixelFormatType_32BGRA这种格式的CVPixelBufferRef,其他的格式都会失败。
CVPixelBufferRef CreatePixelBuffer(size_t width, size_t height)
{
    CVPixelBufferRef pixel_buffer;
    CFDictionaryRef empty; // empty value for attr value.
    CFMutableDictionaryRef attrs;
    // our empty IOSurface properties dictionary
    empty = CFDictionaryCreate(kCFAllocatorDefault, nullptr, nullptr, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
    attrs = CFDictionaryCreateMutable(kCFAllocatorDefault, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
    CFDictionarySetValue(attrs, kCVPixelBufferIOSurfacePropertiesKey, empty);

    CVReturn err = CVPixelBufferCreate(kCFAllocatorDefault, width, height, kCVPixelFormatType_32BGRA, attrs, &pixel_buffer);
    if (err) {
        LOG(LS_ERROR) << "FBO size " << width << "x" << height << ", Error at CVPixelBufferCreate " << err;
    }
    CFRelease(attrs);
    CFRelease(empty);
    return pixel_buffer;
}
  • 获取OpenGLES的Texture ID
    CVPixelBufferRef的格式是GL_BGRA,我们需要的OpenGLES的格式是GL_RGBA
CVPixelBufferRef pixel_buffer = CreatePixelBuffer(width, height);
RTC_CHECK(pixel_buffer);

CVOpenGLESTextureRef gles_texture_ref;
CVReturn err = CVOpenGLESTextureCacheCreateTextureFromImage(kCFAllocatorDefault, texture_cache, pixel_buffer, nullptr,
        GL_TEXTURE_2D, GL_RGBA/*gles format*/, width, height, GL_BGRA/*pixbuffer format*/, GL_UNSIGNED_BYTE, 0, &gles_texture_ref);
if (err) {
    LOG(LS_ERROR) << "CVOpenGLESTextureCacheCreateTextureFromImage error: " << err;
    framebuffer_pool->ReturnFrameBuffer(tex);
    CVPixelBufferRelease(pixel_buffer);
    pixel_buffer = nullptr;
    gles_texture_ref = nil;
    return;
}

RTC_CHECK(CVOpenGLESTextureGetTarget(gles_texture_ref) == GL_TEXTURE_2D) << "Unexpected GLES texture target";
uint32_t texture_id = CVOpenGLESTextureGetName(gles_texture_ref);
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值