2

我正在使用 AVAssetReaderOutput(更具体地说是 AVAssetReaderTrackOutput)逐帧处理视频。我使用 copyNextSampleBuffer() 方法获取视频的连续帧。处理后我不保留对帧的任何引用,但是当我循环并读取整个视频时,我看到了渐进式内存消耗,并且内存使用量大约是视频的大小。在处理大 (>1GB) 文件时,这是有问题的。最初我以为我可能有内存泄漏,但我已将问题隔离到 AVAssetReaderTrackOutput 对象。

例如,如果我只是循环播放视频并使用 copyNextSampleBuffer() 方法,我会看到内存消耗问题。在以下代码片段中,asset 是从视频文件初始化的 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 对象消耗的内存。例如,如果我在使用后将对象设置为 nil,则不会根据 Xcode 调试导航器释放内存:

videoTrackOutput = nil
assetReader = nil

我错过了什么吗?是否有另一种方法来释放似乎被 videoTrackOutput 对象使用的内存?

如果没有,有没有其他方法可以逐帧读取不存在此问题的视频?

4

1 回答 1

3

如果您查阅 文档copyNextSampleBuffer,您会注意到以下内容:

所有权遵循创建规则

Create Rule 来自 Core Foundation:如果函数包含“Create”或“Copy”字样,那么您有责任释放返回的对象。ARC 会自动为 ARC 管理的对象执行此操作,但CMSampleBuffer不是 ARC 管理的。

所以当你用完这个对象后,你需要调用CFRelease它来避免内存泄漏。

于 2016-01-17T16:18:15.707 回答