【问题标题】:iOS - Video decoding with OpenGL ES 2.0iOS - 使用 OpenGL ES 2.0 进行视频解码
【发布时间】:2016-09-01 18:38:50
【问题描述】:

我一直在尝试将 .h264 视频解码为 opengl,但我显示的帧是黑色的。我没有看到任何错误,如果我将 CMSampleBufferRef 中的帧导出到相机胶卷中,它们就很好。

那可能是在 openGL 方面?但是当我显示图像而不是视频时,它工作正常,所以不知道在哪里看。

这是初始化视频解码器的代码:

- (void)initVideo {

    glActiveTexture(GL_TEXTURE0);
    glGenTextures(1, &_glTextureHook);

    NSURL * url = [NSURL URLWithString:[self.videoMedia getFilePath]];
    self.videoAsset = [[AVURLAsset alloc] initWithURL:url options:NULL];

    dispatch_semaphore_t sema = dispatch_semaphore_create(0);

    [self.videoAsset loadValuesAsynchronouslyForKeys:@[@"tracks"] completionHandler:^{

        self.videoTrack = [self.videoAsset tracksWithMediaType:AVMediaTypeVideo][0];

        NSString *key = (NSString *) kCVPixelBufferPixelFormatTypeKey;
        NSNumber *value = @(kCVPixelFormatType_32BGRA);
        NSDictionary *settings = @{key : value};

        self.outputVideoTrackOuput = [[AVAssetReaderTrackOutput alloc]
                                      initWithTrack:self.videoTrack outputSettings:settings];

        self.assetReader = [[AVAssetReader alloc] initWithAsset:self.videoAsset error:nil];
        [self.assetReader addOutput:self.outputVideoTrackOuput];
        [self.assetReader startReading];

        dispatch_semaphore_signal(sema);
    }];

    dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
}

以及检索opengl纹理的代码,视频的每一帧:

- (void)play {

    if (self.assetReader.status == AVAssetReaderStatusReading) {
        CMSampleBufferRef sampleBuffer = [self.outputVideoTrackOuput copyNextSampleBuffer];
        if(sampleBuffer) {
            CVImageBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);

            if(pixelBuffer) {
                CVPixelBufferLockBaseAddress(pixelBuffer, 0);

                glBindTexture(GL_TEXTURE_2D, _glTextureHook);
                glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1920, 1080, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, CVPixelBufferGetBaseAddress(pixelBuffer));
                CVPixelBufferUnlockBaseAddress(pixelBuffer, 0);
            }

            CFRelease(sampleBuffer);
        }
    }
}

顶点着色器和片段对于图像和视频是相同的(适用于图像)。我看到的唯一区别是 glTexImage2D,其中两种格式都是 GL_RGBA 的图像。

我确保视频解码器的 _glTextureHook 已正确发送到着色器管理器,上下文已在线程上激活等。

这是片段着色器的代码(非常基础,顶点着色器也一样):

precision lowp float;

uniform sampler2D Texture;

varying vec4 DestinationColor;
varying vec2 TexCoordOut;

void main() {
    gl_FragColor = DestinationColor * texture2D(Texture, TexCoordOut);
}

【问题讨论】:

  • 你在openGL下播放ios视频​​成功了吗?如果是,您介意分享代码吗?提前谢谢你!
  • 感谢您的代码,我这几天一直在寻找一个具体的例子。就像@loki 问的那样,你成功了吗?您是否在任何时候都涉及过音频?

标签: ios objective-c video opengl-es opengl-es-2.0


【解决方案1】:

我只是在创建纹理后错过了这些线条:

glBindTexture(GL_TEXTURE_2D, _glTextureHook);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多