Утечка памяти при создании пиксельного буфера изображения

Я пытаюсь создать видео с вводом изображений, используя AVAssetWriterInput, для которого мне нужно создать пиксельный буфер моих изображений.

Для этого я вызываю функцию ниже, которая работает, но после создания нескольких видео приложение получает предупреждение о памяти и вылетает. Я отладил его с помощью инструментов и обнаружил утечку памяти здесь.

Я попытался поместить переменные pixelBufferPointer и pxData в качестве переменных класса и уничтожить/деаллок после создания видео, но это не имело никакого значения. Есть ли что-то, что я должен сделать, чтобы освободить эту память?

func createPixelBufferFromCGImage(image: CGImageRef) -> CVPixelBufferRef {
    let options = [
        "kCVPixelBufferCGImageCompatibilityKey": true,
        "kCVPixelBufferCGBitmapContextCompatibilityKey": true
    ]

    var videoWidth = 496
    var videoHeight = 668

    let frameSize = CGSizeMake(CGFloat(videoWidth), CGFloat(videoHeight))

    var pixelBufferPointer = UnsafeMutablePointer<Unmanaged<CVPixelBuffer>?>.alloc(1)

    var status:CVReturn = CVPixelBufferCreate(
        kCFAllocatorDefault,
        Int(frameSize.width),
        Int(frameSize.height),
        OSType(kCVPixelFormatType_32ARGB),
        options,
        pixelBufferPointer
    )

    var lockStatus:CVReturn = CVPixelBufferLockBaseAddress(pixelBufferPointer.memory?.takeUnretainedValue(), 0)

    var pxData:UnsafeMutablePointer<(Void)> = CVPixelBufferGetBaseAddress(pixelBufferPointer.memory?.takeUnretainedValue())

    let bitmapinfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.NoneSkipFirst.rawValue)
    let rgbColorSpace:CGColorSpace = CGColorSpaceCreateDeviceRGB()

    var context:CGContextRef = CGBitmapContextCreate(
        pxData,
        Int(frameSize.width),
        Int(frameSize.height),
        8,
        //4 * CGImageGetWidth(image),
        4 * Int(frameSize.width),
        rgbColorSpace,
        bitmapinfo
    )

    CGContextDrawImage(context, CGRectMake(0, 0, frameSize.width, frameSize.height), image)

    CVPixelBufferUnlockBaseAddress(pixelBufferPointer.memory?.takeUnretainedValue(), 0)

    UIGraphicsEndImageContext()

    return pixelBufferPointer.memory!.takeUnretainedValue()
}

person carlosb    schedule 13.10.2015    source источник


Ответы (4)


Unmanaged<CVPixelBuffer> протекает.

Я бы предпочел ответ Рассела Остина, но я не мог понять, как передать pixelBufferPointer в CVPixelBufferCreate без синтаксической ошибки (быстрый нуб). В противном случае, изменение строки

return pixelBufferPointer.memory!.takeUnretainedValue()

to

return pixelBufferPointer.memory!.takeRetainedValue()

устраняет утечку

