diff options
author | Mathieu Duponchelle <mathieu.duponchelle@opencreed.com> | 2016-06-05 23:32:50 +0200 |
---|---|---|
committer | Mathieu Duponchelle <mathieu.duponchelle@opencreed.com> | 2016-06-05 23:36:01 +0200 |
commit | c26379435d2baa57505f928c7b0cd263a37fa36f (patch) | |
tree | 96d7932cdfde65c5a8b8415a2ddf069732c819c1 /sdk-playback-tutorial-hardware-accelerated-video-decoding.md | |
parent | 6cdcdcd2d9fc6e12803d1a3151084fbf9e631819 (diff) |
Make naming consistent
Diffstat (limited to 'sdk-playback-tutorial-hardware-accelerated-video-decoding.md')
-rw-r--r-- | sdk-playback-tutorial-hardware-accelerated-video-decoding.md | 346 |
1 files changed, 346 insertions, 0 deletions
diff --git a/sdk-playback-tutorial-hardware-accelerated-video-decoding.md b/sdk-playback-tutorial-hardware-accelerated-video-decoding.md new file mode 100644 index 0000000..43bcd92 --- /dev/null +++ b/sdk-playback-tutorial-hardware-accelerated-video-decoding.md @@ -0,0 +1,346 @@ +# Playback tutorial 8: Hardware-accelerated video decoding + +# Goal + +Hardware-accelerated video decoding has rapidly become a necessity, as +low-power devices grow more common. This tutorial (more of a lecture, +actually) gives some background on hardware acceleration and explains +how does GStreamer benefit from it. + +Sneak peek: if properly setup, you do not need to do anything special to +activate hardware acceleration; GStreamer automatically takes advantage +of it. + +# Introduction + +Video decoding can be an extremely CPU-intensive task, especially for +higher resolutions like 1080p HDTV. Fortunately, modern graphics cards, +equipped with programmable GPUs, are able to take care of this job, +allowing the CPU to concentrate on other duties. Having dedicated +hardware becomes essential for low-power CPUs which are simply incapable +of decoding such media fast enough. + +In the current state of things (July-2012) each GPU manufacturer offers +a different method to access their hardware (a different API), and a +strong industry standard has not emerged yet. + +As of July-2012, there exist at least 8 different video decoding +acceleration APIs: + +[VAAPI](http://en.wikipedia.org/wiki/Video_Acceleration_API) (*Video +Acceleration API*): Initially designed by +[Intel](http://en.wikipedia.org/wiki/Intel) in 2007, targeted at the X +Window System on Unix-based operating systems, now open-source. It is +currently not limited to Intel GPUs as other manufacturers are free to +use this API, for example, [Imagination +Technologies](http://en.wikipedia.org/wiki/Imagination_Technologies) or +[S3 Graphics](http://en.wikipedia.org/wiki/S3_Graphics). Accessible to +GStreamer through +the [gstreamer-vaapi](http://gitorious.org/vaapi/gstreamer-vaapi) and +[Fluendo](http://en.wikipedia.org/wiki/Fluendo)’s Video Acceleration +Decoder (fluvadec) plugins. + +[VDPAU](http://en.wikipedia.org/wiki/VDPAU) (*Video Decode and +Presentation API for UNIX*): Initially designed by +[NVidia](http://en.wikipedia.org/wiki/NVidia) in 2008, targeted at the X +Window System on Unix-based operating systems, now open-source. Although +it is also an open-source library, no manufacturer other than NVidia is +using it yet. Accessible to GStreamer through +the [vdpau](http://cgit.freedesktop.org/gstreamer/gst-plugins-bad/tree/sys/vdpau) element +in plugins-bad and [Fluendo](http://en.wikipedia.org/wiki/Fluendo)’s +Video Acceleration Decoder (fluvadec) plugins. + +[DXVA](http://en.wikipedia.org/wiki/DXVA) (*DirectX Video +Acceleration*): [Microsoft](http://en.wikipedia.org/wiki/Microsoft) API +specification for the Microsoft Windows and Xbox 360 +platforms. Accessible to GStreamer through +the [Fluendo](http://en.wikipedia.org/wiki/Fluendo)’s Video +Acceleration Decoder (fluvadec) plugin. + +[XVBA](http://en.wikipedia.org/wiki/Xvba) (*X-Video Bitstream +Acceleration*): Designed by [AMD +Graphics](http://en.wikipedia.org/wiki/AMD_Graphics), is an arbitrary +extension of the X video extension (Xv) for the X Window System on Linux +operating-systems. Currently only AMD's ATI Radeon graphics cards +hardware that have support for Unified Video Decoder version 2.0 or +later are supported by the proprietary ATI Catalyst device +driver. Accessible to GStreamer through +the [Fluendo](http://en.wikipedia.org/wiki/Fluendo)’s Video +Acceleration Decoder +(fluvadec) plugin. + +[VDA](http://developer.apple.com/library/mac/#technotes/tn2267/_index.html) +(*Video Decode Acceleration*): Available on [Mac OS +X](http://en.wikipedia.org/wiki/OS_X) v10.6.3 and later with Mac models +equipped with the NVIDIA GeForce 9400M, GeForce 320M, GeForce GT 330M, +ATI HD Radeon GFX, Intel HD Graphics and others. Only accelerates +decoding of H.264 media. Accessible to GStreamer through +the [Fluendo](http://en.wikipedia.org/wiki/Fluendo)’s Video +Acceleration Decoder (fluvadec) plugin. + +[OpenMAX](http://en.wikipedia.org/wiki/OpenMAX) (*Open Media +Acceleration*): Managed by the non-profit technology consortium [Khronos +Group](http://en.wikipedia.org/wiki/Khronos_Group "Khronos Group"), +it is a "royalty-free, cross-platform set of C-language programming +interfaces that provides abstractions for routines especially useful for +audio, video, and still images". Accessible to GStreamer through +the [gstreamer-omx](http://git.freedesktop.org/gstreamer/gst-omx) plugin. + +[OVD](http://developer.amd.com/sdks/AMDAPPSDK/assets/OpenVideo_Decode_API.PDF) +(*Open Video Decode*): Another API from [AMD +Graphics](http://en.wikipedia.org/wiki/AMD_Graphics), designed to be a +platform agnostic method for softrware developers to leverage the +[Universal Video +Decode](http://en.wikipedia.org/wiki/Unified_Video_Decoder) (UVD) +hardware inside AMD Radeon graphics cards. Currently unavailable to +GStreamer. + +[DCE](http://en.wikipedia.org/wiki/Distributed_Codec_Engine) +(*Distributed Codec Engine*): An open source software library ("libdce") +and API specification by [Texas +Instruments](http://en.wikipedia.org/wiki/Texas_Instruments), targeted +at Linux systems and ARM platforms. Accessible to GStreamer through +the [gstreamer-ducati](https://github.com/robclark/gst-ducati) plugin. + +There exist some GStreamer plugins, like the +[gstreamer-vaapi](http://gitorious.org/vaapi/gstreamer-vaapi) project or +the +[vdpau](http://cgit.freedesktop.org/gstreamer/gst-plugins-bad/tree/sys/vdpau) +element in plugins-bad, which target one particular hardware +acceleration API and expose its functionality through different +GStreamer elements. The application is then responsible for selecting +the appropriate plugin depending on the available APIs. + +Some other GStreamer plugins, like +[Fluendo](http://en.wikipedia.org/wiki/Fluendo)’s Video Acceleration +Decoder (fluvadec), detect at runtime the available APIs and select one +automatically. This makes any program using these plugins independent of +the API, or even the operating system. + +# Inner workings of hardware-accelerated video decoding plugins + +These APIs generally offer a number of functionalities, like video +decoding, post-processing, presentation of the decoded frames, or +download of such frames to system memory. Correspondingly, plugins +generally offer a different GStreamer element for each of these +functions, so pipelines can be built to accommodate any need. + +For example, the `gstreamer-vaapi` plugin offers the `vaapidecode`, +`vaapiupload`, `vaapidownload` and `vaapisink` elements that allow +hardware-accelerated decoding through VAAPI, upload of raw video frames +to GPU memory, download of GPU frames to system memory and presentation +of GPU frames, respectively. + +It is important to distinguish between conventional GStreamer frames, +which reside in system memory, and frames generated by +hardware-accelerated APIs. The latter reside in GPU memory and cannot be +touched by GStreamer. They can usually be downloaded to system memory +and treated as conventional GStreamer frames, but it is far more +efficient to leave them in the GPU and display them from there. + +GStreamer needs to keep track of where these “hardware buffers” are +though, so conventional buffers still travel from element to element, +but their only content is a hardware buffer ID, or handler. If retrieved +with an `appsink`, for example, hardware buffers make no sense, since +they are meant to be handled only by the plugin that generated them. + +To indicate this, these buffers have special Caps, like +`video/x-vdpau-output` or `video/x-fluendo-va`. In this way, the +auto-plugging mechanism of GStreamer will not try to feed hardware +buffers to conventional elements, as they would not understand the +received buffers. Moreover, using these Caps, the auto-plugger is able +to automatically build pipelines that use hardware acceleration, since, +after a VAAPI decoder, a VAAPI sink is the only element that fits. + +This all means that, if a particular hardware acceleration API is +present in the system, and the corresponding GStreamer plugin is also +available, auto-plugging elements like `playbin` are free to use +hardware acceleration to build their pipelines; the application does not +need to do anything special to enable it. Almost: + +When `playbin` has to choose among different equally valid elements, +like conventional software decoding (through `vp8dec`, for example) or +hardware accelerated decoding (through `vaapidecode`, for example), it +uses their *rank* to decide. The rank is a property of each element that +indicates its priority; `playbin` will simply select the element that +is able to build a complete pipeline and has the highest rank. + +So, whether `playbin` will use hardware acceleration or not will depend +on the relative ranks of all elements capable of dealing with that media +type. Therefore, the easiest way to make sure hardware acceleration is +enabled or disabled is by changing the rank of the associated element, +as shown in this code: + +``` lang=c +static void enable_factory (const gchar *name, gboolean enable) { + GstRegistry *registry = NULL; + GstElementFactory *factory = NULL; + + registry = gst_registry_get_default (); + if (!registry) return; + + factory = gst_element_factory_find (name); + if (!factory) return; + + if (enable) { + gst_plugin_feature_set_rank (GST_PLUGIN_FEATURE (factory), GST_RANK_PRIMARY + 1); + } + else { + gst_plugin_feature_set_rank (GST_PLUGIN_FEATURE (factory), GST_RANK_NONE); + } + + gst_registry_add_feature (registry, GST_PLUGIN_FEATURE (factory)); + return; +} +``` + +The first parameter passed to this method is the name of the element to +modify, for example, `vaapidecode` or `fluvadec`. + +The key method is `gst_plugin_feature_set_rank()`, which will set the +rank of the requested element factory to the desired level. For +convenience, ranks are divided in NONE, MARGINAL, SECONDARY and PRIMARY, +but any number will do. When enabling an element, we set it to +PRIMARY+1, so it has a higher rank than the rest of elements which +commonly have PRIMARY rank. Setting an element’s rank to NONE will make +the auto-plugging mechanism to never select it. + +# Hardware-accelerated video decoding and the GStreamer SDK + +There are no plugins deployed in the GStreamer SDK Amazon 2012.7 that +allow hardware-accelerated video decoding. The main reasons are that +some of them are not yet fully operational, or still have issues, or are +proprietary. Bear in mind that this situation is bound to change in the +near future, as this is a very active area of development. + +Some of these plugins can be built from their publicly available +sources, using the Cerbero build system (see [Installing on +Linux](Installing%2Bon%2BLinux.html)) or independently (linking against +the GStreamer SDK libraries, obviously). Some other plugins are readily +available in binary form from their vendors. + +The following sections try to summarize the current state of some of +these plugins. + +### vdpau in gst-plugins-bad + + - GStreamer element for VDPAU, present in + [gst-plugins-bad](http://cgit.freedesktop.org/gstreamer/gst-plugins-bad/tree/sys/vdpau). + - Supported codecs: + +<table> +<thead> +<tr class="header"> +<th>MPEG2</th> +<th>MPEG4</th> +<th>H.264</th> +</tr> +</thead> +<tbody> +</tbody> +</table> + +### gstreamer-vaapi + + - GStreamer element for VAAPI. Standalone project hosted at + [gstreamer-vaapi](http://gitorious.org/vaapi/gstreamer-vaapi). + - Supported codecs: + +<table> +<thead> +<tr class="header"> +<th>MPEG2</th> +<th>MPEG4</th> +<th>H.264</th> +<th>VC1</th> +<th>WMV3</th> +</tr> +</thead> +<tbody> +</tbody> +</table> + + - Can interface directly with Clutter (See [Basic tutorial 15: Clutter + integration](Basic%2Btutorial%2B15%253A%2BClutter%2Bintegration.html)), + so frames do not need to leave the GPU. + - Compatible with `playbin`. + +### gst-omx + + - GStreamer element for OpenMAX. Standalone project hosted at + [gst-omx](http://git.freedesktop.org/gstreamer/gst-omx/). + - Supported codecs greatly vary depending on the underlying hardware. + +### fluvadec + + - GStreamer element for VAAPI, VDPAU, DXVA2, XVBA and VDA from + [Fluendo](http://en.wikipedia.org/wiki/Fluendo) (propietary). + - Supported codecs depend on the chosen API, which is selected at + runtime depending on what is available on the system: + +<table> +<thead> +<tr class="header"> +<th> </th> +<th>MPEG2</th> +<th>MPEG4</th> +<th>H.264</th> +<th>VC1</th> +</tr> +</thead> +<tbody> +<tr class="odd"> +<td>VAAPI</td> +<td><span>✓</span></td> +<td><span>✓</span></td> +<td><span>✓</span></td> +<td><span>✓</span></td> +</tr> +<tr class="even"> +<td>VDPAU</td> +<td><span>✓</span></td> +<td><span>✓</span></td> +<td><span>✓</span></td> +<td><span>✓</span></td> +</tr> +<tr class="odd"> +<td>XVBA</td> +<td> </td> +<td> </td> +<td><span>✓</span></td> +<td><span>✓</span></td> +</tr> +<tr class="even"> +<td>DXVA2</td> +<td> </td> +<td> </td> +<td><span>✓</span></td> +<td> </td> +</tr> +<tr class="odd"> +<td>VDA</td> +<td> </td> +<td> </td> +<td><span>✓</span></td> +<td> </td> +</tr> +</tbody> +</table> + + - Can interface directly with Clutter (See [Basic tutorial 15: Clutter + integration](Basic%2Btutorial%2B15%253A%2BClutter%2Bintegration.html)), + so frames do not need to leave the GPU. + - Compatible with `playbin`. + +# Conclusion + +This tutorial has shown a bit how GStreamer internally manages hardware +accelerated video decoding. Particularly, + + - Applications do not need to do anything special to enable hardware + acceleration if a suitable API and the corresponding GStreamer + plugin are available. + - Hardware acceleration can be enabled or disabled by changing the + rank of the decoding element with `gst_plugin_feature_set_rank()`. + +It has been a pleasure having you here, and see you soon\! |