(七) EGL和OpenGLES Shader显示YUV视频

这篇博客介绍了如何在C++中使用EGL和OpenGLES Shader显示YUV420格式的视频。通过解析代码,展示了从YUV到RGB的转换过程,并探讨了纹理数据的范围问题。
摘要由CSDN通过智能技术生成
EGL为OpenGL与系统窗口对应的适配层    官方文档 https://www.khronos.org/registry/EGL/sdk/docs/man/
	EGL在android中可以用c来调,也可以用java来调用

glsl提供了大量的内置函数

官网下载 ffmpeg builds 将 ffmpeg.exe 命令配置到环境变量 E:\mpeg\ffmpeg-4.0.2-cmd\bin
	E:\mpeg\videos 下执行命令 ffmpeg -i 1080.mp4 -pix_fmt yuv420p -s 424x240 out.yuv    将当前目录下的 mp4 视频转换为 yuv420p 格式(20多M转换成了200多M)

YUV420平面方式存储(下图是I420排列,其他存储排列形式参看 media.txt ):
这里写图片描述

###代码(c++)
#include “common.hpp”
#include <android/native_window.h>
#include <android/native_window_jni.h>
#include <EGL/egl.h> // EGL

static bool isPlay;

#define get_str(x) #x // 已 define、# 形式定义字符串,这样写的好处是不用写字符串的 "" 符号了
static const char *vertShader = get_str( // 这样赋值字符串,数据类型需要是 const char * ,否则会报警告
    attribute vec4 aPosition; //顶点坐标
    attribute vec2 aTexCoord; //材质顶点坐标
    varying vec2 vTexCoord;   //输出的材质坐标
    void main()
    {
        vTexCoord = vec2(aTexCoord.x,1.0-aTexCoord.y);
        gl_Position = aPosition;
    }
);
static char fragShader[1024]; // 片元着色器源码

JNIEXPORT void JNICALL Java_hankin_hjmedia_mpeg_Mp8_11Activity_show(JNIEnv *env, jobject instance, jstring url_, jobject surface, jstring vertStr_, jstring fragStr_)
{
    isPlay = true;
    const char * url = env->GetStringUTFChars(url_, NULL);
    const char * vertStr = env->GetStringUTFChars(vertStr_, NULL); // 顶点着色器源码在此文件中写成字符串了,没用assets里的,它们是一样的
    const char * fragStr = env->GetStringUTFChars(fragStr_, NULL);
    char path[512];
    strcpy(path, url);
    strcpy(fragShader, fragStr); // 片元着色器源码
    env->ReleaseStringUTFChars(vertStr_, vertStr);
    env->ReleaseStringUTFChars(fragStr_, fragStr);
    env->ReleaseStringUTFChars(url_, url);
    if (path[0]=='\0' || fragShader[0]=='\0')
    {
        LOGE("peth or fragShader is empty.");
        return;
    }

    ANativeWindow * nwin = ANativeWindow_fromSurface(env, surface); // 获取原始窗口
    // 1、display  EGL创建步骤
    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); // 创建EGL显示设备,选择默认的
    if (display == EGL_NO_DISPLAY)
    {
        LOGE("eglGetDisplay failed.");
        return;
    }
    /*
         EGLAPI EGLBoolean EGLAPIENTRY eglInitialize ( // 初始化EGLdisplay
             EGLDisplay dpy, // display
             EGLint *major, // 主版本号
             EGLint *minor // 次版本号, 两个都传空表示使用默认值 2.0 ?
         );
     */
    if (EGL_TRUE != eglInitialize(display, NULL, NULL)) // 初始化EGLdisplay,后面两个参数为 主版本号与次版本号, 传空表示使用默认值
    {
        LOGE("eglInitialize failed.");
        return;
    }
    /
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值