person Rhythmic Fistman    schedule 14.10.2015
comment
Эй, чувак, ты можешь избавить меня от этой проблемы? - person ; 22.12.2020
comment
Какая проблема @RB1509? - person Rhythmic Fistman; 01.01.2021
comment
спасибо за ваш ответ :) у меня проблема с записью просмотра, и я не могу задать вопрос, так что не могли бы вы помочь мне сократить это? - person ; 01.01.2021
comment
переменный буфер: CVPixelBuffer? autoreleasepool { буфер = self.pixelBufferFromImage(изображение: изображение) } если буфер != nil { пусть результат = self.adapter.append(буфер!, withPresentationTime: присутствует) если !result { print(self.writer.error) } буфер = ноль} - person ; 01.01.2021
comment
это мой код, я не могу предоставить полный код, но я также отлаживаю, и этот код занимает до 1,34 ГБ памяти на моем устройстве во время записи, происходит сбой. еще одна вещь, код которой находится в writeVideoFromImageFrames, который будет использоваться для преобразования видео из изображений. - person ; 01.01.2021
comment
Нужно показать еще код, особенно pixelBufferFromImage — почему нельзя задать вопрос? - person Rhythmic Fistman; 01.01.2021
comment
Извините, мы больше не принимаем вопросы от этого аккаунта. Посетите Справочный центр, чтобы узнать больше. - person ; 01.01.2021
comment
это показывает мне это всякий раз, когда я пытаюсь задать вопрос. - person ; 01.01.2021
comment
подождите, я поделюсь с вами ссылкой, где вы можете увидеть мой код. - person ; 01.01.2021
comment
не могли бы вы проверить это. - person ; 01.01.2021
comment
там я делаю 2 функции для cvpixelbuffer. один из них я использовал в своем коде, но он вылетает из-за утечки памяти. - person ; 01.01.2021
comment
вам нужно задать новый вопрос с приведенным выше кодом. между прочим, похоже, что frameBuffer никогда не сливается - person Rhythmic Fistman; 01.01.2021
comment
пожалуйста, направьте меня по этому вопросу. - person ; 02.01.2021
comment
frameBuffer никогда не опорожняется. Означает ?? - person ; 02.01.2021
comment
не могли бы вы сделать мне одолжение, задав этот вопрос, потому что мой аккаунт больше не принимает вопросы. - person ; 02.01.2021

Взгляните на утечку памяти в CIContext createCGImage в iOS 9?

У меня аналогичная проблема, утечка связана со следующим кодом

CGImageRef processedCGImage = [_context createCGImage:ciImage
                                                             fromRect:[ciImage extent]];

Здесь для получения дополнительной контекстной информации: Утечка памяти в CMSampleBufferGetImageBuffer

person loretoparisi    schedule 13.10.2015
comment
Спасибо за ваш быстрый ответ. Я не уверен, что это та же ошибка, потому что я запускаю этот код на iOS 8.3 и не использую createCGImage. - person carlosb; 13.10.2015
comment
это правильно, но у меня есть некоторые подозрения, что эти примитивы CVPixelBufferGetBaseAddress, CGBitmapContextCreate, CGContextDrawImage используются при работе с createCGImage с использованием CIContext. Я уверен, что они связаны. - person loretoparisi; 13.10.2015

Вам не нужно использовать типы UnsafeMutablePointer. Вы, вероятно, пытались преобразовать какой-то пример Objective-C. Я делал то же самое, но в конце концов нашел, как это сделать без. Пытаться

var pixelBufferPointer: CVPixelBuffer?
...
var status:CVReturn = CVPixelBufferCreate(
    kCFAllocatorDefault,
    Int(frameSize.width),
    Int(frameSize.height),
    OSType(kCVPixelFormatType_32ARGB),
    options,
    &pixelBufferPointer
)

и

var pxData = CVPixelBufferGetBaseAddress(pixelBufferPointer)

Тогда вам не нужно делать takeUnRetainedValue и т.д.

Вы также можете попробовать использовать AVAssetWriterInputPixelBufferAdaptor и пул буферов пикселей. Это должно быть более эффективным. см. этот пример< /а>

person Russell Austin    schedule 13.10.2015
comment
я уже установил этот код, но кажется, что происходит утечка памяти из буфера, пока кадры в цикле. - person ; 22.12.2020

При использовании CVPixelBufferCreate UnsafeMutablePointer необходимо уничтожить после извлечения из него memory.

Когда я создаю CVPixelBuffer, я делаю это так:

func allocPixelBuffer() -> CVPixelBuffer {
    let pixelBufferAttributes : CFDictionary = [...]
    let pixelBufferOut = UnsafeMutablePointer<CVPixelBuffer?>.alloc(1)
    _ = CVPixelBufferCreate(kCFAllocatorDefault, 
                            Int(Width), 
                            Int(Height), 
                            OSType(kCVPixelFormatType_32ARGB),
                            pixelBufferAttributes, 
                            pixelBufferOut)

    let pixelBuffer = pixelBufferOut.memory!
    pixelBufferOut.destroy()
    return pixelBuffer
}
person Sebastian Krogull    schedule 14.10.2015