QML用openGL渲染NV12_nv12转rgb的 opengl_这是一个正经昵称的博客-程序员宅基地

技术标签: qml  Qt  opengles  问题记录  

前言

把之前写在windows的播放器移植到了我的安卓手机,就碰到了QOpenGLWidget需要替换的问题。
知乎、CSDN一搜就有渲染YUV420P的代码,git也有。没打招呼不放链接了。
用的是fbo的那个。主要记录下参数和问题。


一、QOpenGLTexture改动

NV12的UV数据是在一起的,所以texture只要创建两个,一个Y,一个UV。
格式套用RGB,RED放Y,GREEN和BLUE放UV:

	...
	mTexY->setFormat(QOpenGLTexture::R8_UNorm);
	...
	mTexUV->setFormat(QOpenGLTexture::RG8_UNorm);
	...

理所当然后面的都要调整:

	mTexY->setSize(w, h);
    mTexY->allocateStorage(QOpenGLTexture::Red, QOpenGLTexture::UInt8);

    mTexUV->setSize(w/2, h/2);
    mTexUV->allocateStorage(QOpenGLTexture::RG, QOpenGLTexture::UInt8);
	QOpenGLPixelTransferOptions options;
    options.setImageHeight(data.height);

    options.setRowLength(data.lineSize0);
    mTexY->setData(QOpenGLTexture::Red, QOpenGLTexture::UInt8, data.data0.data(), &options);

    options.setRowLength(data.lineSize1/2);
    options.setImageHeight(data.height/2);
    mTexUV->setData(QOpenGLTexture::RG, QOpenGLTexture::UInt8, data.data1.data(), &options);

上面lineSize是ffmpeg解码出来的,linesize0和linesize1都是图像的宽。

二、Fragment Src

	const char *fsrc = "\
    varying mediump vec4 textureOut; \
    uniform sampler2D textureY; \
    uniform sampler2D textureUV; \
    void main(void) \
    {\
        vec3 yuv; \
        vec3 rgb; \
        yuv.x = texture2D(textureY, textureOut.st).r - 0.0625; \
        yuv.y = texture2D(textureUV, textureOut.st).r - 0.5; \
        yuv.z = texture2D(textureUV, textureOut.st).g - 0.5; \
        rgb = mat3( 1,       1,         1, \
                    0,       -0.39465,  2.03211, \
                    1.13983, -0.58060,  0) * yuv; \
        gl_FragColor = vec4(rgb, 1); \
    }";

NV21就把yuv.y和yuv.z的.r .g换一下。

三、 渲染

绘制之前纹理绑定记得改:

	m_program.setUniformValue("textureY",0);
    m_program.setUniformValue("textureUV",1);

Qt5.12.1没有GL_QUADS了,搜一下这些关键词百度有一个解释绘制过程的文章,看了下画4个点的多边形和4个点的多三角是一样的:

	glDrawArrays(GL_TRIANGLE_FAN,0,4);

用这个。


其他问题

原先写好了code怎么也渲染不出来,跟了下打印,发现QML把宽高初始化给OpenGL和ffmpeg了,但是和本身控件大小不一致,就造成了glViewport和解码出来的图都不能渲染。
QML控件初始化完时在那个槽函数重设一下宽高,YUV宽高和OpenGL各个设置的大小都是一致的就没问题。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_20408527/article/details/121223761

智能推荐

python中的mul函数_mul函数的具体用法-程序员宅基地

展开全部PHP基础Author:陈庆平 (Andych)E-mail:[email protected]一、PHP入门二、PHP变量62616964757a686964616fe4b893e5b19e313332623836391、php变量的命名变量由字母,数字,下划线组成1)变量名区分大小写2)变量名必须以$开头3)不能以数字开头4)不能是系统关键字$example , $sut_name ,..._python mul

可执行jar-程序员宅基地

