В нашем приложении для iOS мы используем настраиваемые фильтры с использованием Metal (оболочки CIKernel / CIColorKernel).
Предположим, у нас есть видео 4K и пользовательская композиция видео с выходным размером 1080p, которая применяет расширенный фильтр к видеобуферам.
Очевидно, нам не нужно фильтровать видео в исходном размере, поэтому мы Вероятно, завершит работу приложения с предупреждением о памяти (реальная история).
Это конвейер видеофильтрации:
Получение буфера в 4K (как CIImage
) ->
Применить фильтр к CIImage
-> strong >
фильтр применяет функцию фильтра 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
}
}
Я уверен, что я не первый, кто столкнулся с этой проблемой
Что делать, если входящий видеобуфер слишком велик (с точки зрения памяти) для фильтрации, и их размер необходимо оперативно изменять на лету? Без перекодирования видео раньше?
CILanczosScaleTransform
, в цепочку перед вашим пользовательским фильтром / ядром? - person warrenm   schedule 23.07.2019CIImage
transformed(by:)
для уменьшения размера изображения (что, похоже, не влияет на использование ОЗУ). Это то же самое, чтоCILanczosScaleTransform
или Ланц делает что-то другое? - person Roi Mulia   schedule 23.07.2019