Распределение памяти в AVAssetWriter после создания mov ie - PullRequest
0 голосов
/ 14 января 2020

В моем приложении есть подпрограмма, которая записывает MTL-текстуры в mov ie через AVAssetWriter. Когда я запускаю приложение на устройстве, управление памятью остается стабильным, а mov ie создается и записывается на диск. Однако, когда я опубликовал приложение в App Store (и скачал его), приложение вылетает вскоре после создания mov ie, независимо от размера mov ie. Запуск приложения через инструменты показывает огромное выделение памяти, происходящее в подпрограмме, которая извлекает PixelBuffer из MTLTextures. Вот где происходит крэ sh. Рассматриваемая процедура выполняется внутри al oop для каждой MTL-текстуры, которую я хочу записать:

func AVAssetWriterEncodeFrame(forTexture texture: MTLTexture) {

    while !assetWriterVideoInput!.isReadyForMoreMediaData  {
    } // hang out here until isReadyForMoreMediaData == true

    autoreleasepool(invoking: { () -> () in

      let fps: Int32 = Int32(Constants.movieFPS)

      guard let pixelBufferPool = assetWriterPixelBufferInput!.pixelBufferPool else {
        print("[MovieMakerVC]: Pixel buffer asset writer input did not have a pixel buffer pool available; cannot retrieve frame")
        return
      }

      var maybePixelBuffer: CVPixelBuffer? = nil
      let status  = CVPixelBufferPoolCreatePixelBuffer(nil, pixelBufferPool, &maybePixelBuffer)
      if status != kCVReturnSuccess {
        print("[MovieMakerVC]: Could not get pixel buffer from asset writer input; dropping frame...")
        return
      }
      guard let pixelBuffer = maybePixelBuffer else { return }
      CVPixelBufferLockBaseAddress(pixelBuffer, [])
      let pixelBufferBytes = CVPixelBufferGetBaseAddress(pixelBuffer)!

      // Use the bytes per row value from the pixel buffer since its stride may be rounded up to be 16-byte aligned
      let bytesPerRow = CVPixelBufferGetBytesPerRow(pixelBuffer)
      let region = MTLRegionMake2D(0, 0, texture.width, texture.height)

      texture.getBytes(pixelBufferBytes, bytesPerRow: bytesPerRow, from: region, mipmapLevel: 0)

      let presentationTime = CMTimeMake(value: Int64(frameIndexForPresentationTime), timescale: fps)

      assetWriterPixelBufferInput!.append(pixelBuffer, withPresentationTime: presentationTime)

      CVPixelBufferUnlockBaseAddress(pixelBuffer, [])

      frameIndexForPresentationTime += frameHoldLength  // set up for next frame

    }) // end of autoreleasepool

  } // end of func AVAssetWriterEncodeFrame(forTexture texture: MTLTexture)

allocations crash

allocations list

Пик, видимый на графике, бесконтрольно возрастает ПОСЛЕ того, как mov ie записывается на диск. Список распределений показывает тысячи записей, которые выглядят следующим образом:

@ autoreleasepool content. ... 4 КиБ А.В. Основание. - [AVAssetWriterinput helper]. (как видно на изображении выше)

Может кто-нибудь указать, что я делаю неправильно, и, надеюсь, как это исправить?

1 Ответ

0 голосов
/ 19 января 2020

Виновным оказался этот бит кода:

while! AssetWriterVideoInput! .IsReadyForMoreMediaData {} // зависать здесь до тех пор, пока isReadyForMoreMediaData == true

Оказывается, что тестирование для ложность этого условия в объекте AVAssetWriterInputPixelBufferAdaptor является действительно ПЛОХОЙ идеей.

Вместо этого, оборачивая всю эту логику c blo c следующим образом, можно получить go:

var frameIsCaptured: Bool = false

while (assetWriterVideoInput!.isReadyForMoreMediaData && frameIsCaptured == false) {     
    ... // insert all the texture processing logic
    texture.getBytes(pixelBufferBytes, bytesPerRow: bytesPerRow, from: region, mipmapLevel: 0)
    ... // insert pixelBuffer ingestion logic
    frameIsCaptured = true. // needed so we only process this texture once
}

То, что я делал раньше, достигло того же самого в том смысле, что подпрограмма будет бесконечно продолжаться до тех пор, пока isReadyForMoreMediaData не станет истиной (в этот момент я буду выполнять всю текстурную работу, необходимую для добавления pixelBuffer к mov ie -in-progress), но нелепые накладные расходы, создаваемые этим пустым l oop, не являются чем-то, что, похоже, является недостатком дизайна для решения. Конечно, Инструменты указали на проблему в этом oop, но мне потребовалось некоторое время, чтобы увидеть свет.

...