Последовательное чтение видеофайлов с помощью AVAssetReader завершается неудачно в OSX Lion - PullRequest
0 голосов
/ 23 января 2012

У меня есть функция для чтения видеофайлов H264. Я хочу использовать его для последовательного чтения многих видеофайлов. Кажется, он работает для файлов (случайное время), частично не работает для нескольких файлов (читает некоторые и не все кадры), а затем полностью завершается неудачей (чтение 0 кадров). Я проверил это, перебирая один и тот же видеофайл, и поэтому эта неопределенность странная.

Я получаю сообщение об ошибке:

Ошибка Domain = AVFoundationErrorDomain Code = -11800 «Операция не может быть завершена» UserInfo = 0x105d07480 {NSLocalizedFailureReason = Произошла неизвестная ошибка (-6662), NSLocalizedDescription = Операция не может быть завершена, NSUnderlyingError = 0x10015n50 "Операция не может быть выполнена не будет завершено. (OSStatus error -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 голосов
/ 23 января 2012

Может быть интересно попытаться добавить CMSampleBufferMakeDataReady () после вызова copyNextSampleBuffer. Обычно это вызывается, когда вы собираетесь использовать данные, но мне интересно, чтобы некоторые из декодеров нуждались в этом для правильной обработки последующих блоков.

Вам также следует попробовать профилировать это в Инструментах и ​​посмотреть, растет ли память в этом цикле. Похоже, что вы правильно вызываете CFRelease в буфере образца, но в AVAssetReaderOutput могут быть некоторые большие автоматически высвобождаемые объекты. Если похоже, что память накапливается, вы можете попытаться поместить NSAutoreleasePool в цикл, чтобы очистить это.

...