使用D3D渲染YUV视频数据<转>
转载地址:http://blog.csdn.net/dengzikun/article/details/5824874
源码地址:http://download.csdn.net/download/dengzikun/2909129
在PC机上,对于YUV格式的视频如YV12,YUY2等的显示方法,一般是采用DIRECTDRAW,使用显卡的OVERLAY表面显示。OVERLAY技术主要是为了解决在PC上播放VCD而在显卡上实现的一个基于硬件的技术。OVERLAY的出现,很好的解决了在PC上播放VCD所遇到的困难。早期PC处理能力有限,播放VCD时,不但要做视频解码工作,还需要做YUV到RGB的颜色空间转换,软件实现非常耗费资源,于是,YUV OVERLAY表面出现了,颜色空间转换被转移到显卡上去实现,显卡做这些工作是具有天生优势的。
随着显卡技术的发展,OVERLAY的局限性也越来越充分的暴露出来。一般显卡只支持一个OVERLAY表面,用OVERLAY实现多画面比较困难,视频和文本的叠加也有困难,当然,要实现一些特效就更难了。更重要的是,OVERLAY技术在显卡上是属于2D模块,在高品质3D游戏的推动下,现在的显卡的功能和性能,主要体现在3D模块上,厂商投入最大的,也是在GPU的3D模块上。OVERLAY技术无法利用和发挥显卡GPU的3D性能。微软早就停止了对DIRECTDRAW的支持,鼓励开发人员转向DIRECT3D,所以OVERLAY也无法使用新的API。
早期的3D渲染,主要是使用CPU做的,显卡做的较少。后来,显卡GPU的处理能力越来越强,承担的3D渲染功能也越来越多,开始使用的是固定渲染管线,也就是说所有的渲染算法都是显卡内置的,我们只能组合使用这些算法。现在的显卡采用的都是可编程的渲染管线,也就是说我们可以编写自己的渲染算法,下载到显卡上去执行,替换固定渲染管线算法,灵活性大大提高。随着GPU效能的提高,显卡在图像处理、视频处理、科学计算等领域得到了广泛的应用。
使用D3D渲染YUV视频,可以采用D3D SURFACE渲染,也可以采用D3D纹理来渲染。SURFACE渲染比较简单,但功能限制较多,下面我们只讨论D3D纹理视频渲染。纹理视频渲染,就是把视频数据填充到二维纹理中,结合我们自己写的一段像素Shader代码,送到显卡的GPU渲染管线中去渲染。
以下假设读者了解所讨论的视频格式细节。
对于YV12视频数据,可以创建三个纹理,分别填充Y、U、V视频数据。对于缺失的U、V采样点,我们可以利用显卡内置的双线性滤波算法插值出来,这是简单的方法。当然,也可以采用更好的图像插值算法,以达到更高的图像质量,这需要我们通过Shader实现我们的插值算法,然后分别把U、V渲染到纹理,实现更好的插值。相对与双线性滤波,缺点是复杂更度高,效率低。U、V插值后,视频数据从YUV420转换为YUV444,然后做颜色空间转换,从YUV444转换为RGB32,转换的Shader代码很简单,就是一个矩阵乘法运算。对于I420数据,就是把YV12数据的U、V数据在内存中的位置对调,其他处理和YV12一样。
NV12格式,Y平面和YV12一样,UV部分是打包格式。所以UV部分需要单独处理,先把UV部分填充到一个纹理中,然后对UV纹理做两次简单的渲染到纹理,从而把U、V数据分别渲染到两个纹理。经过这样的处理,我们得到的数据就和YV12的数据一样了,接下来的处理就可以参照YV12的处理流程和方法了。
对于打包格式的数据YUY2,渲染时需要插值出缺失的U、V采样。YUY2在只在奇数像素上缺失U、V采样,这样处理的时候需要区分奇偶像素,对于偶数像素,不需要做U、V插值,直接做颜色空间转换。对于奇数像素,需要利用相邻的U、V采样做插值,可以采用Catmull-Rom插值算法或者线性插值算法。插值后,就可以做颜色空间转换。UYVY的做法和YUY2类似。
对于RGB格式,我所使用的NVIDIA GeForce 9800 GT显卡支持RGB32,RGB555,RGB565,不支持RGB24。所以对于RGB24,需要在Shader代码中分别取出R、G、B,再组成RGB32输出即可。RGB32,RGB555,RGB565不需要额外处理,可以直接渲染。
对于平面文本叠加,采用了微软提供的CD3DFont类,但这个类不支持中文,我在这个类的基础上做了一些修改,实现了一个支持中文的文本叠加类。这两个类互相配合,可以高效地实现平面文本叠加。
以上所讨论的内容,均使用Direct3D9.0c进行了验证测试。对OpenGL了解不多,但我想这些方法对于OpenGL应该同样适用,毕竟这两个3D架构在PC上实现的功能是相近的。
使用3D渲染平面视频,可以实现多种特效,像多画面、画中画、文本叠加、缩放,都很容易实现,性能也很好。如果结合其他3D技术,还可以做出很炫很酷的特效,就看我们的想象力了。
使用D3D渲染YUV视频数据<转>的更多相关文章
- 使用D3D渲染YUV视频数据
源代码下载 在PC机上,对于YUV格式的视频如YV12,YUY2等的显示方法,一般是采用DIRECTDRAW,使用显卡的OVERLAY表面显示.OVERLAY技术主要是为了解决在PC上播放VCD而在显 ...
- 使用DirectDraw直接显示YUV视频数据
最近在编写一个进行视频播放的ActiveX控件,工作已经接近尾声,现将其中显示YUV数据的使用DirectDraw的一些经验总结如下:(解码部分不是我编写的,我负责从网络接收数据,将数据传给解码器,并 ...
- 如何使用DirectDraw直接显示RGB、YUV视频数据(播放yuv)
#include "draw.h"void CTest100Dlg::OnButton1() { // TODO: Add your control notification ha ...
- 基于RTP的H264视频数据打包解包类
from:http://blog.csdn.net/dengzikun/article/details/5807694 最近考虑使用RTP替换原有的高清视频传输协议,遂上网查找有关H264视频RTP打 ...
- JavaCV 采集摄像头及桌面视频数据
javacv 封装了javacpp-presets库很多native API,简化了开发,对java程序员来说比较友好. 之前使用JavaCV库都是使用ffmpeg native API开发,这种方式 ...
- FFmpeg YUV视频序列编码为视频
上一篇已经写了如何配置好开发环境,这次就先小试牛刀,来个视频的编码.搞视频处理的朋友肯定比较熟悉YUV视频序列,很多测试库提供的视频数据都是YUV视频序列,我们这里就用用YUV视频序列来做视频.关于Y ...
- D3D-GetBackBuffer &GetFrontBufferData 抓屏&D3D抓取GPU数据
HRESULT GetBackBuffer( [in] UINT iSwapChain, [in] UINT ...
- 实战OpenGLES--iOS平台使用OpenGLES渲染YUV图片
上一篇文章 实战FFmpeg--iOS平台使用FFmpeg将视频文件转换为YUV文件 演示了如何将视频文件转换为yuv文件保存,现在要做的是如何将yuv文件利用OpenGLES渲染展示出图像画面.要将 ...
- 使用ffmpeg将BMP图片编码为x264视频文件,将H264视频保存为BMP图片,yuv视频文件保存为图片的代码
ffmpeg开源库,实现将bmp格式的图片编码成x264文件,并将编码好的H264文件解码保存为BMP文件. 实现将视频文件yuv格式保存的图片格式的測试,图像格式png,jpg, gif等等測试均O ...
随机推荐
- Git分支管理及合并
Git分支管理 建立分支 git branch [name] 切换到分支 git checkout [name] 查看有哪些分支 git branch 比较分支 git diff [b ...
- c/c++指针常见错误
一 #include <bits/stdc++.h> using namespace std; void f(char *str) { char *s = str; str[] = ' / ...
- PostgreSQL常用插件收集
hexdump -C 数据表文件 -- 查看表文件中数据. pg_stat_statements pgcompacttable -- 在减少锁的情况下,清理表和索引的老空间. pg_repack--P ...
- Java中,什么时候用logger.debuge,info,error
简单的说,就是配合log的等级过滤输出比如,你在开发的时候,要验证一个方法有没有被调用到,为了方便调试,通常会在这个方法开始的时候加一些system.out.但是项目真正发布的时候这些代码通常是要移除 ...
- HDU 3986
http://acm.hdu.edu.cn/showproblem.php?pid=3986 从开始的最短路里依次删一条边,求新的最短路,求最长的最短路 删边操作要标记节点以及节点对应的边 #incl ...
- Jmeter-Critical Section Controller(临界区控制器)
The Critical Section Controller ensures that its children elements (samplers/controllers, etc.) will ...
- mybatis异常:Could not find result map Java.util.Map 问题分析及解决 定位不到具体的位置的错误
mybatis异常:Could not find result map Java.util.Map 问题分析及解决 报这个错误呢,很难受的就是你定位不到具体的地方,找不到位置修改,你只知道有错误,但是 ...
- python静态方法类方法属性方法
Python的静态方法和类成员方法都可以被类或实例访问,两者概念不容易理清,但还是有区别的: 1)静态方法无需传入self参数,类成员方法需传入代表本类的cls参数: 2)从第1条,静态方法是无法访问 ...
- [Luogu4899][IOI2018] werewolf 狼人
luogu sol \(\mbox{IOI2018}\)的出题人有没有看过\(\mbox{NOI2018}\)的题目呀... \(\mbox{Kruskal}\)重构树+二维数点. 题目相当于是问你从 ...
- 【java多线程】java的内存模型
Java内存模型 下面是我从百度上引入的一张具有代表性的图 ①解释:我根据这张图来解释java内存模型,从图中可以看出每个线程都需要从主内存中读取操作,这个就是java内存模型的规定之一,所有的变量存 ...