__copy_helper_block_ AVFoundation 崩溃
__copy_helper_block_ crash in AVFoundation
我的视频处理应用程序发生奇怪的崩溃。它使用 AVFoundation
处理视频和音频,使用 GPUImage
进行过滤。我自己从未遇到过这个问题,但在将其发布到 App Store 后,它经常出现在 Crashlytics 中。这是崩溃的日志:
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
这就是我将 AVFoundation
连接到 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()
}
}
}
知道我的代码有什么问题吗?非常感谢任何问题、评论、提示和答案。
大胆猜测:一些聪明人在 8.x 的 avfoundation 中破坏了一些东西
不知何故,我觉得这可能 "just work" 7.x
如果我的理论成功,bugreporter 是解决这个问题的一种方法
(他们将立即开始忽略新的错误报告)
这是 GPUImageMovie
中的一个问题 - 当实例将自己添加为 AVPlayerItemVideoOutput
委托时:
[playerItemOutput setDelegate:self queue:videoProcessingQueue]
、playerItemOutput
在 GPUImageMovie
实例解除分配时不释放其委托。稍后,这会导致从已释放的对象 (outputSequenceWasFlushed:)
调用方法,然后发生崩溃。这是在 NSZombie 检测器的帮助下发现的,我通过在 GPUImageMovie
dealloc 方法中添加它来修复它:[playerItemOutput setDelegate:nil queue:nil];
祝你好运,尼基塔 ;)
我同意 Igor 的观点,但是将 playerItemOutput
的委托设置为 nil
对我没有帮助。
所以我添加了
runSynchronouslyOnVideoProcessingQueue(^{
[playerItemOutput setDelegate: nil
queue: nil];
[_playerItem removeOutput: playerItemOutput];
playerItemOutput = nil;
});
在 endProcessing
方法中使 displayLink
.
无效后
希望对您有所帮助。
我的视频处理应用程序发生奇怪的崩溃。它使用 AVFoundation
处理视频和音频,使用 GPUImage
进行过滤。我自己从未遇到过这个问题,但在将其发布到 App Store 后,它经常出现在 Crashlytics 中。这是崩溃的日志:
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
这就是我将 AVFoundation
连接到 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()
}
}
}
知道我的代码有什么问题吗?非常感谢任何问题、评论、提示和答案。
大胆猜测:一些聪明人在 8.x 的 avfoundation 中破坏了一些东西 不知何故,我觉得这可能 "just work" 7.x 如果我的理论成功,bugreporter 是解决这个问题的一种方法 (他们将立即开始忽略新的错误报告)
这是 GPUImageMovie
中的一个问题 - 当实例将自己添加为 AVPlayerItemVideoOutput
委托时:
[playerItemOutput setDelegate:self queue:videoProcessingQueue]
、playerItemOutput
在 GPUImageMovie
实例解除分配时不释放其委托。稍后,这会导致从已释放的对象 (outputSequenceWasFlushed:)
调用方法,然后发生崩溃。这是在 NSZombie 检测器的帮助下发现的,我通过在 GPUImageMovie
dealloc 方法中添加它来修复它:[playerItemOutput setDelegate:nil queue:nil];
祝你好运,尼基塔 ;)
我同意 Igor 的观点,但是将 playerItemOutput
的委托设置为 nil
对我没有帮助。
所以我添加了
runSynchronouslyOnVideoProcessingQueue(^{
[playerItemOutput setDelegate: nil
queue: nil];
[_playerItem removeOutput: playerItemOutput];
playerItemOutput = nil;
});
在 endProcessing
方法中使 displayLink
.
希望对您有所帮助。