如何调整/缩放 MTLTexture?

4

我有一个MTLTexture,它的大小与它所在的MTLView相同。但是,为了录制需要标准视频大小(即1280x720),我将纹理写入AVAssetWriterInputPixelBufferAdaptor。

目前,我正在使用MTLRegionMake2D来指定要提取的纹理区域。在宽度较长的手机上,裁剪的效果不太明显。但在更加方形和大的iPad上,裁剪很明显。理想情况下,我希望先调整纹理的大小,使其与视频宽度或高度相同,然后再裁剪其余部分(而不仅仅是裁剪)。

调整MTLTexture大小的适当方法是什么?

示例代码:

guard let pixelBufferPool = assetWriterPixelBufferInput.pixelBufferPool else { return }

var maybePixelBuffer: CVPixelBuffer? = nil
let status  = CVPixelBufferPoolCreatePixelBuffer(nil, pixelBufferPool, &maybePixelBuffer)
if status != kCVReturnSuccess { return }

guard let pixelBuffer = maybePixelBuffer else { return }

CVPixelBufferLockBaseAddress(pixelBuffer, [])
let pixelBufferBytes = CVPixelBufferGetBaseAddress(pixelBuffer)!

let bytesPerRow = CVPixelBufferGetBytesPerRow(pixelBuffer)
let region = MTLRegionMake2D(0, 0, Int(videoSize.width), Int(videoSize.height))

texture.getBytes(pixelBufferBytes, bytesPerRow: bytesPerRow, from: region, mipmapLevel: 0)

let frameTime = CACurrentMediaTime()
let presentationTime = CMTimeMakeWithSeconds(frameTime, 240)
assetWriterPixelBufferInput.append(pixelBuffer, withPresentationTime: presentationTime)

CVPixelBufferUnlockBaseAddress(pixelBuffer, [])
1个回答

2
最终我使用了 MPSImageLanczosScale 来缩放纹理,参见:
苹果文档: https://developer.apple.com/documentation/metalperformanceshaders/mpsimagelanczosscale 示例: Crop and scale MTLTexture 重新缩放后,仍需使用区域来剪裁余下部分。我有一些逻辑来检测设备的方向(竖屏/横屏)和类型(平板/手机),以确定适当的裁剪方式。在我的情况下(对于竖屏),我选择在瘦设备(手机)上垂直居中裁剪顶部/底部,在宽设备(平板电脑)上水平居中裁剪左侧/右侧。横屏也有类似的逻辑,但是方向相反。

你应该能够通过在矩阵中适当的平移来生成一个较小的MPSImage来进行裁剪。这样可以节省工作和内存,并且整体效果更好。 - Ian Ollmann
感谢您的建议,@Ian Ollmann。我无法评论这种方法的效率如何,但它确实起作用了。感谢您的提示。 - JCutting8

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接