javaFx 可执行jar (jdk 11)目录src/main/java/com.mypackAppMain.javapackage com.mypack;import javafx.application.Application;/** * 打包运行 * 错误: 缺少 JavaFX 运行时组件, 需要使用该组件来运行此应用程序。 * 原因:模块化 ..._javafx.application.application 属于哪个jar

java输出变量数据类型_了解Java变量和数据类型-程序员宅基地

java输出变量数据类型At SitePoint we’re always looking to expand the range of topics we cover. Lately, we’ve set our sights on exploring the world of Java. If you’re a strong Java developer who wants to contri...

VM的安装中BIOS固件问题-程序员宅基地

VM的安装中BIOS固件问题这里假设你已经安装好vm却在运行时出现BIOS固件禁止虚拟内存运行,那么接下你就要重启电脑,在开机界面(比如我的电脑是LENOVO E750,那么就在LENOVO图标出现的时候)按下F2(其他型号品牌的电脑可能需要按下F1或者Delete或者Backspace)这个可以多次尝试调出 ThinkPad Setup界面找到Security下面的Virtualizat...

Python语法学习记录(13):字符串_"python中b=\" abcdefghijklmnopqrstuvwxyz \"的输入有什么错误-程序员宅基地

文章目录1、字符串简介:2、字符串的操作:2.1 字符串的赋值定义、子字符串字符串的赋值与定义:子字符串的提取:2.2 字符串运算符2.3 字符串的内置函数:2.4 字符串的转换:2.5 字符串的分割与拼接:2.6 字符串查找、替换、索引、计数:字符映射表:2.7 字符串的大小写和部分字符处理:2.8 字符串的编码解码:2.9 判断字符串的某种情况:3、字符串格式化3.1 python字符串格式化..._"python中b=\" abcdefghijklmnopqrstuvwxyz \"的输入有什么错误"

PowerSensor AI教程1.3 - 数字识别 - edge调用-程序员宅基地

介绍本章主要介绍edge环节,即如何通过调度程序看,将编译好elf模型部署到powersensor上面运行。本章需要使用新的powersensor镜像(2020.5月以后发布的镜像会带有DPU),下载地址:链接:https://pan.baidu.com/s/18CFK2aXonxuFF6-L_ittdw提取码:8ve4本章的例程与上一节的相同,请移步Powersensor AI教程1.1-数字识别-tf模型训练下载。主要过程进入powersenosr的jupyter文件管理页面,在/po_powersensor ai

随便推点

LightOJ - 1246-程序员宅基地

题解:第二类斯特林数我们可以把一个大矩形分成两个小矩形,就想国际象棋的棋盘一样,黑色的在一起白色在一起,这样的话我们在同一个矩形里的任意两个格子之间的曼哈顿距离一定是偶数,所以就变成了,我们从k个颜色里面选i个颜色放第一个矩形里面,从k-i个颜色里面选j个颜色放第二个矩形里面,这样就变成了第二类斯特林数,把n个两两不同的颜色放入k个无差别的非空子集里面(有差别的话乘以一个1/k!1/k!1/k!)最后就是答案了。#include <bits/stdc++.h>using namespace_lightoj - 1246

显示事务CATransaction-程序员宅基地

[CATransaction begin];[CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions]; //等价于[CATransaction setDisableActions: YES]; 执行显示动画, 不显示动画过程layer.hidden = YES; [CATr

sort和sorted的区别_sorted和sort的区别_进步者-王东太的博客-程序员宅基地

sort()与sorted()的不同在于,sort是在原位重新排列列表,而sorted()是产生一个新的列表。sort 是应用在 list 上的方法,sorted 可以对所有可迭代的对象进行排序操作。list 的 sort 方法返回的是对已经存在的列表进行操作,而内建函数 sorted 方法返回的是一个新的 list,而不是在原来的基础上进行的操作。..._sorted和sort的区别

题目38 解析url(ok)_ok解析网址-程序员宅基地

一个工厂有m条流水线来并行完成n个独立的作业该工厂设置了一个调度系统在安排作业时,总是优先执行处理时间最短的作业现给定流水线个数m需要完成的作业数n每个作业的处理时间分别为 t1,t2...tn请你编程计算处理完所有作业的耗时为多少当n>m时 首先处理时间短的m个作业进入流水线其他的等待当某个作业完成时,依次从剩余作业中取处理时间最短的进入处理输入描述:第一行为两个整数(采取空格分隔)分别表示流水线个数m和作业数n第二行输入n个整数(采取空格分隔)表示每个作业的处理_ok解析网址

ajax发送put请求参数,请求参数和PUT方法(Request params and PUT method)-程序员宅基地

请求参数和PUT方法(Request params and PUT method)我试图通过基于Grails的应用程序获取PUT请求传递的请求参数。我正在使用以下客户端代码发出请求:$.ajax({url: 'api/controllerName/anId',type: 'PUT',data: $('form').serialize()})与以下映射:"/api/$controller/$id?"..._put参数

LeetCode DI序列的有效排列(分治+动态规划)_我们给出一个字符串s,它是一个源于-程序员宅基地

我们给出 S,一个源于 {‘D’, ‘I’} 的长度为 n 的字符串 。(这些字母代表 “减少” 和 “增加”。)有效排列 是对整数 {0, 1, …, n} 的一个排列 P[0], P[1], …, P[n],使得对所有的 i:如果 S[i] == ‘D’,那么 P[i] > P[i+1],以及;如果 S[i] == ‘I’,那么 P[i] < P[i+1]。有多少个有效排列..._我们给出一个字符串s,它是一个源于

推荐文章

热门文章

相关标签