更新:我以爲問題是內存不足;不是。這個錯誤在4.3中始終發生,即使在內存很低的情況下也不會發生在4.1/4.2中。AVAssetExportSession在iOS 4.3中發生dealloc崩潰
這是在一個小型的Objective-C庫中,我不得不寫一些主要是Monotouch應用程序--AVFoundation尚未完全綁定。
這裏的痕跡:
0 Orbiter 0x007977d8 mono_handle_native_sigsegv + 404
1 Orbiter 0x007746b4 mono_sigsegv_signal_handler + 348
2 libsystem_c.dylib 0x34ce472f _sigtramp + 42
3 AVFoundation 0x365b3ab5 -[AVAssetExportSession dealloc] + 164
4 CoreFoundation 0x34bc2c43 -[NSObject(NSObject) release] + 30
5 AVFoundation 0x365b3607 -[AVAssetExportSession release] + 62
6 CoreFoundation 0x34bdd047 sendRelease + 14
7 libsystem_blocks.dylib 0x312c292f _Block_object_dispose + 118
8 AVFoundation 0x365b45b3 __destroy_helper_block_5 + 22
9 libsystem_blocks.dylib 0x312c288f _Block_release + 58
10 libdispatch.dylib 0x30df18ed _dispatch_call_block_and_release + 16
11 libdispatch.dylib 0x30deced1 _dispatch_queue_drain + 240
12 libdispatch.dylib 0x30ded043 _dispatch_queue_invoke + 78
13 libdispatch.dylib 0x30dec611 _dispatch_worker_thread2 + 196
14 libsystem_c.dylib 0x34cda591 _pthread_wqthread + 264
15 libsystem_c.dylib 0x34cdabc4 _init_cpu_capabilities + 4294967295
下面的代碼:
@implementation AVUtils : NSObject
+ (void) dubAudio:(NSURL*)videoUrl
withTrack:(NSURL*)audioUrl
outputTo:(NSURL*)newUrl
handleSuccess:(void(^)(void))successHandler
handleFailure:(void(^)(NSError* err))failureHandler
{
AVURLAsset* video = [[AVURLAsset alloc]initWithURL:videoUrl options:nil];
AVAssetTrack* videoTrack = [[video tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
CMTime videoDuration = video.duration;
AVURLAsset* audio = [[AVURLAsset alloc]initWithURL:audioUrl options:nil];
AVAssetTrack* audioTrack = [[audio tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0];
CMTime audioDuration = audio.duration;
CMTime newDuration = CMTimeMinimum(audioDuration, videoDuration);
CMTimeRange newTimeRange = CMTimeRangeMake(kCMTimeZero, newDuration);
AVMutableComposition* newComposition = [AVMutableComposition composition];
NSError* theError;
BOOL success;
AVMutableCompositionTrack* newAudioTrack = [newComposition addMutableTrackWithMediaType:AVMediaTypeAudio
preferredTrackID:kCMPersistentTrackID_Invalid];
theError = nil;
success = [newAudioTrack insertTimeRange:newTimeRange ofTrack:audioTrack atTime:kCMTimeZero error:&theError];
if (success == NO) {
UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:@"Error adding audio track"
message:[theError localizedDescription]
delegate: nil
cancelButtonTitle:@"Cancel"
otherButtonTitles:nil];
[alertView show];
[alertView release];
} else {
AVMutableCompositionTrack* newVideoTrack = [newComposition addMutableTrackWithMediaType:AVMediaTypeVideo
preferredTrackID:kCMPersistentTrackID_Invalid];
theError = nil;
success = [newVideoTrack insertTimeRange:newTimeRange ofTrack:videoTrack atTime:kCMTimeZero error:&theError];
if (success == NO) {
UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:@"Error adding audio track"
message:[theError localizedDescription]
delegate: nil
cancelButtonTitle:@"Cancel"
otherButtonTitles:nil];
[alertView show];
[alertView release];
} else {
AVAssetExportSession* _assetExport = [[AVAssetExportSession alloc] initWithAsset:newComposition presetName:AVAssetExportPresetPassthrough];
_assetExport.outputFileType = @"com.apple.quicktime-movie";
_assetExport.outputURL = newUrl;
_assetExport.shouldOptimizeForNetworkUse = YES;
[_assetExport exportAsynchronouslyWithCompletionHandler:
^(void) {
if (_assetExport.status == AVAssetExportSessionStatusCompleted) {
successHandler();
} else {
failureHandler(_assetExport.error);
}
[_assetExport release];
[video release];
[audio release];
[newComposition release];
}
];
}
}
}
@end
我的理論是,我是泄漏的指針_assetExport.error
,其傳遞到另一個線程 - 我是 - - 當它被解除引用時它是無效的,因爲_assetExport
被垃圾收集。但是,我證實,即使導出成功,segfault也會發生,所以在這種情況下不是這樣。
我是Obj-C的新手 - 任何人都可以看到我在這裏做的任何其他明顯的缺陷?
我很好奇,你發現哪些API在MonoTouch中缺失? – 2011-03-19 02:37:24
嘿,米格爾 - 我認爲AVMutableCompositionTrack.InsertTimeRange()是最大的一個。這是在11月份,所以它可能自那時起被添加,我沒有注意到。 – 2011-03-19 14:36:59