Я использую AVAssetReaderOutput (более конкретно AVAssetReaderTrackOutput) для обработки видео по кадрам. Я получаю последовательные кадры видео, используя метод copyNextSampleBuffer(). Я не поддерживаю никаких ссылок на фреймы после обработки, но я вижу прогрессивное потребление памяти, когда я просматриваю и просматриваю все видео, а объем использования памяти примерно равен размеру видео. Это проблема при работе с большими (> 1 ГБ) файлами. Первоначально я думал, что у меня может быть утечка памяти, но я выделил проблему для объекта AVAssetReaderTrackOutput.AVAssetReaderOutput memory issue
Например, если я просто просматриваю видео и использую метод copyNextSampleBuffer(), я вижу проблему с потреблением памяти. В следующем фрагменте кода, актив является объектом AVURLAsset инициализируется из видеофайла:
guard let videoTrack = asset.tracksWithMediaType(AVMediaTypeVideo).first else { return }
let outputSettings: [String: AnyObject] = [kCVPixelBufferPixelFormatTypeKey as String: NSNumber(unsignedInt: kCVPixelFormatType_32ARGB)]
videoTrackOutput = AVAssetReaderTrackOutput(track: videoTrack, outputSettings: outputSettings)
videoTrackOutput.alwaysCopiesSampleData = false
assetReader.addOutput(videoTrackOutput)
let _ = assetReader.startReading()
while self.assetReader.status == AVAssetReaderStatus.Reading {
videoTrackOutput.copyNextSampleBuffer()
}
Я думал об изменении способа чтения для чтения и обработки видео в более короткие сегменты, чтобы избежать чрезмерного использования памяти, но я не удалось освободить память, потребляемую объектом AVAssetReaderTrackOutput. Например, если установить объект в ноль после его использования, память не освобождается в соответствии с Xcode отладки навигатора:
videoTrackOutput = nil
assetReader = nil
я упускаю что-то? Есть ли другой способ освободить память, которая, по-видимому, используется объектом videoTrackOutput?
Если нет, есть ли другой способ прочитать видео кадр за кадром, который не имеет этой проблемы?
Я пробовал это, но компилятор дает ошибку при попытке вызвать CFRelease: «CFRelease» недоступен: объекты Core Foundation автоматически управляются памятью. Есть ли другой способ освободить буфер? – jbaraga
Является ли приведенный выше код действительно показательным для вашего реального кода? Вы называете это в цикле? Если это так, вам нужно добавить блок autoreleasepool {} в цикле, или вы можете увеличить потребление памяти (хотя в конечном итоге оно исчезнет). –
Хорошее предложение, но, к сожалению, оно не влияет на использование памяти. Даже после того, как блок кода завершил выполнение, память не будет выпущена. Я не поддерживаю никаких ссылок на буфер. – jbaraga