开发者

How do I run AVAssetReader at the same rate on a secondary thread as it does on the main thread?

开发者 https://www.devze.com 2023-04-03 15:48 出处:网络
I have an OpenGL iOS application and am using an AVAssetReader to read frames from a video and texture a simple model with the video content.

I have an OpenGL iOS application and am using an AVAssetReader to read frames from a video and texture a simple model with the video content.

Everything is working as expected, except I am using the AVAssetReader on a secondary thread and binding the textures on the main thread. The problem with this is that the video is running very slow, frame by frame.

Is there any way to synchronise the video position with the current time so that it doesn't appear to be going in slow motion?

Extra Info

This is how I read the video (on the secondary thread):

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 output开发者_运维百科Settings: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];


I solved this by moving the content of the while loop in another function then used NSTimer to call that function at a rate of 1.0/track.nominalFrameRate

0

精彩评论

暂无评论...
验证码 换一张
取 消