目标

视频的硬件解码近来发展非常快速,尤其是在低功耗的设备上。本教程会讲述一些硬件加速的背景知识并解释一下GStreamer是怎么做的。

悄悄告诉你,如果设置正确地话,我们什么也不用做,GStreamer自动做完这一切的。

介绍

视频解码是非常消耗CPU的一个任务,尤其是1080P这种高分辨率的高清节目。幸运的是,现在的显卡都带了可编程的GPU,如果我们用GPU用来做视频解码,那么CPU就可以解放出来做其他的任务了。低功耗的CPU是无法做解码这样的工作的,这时硬件的配合就是必须的了。

目前来说(2012.07),每个GPU的制造商都提供了访问它们的硬件的方法(API),不幸的是各家并不相同,并没有一个强制的标准。

VAAPI(Video Acceleration API):2007年Intel设计的,目的是在Unix操作系统的XWindow系统下运行,现在开源了。现在不仅仅局限于Intel的GPU了,其他制造商也可以使用了。GStreamer通过gstreamer-vaapi和fluvadec这个插件来使用。

VDPAU(Video Decode and Presentation API for Unix):2008年NVidia设计的,最早也是运行在Unix的XWindow系统下,现在同样开源了。虽然同样已经是开源库了,但除了NVidia自己外还没有其他制造商使用。GStreamer通过vdpau和fluvadec这个插件来使用。

DXVA(DirectX Video Acceleration):微软为了Windows系统和XBox360定制的。GStreamer通过fluvadec这个插件来使用。

XVBA(X-Video Bitstream Acceleration):AMD设计,在Linux操作系统的XWindow系统下下X
Video的扩展。目前在AMD的ATI显卡中有支持。GStreamer通过fluvadec这个插件来使用。

VDA(Video Decode Acceleration):应用于Mac OSX10.6.3之后,仅仅加速H.264的解码,GStreamer通过fluvadec这个插件来使用。

OpenMAX(Open Media Acceleration):由非盈利性联合Khronos Group设计的,是一组跨平台的C语言编程接口。GStreamer通过gstreamer-omx这个插件来使用。

OVD(Open Video Decode):AMD的又一个API,GStreamer目前不能使用这个接口。

DCE(Distributed Codec Engine):一个开源的软件库(libdce)和TI定制的API,提供给linux系统和ARM平台的。GStreamer通过gstreamer-ducati插件可以使用。

硬件加速视频解码插件内部的工作原理

通常这些API提供了一系列的功能,比如:视频解码,后处理,解码帧的描述,或者把帧下载到系统内存等等。相应的,不同的功能插件一般是给不同的element使用的,这样pipeline可以适应任何需求。

例如:gstreamer-vaapi这个插件提供了vaapidecode、vaapiupload、vaapidownload、vaapisink这些element,允许通过VAAPI来使用硬件加速功能,上传原始视频帧数据到GPU内存,下载GPU帧到系统内存并且描述GPU帧的内容。

这里区分传统的GStreamer帧(在系统内存中)和由硬件加速API生成的帧是很重要的。硬件加速生成的帧位于GPU的内存中,是GStreamer不能直接操作的。通常他们是下载到系统内存中,然后就可以被当成普通帧来处理了,但留在GPU中由GPU来显示效率是最高的。

GStreamer需要追踪这些“硬件缓冲区”,因为这样传统的缓冲区可以继续从一个element流向另一个element,但他们的内容尽皆是硬件缓冲区的ID或者Handler。比如:一个appsink获得了硬件缓冲区ID,硬件缓冲区什么都不会响应,因为它们只能由生成它们的插件来处理。

为了让这个更加明确,这些缓冲区都有特殊的Caps,就像video/x-vdpau-output或者video/x-fluendo-va这样。在这种方式下,GStreamer的自动插入机制不会试着把硬件缓冲区去传给传统的element——因为他们根本风马牛不相及。而且,使用了这些Caps之后,自动插入机制就可以使用硬件加速来搭建pipeline了,因为,在VAAIP解码器之后,只有VAAPI
sink这一种element是可以连接上去的。

