简体   繁体   English

CVMetalTextureCacheCreateTextureFromImage始终返回null

[英]CVMetalTextureCacheCreateTextureFromImage always return null

I'm trying to render I420 (YCbCr planner) via MetalKit 我正试图通过MetalKit渲染I420(YCbCr规划器)

most of examples are using the CMSampleBuffer which from Camera, 大多数例子都是使用来自Camera的CMSampleBuffer,

but my goal is using a given I420 bytes. 但我的目标是使用给定的I420字节。

I do something like this: 我做这样的事情:

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);

basically the code is almost same as other examples but I create my own CVPixelBuffer by myself. 基本上代码与其他示例几乎相同,但我自己创建自己的CVPixelBuffer。

I got no error when I creating CVPixelBuffer and CVMetalTexture, 我创建CVPixelBuffer和CVMetalTexture时没有出错,

but it always return null for yTexture. 但它总是为yTexture返回null。

How do I create the right CVPixelBuffer and use it to render ? 如何创建正确的CVPixelBuffer并使用它进行渲染?

problem solved. 问题解决了。

iosurface is important, I found iosurface always be null if you create CVPixelBuffer by CVPixelBufferCreateWithBytes or CVPixelBufferCreateWithPlanarBytes. iosurface很重要,如果你通过CVPixelBufferCreateWithBytes或CVPixelBufferCreateWithPlanarBytes创建CVPixelBuffer,我发现iosurface总是为null。

once you use a CVPixelBuffer which's iosurface is null, then MetalTexture always be null. 一旦你使用了iosurface为null的CVPixelBuffer,那么MetalTexture总是为空。

should do something like this: 应该做这样的事情:

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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM