Как запустить AVAssetReader с той же скоростью во вторичном потоке, что и в основном? - PullRequest
1 голос
/ 09 сентября 2011

У меня есть приложение OpenGL для iOS, и я использую AVAssetReader для чтения кадров из видео и текстурирования простой модели с видеоконтентом.

Все работает как положено, за исключением того, что я использую AVAssetReader во вторичном потоке и связываю текстуры в основном потоке. Проблема в том, что видео работает очень медленно, кадр за кадром.

Можно ли синхронизировать положение видео с текущим временем, чтобы оно не отображалось в замедленном режиме?

Дополнительная информация

Вот как я читаю видео (на вторичной ветке):

NSAutoreleasePool *pool = [NSAutoreleasePool new];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];    
NSString* fullPath = [[documentsDirectory stringByAppendingPathComponent:@"sample_video.mp4"] retain];
NSString *urlAddress = fullPath;
NSURL *url = [NSURL fileURLWithPath:urlAddress];
AVURLAsset *urlAsset = [[AVURLAsset alloc] initWithURL:url options:nil];
NSArray *tracks = [urlAsset tracksWithMediaType:AVMediaTypeVideo];
AVAssetTrack *track = [tracks objectAtIndex:0];
NSDictionary* trackDictionary = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:kCVPixelFormatType_32BGRA] 
                                                            forKey:(id)kCVPixelBufferPixelFormatTypeKey];

AVAssetReaderTrackOutput *asset_reader_output = [[AVAssetReaderTrackOutput alloc] initWithTrack:track outputSettings:trackDictionary];

AVAssetReader *asset_reader = [[AVAssetReader alloc] initWithAsset:urlAsset error:nil];
[asset_reader addOutput:asset_reader_output];
[asset_reader startReading];

while (asset_reader.status == AVAssetReaderStatusReading){

    CMSampleBufferRef sampleBufferRef = [asset_reader_output copyNextSampleBuffer];

    if (sampleBufferRef){
            [self performSelectorOnMainThread:@selector(bindNewFrame) withObject:nil waitUntilDone:YES];
    }
    CMSampleBufferInvalidate(sampleBufferRef);
    CFRelease(sampleBufferRef);
}
[pool release];

1 Ответ

1 голос
/ 13 сентября 2011

Я решил это, переместив содержимое цикла while в другую функцию, затем использовал NSTimer для вызова этой функции со скоростью 1,0 / track.nominalFrameRate

...