1

在我们的 iOS 应用程序中,我们使用使用 Metal 的自定义过滤器(CIKernel/CIColorKernel 包装器)。

假设我们有一个 4K 视频和一个输出大小为 1080p 的自定义视频合成,它在视频缓冲区上应用了高级过滤器。
显然,我们不需要过滤原始大小的视频,这样做我们可能会终止应用程序并发出内存警告(真实故事)。

这是视频过滤管道:

以 4K (asCIImage )获取缓冲区-->
应用过滤器CIImage -->
过滤器将CIKernel Metal过滤器功能应用到CIImage-->
将过滤CIImage后的组合返回

我能想到的唯一两个应用调整大小的地方是在我们将其发送到过滤器进程之前或在Metal函数内。

public class VHSFilter: CIFilter {

    public override var outputImage: CIImage? {
        // InputImage size is 4K
        guard let inputImage = self.inputImage else { return nil }

        // Manipulate the image here

        let roiCallback: CIKernelROICallback = { _, rect -> CGRect in
            return inputImage.extent
        }


        // Or inside the Kernel Metal function
        let outputImage = self.kernel.apply(extent: inputExtent,
                                            roiCallback: roiCallback,
                                            arguments: [inputImage])

        return outputImage

    }
}

我确定我不是第一个遇到这个问题的人

当传入的视频缓冲区太大(内存方面)无法过滤时该怎么办,并且他们需要有效地即时调整大小?之前没有重新编码视频?

4

1 回答 1

0

正如warrenm所说,您可以在处理之前使用CILanczosScaleTransform过滤器对视频帧进行下采样。但是,这仍然会导致 AVFoundation 以全分辨率分配缓冲区。

我假设您使用 aAVMutableVideoComposition进行过滤?在这种情况下,您只需将renderSize合成的 设置为目标大小。从文档:

视频合成应呈现的大小。

这将告诉 AVFoundation 在将帧交给过滤器管道之前重新采样帧(高效、快速)。

于 2019-07-23T11:33:44.600 回答