1

I'm reading video data with an AVAssetReader and "looping" the content by reading it again and modifying the timestamps. The relevant code is:

  private func readFrame() -> CMSampleBuffer? {
    let buffer = output?.copyNextSampleBuffer()
    guard buffer != nil else {
      do {
        reader?.cancelReading()
        try loop()
      } catch let e {
        return nil
      }
      return readFrame()
    }
    
    // if we've looped, add previous loop times
    // MEMORY LEAK IS IN HERE
    if CMTimeCompare(offsetTime, .zero) > 0 {
      var newTiming = [CMSampleTimingInfo(
        duration: CMSampleBufferGetDuration(buffer!),
        presentationTimeStamp: CMTimeAdd(CMSampleBufferGetOutputPresentationTimeStamp(buffer!), offsetTime),
        decodeTimeStamp: CMTimeAdd(CMSampleBufferGetOutputDecodeTimeStamp(buffer!), offsetTime)
      )]
      
      CMSampleBufferCreateCopyWithNewTiming(allocator: kCFAllocatorDefault, sampleBuffer: buffer!, sampleTimingEntryCount: 1, sampleTimingArray: &newTiming, sampleBufferOut: &loopedBuffer)
      return loopedBuffer
    }
    
    return buffer
  }

  private func loop() throws {
    guard (reader?.status == .some(.completed)) else {
      throw FileError.cannotLoop(reader?.error)
    }
    offsetTime = CMTimeAdd(offsetTime, assetDuration)
    try createReader() // creates a new reader and calls reader.startReading()
  }

Once the video finishes its first loop (that is, once offsetTime is greater than zero), memory begins to blow up. Commenting out the code that creates a new buffer with updated timing fixes the memory leak (but that's not viable because I need the updated timing).

Presumably CMSampleBufferCreateCopyWithNewTiming is allocating new space for each buffer, and that buffer is never cleaned up. I've read about autoreleasepool as a potential option, but this buffer gets passed around a lot (it goes through a custom Publisher). Is there a way to remove the memory leak? I would be fine with allocating space for 1 buffer and just overwriting it again and again on each frame - is that possible?

Adam A
  • 14,469
  • 6
  • 30
  • 38
  • I ended up hacking in an offset later in the pipeline so I'm now passing the unmodified buffer all the time. Having the bad timestamps leak so far out feels pretty bad though... – Adam A May 14 '21 at 23:25
  • Not related to your problem, but if you have paid developer account you have 2 `apple techical support requests` per year – vpoltave May 15 '21 at 09:37
  • very good to know! Thanks! – Adam A May 17 '21 at 00:16
  • i want to modify CMSampleBuffer too, because i want to add some filter into webrtc video call, did u have any solution? – famfamfam Nov 27 '21 at 14:58

0 Answers0