Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

218
Visualizações
How to manually release CMSampleBuffer

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?

over 4 years ago · Santiago Trujillo
2 Respostas
Responde à pergunta

0

I recently solved a similar issue by using an autoreleasepool

Try wrapping the area where sampleBuffer is used in an autoreleasepool. Something like this:

var outputSamples = [Float]()

assetReader.startReading()
while assetReader.status == .reading {
    let trackOutput = assetReader.outputs.first!

    autoreleasepool {
        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)

If I understand correctly, once it moves out of the scope of autoreleasepool, the sampleBuffer will be released

over 4 years ago · Santiago Trujillo Relatório

0

This is not really a solution, because it seems that releasing memory manually is impossible and using while loop in conjunction with assetReader results in memory not being released when unsafe mutable bytes are read.

The problem was solved by a workaround: converting the audio file into CAF format before exposing it to the while loop.

Downside: it takes a hot second, the longer the audio file - the more time it takes.

Upside: it only used minuscule amount of memory, which was the problem in the first place.

Inspired by: https://stackoverflow.com/users/2907715/carpsen90 answer in Extract meter levels from audio file

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda