This code leads to memory leak and app crash:
var outputSamples = [Float]()
assetReader.startReading()
while assetReader.status == .reading {
let trackOutput = assetReader.outputs.first!
if let sampleBuffer = trackOutput.copyNextSampleBuffer(),
let blockBuffer = CMSampleBufferGetDataBuffer(sampleBuffer) {
let blockBufferLength = CMBlockBufferGetDataLength(blockBuffer)
let sampleLength = CMSampleBufferGetNumSamples(sampleBuffer) * channelCount(from: assetReader)
var data = Data(capacity: blockBufferLength)
data.withUnsafeMutableBytes { (blockSamples: UnsafeMutablePointer<Int16>) in
CMBlockBufferCopyDataBytes(blockBuffer, atOffset: 0, dataLength: blockBufferLength, destination: blockSamples)
CMSampleBufferInvalidate(sampleBuffer)
let processedSamples = process(blockSamples,
ofLength: sampleLength,
from: assetReader,
downsampledTo: targetSampleCount)
outputSamples += processedSamples
}
}
}
var paddedSamples = [Float](repeating: silenceDbThreshold, count: targetSampleCount)
paddedSamples.replaceSubrange(0..<min(targetSampleCount, outputSamples.count), with: outputSamples)
This is due to copyNextSampleBuffer() and The Create Rule.
In turn, we can not use CFRelease() in Swift. The reason why a link to the Objective-C only rule is there is beyond my understanding.
Is there a way to release CMSampleBuffer manually in Swift?