【问题标题】:Can I use AVFoundation to stream downloaded video frames into an OpenGL ES texture?我可以使用 AVFoundation 将下载的视频帧流式传输到 OpenGL ES 纹理吗?
【发布时间】:2012-09-19 18:06:31
【问题描述】:

我已经能够使用 AVFoundation 的 AVAssetReader 类将视频帧上传到 OpenGL ES 纹理中。但是,它有一个caveat,因为它在与指向远程媒体的AVURLAsset 一起使用时会失败。这个失败没有很好的记录,我想知道是否有任何方法可以解决这个缺点。

【问题讨论】:

    标签: objective-c ios opengl-es streaming avfoundation


    【解决方案1】:

    iOS 6 中发布了一些 API,我可以使用这些 API 使该过程变得轻而易举。它根本不使用AVAssetReader,而是依赖于一个名为AVPlayerItemVideoOutput 的类。可以通过新的-addOutput: 方法将此类的实例添加到任何AVPlayerItem 实例。

    AVAssetReader 不同,该类适用于由远程AVURLAsset 支持的AVPlayerItems,并且还具有允许通过@ 支持非线性播放的更复杂的播放接口的好处987654330@(而不是AVAssetReader的严格限制-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 的 GLCameraRippleRosyWriter 演示。

    【讨论】:

    • 它没有可怕地记录在案,头文件中有一些相当不错的东西。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-26
    • 1970-01-01
    • 2016-06-13
    相关资源
    最近更新 更多