1

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]);
}
4

1 に答える 1

0

copyNextSampleBuffer の呼び出しの後に CMSampleBufferMakeDataReady() を追加してみるのも面白いかもしれません。これは通常、データを使用するときに呼び出されますが、一部のデコーダーでは、後続のブロックを適切に処理するためにこれを呼び出す必要があるのではないかと思います。

また、Instruments でこれをプロファイリングして、このループ中にメモリが増加しているかどうかを確認する必要があります。サンプル バッファで CFRelease を適切に呼び出しているように見えますが、構築中の AVAssetReaderOutput にいくつかの大きな自動解放オブジェクトがある可能性があります。メモリが蓄積されているように見える場合は、ループ内に NSAutoreleasePool を配置してこれをクリーンアップしてみてください。

于 2012-01-23T04:06:16.777 に答える