यह कोड मेमोरी लीक और ऐप क्रैश की ओर जाता है:

    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)

यह copyNextSampleBuffer() और नियम बनाएं< /ए>.

बदले में, हम स्विफ्ट में CFRelease () का उपयोग नहीं कर सकते। ऑब्जेक्टिव-सी ओनली रूल का लिंक होने का कारण मेरी समझ से परे है।

क्या स्विफ्ट में मैन्युअल रूप से CMSampleBuffer जारी करने का कोई तरीका है?

2
DmitryoN 27 फरवरी 2019, 13:27

2 जवाब

सबसे बढ़िया उत्तर

यह वास्तव में एक समाधान नहीं है, क्योंकि ऐसा लगता है कि मेमोरी को मैन्युअल रूप से जारी करना असंभव है और एसेट रीडर के साथ संयोजन के दौरान लूप का उपयोग करने से मेमोरी जारी नहीं होती है जब असुरक्षित म्यूटेबल बाइट्स पढ़े जाते हैं।

समस्या को एक वैकल्पिक हल द्वारा हल किया गया था: ऑडियो फ़ाइल को थोड़ी देर के लूप में उजागर करने से पहले सीएएफ प्रारूप में परिवर्तित करना।

नकारात्मक पक्ष: यह एक गर्म सेकंड लेता है, ऑडियो फ़ाइल जितनी लंबी होती है - उतना ही अधिक समय लगता है।

उल्टा: यह केवल कम मात्रा में स्मृति का उपयोग करता था, जो पहली जगह में समस्या थी।

इससे प्रेरित: https://stackoverflow.com/users/2907715/carpsen90 उत्तर ऑडियो फ़ाइल से मीटर स्तर निकालें

1
DmitryoN 5 मार्च 2019, 10:11

मैंने हाल ही में एक ऑटोरेलीजपूल का उपयोग करके इसी तरह की समस्या को हल किया है

उस क्षेत्र को लपेटने का प्रयास करें जहां ऑटोरिलीजपूल में sampleBuffer का उपयोग किया जाता है। कुछ इस तरह:

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)

अगर मैं सही ढंग से समझूं, तो एक बार यह autoreleasepool के दायरे से बाहर निकल जाएगा, तो नमूनाबफ़र जारी किया जाएगा

3
Doug Mead 1 जून 2020, 20:16