2012-01-23 1 views
0

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

Сообщение об ошибке я получаю:

Ошибка домена = 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]); 
} 
+0

Вопрос заключается в том, что у вас возникли проблемы с чтением нескольких видеофайлов, но описание и образец кода, похоже, не имеют отношения к нескольким файлам. Если я не пропустил что-то, похоже, вы должны улучшить формулировку вопроса. –

+0

Я изменил его, чтобы показать, что я имел в виду чтение файлов назад, а не много файлов одновременно. –

ответ

0

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

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

+0

CMSampleBufferMakeDataReady() не имеет никакого значения. Кроме того, память в этом цикле не растет. OTOH, VTDecoderXPCService действительно на мгновение становится огромным (> 2 ГБ для виртуальной памяти), а затем его нет. –

+0

Хорошо, тогда вы можете попробовать посмотреть образец avexport по адресу https://developer.apple.com/library/mac/#samplecode/avexporter/Introduction/Intro.html#//apple_ref/doc/uid/DTS40011051 и посмотреть, что различия в вашем коде. Вы также можете попробовать запустить тот же фильм через этот пример кода и посмотреть, есть ли у него такая же проблема. На образцовой кодовой странице разработчика Mac также есть другие образцы AVFoundation. –

+0

Забудьте об этом примере, попробуйте использовать образец AVReaderWriter по адресу https://developer.apple.com/library/mac/#samplecode/ReaderWriter/Introduction/Intro.html#//apple_ref/doc/uid/DTS40011124. –