博客
关于我
[FFmpeg + OpenGL + OpenSL ES]OpenGL ES 渲染获取到的yuv数据 - 7
阅读量:273 次
发布时间:2019-03-01

本文共 2444 字,大约阅读时间需要 8 分钟。

在OpenGL中渲染YUV数据时,通常会使用3个纹理分别获取Y、U和V的值,然后通过公式转换为RGB颜色。这种方法让转换过程在GPU完成,效率远高于CPU。

渲染流程

YUV数据的转换涉及三个步骤:获取纹理数据、执行转换公式以及输出结果。每个步骤都需要精确的计算和优化。

获取纹理数据

在OpenGL中,使用顶点着色器和片元着色器来处理纹理数据。顶点着色器负责顶点坐标的处理,片元着色器则负责纹理的采样和转换。代码如下:

attribute vec4 av_Position;attribute vec2 af_Position;varying vec2 v_texPosition;void main() {    v_texPosition = af_Position;    gl_Position = av_Position;}

片元着色器代码:

precision mediump float;varying vec2 v_texPosition;uniform sampler2D sampler_y;uniform sampler2D sampler_u;uniform sampler2D sampler_v;void main() {    float y = texture2D(sampler_y, v_texPosition).r;    float u = texture2D(sampler_u, v_texPosition).r - 0.5;    float v = texture2D(sampler_v, v_texPosition).r - 0.5;    vec3 rgb = vec3(        y + 1.403 * v,        y - 0.344 * u - 0.714 * v,        y + 1.770 * u    );    gl_FragColor = vec4(rgb, 1.0);}

Java工程配置

在Android项目中,需要配置OpenGL渲染环境。创建opengl包,添加必要的GL类:

public class WlRender implements GLSurfaceView.Renderer {    private Context mContext;    private int program_yuv;    private int avPosition_yuv;    private int afPosition_yuv;    private int[] textureId_yuv;    private int width_yuv;    private int height_yuv;    private ByteBuffer y, u, v;    public WlRender(Context context) {        mContext = context;        // 初始化顶点和纹理坐标        // ...    }    @Override    public void onSurfaceCreated(GL10 gl10, EGLConfig eglConfig) {        initRanderYUV();    }    @Override    public void onSurfaceChanged(GL10 gl10, int width, int height) {        GLES20.glViewport(0, 0, width, height);    }    @Override    public void onDrawFrame(GL10 gl10) {        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);        renderYUV();        GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);    }    private void initRanderYUV() {        // 加载着色器程序        // ...        // 创建并绑纹理        GLES20.glGenTextures(3, textureId_yuv);        // 设置纹理参数        // ...    }    public void setYUVRenderData(int width, int height, byte[] y, byte[] u, byte[] v) {        this.width_yuv = width;        this.height_yuv = height;        this.y = ByteBuffer.wrap(y);        this.u = ByteBuffer.wrap(u);        this.v = ByteBuffer.wrap(v);    }    private void renderYUV() {        if (width_yuv > 0 && height_yuv > 0 && y != null && u != null && v != null) {            GLES20.glUseProgram(program_yuv);            // 启用顶点和纹理位置            // ...            // 绘制纹理            // ...        }    }}

注意事项

目前绘制存在问题,但程序能正常运行。后续需要解决这些问题,确保图像正确显示。

转载地址:http://udzo.baihongyu.com/

你可能感兴趣的文章
OpenCV与AI深度学习 | 实战 | YOLOv10模型微调检测肾结石并提高准确率
查看>>
OpenCV与AI深度学习 | 实战 | 使用OpenCV和Streamlit搭建虚拟化妆应用程序(附源码)
查看>>
OpenCV与AI深度学习 | 实战 | 使用OpenCV确定对象的方向(附源码)
查看>>
OpenCV与AI深度学习 | 实战 | 使用YOLOv8 Pose实现瑜伽姿势识别
查看>>
OpenCV与AI深度学习 | 实战 | 使用YoloV8实例分割识别猪的姿态(含数据集)
查看>>
OpenCV与AI深度学习 | 实战 | 使用姿态估计算法构建简单的健身训练辅助应用程序
查看>>
OpenCV与AI深度学习 | 实战 | 基于OpenCV和K-Means聚类实现颜色分割(步骤 + 代码)
查看>>
OpenCV与AI深度学习 | 实战 | 基于YoloV5和Mask RCNN实现汽车表面划痕检测(步骤 + 代码)
查看>>
OpenCV与AI深度学习 | 实战 | 基于YOLOv9+SAM实现动态目标检测和分割(步骤 + 代码)
查看>>
OpenCV与AI深度学习 | 实战 | 基于YOLOv9和OpenCV实现车辆跟踪计数(步骤 + 源码)
查看>>
OpenCV与AI深度学习 | 实战 | 文本图片去水印--同时保持文本原始色彩(附源码)
查看>>
OpenCV与AI深度学习 | 实战 | 通过微调SegFormer改进车道检测效果(数据集 + 源码)
查看>>
OpenCV与AI深度学习 | 实战—使用YOLOv8图像分割实现路面坑洞检测(步骤 + 代码)
查看>>
OpenCV与AI深度学习 | 实战篇——基于YOLOv8和OpenCV实现车速检测(详细步骤 + 代码)
查看>>
OpenCV与AI深度学习 | 实战|OpenCV实时弯道检测(详细步骤+源码)
查看>>
OpenCV与AI深度学习 | 实用技巧 | 使用OpenCV进行模糊检测
查看>>
OpenCV与AI深度学习 | 实践教程|旋转目标检测模型-TensorRT 部署(C++)
查看>>
OpenCV与AI深度学习 | 工业缺陷检测中数据标注需要注意的几个事项
查看>>
OpenCV与AI深度学习 | 干货 | 深度学习模型训练和部署的基本步骤
查看>>
OpenCV与AI深度学习 | 手把手教你用Python和OpenCV搭建一个半自动标注工具(详细步骤 + 源码)
查看>>