App freezes when calling AVAssetExportSession.cancelExport() using customVideoCompositorClass

55 Views Asked by At

I'm exporting video using AVMutableVideoComposition and customVideoCompositorClass which works fine. But by cancelling the AVAssetExportSession via cancelExport() my app goes hanging and not responding at all.

func cancel() {
  exportSession?.cancelExport()
  exportSession = nil
}

I tried to bypass the customVideoCompositorClass for testing purposes and was able to cancel the export as intended. No hangs, everything smooth. However I can't bypass the custom compositor since it handles all the drawing logic.

Here is the configuration of AVMutableVideoComposition:

let mainComposition = AVMutableVideoComposition()
mainComposition.customVideoCompositorClass = CustomVideoCompositor.self
mainComposition.frameDuration = // time range
mainComposition.renderSize = // render size
mainComposition.instructions = [ ... ]

and this is the inner part of custom video compositor which I borrowed from AVCustomEdit repository in GitHub:

  ...

  private var renderingQueue = DispatchQueue(label: "com.identifier.CustomVideoCompositor.RenderingQueue")
  private var shouldCancelAllRequests = false

  func startRequest(_ request: AVAsynchronousVideoCompositionRequest) {
    autoreleasepool {
      renderingQueue.async {
        if self.shouldCancelAllRequests {
          request.finishCancelledRequest()
          return
        }

        guard let frame = self.newRenderedPixelBuffer(forRequest: request) else {
          request.finish(with: errorForInvalidPixelBuffer)
          return
        }

        request.finish(withComposedVideoFrame: frame)
      }
    }
  }

  func cancelAllPendingVideoCompositionRequests() {
    // Pending requests will call `finishCancelledRequest`, those already rendering
    // will call `finishWithComposedVideoFrame`.
    renderingQueue.sync {
      shouldCancelAllRequests = true
    }

    // Start accepting requests again.
    renderingQueue.async { [self] in
      shouldCancelAllRequests = false
    }
  }
 
  ...

As far as understand my custom compositor should be triggered with cancelAllPendingVideoCompositionRequests() method when calling AVAssetExportSession.cancelExport() which should cancel all the upcoming frames and end up with request.finishCancelledRequest(). But in practice I couldn't even hit the debug breakpoint on this line.

Any thoughts on this very strange behaviour?

0

There are 0 best solutions below