这些都说明,如果一个硬件加速的API在系统中可用而且对应的GStreamer插件也有的话,playbin2等自动连接的element可用随意的使用它们来搭建pipeline,应用不需要做什么特殊的处理。

当playbin2必须在一些element中选择时,就像是选择传统的软件解码还是硬件加速的解码,它会使用rank来决定。这个rank属性是每个element都有的,它会指明优先级,playbin2会选用最高的rank的element来搭建pipeline。

所以,playbin2是否使用硬件加速的element取决于当时所有可用的element的rank值。而且,最简单地确保硬件加速的element被选中的方法是修改rank属性的值。代码如下:

[objc] view
plain
 copy

  1. static void enable_factory (const gchar *name, gboolean enable) {
  2. GstRegistry *registry = NULL;
  3. GstElementFactory *factory = NULL;
  4. registry = gst_registry_get_default ();
  5. if (!registry) return;
  6. factory = gst_element_factory_find (name);
  7. if (!factory) return;
  8. if (enable) {
  9. );
  10. }
  11. else {
  12. gst_plugin_feature_set_rank (GST_PLUGIN_FEATURE (factory), GST_RANK_NONE);
  13. }
  14. gst_registry_add_feature (registry, GST_PLUGIN_FEATURE (factory));
  15. return;
  16. }

传给方法的第一个参数是要修改的element的名字,比如:vaapidecode或者fluvadec。

这里主要的方法是gst_plugin_feature_set_rank(),它会设置element的rank。为了方便起见,rank分成NONE,MARGINAL,SECONDARY和PRIMARY,但任何数字都可以的。比如我们可用给某个element设置PRIMARY+1,那么它就比其他设置成PRIMARY的rank高,设置一个element的rank是NONE,会让自动连接机制屏蔽它(永远选不上)。

硬件加速视频解码和GStreamer的SDK

GStreamer的SDK在2012年七月前是没有硬件加速的视频解码的插件的。主要原因是有些还没有完全写完,还有一些问题。但请记住这个情况会在不久改变。

有些插件可用在它们公开源码的基础上自己编译出来,使用Cerbero编译系统。有些插件是供应商已经编译好了。

下面会简单介绍一下当前这些插件的情况。

vdpad在gst-plugin-bad

针对VDPAU的GStreamer element,在gst-plugin-bad里面

支持mpeg2,mpeg4和H264的编解码

gstreamer-vaapi

针对VAAPI的GStreamer element,项目的网址请猛戳这里

支持mpeg2,mpeg4,H264,VC1和WMV3的编解码

可用直接和Clutter配合使用,这样帧就可以一直在GPU里面

和playbin2兼容

gst-omx

针对OpenMax的GStreamer element,项目网址请猛戳这里

在不同的硬件下支持不同的编解码

fluvadec

针对VAAPI,VDPAU,DXVA2,XVBA和VDA的GStreamer element.

根据不同的API,支持不同的编解码


MPEG2 MPEG4 H.264 VC1
VAAPI
VDPAU
XVBA

DXVA2


VDA


可用直接和Clutter配合使用,这样帧就可以一直在GPU里面

和playbin2兼容


