在OSX Lion中使用AVAssetReader顺序读取视频文件失败

时间:2012-01-23 00:22:49

标签: macos osx-lion avassetreader

我有读取H264视频文件的功能。我想用它来顺序读取很多视频文件。它似乎适用于文件(随机时间),部分失败的几个文件(读取一些而不是所有帧)然后完全失败(读取0帧)。我通过循环同一个视频文件对此进行了测试,因此这种不确定性很奇怪。

我得到的错误信息是:

错误Domain = AVFoundationErrorDomain Code = -11800“操作无法完成”UserInfo = 0x105d07480 {NSLocalizedFailureReason =发生未知错误(-6662),NSLocalizedDescription =操作无法完成,NSUnderlyingError = 0x100159350“操作无法执行不完整。(OSStatus错误-6662。)“}

我使用ARC和OSX Lion。非常感谢任何帮助:

void uncompressMovie(NSString *moviePath) { 
AVAsset *asset = [AVAsset assetWithURL:[NSURL fileURLWithPath:moviePath]];

NSArray* video_tracks = [asset tracksWithMediaType:AVMediaTypeVideo];
AVAssetTrack *video_track = [video_tracks objectAtIndex:0];

// Decompress to ARGB with the asset reader
NSDictionary *decompressionVideoSettings = [NSDictionary dictionaryWithObjectsAndKeys:
                                            [NSNumber numberWithUnsignedInt:kCVPixelFormatType_32ARGB], (id)kCVPixelBufferPixelFormatTypeKey,
                                            [NSDictionary dictionary], (id)kCVPixelBufferIOSurfacePropertiesKey,
                                            nil];
AVAssetReaderTrackOutput *asset_reader_output = [AVAssetReaderTrackOutput assetReaderTrackOutputWithTrack:video_track outputSettings:decompressionVideoSettings];

NSError *error = [[NSError alloc] init];
AVAssetReader *asset_reader = [[AVAssetReader alloc] initWithAsset:asset error:&error]; 

if ([asset_reader canAddOutput:asset_reader_output]) {
    [asset_reader addOutput:asset_reader_output];

    if ([asset_reader startReading] == YES) {
        int count = 0;

        while ( [asset_reader status]==AVAssetReaderStatusReading ) {
            sampleBuffer = [asset_reader_output copyNextSampleBuffer];
            if (sampleBuffer == NULL) {
                if ([asset_reader status] == AVAssetReaderStatusFailed) 
                    break;
                else    
                    continue;
            }
            count++;

            // Will do some work here            

            CFRelease(sampleBuffer);
        }

        if (count == 0) {
            NSLog(@"I am doomed %@", [asset_reader error]);
            exit(1);
        }

        NSLog(@"Processed %d frames from %@", count, moviePath);
    } else
        NSLog(@"Couldn't start");
}

if ([asset_reader status] != AVAssetReaderStatusCompleted)
    [asset_reader cancelReading];
// unlink([moviePath UTF8String]);
}

1 个答案:

答案 0 :(得分:0)

在调用copyNextSampleBuffer之后尝试添加CMSampleBufferMakeDataReady()可能会很有趣。这通常在您打算使用数据时调用,但我想知道某些解码器需要调用它来正确处理后续块。

您还应该尝试在Instruments中对此进行分析,并查看在此循环中内存是否正在增长。看起来您正在样本缓冲区上正确调用CFRelease,但AVAssetReaderOutput中可能存在一些正在构建的大型自动释放对象。如果看起来内存正在建立,那么你可能会尝试在循环中放置一个NSAutoreleasePool来清理它。