【问题标题】:what is the relation between CVBuffer and CVImageBufferCVBuffer 和 CVImageBuffer 的关系是什么
【发布时间】:2016-04-21 19:28:45
【问题描述】:

如果您从苹果查看此文档

https://developer.apple.com/library/tvos/documentation/QuartzCore/Reference/CVBufferRef/index.html#//apple_ref/c/tdef/CVBufferRef

在第二行中,它说:“一个 CVBuffer 对象可以保存视频、音频或其他类型的数据。您可以在任何核心视频缓冲区上使用 CVBuffer 编程接口。”这意味着它也可以保存图像。如果是,那为什么我们有 CVImageBuffer。

我刚刚完成了一些使用 AVAssetImageGenerator 从视频生成图像的工作。现在我想合并帧以制作视频。所以,我刚刚开始阅读此内容。

我目前的状态:
1.现在我知道我需要使用 AVAssetWriter。
2.然后我需要使用 AVAssetWriterInput 为其提供输入。
3.我需要使用一些CV和CG类。

如果我们有 CVBuffer,请帮助我了解使用 CVImageBuffer 的原因。我知道 CVBuffer 是抽象的,但 CVImageBuffer 不是从 CVBuffer 继承的。这让我更加困惑。

【问题讨论】:

    标签: ios core-video


    【解决方案1】:

    CVImageBuffer 确实继承自CVBuffer,但仅以“c 中的模拟面向对象”方式。也就是说,如果您知道 CVBuffer 的类型是某个子类的类型,那么您可以安全地转换为该类型,例如:

    if (CFGetTypeID(myCVBuffer) == CVMetalTextureGetTypeID()) {
        CVMetalTextureRef metalBuffer = myCVBuffer;
        // do something with metalBuffer
    }
    

    事实上,你甚至不需要强制转换(即使在 swift 中也不需要!),因为 CVBuffer 类型都是相同的(typealiases 在 swift 中):

    typedef CVBufferRef CVImageBufferRef;
    typedef CVImageBufferRef CVPixelBufferRef;
    typedef CVImageBufferRef CVMetalTextureRef;
    // ...
    

    您注意到CVBuffer 是一个抽象基类,但您可能错过了CVImageBuffer 也是抽象的:它添加了一些涉及图像尺寸和颜色空间的函数,并定义了用于访问特定图像的图像附件键元数据。

    我假设您的图片是 CGImages,因为您使用的是 AVAssetImageGenerator。此时你有两个选择。您可以转换 CGImage -> CVPixelBuffer 并将其直接附加到您添加到 AVAssetWriterInputAVAssetWriterInputPixelBufferAdaptor。或者您可以使用CMSampleBufferCreateReadyWithImageBuffer 从上面创建的CVPixelBuffer 创建一个CMSampleBuffer,并将其直接附加到您的AVAssetWriterInput

    Some people prefer the pixel buffer adaptor approach,但老实说,上述两种方法都令人生畏并且效率低下(例如,我认为您不能在不复制 CGImage 像素的情况下创建 CVPixelBuffer),所以为什么不转储AVAssetImageGenerator 及其不受欢​​迎的CGImages 并直接使用AVAssetReader + AVAssetReaderOutput?它将出售CMSampleBuffers,您可以在不转换*的情况下将其附加到您的作家输入中,您将有更好的机会不讨厌自己的生活。

    * 实际上您可能需要更改样本缓冲区的呈现时间戳,仍然非常简单:CMSampleBufferCreateCopyWithNewTiming

    【讨论】:

    • 谢谢,但是这种“用 c 模拟面向对象”的方式是什么意思?您能详细说明一下吗?
    • CoreVideo 是一个 C API,C 没有继承作为语言特性。但是,您可以通过警告来模拟它(证明/有趣的事实:c++,它确实具有继承,用于编译为 C - 直到异常让人们放弃)。以下是在 C 中模拟继承的一种方法示例:codeproject.com/Articles/108830/…
    • 这能回答你的问题吗?
    猜你喜欢
    • 2014-03-14
    • 2013-06-14
    • 2018-02-16
    • 2020-05-04
    • 2020-01-08
    • 2015-01-13
    • 2017-11-06
    • 2015-07-09
    相关资源
    最近更新 更多