iOS 4.3中的AVAssetExportSession dealloc崩溃

时间:2011-03-17 23:07:21

标签: iphone objective-c ios4 xamarin.ios avfoundation

更新:我认为问题是内存不足;不是。这种错误在4.3中始终如一,即使在相当低的内存条件下也不会发生在4.1 / 4.2中。

这是一个小型的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是垃圾集。但我确认即使导出成功也会发生段错误,所以在这种情况下不是这样。

我是Obj-C的新手 - 任何人都可以看到我在这里做的任何其他明显的缺陷吗?

1 个答案:

答案 0 :(得分:2)

看起来关于完成Block的内存管理是个问题。崩溃日志说它在_assetExport的发布时崩溃了..你绝对不应该发布newComposition(你没有分配它或保留它)。

相关问题