繁体   English   中英

CVMetalTextureCacheCreateTextureFromImage 在 macOS 10.13 上返回 -6660

[英]CVMetalTextureCacheCreateTextureFromImage returns -6660 on macOS 10.13

我正在将屏幕从我的 iPhone 设备录制到我的 Mac。 作为预览层,我直接从AVCaptureVideoDataOutput收集样本缓冲区,从中我创建纹理并使用Metal渲染它们。 我遇到的问题是,在10.13之前在 macOS 中工作的代码在更新到10.13后停止工作。 即,

CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(_currentSampleBuffer);

if (!imageBuffer) return;

CVPixelBufferLockBaseAddress(imageBuffer,0);
size_t width = CVPixelBufferGetWidth(imageBuffer);
size_t height = CVPixelBufferGetHeight(imageBuffer);

CVMetalTextureRef metalTexture = NULL;
CVReturn result = CVMetalTextureCacheCreateTextureFromImage(nil,
                                                            self.textureCache,
                                                            imageBuffer,
                                                            nil,
                                                            self.pixelFormat,
                                                            width,
                                                            height,
                                                            0,
                                                            &metalTexture);

if (result == kCVReturnSuccess) {
    self.texture = CVMetalTextureGetTexture(metalTexture);
}

返回result = -6660 ,这可以转换为通用的kCVReturnError ,如Apple 官方文档中所示,以及metalTexture = NULL

我使用的像素格式是MTLPixelFormatBGRG422因为来自相机的样本是2vuy

作为从sampleBuffer创建metalTexture一种解决方法,我现在正在创建一个中间NSImage如下所示:

CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(_currentSampleBuffer);
NSCIImageRep *imageRep = [NSCIImageRep imageRepWithCIImage:[CIImage imageWithCVImageBuffer:imageBuffer]];
    
NSImage *image = [[NSImage alloc] initWithSize:[imageRep size]];
[image addRepresentation:imageRep];

MTLTexture创建MTLTexture 这显然是直接使用CVMetalTextureCacheCreateTextureFromImage的次要解决方案。

再一次,有问题的代码在macOS < 10.13工作得很好,我想知道是否有人有类似的问题,如果有,你有什么想法如何克服这个问题吗?

我遇到了同样的问题,问题不是在配置AVCaptureVideoDataOutput时要求金属兼容性。 我猜系统开始在 macOS 10.13 中检查这个,可能是在没有请求时应用一些优化。

解决方案是将kCVPixelBufferMetalCompatibilityKey添加到AVCaptureVideoDataOutputvideoSettings属性。

在 Objective-C 中:

outputCapture.videoSettings = @{
  /* ... */
  (NSString *)kCVPixelBufferMetalCompatibilityKey: @YES
};

在斯威夫特:

outputCapture.videoSettings = [
  /* ... */
  kCVPixelBufferMetalCompatibilityKey as String: true
]

我认为这需要一个雷达,要求 Apple 在发生这种情况时至少打印一条警告消息。 如果我得到它,我会更新它。

我找到了一个解决方法,它将2vuy格式保留在像素缓冲区中,但不好的是你制作了影响性能的像素缓冲区数据的副本。 我将其发布以供将来参考,或者如果其他人认为它有用。 基本上我们拦截像素缓冲区,然后在复制数据的同时添加属性。

NSDictionary *attributes = @{
                             @"IOSurfaceCoreAnimationCompatibility": @YES
                             };
CVPixelBufferRef copy = NULL;

CVPixelBufferCreate(kCFAllocatorDefault,
                    CVPixelBufferGetWidth(pixelBuffer),
                    CVPixelBufferGetHeight(pixelBuffer),
                    CVPixelBufferGetPixelFormatType(pixelBuffer),
                    (__bridge CFDictionaryRef)attributes,
                    &copy);

CVPixelBufferLockBaseAddress(pixelBuffer, kCVPixelBufferLock_ReadOnly);
CVPixelBufferLockBaseAddress(copy, 0);

void *baseAddress = CVPixelBufferGetBaseAddress(pixelBuffer);
void *copyBaseAddress = CVPixelBufferGetBaseAddress(copy);

memcpy(copyBaseAddress, baseAddress, CVPixelBufferGetDataSize(pixelBuffer));

CVPixelBufferUnlockBaseAddress(copy, 0);
CVPixelBufferUnlockBaseAddress(pixelBuffer, kCVPixelBufferLock_ReadOnly);

另一种从CVPixelBufferRef到 Metal 纹理的方法,您可以通过CIImage并使用CIContext和 Metal 设备(希望最大限度地减少 CPU 参与复制像素缓冲区);

确保您的目标金属纹理大小合适。

CIContext* ciContext = [CIContext contextWithMTLDevice:mtlDevice
    options:[NSDictionary dictionaryWithObjectsAndKeys:@(NO),kCIContextUseSoftwareRenderer,nil]
];

id<MTLCommandBuffer> metalCommandBuffer=[mtlCommandQueue commandBufferWithUnretainedReferences];

CIImage* ciImage = [[CIImage alloc] initWithCVPixelBuffer:cvPixelBuffer];

[ciContext render:ciImage 
    toMTLTexture:metal_texture 
    commandBuffer:mtlCommandBuffer
    bounds:[ciImage extent])
    colorSpace:[ciImage colorSpace]];

暂无
暂无

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

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