• 【GStreamer开发】GStreamer播放教程08——视频解码的硬件加速


    目标

          视频的硬件解码近来发展非常快速,尤其是在低功耗的设备上。本教程会讲述一些硬件加速的背景知识并解释一下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
     在CODE上查看代码片派生到我的代码片
    1. static void enable_factory (const gchar *name, gboolean enable) {  
    2.     GstRegistry *registry = NULL;  
    3.     GstElementFactory *factory = NULL;  
    4.        
    5.     registry = gst_registry_get_default ();  
    6.     if (!registry) return;  
    7.        
    8.     factory = gst_element_factory_find (name);  
    9.     if (!factory) return;  
    10.        
    11.     if (enable) {  
    12.         gst_plugin_feature_set_rank (GST_PLUGIN_FEATURE (factory), GST_RANK_PRIMARY + 1);  
    13.     }  
    14.     else {  
    15.         gst_plugin_feature_set_rank (GST_PLUGIN_FEATURE (factory), GST_RANK_NONE);  
    16.     }  
    17.        
    18.     gst_registry_add_feature (registry, GST_PLUGIN_FEATURE (factory));  
    19.     return;  
    20. }  
          传给方法的第一个参数是要修改的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兼容


  • 相关阅读:
    阿里巴巴微服务开源项目盘点(持续更新)
    云计算、大数据、编程语言学习指南下载,100+技术课程免费学!这份诚意满满的新年技术大礼包,你Get了吗?
    【机器学习PAI实战】—— 玩转人工智能之综述
    泡沫下的破浪者,智能语音产品到底落地何处?
    我们总结了每个技术团队都会遇到的 4 个难题
    在 Ali Kubernetes 系统中,我们这样实践混沌工程
    云上护航服务—保障云上的尖峰时刻
    本地 vs. 云:大数据厮杀的最终幸存者会是谁?— InfoQ专访阿里云智能通用计算平台负责人关涛
    WAF开放规则定义权:专家策略+用户自定义策略=Web安全
    队列的其本应用_迷官问题
  • 原文地址:https://www.cnblogs.com/huty/p/8517333.html
Copyright © 2020-2023  润新知