目标

视频的硬件解码近来发展非常快速,尤其是在低功耗的设备上。本教程会讲述一些硬件加速的背景知识并解释一下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. 【概率论】5-8:Beta分布(The Beta Distributions)

    title: [概率论]5-8:Beta分布(The Beta Distributions) categories: - Mathematic - Probability keywords: - Th ...

  2. 30、提高并行度&广播共享数据

    一.提高并行度 1.图解 实际上Spark集群的资源并不一定会被充分利用到,所以要尽量设置合理的并行度,来充分地利用集群的资源.才能充分提高Spark应用程序的性能. Spark会自动设置以文件作为输 ...

  3. 【一起来烧脑】一步学会Vue.js系统

    Vuejs是一个构建数据驱动的web界面的库,通过api实现响应的数据绑定和组合的视图组件,Vue.js的核心是一个响应的数据绑定系统,它让数据与DOM保持同步非常简单,一旦创建了绑定,DOM 将与数 ...

  4. 讲解SQL数据库语句

    前言 大家好,我是 Vic,今天给大家带来讲解SQL数据库语句的概述,希望你们喜欢 数据库语句 create database teach; use teach; create table `teac ...

  5. C++ 如何进阶?

    1.C++的用途和意义 总体来说,C++作为一门软件开发语言,它的流行度是在减少的.主要原因在于语言的复杂和灵活导致软件开发成本提高,这体现在开发周期和人力上.它不适用于startup公司的快速开发, ...

  6. GoCN每日新闻(2019-09-24)

    1. Go 搭建的高效网页爬虫:https://creekorful.me/building-fast-modern-web-crawler/ 2. Go 时区处理:https://medium.co ...

  7. 7中漂亮的纯css字体

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  8. 7、vueJs基础知识07

    UI组件库 element-ui和mint-ui 其实都是借鉴了bootstrap bootstrap: 由twitter 开源 简洁.大方 官网文档https://www.bootcss.com/ ...

  9. vgg16中的函数

    1.inspect.getfile(文件名)文件名一般与类名相同,返回文件目录包含文件名 import inspect class os测试: def __init__(self): path = i ...

  10. zookeeper/kafka的部署

    Ubuntu中安装zookeeper及kafka并配置环境变量   首先安装zookeeper zookeeper需要jdk环境,请在jdk安装完成的情况下安装zookeeper1.从官网下载zook ...