【问题标题】:CVMetalTextureCacheCreateTextureFromImage always return nullCVMetalTextureCacheCreateTextureFromImage 总是返回 null
【发布时间】:2016-11-02 09:04:29
【问题描述】:

我正在尝试通过 MetalKit 渲染 I420(YCbCr 规划器)

大多数示例都使用来自 Camera 的 CMSampleBuffer,

但我的目标是使用给定的 I420 字节。

我会这样做:

let data = NSMutableData(contentsOfURL: NSBundle.mainBundle().URLForResource("yuv_640_360", withExtension: "yuv")!)

// Cache for Y

CVMetalTextureCacheCreate(kCFAllocatorDefault, nil, self.device!, nil, &videoTextureCache)

var pixelBuffer: CVPixelBuffer?

CVPixelBufferCreateWithBytes(kCFAllocatorDefault, Int(size.width), Int(size.height), kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange, data.mutableBytes, Int(size.width), nil, nil, [
    "kCVPixelBufferMetalCompatibilityKey": true,
    "kCVPixelBufferOpenGLCompatibilityKey": true,
    "kCVPixelBufferIOSurfacePropertiesKey": []
    ]
    , &pixelBuffer)

// Y texture

var yTextureRef : Unmanaged<CVMetalTexture>?

let yWidth = CVPixelBufferGetWidthOfPlane(pixelBuffer, 0)

let yHeight = CVPixelBufferGetHeightOfPlane(pixelBuffer, 0)

let result = CVMetalTextureCacheCreateTextureFromImage(kCFAllocatorDefault, (videoTextureCache?.takeUnretainedValue())!, pixelBuffer, nil, MTLPixelFormat.R8Unorm, yWidth, yHeight, 0, &yTextureRef);

基本上代码与其他示例几乎相同,但我自己创建了自己的 CVPixelBuffer。

我在创建 CVPixelBuffer 和 CVMetalTexture 时没有出错,

但它总是为 yTexture 返回 null。

如何创建正确的 CVPixelBuffer 并使用它进行渲染?

【问题讨论】:

    标签: ios metal core-video cvpixelbuffer metalkit


    【解决方案1】:

    问题解决了。

    iosurface 很重要,如果您通过 CVPixelBufferCreateWithBytes 或 CVPixelBufferCreateWithPlanarBytes 创建 CVPixelBuffer,我发现 iosurface 始终为 null。

    一旦你使用了 iosurface 为 null 的 CVPixelBuffer,那么 MetalTexture 总是为 null。

    应该这样做:

    let result = CVPixelBufferCreate(kCFAllocatorDefault, width, height, kCVPixelFormatType_420YpCbCr8Planar, [
        String(kCVPixelBufferIOSurfacePropertiesKey): [
            "IOSurfaceOpenGLESFBOCompatibility": true,
            "IOSurfaceOpenGLESTextureCompatibility": true,
            "IOSurfaceCoreAnimationCompatibility": true,
            ]
        ], &self.pixelBuffer)
    
    CVPixelBufferLockBaseAddress(self.pixelBuffer!, 0)
    
    for index in 0...2 {
    
        memcpy(CVPixelBufferGetBaseAddressOfPlane(self.pixelBuffer!, index), planesAddress[index], planesWidth[index] * planesHeight[index])
    
    }
    
    CVPixelBufferUnlockBaseAddress(self.pixelBuffer!, 0)
    

    【讨论】:

    • 你在那里救了我。谢谢!
    • 看起来像 kCVPixelBufferMetalCompatibilityKey : true 也可以
    • 嗨,你能看看我的问题吗?这里:stackoverflow.com/questions/54792774/…
    • 你拯救了我的一天! CVMetalTextureCacheCreateTextureFromImage() 返回 osstatus: -6660 没有任何意义。然后用iosurface设置pixelbuffer:true,问题就解决了。
    猜你喜欢
    • 2014-03-04
    • 2014-05-06
    • 2012-06-05
    • 2014-05-30
    • 2014-02-23
    • 2017-10-12
    • 2013-08-16
    • 2016-03-28
    • 2020-09-03
    相关资源
    最近更新 更多