2015-03-17 35 views
6

Mam dziwną awarię w mojej aplikacji do przetwarzania wideo. Używa ona AVFoundation do pracy z wideo & audio i GPUImage do filtrowania. Nigdy nie stanąłem w obliczu tego problemu, ale po wypuszczeniu go do App Store pojawił się dość często w Crashlytics. Oto log z katastrofy:__copy_helper_block_ crash w AVFoundation

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 

ten sposób połączyć AVFoundation do 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() 
     } 
    }  
} 

jakieś pomysły co jest nie tak z moim kodzie? Wszelkie pytania, komentarze, wskazówki i odpowiedzi są bardzo cenne.

+0

Właśnie natknęliśmy się na tę samą awarię w naszej aplikacji, która korzysta z GPUImage do przetwarzania wideo - tylko zastanawiasz się, czy miałeś szczęście znaleźć poprawkę? – Greg

Odpowiedz

6

jest to problem w GPUImageMovie - gdy instancja dodaje się jako AVPlayerItemVideoOutput delegat: [playerItemOutput setDelegate:self queue:videoProcessingQueue], playerItemOutput nie zwalnia jego delegata, gdy GPUImageMovie instancji dealokując. Później powoduje to wywołanie metody z deallocated obiektu (outputSequenceWasFlushed:) i dostajesz awarię. Stwierdzono to przy pomocy detektora NSZombie i naprawiłem go dodając ten w GPUImageMovie metody dealloc: [playerItemOutput setDelegate:nil queue:nil];

Powodzenia, Nikita;)

0

Dzikie przypuszczenie: niektóre smartass złamał coś avfoundation w 8.x jakoś rzeczy może to „po prostu działa” w 7.x Jeśli moja teoria patelnie z bugreporter to da sposobem radzenia sobie z tym (zaczną ignorując nową wypełnienie i wysłanie natychmiast)

0

Zgadzam się z Igorem, ale ustawienie playerItemOutput „s delegata do nil nie zrobił” Pomóż mi. Więc dodałem

runSynchronouslyOnVideoProcessingQueue(^{ 

    [playerItemOutput setDelegate: nil 
          queue: nil]; 
    [_playerItem removeOutput: playerItemOutput]; 
    playerItemOutput = nil; 
    }); 

w endProcessing metody po unieważnieniu displayLink.

Nadzieję, że pomaga.