I'm using AVAssetReaders with AVSampleBufferDisplayLayers to display multiple videos at once. I'm seeing this issue on iOS 13.1.3, 13.2b2, on various hardware like iPad 10.5 and iPad 12.9.
It works well for a while, then a random call to copyNextSampleBuffer never returns, blocking that thread indefinitely and eating up resources.
I have tried different threading approaches with no avail:
- If copyNextSampleBuffer() and reader.cancelReading() are done on the same queue, then copyNextSampleBuffer() gets stuck and the cancelReading() never gets processed because the queue is blocked. If I manually (with the debugger) jump in on that blocked queue and execute cancelReading(), immediately an EXC_BREAKPOINT crashes the app
- If copyNextSampleBuffer() and reader.cancelReading() are done on different queues, then copyNextSampleBuffer() crashes with EXC_BAD_ACCESS
Here's the stacktrace (same queue approach). I don't understand why it's stuck, my expectation is that copyNextSampleBuffer should always return (ie. with nil in error case).
- VideoPlayerView: UIView with AVSampleBufferDisplayLayer
- AVAssetFactory: Singleton with the queue that creates & manages all AVAssetReader / AVAsset* objects
* thread #22, queue = 'AVAssetFactory'
frame #0: 0x00000001852355f4 libsystem_kernel.dylib`mach_msg_trap + 8
frame #1: 0x0000000185234a60 libsystem_kernel.dylib`mach_msg + 72
frame #2: 0x00000001853dc068 CoreFoundation`__CFRunLoopServiceMachPort + 216
frame #3: 0x00000001853d7188 CoreFoundation`__CFRunLoopRun + 1444
frame #4: 0x00000001853d68bc CoreFoundation`CFRunLoopRunSpecific + 464
frame #5: 0x000000018f42b6ac AVFoundation`-[AVRunLoopCondition _waitInMode:untilDate:] + 400
frame #6: 0x000000018f38f1dc AVFoundation`-[AVAssetReaderOutput copyNextSampleBuffer] + 148
frame #7: 0x000000018f3900f0 AVFoundation`-[AVAssetReaderTrackOutput copyNextSampleBuffer] + 72
* frame #8: 0x0000000103309d98 Photobooth`closure #1 in AVAssetFactory.nextSampleBuffer(reader=0x00000002814016f0, retval=(Swift.Optional<CoreMedia.CMSampleBuffer>, Swift.Optional<AVFoundation.AVAssetReader.Status>) @ 0x000000016dbd1cb8) at AVAssetFactory.swift:108:34
frame #9: 0x0000000102f4f480 Photobooth`thunk for @callee_guaranteed () -> () at <compiler-generated>:0
frame #10: 0x0000000102f4f4a4 Photobooth`thunk for @escaping @callee_guaranteed () -> () at <compiler-generated>:0
frame #11: 0x000000010bfe6c04 libdispatch.dylib`_dispatch_client_callout + 16
frame #12: 0x000000010bff5888 libdispatch.dylib`_dispatch_lane_barrier_sync_invoke_and_complete + 124
frame #13: 0x0000000103309a5c Photobooth`AVAssetFactory.nextSampleBuffer(reader=0x00000002814016f0, self=0x0000000281984f60) at AVAssetFactory.swift:101:20
frame #14: 0x00000001032ab690 Photobooth`closure #1 in VideoPlayerView.setRequestMediaLoop(self=0x000000014b8da1d0, handledCompletion=false) at VideoPlayerView.swift:254:70
frame #15: 0x0000000102dce978 Photobooth`thunk for @escaping @callee_guaranteed () -> () at <compiler-generated>:0
frame #16: 0x000000018f416848 AVFoundation`-[AVMediaDataRequester _requestMediaDataIfReady] + 80
frame #17: 0x000000010bfe5828 libdispatch.dylib`_dispatch_call_block_and_release + 24
frame #18: 0x000000010bfe6c04 libdispatch.dylib`_dispatch_client_callout + 16
frame #19: 0x000000010bfedb74 libdispatch.dylib`_dispatch_lane_serial_drain + 744
frame #20: 0x000000010bfee744 libdispatch.dylib`_dispatch_lane_invoke + 500
frame #21: 0x000000010bff9ae4 libdispatch.dylib`_dispatch_workloop_worker_thread + 1324
frame #22: 0x000000018517bfa4 libsystem_pthread.dylib`_pthread_wqthread + 276
I've tried all kinds of other things like making sure the AVAssets and all objects are made on one queue, and stopping the AVAssetReaders from ever deallocing to see if that helps. Nothing works. Any ideas?