我可以使用AVFoundation将下载的video帧传输到OpenGL ES纹理中吗?
我已经能够使用AVFoundation的AVAssetReader
类将video帧上传到OpenGL ES纹理。 但是,它有一个警告 ,因为在与指向远程媒体的AVURLAsset
一起使用时会失败。 这个故障没有很好的logging,我想知道是否有任何解决方法的缺点。
iOS 6已经发布了一些API,我可以用它来简化这个过程。 它根本不使用AVAssetReader
,而是依赖于名为AVPlayerItemVideoOutput
的类。 这个类的一个实例可以通过一个新的-addOutput:
方法添加到任何AVPlayerItem
实例。
与AVAssetReader
不同的AVAssetReader
,此类对于由远程AVURLAsset
支持的AVPlayerItem
可以正常工作,并且还具有允许通过-copyPixelBufferForItemTime:itemTimeForDisplay:
而不是-copyPixelBufferForItemTime:itemTimeForDisplay:
支持非线性播放的更复杂的回放接口严重限制-copyNextSampleBuffer
方法。
样本代码
// Initialize the AVFoundation state AVURLAsset *asset = [AVURLAsset URLAssetWithURL:someUrl options:nil]; [asset loadValuesAsynchronouslyForKeys:[NSArray arrayWithObject:@"tracks"] completionHandler:^{ NSError* error = nil; AVKeyValueStatus status = [asset statusOfValueForKey:@"tracks" error:&error]; if (status == AVKeyValueStatusLoaded) { NSDictionary* settings = @{ (id)kCVPixelBufferPixelFormatTypeKey : [NSNumber numberWithInt:kCVPixelFormatType_32BGRA] }; AVPlayerItemVideoOutput* output = [[[AVPlayerItemVideoOutput alloc] initWithPixelBufferAttributes:settings] autorelease]; AVPlayerItem* playerItem = [AVPlayerItem playerItemWithAsset:asset]; [playerItem addOutput:[self playerItemOutput]]; AVPlayer* player = [AVPlayer playerWithPlayerItem:playerItem]; // Assume some instance variable exist here. You'll need them to control the // playback of the video (via the AVPlayer), and to copy sample buffers (via the AVPlayerItemVideoOutput). [self setPlayer:player]; [self setPlayerItem:playerItem]; [self setOutput:output]; } else { NSLog(@"%@ Failed to load the tracks.", self); } }]; // Now at any later point in time, you can get a pixel buffer // that corresponds to the current AVPlayer state like this: CVPixelBufferRef buffer = [[self output] copyPixelBufferForItemTime:[[self playerItem] currentTime] itemTimeForDisplay:nil];
一旦你有了你的缓冲区,你可以把它上传到OpenGL,但是你想要的。 我推荐使用可怕的CVOpenGLESTextureCacheCreateTextureFromImage()
函数,因为您将在所有较新的设备上获得硬件加速,这比glTexSubImage2D()
快得多。 请参阅Apple的GLCameraRipple和RosyWriter演示。