OpenGLES渲染yuv数据,YUV是一种颜色编码方法,主要用于电视系统以及模拟视频领域

OpenGLES渲染yuv数据

HarmonyOS
2024-05-21 22:17:17
浏览
收藏 0
回答 1
待解决
回答 1
按赞同
/
按时间
xdpan

一、yuv数据介绍

YUV,分为三个分量,“Y”表示明亮度(Luminance或Luma),也就是灰度值;而“U”和“V” 表示的则是色度(Chrominance或Chroma),作用是描述影像色彩及饱和度,用于指定像素的颜色

与我们熟知的RGB类似,YUV也是一种颜色编码方法,主要用于电视系统以及模拟视频领域,它将亮度信息(Y)与色彩信息(UV)分离,没有UV信息一样可以显示完整的图像,只不过是黑白的,这样的设计很好地解决了彩色电视机与黑白电视的兼容问题。并且,YUV不像RGB那样要求三个独立的视频信号同时传输,所以用YUV方式传送占用极少的频宽。

YUV码流的存储格式其实与其采样的方式密切相关,主流的采样方式有三种,YUV4:4:4,YUV4:2:2,YUV4:2:0.

YU12和YV12属于YUV420格 式,又叫Plane模式,Y , U , V分别在不同平面,也就是有三个plane。将Y、U、V分量分别打包,依次存储。其每一个像素点的YUV数据提取遵循YUV420格式的提取方式,即4个Y分量共用一 组UV。注意,上图中,Y'00、Y'01、Y'10、Y'11共用Cr00、Cb00,其他依次类推。 YU12格式也叫作I420格式,首先是所有Y值,然后是所有U值,最后是所有V值 

二、EGL环境搭建

1.1 关键方法介绍

1)eglGetDisplay

获取EGL显示窗口

2)eglInitialize

对(1)中获取到的Display进行初始化

3)eglChooseConfig

根据对窗口的条件要求从系统中选择最佳的配置数据

4)eglCreateContext

结合EGLDisplay与EGLConfig创建EGL上下文

6)eglMakeCurrent

7)eglSwapBuffer

三、OpenGL 着色器

2.1 关键方法介绍

加载着色器

1)eglCreateShader

根据指定类型(GL_FRAGMENT_SHADER、GL_VERTEX_SHADER…)创建一个空的OpenGL Shader

2)glShaderSource

给创建出来的Shader输入GLSL代码

3)glCompileShader

编译shader

4)glGetShaderiv

获取编译过程中的状态信息

GL_COMPILE_STATUS 获取编译状态,0表示编译失败

GL_INFO_LOG_LENGTH 获取编译中的日志字符长度

5)glGetShaderInfoLog

根据(4)中的日志长度得到编译中的日志信息

6)glDeleteShader

清除Shader

创建着色器程序

7)glCreateProgram

创建一个空的着色器程序

8)glAttachShader

为着色器程序添加Shader

9)glLinkProgram

对(8)中的Shader进行链接

10)glGetProgramiv

获取链接过程中的状态信息

GL_LINK_STATUS 获取链接状态码,0表示链接失败

GL_INFO_LOG_LENGTH 获取链接过程中的日志字符长度

11)glGetProgramInfoLog

根据(10)中的日志长度得到链接过程中的日志信息

12)glDeleteProgram

清理着色器程序

渲染流程

四、demo代码

1)顶点着色器

/**  * Vertex shader.  */ 
const char 
VERTEX_SHADER[] = "attribute vec4 aPosition; \n" 
"attribute vec2 aTextCoord;\n" 
"varying vec2 vTextCoord;\n" 
"void main() {\n" 
"vTextCoord = vec2(aTextCoord.x, 1.0 - aTextCoord.y);\n" 
"gl_Position = aPosition;\n" 
"}\n";

2)片段着色器

/**  * Fragment shader.  */ 
const char 
FRAGMENT_SHADER[] = "precision mediump float;\n" 
"varying vec2 vTextCoord;\n" 
"uniform sampler2D yTexture;\n" 
"uniform sampler2D uTexture;\n" 
"uniform sampler2D vTexture;\n" 
"\n" 
"void main()\n" 
"{\n" 
"    vec3 yuv;\n" 
"    vec3 rgb;\n" 
"    yuv.r = texture2D(yTexture, vTextCoord).g;\n" 
"    yuv.g = texture2D(uTexture, vTextCoord).g - 0.5;\n" 
"    yuv.b = texture2D(vTexture, vTextCoord).g - 0.5;\n" 
"\n" 
"    rgb = mat3(\n" 
"    1.0, 1.0, 1.0,\n" 
"    0.0, -0.39465, 2.03211,\n" 
"    1.13983, -0.5806, 0.0\n" 
"    ) * yuv;\n" 
"    gl_FragColor = vec4(rgb, 1.0);\n" 
"}\n";

3)初始化GL环境

4)加载yuv数据

5)上屏渲染

分享
微博
QQ
微信
回复
2024-05-22 21:12:54
相关问题
摄像头获取到的yuv数据是否有旋转
185浏览 • 1回复 待解决
使用Promise实现一种串行调用方式
402浏览 • 1回复 待解决
java主要用来干嘛的?
7383浏览 • 1回复 待解决
视频都支持哪些编码格式
202浏览 • 1回复 待解决
求鸿蒙视频编码解码的具体demo
5488浏览 • 1回复 待解决
视频解码结果通过到vulkan渲染
629浏览 • 1回复 待解决
Color.Black如何转成对应的颜色编码
807浏览 • 1回复 待解决
视频进度滑动条的三实现方式
391浏览 • 1回复 待解决
为什么鸿蒙系统要用Linux内核
5384浏览 • 2回复 待解决