【发布时间】:2021-05-02 10:58:03
【问题描述】:
我正在使用MPSImageLanczosScale 使用Metal 框架来缩放图像纹理(从CVPixelBufferRef 开始)。问题是 MPSImageLanczosScale 仅从 10.13 开始可用。但我的应用程序从 10.11 开始支持。我不能停止支持较低的操作系统版本,因为仍然有很多用户使用这些版本。有没有其他方法可以使用 Metal(或使用任何其他方式)缩放图像?
注意:我使用的是 Metal,因为我需要基于 GPU 的图像缩放以避免任何 CPU 消耗。所以我正在寻找基于 GPU 的图像缩放解决方案。
包括当前的实现供您参考。
-(CVImageBufferRef)rescaleGPU:(CVImageBufferRef)sourceImageBuffer {
CVReturn error;
CGFloat backingScaleFactor = [[NSScreen mainScreen] backingScaleFactor];
CVMetalTextureRef textureRef;
error = CVMetalTextureCacheCreateTextureFromImage(kCFAllocatorDefault, _videoTextureCache, sourceImageBuffer, NULL, MTLPixelFormatBGRA8Unorm, g_screenWidth * backingScaleFactor, g_screenHeight * backingScaleFactor, 0, &textureRef);
id <MTLTexture> _metalTexture = CVMetalTextureGetTexture(textureRef);
id<MTLTexture> _destinationTexture = [_device newTextureWithDescriptor:self.textureDescriptor];
id<MTLCommandBuffer> commandBuffer = [_commandQueue commandBuffer];
[self.scaleFilter encodeToCommandBuffer:commandBuffer sourceTexture:_metalTexture destinationTexture:_destinationTexture];
id<MTLBlitCommandEncoder> blitEncoder = [commandBuffer blitCommandEncoder];
[blitEncoder synchronizeTexture:_destinationTexture slice:0 level:0];
[blitEncoder endEncoding];
[commandBuffer commit];
[commandBuffer waitUntilCompleted];
void* destData = malloc(scaleHeight * scaleWidth * 4);
[_destinationTexture getBytes:destData bytesPerRow:scaleWidth * 4 fromRegion:self.destinationRegion mipmapLevel:0];
CVPixelBufferCreateWithBytes(kCFAllocatorDefault, scaleWidth, scaleHeight, kCVPixelFormatType_32BGRA, destData, scaleWidth * 4, NULL, NULL, NULL, &finalBuffer);
CVBufferRelease(textureRef);
[_destinationTexture release];
free(destData);
return finalBuffer;
}
【问题讨论】:
标签: macos metal image-scaling cvpixelbuffer