__copy_helper_block_ crash en AVFoundation

Tengo una falla extraña en mi aplicación de procesamiento de video. Utiliza AVFoundation para trabajar con video y audio y GPUImage para filtrar. Nunca me he enfrentado a este problema, pero después de haberlo publicado en App Store apareció en Crashlytics con bastante frecuencia. Aquí está el logging del crash:

 Thread : Crashed: AVPlayerItemOutput queue 0 libobjc.A.dylib 0x00000001986f80b4 objc_retain + 20 1 libsystem_blocks.dylib 0x0000000198d79bf8 _Block_object_assign + 320 2 AVFoundation 0x0000000186895a34 __copy_helper_block_171 + 36 3 libsystem_blocks.dylib 0x0000000198d79738 _Block_copy_internal + 384 4 libdispatch.dylib 0x0000000198d252fc _dispatch_Block_copy + 36 5 libdispatch.dylib 0x0000000198d2685c dispatch_async + 68 6 AVFoundation 0x00000001868959ac -[AVPlayerItemVideoOutput _dispatchOutputSequenceWasFlushed] + 112 7 libdispatch.dylib 0x0000000198d2536c _dispatch_client_callout + 16 8 libdispatch.dylib 0x0000000198d2e6e8 _dispatch_barrier_sync_f_invoke + 76 9 AVFoundation 0x00000001868940a8 AVPlayerItemVideoOutput_figVCSequentialAvailable + 196 10 MediaToolbox 0x000000018a3c16f8 FigVisualContextImageAvailableSequential + 108 11 MediaToolbox 0x000000018a348ce8 itemremote_postNotificationWithPayload + 3996 12 MediaToolbox 0x000000018a342d60 FigPlayerRemoteCallbacksServer_SendNotifyPing + 924 13 MediaToolbox 0x000000018a342998 _XSendNotifyPing + 60 14 MediaToolbox 0x000000018a33f0d4 figmoviecallbacks_server + 112 15 MediaToolbox 0x000000018a33f018 fpr_ClientPortCallBack + 208 16 CoreFoundation 0x0000000187f44ce0 __CFMachPortPerform + 180 17 CoreFoundation 0x0000000187f598fc __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 56 18 CoreFoundation 0x0000000187f5985c __CFRunLoopDoSource1 + 436 19 CoreFoundation 0x0000000187f577dc __CFRunLoopRun + 1640 20 CoreFoundation 0x0000000187e851f4 CFRunLoopRunSpecific + 396 21 GraphicsServices 0x00000001910135a4 GSEventRunModal + 168 22 UIKit 0x000000018c7b6784 UIApplicationMain + 1488 23 MerryVideoEditor 0x000000010024b804 main (main.m:16) 24 libdyld.dylib 0x0000000198d4ea08 start + 4 

Así es como conecto AVFoundation a GPUImage :

 class ProjectEditorViewController: UIViewController { private var videoPlayerView = VideoPlayerView() private var movieFile: GPUImageMovie! private var currentComposition: AVComposition! //...and other properties } // MARK: - Filtering & Playback extension ProjectEditorViewController{ func updatePlayer() { currentFilter.removeAllTargets() movieFile?.removeAllTargets() movieFile?.endProcessing() let time = self.videoPlayerView.player?.currentItem.currentTime() ?? kCMTimeZero let (composition, audioMix) = compositionBuilder.buildCompositionFromTimeLine(timeLine) videoPlayerView.setAsset(composition) videoPlayerView.playerItem.audioMix = audioMix movieFile = GPUImageMovie(playerItem: videoPlayerView.player.currentItem) currentFilter.applyFromOutput(movieFile, toInput: gpuPlayerView) movieFile.startProcessing() addSyncLayerIfNeededForComposition(composition) videoPlayerView.player.seekToTime(time, toleranceBefore: kPlayerToleranceSeekTime, toleranceAfter: kPlayerToleranceSeekTime) currentComposition = composition } func updatePlayerFilter(){ if movieFile != nil{ movieFile.removeAllTargets() currentFilter.applyFromOutput(movieFile, toInput: gpuPlayerView) if(!videoPlayerView.isPlaying) { movieFile.startProcessing() } addSyncLayerIfNeededForComposition(currentComposition) }else{ updatePlayer() } } } 

¿Alguna idea de lo que está mal con mi código? Cualquier pregunta, comentario, sugerencia y respuesta son muy apreciadas.

Este es un problema en GPUImageMovie : cuando la instancia se agrega como delegado de AVPlayerItemVideoOutput : [playerItemOutput setDelegate:self queue:videoProcessingQueue] , playerItemOutput no libera su delegado cuando la instancia de GPUImageMovie está desasignando. Más tarde, esto resulta en una llamada de método del object desasignado (outputSequenceWasFlushed:) y obtienes el locking. Esto se encontró con la ayuda del detector NSZombie y lo solucioné agregando esto en el método GPUImageMovie GPUImageMovie: [playerItemOutput setDelegate:nil queue:nil];

Buena suerte, Nikita;)

Adivina salvaje: algunos smartass rompieron algo en estado de 8.x De alguna manera, esto podría "simplemente funcionar" en 7.x Si mi teoría busca un error en el modo de resolver este problema (comenzarán a ignorar el nuevo informe de errores de inmediato)

Estoy de acuerdo con Igor, pero la configuration del delegado de playerItemOutput a nil no me ayudó. Entonces agregué

 runSynchronouslyOnVideoProcessingQueue(^{ [playerItemOutput setDelegate: nil queue: nil]; [_playerItem removeOutput: playerItemOutput]; playerItemOutput = nil; }); 

en el método endProcessing después de invalidar displayLink .

Espero que ayude.