【GStreamer开发】GStreamer播放教程08——视频解码的硬件加速的更多相关文章

  1. gstreamer应用开发(播放器)之旅

    GStreamer开发,主要分为两块:应用开发.插件开发. 插件开发人员,通常是编解码库的作者(做出了编解码库后,希望gstreamer能用起来这个库,因此增加这个适配层).芯片原厂人员(将自家的hw ...

  2. 安装gstreamer开发环境

    ubuntu中安装gstreamer开发环境: * 安装gstreamer基本库,工具,以及插件 sudo apt--dev gstreamer-tools gstreamer0.-tools gst ...

  3. 【转】一步一步教你在Ubuntu12.04搭建gstreamer开发环境

    原文网址:http://blog.csdn.net/xsl1990/article/details/8333062 闲得蛋疼    无聊寂寞冷    随便写写弄弄 看到网上蛮多搭建gstreamer开 ...

  4. 开发快平台(M302I小e开发板系列教程)

    开发快平台(M302I小e开发板系列教程) 开发块平台ESP8266模块相关理解 一. M302I小e开发板源码注释,源码基于:v1.4.0.8-u34.zip 1. user_main.c /*** ...

  5. Apple Watch开发快速入门教程

     Apple Watch开发快速入门教程  试读下载地址:http://pan.baidu.com/s/1eQ8JdR0 介绍:苹果为Watch提供全新的开发框架WatchKit.本教程是国内第一本A ...

  6. C#开发Unity游戏教程循环遍历做出判断及Unity游戏示例

    C#开发Unity游戏教程循环遍历做出判断及Unity游戏示例 Unity中循环遍历每个数据,并做出判断 很多时候,游戏在玩家做出判断以后,游戏程序会遍历玩家身上大量的所需数据,然后做出判断,即首先判 ...

  7. C#开发Unity游戏教程之判断语句

    C#开发Unity游戏教程之判断语句 游戏执行路径的选择——判断 玩家在游戏时,无时无刻不在通过判断做出选择.例如,正是因为玩家做出的选择不同,才导致游戏朝着不同的剧情发展,因此一个玩家可以对一个游戏 ...

  8. C#开发Unity游戏教程之游戏对象的行为逻辑方法

    C#开发Unity游戏教程之游戏对象的行为逻辑方法 游戏对象的行为逻辑——方法 方法(method),读者在第1章新建脚本时就见过了,而且在第2章对脚本做整体上的介绍时也介绍过,那么上一章呢,尽管主要 ...

  9. C#开发Unity游戏教程之使用脚本变量

    C#开发Unity游戏教程之使用脚本变量 使用脚本变量 本章前面说了那么多关于变量的知识,那么在脚本中要如何编写关于变量的代码,有规章可循吗?答案是有的.本节会依次讲解变量的声明.初始化.赋值和运算. ...

随机推荐

  1. Jenkins 通过 maven 构建编译 JAVA 项目环境

    Jenkins 通过maven 构建编译 JAVA 项目环境 官网下载合适Jenkins版本包: 1.jenkins http://mirrors.jenkins.io/war-stable/ 2.J ...

  2. C# 异常 抛异常的时候 同时抛出 传入的参数

    abp的审计日志都把这些功能实现了 可以借鉴 抛异常的时候 同时抛出 传入的参数 大致这样实现,aop,方法执行先,先把参数写入到栈中,抛异常时,栈中自然就有此时的参数了. 可用于重现该异常. 获取把 ...

  3. 【一起来烧脑】一步学会CSS3体系

    [外链图片转存失败(img-yfi1VPyy-1563434266398)(https://upload-images.jianshu.io/upload_images/11158618-fc8784 ...

  4. [golang]golang如何覆盖输出console,实现进度条;golang一个骚气的进度提示库

    [golang]golang如何覆盖输出console,实现进度条 package main import( "fmt" "os" "time&quo ...

  5. MySQL:服务无法启动(1067)问题

    打开安装文件下的my.ini 找到: #Path to the database rootdatadir="C:/ProgramData/MySQL/MySQL Server 5.5/dat ...

  6. Redis哨兵参数

    一.常用命令 sentinel的基本状态信息INFO 列出所有被监视的主服务器,以及这些主服务器的当前状态SENTINEL masters 列出指定主redis的从节点状态情况SENTINEL sla ...

  7. 2018-2019-2 《网络对抗技术》Exp8 Web基础 20165326

    Web基础 实验要求 本实践的要求: Web前端HTML,能正常安装.启停Apache.理解HTML,理解表单,理解GET与POST方法,编写一个含有表单的HTML. Web前端javascipt.理 ...

  8. Unity火爆插件Behavior Designer行为树插件学习

    如果要让游戏里的角色或者NPC能执行预设的AI逻辑,最简单的用IF..ELSE...神器既可以实现, 但是再复杂的一般用经典的状态机来切换状态,但是写起来比较麻烦.相对的,行为树(Behavior T ...

  9. text-align-last 实现文本居中对齐

    1.示例代码 <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> < ...

  10. 谱聚类算法及其代码(Spectral Clustering)

    https://blog.csdn.net/liu1194397014/article/details/52990015 https://blog.csdn.net/u011089523/articl ...