首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用NV12将RGBA转换为OpenGL?

如何使用NV12将RGBA转换为OpenGL?
EN

Stack Overflow用户
提问于 2019-03-25 07:29:09
回答 1查看 2K关注 0票数 4

我需要将NV12转换为OpenGL着色器作为编码器输入。

已经渲染了两个不同的片段着色器,这两个纹理是从一个相机。使用v4l2获取相机图像。然后,将YUV转换为RGB让OpenGL呈现。下一步,我需要将RGB转换为NV12作为编码器输入,因为编码器只接受NV12格式。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-03-25 16:58:42

使用计算着色器将RGB转换为平面YUV,然后将UV平面降至2倍。

这是计算机着色器:

代码语言:javascript
复制
#version 450 core
layout(local_size_x = 32, local_size_y = 32) in;
layout(binding = 0) uniform sampler2D src;
layout(binding = 0) uniform writeonly image2D dst_y;
layout(binding = 1) uniform writeonly image2D dst_uv;
void main() {
    ivec2 id = ivec2(gl_GlobalInvocationID.xy);
    vec3 yuv = rgb_to_yuv(texelFetch(src, id).rgb);
    imageStore(dst_y, id, vec4(yuv.x,0,0,0));
    imageStore(dst_uv, id, vec4(yuv.yz,0,0));
}

有很多不同的YUV约定,我不知道哪个是你的编码器期望的。因此,将上面的rgb_to_yuv替换为YUV -> RGB转换的逆值。

然后按以下方式进行:

代码语言:javascript
复制
GLuint in_rgb = ...; // rgb(a) input texture
int width = ..., height = ...; // the size of in_rgb

GLuint tex[2]; // output textures (Y plane, UV plane)

glCreateTextures(GL_TEXTURE_2D, tex, 2);
glTextureStorage2D(tex[0], 1, GL_R8, width, height); // Y plane

// UV plane -- TWO mipmap levels
glTextureStorage2D(tex[1], 2, GL_RG8, width, height);

// use this instead if you need signed UV planes:
//glTextureStorage2D(tex[1], 2, GL_RG8_SNORM, width, height);

glBindTextures(0, 1, &in_rgb);
glBindImageTextures(0, 2, tex);
glUseProgram(compute); // the above compute shader

int wgs[3];
glGetProgramiv(compute, GL_COMPUTE_WORK_GROUP_SIZE, wgs);
glDispatchCompute(width/wgs[0], height/wgs[1], 1);

glUseProgram(0);
glGenerateTextureMipmap(tex[1]); // downsamples tex[1] 

// copy data to the CPU memory:
uint8_t *data = (uint8_t*)malloc(width*height*3/2);
glGetTextureImage(tex[0], 0, GL_RED, GL_UNSIGNED_BYTE, width*height, data);
glGetTextureImage(tex[1], 1, GL_RG, GL_UNSIGNED_BYTE, width*height/2,
    data + width*height);

免责声明:

  • 此代码未经测试。
  • 它假定宽度和高度可除以32。
  • 它可能在某个地方遗漏了一个记忆屏障。
  • 这不是从GPU读取数据的最有效的方法--在计算下一个帧时,您可能至少需要在后面读取一个帧。
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55333010

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档