Metal - изменить размер видео буфера перед переходом к пользовательскому фильтру ядра
В нашем приложении для iOS мы используем пользовательские фильтры с использованием Metal (оболочки CIKernel/CIColorKernel).
Давайте предположим, что у нас есть видео 4K и пользовательская композиция видео с выходным размером 1080p, которая применяет расширенный фильтр к буферам видео.
Очевидно, нам не нужно фильтровать видео в его первоначальном размере, поэтому мы, вероятно, закроем приложение предупреждением о памяти (правдивая история).
Это конвейер видеофильтрации:
Получение буфера в 4К (как CIImage
) ->
Применить фильтр на 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
}
}
Я уверен, что я не первый, кто столкнулся с этой проблемой
Что делать, когда входящий видеобуфер слишком велик (по памяти) для фильтрации, и ему необходимо оперативно изменять размер на лету? Без перекодирования видео раньше?
1 ответ
Как говорит Варренм, вы можете использовать CILanczosScaleTransform
фильтр, чтобы уменьшить видеокадры перед обработкой. Однако это все равно заставит AVFoundation выделять буферы в полном разрешении.
Я полагаю, вы используете AVMutableVideoComposition
делать фильтрацию? В этом случае вы можете просто установить renderSize
композиции до целевого размера. Из документов:
Размер, при котором композиция видео должна отображаться.
Это скажет AVFoundation повторно сэмплировать кадры (эффективно, быстро) перед их передачей в конвейер фильтра.