Update theme submodule
[platform/upstream/gstreamer.git] / markdown / tutorials / playback / hardware-accelerated-video-decoding.md
1 # Playback tutorial 8: Hardware-accelerated video decoding
2
3 ### Goal
4
5 Hardware-accelerated video decoding has rapidly become a necessity, as
6 low-power devices grow more common. This tutorial (more of a lecture,
7 actually) gives some background on hardware acceleration and explains
8 how does GStreamer benefit from it.
9
10 Sneak peek: if properly setup, you do not need to do anything special to
11 activate hardware acceleration; GStreamer automatically takes advantage
12 of it.
13
14 ### Introduction
15
16 Video decoding can be an extremely CPU-intensive task, especially for
17 higher resolutions like 1080p HDTV. Fortunately, modern graphics cards,
18 equipped with programmable GPUs, are able to take care of this job,
19 allowing the CPU to concentrate on other duties. Having dedicated
20 hardware becomes essential for low-power CPUs which are simply incapable
21 of decoding such media fast enough.
22
23 In the current state of things (June 2016) each GPU manufacturer offers
24 a different method to access their hardware (a different API), and a
25 strong industry standard has not emerged yet.
26
27 As of June 2016, there exist at least 8 different video decoding
28 acceleration APIs:
29
30  - [VAAPI](http://en.wikipedia.org/wiki/Video_Acceleration_API) (*Video
31 Acceleration API*): Initially designed by
32 [Intel](http://en.wikipedia.org/wiki/Intel) in 2007, targeted at the X
33 Window System on Unix-based operating systems, now open-source. It now also
34 supports Wayland through dmabuf. It is
35 currently not limited to Intel GPUs as other manufacturers are free to
36 use this API, for example, [Imagination
37 Technologies](http://en.wikipedia.org/wiki/Imagination_Technologies) or
38 [S3 Graphics](http://en.wikipedia.org/wiki/S3_Graphics). Accessible to
39 GStreamer through the [gstreamer-vaapi](https://cgit.freedesktop.org/gstreamer/gstreamer-vaapi/) package.
40
41 - [VDPAU](http://en.wikipedia.org/wiki/VDPAU) (*Video Decode and
42 Presentation API for UNIX*): Initially designed by
43 [NVidia](http://en.wikipedia.org/wiki/NVidia) in 2008, targeted at the X
44 Window System on Unix-based operating systems, now open-source. Although
45 it is also an open-source library, no manufacturer other than NVidia is
46 using it yet. Accessible to GStreamer through
47 the [vdpau](http://cgit.freedesktop.org/gstreamer/gst-plugins-bad/tree/sys/vdpau) element in plugins-bad.
48
49  - [OpenMAX](http://en.wikipedia.org/wiki/OpenMAX) (*Open Media
50 Acceleration*): Managed by the non-profit technology consortium [Khronos
51 Group](http://en.wikipedia.org/wiki/Khronos_Group "Khronos Group"),
52 it is a "royalty-free, cross-platform set of C-language programming
53 interfaces that provides abstractions for routines especially useful for
54 audio, video, and still images". Accessible to GStreamer through
55 the [gst-omx](http://git.freedesktop.org/gstreamer/gst-omx) plugin.
56
57  - [OVD](http://developer.amd.com/sdks/AMDAPPSDK/assets/OpenVideo_Decode_API.PDF)
58 (*Open Video Decode*): Another API from [AMD
59 Graphics](http://en.wikipedia.org/wiki/AMD_Graphics), designed to be a
60 platform agnostic method for softrware developers to leverage the
61 [Universal Video
62 Decode](http://en.wikipedia.org/wiki/Unified_Video_Decoder) (UVD)
63 hardware inside AMD Radeon graphics cards. Currently unavailable to
64 GStreamer .
65
66  - [DCE](http://en.wikipedia.org/wiki/Distributed_Codec_Engine)
67 (*Distributed Codec Engine*): An open source software library ("libdce")
68 and API specification by [Texas
69 Instruments](http://en.wikipedia.org/wiki/Texas_Instruments), targeted
70 at Linux systems and ARM platforms. Accessible to GStreamer through
71 the [gstreamer-ducati](https://github.com/robclark/gst-ducati) plugin.
72
73  - [Android
74    MediaCodec](https://developer.android.com/reference/android/media/MediaCodec.html): This is Android's API to access the device's
75    hardware decoder and encoder if available. This is accessible through the
76    `androidmedia` plugin in gst-plugins-bad. This includes both encoding and
77    decoding.
78
79  - Apple VideoTool Box Framework: Apple's API to access h is available
80   through the `applemedia` plugin which includes both encoding through
81   the `vtenc` element and decoding through the `vtdec` element.
82
83  - Video4Linux: Recent Linux kernels have a kernel API to expose
84    hardware codecs in a standard way, this is now supported by the
85    `v4l2` plugin in `gst-plugins-good`. This can support both decoding
86    and encoding depending on the platform.
87
88 ### Inner workings of hardware-accelerated video decoding plugins
89
90 These APIs generally offer a number of functionalities, like video
91 decoding, post-processing, or presentation of the decoded
92 frames. Correspondingly, plugins generally offer a different GStreamer
93 element for each of these functions, so pipelines can be built to
94 accommodate any need.
95
96 For example, the `gstreamer-vaapi` plugin offers the `vaapidecode`,
97 `vaapipostproc` and `vaapisink` elements that allow
98 hardware-accelerated decoding through VAAPI, upload of raw video frames
99 to GPU memory, download of GPU frames to system memory and presentation
100 of GPU frames, respectively.
101
102 It is important to distinguish between conventional GStreamer frames,
103 which reside in system memory, and frames generated by
104 hardware-accelerated APIs. The latter reside in GPU memory and cannot
105 be touched by GStreamer. They can usually be downloaded to system
106 memory and treated as conventional GStreamer frames when they are
107 mapped, but it is far more efficient to leave them in the GPU and
108 display them from there.
109
110 GStreamer needs to keep track of where these “hardware buffers” are
111 though, so conventional buffers still travel from element to
112 element. They look like regular buffers, but mapping their content is
113 much slower as it has to be retrieved from the special memory used by
114 hardware accelerated elements. This special memory types are
115 negotiated using the allocation query mechanism.
116
117 This all means that, if a particular hardware acceleration API is
118 present in the system, and the corresponding GStreamer plugin is also
119 available, auto-plugging elements like `playbin` are free to use
120 hardware acceleration to build their pipelines; the application does not
121 need to do anything special to enable it. Almost:
122
123 When `playbin` has to choose among different equally valid elements,
124 like conventional software decoding (through `vp8dec`, for example) or
125 hardware accelerated decoding (through `vaapidecode`, for example), it
126 uses their *rank* to decide. The rank is a property of each element that
127 indicates its priority; `playbin` will simply select the element that
128 is able to build a complete pipeline and has the highest rank.
129
130 So, whether `playbin` will use hardware acceleration or not will depend
131 on the relative ranks of all elements capable of dealing with that media
132 type. Therefore, the easiest way to make sure hardware acceleration is
133 enabled or disabled is by changing the rank of the associated element,
134 as shown in this code:
135
136 ``` c
137 static void enable_factory (const gchar *name, gboolean enable) {
138     GstRegistry *registry = NULL;
139     GstElementFactory *factory = NULL;
140
141     registry = gst_registry_get_default ();
142     if (!registry) return;
143
144     factory = gst_element_factory_find (name);
145     if (!factory) return;
146
147     if (enable) {
148         gst_plugin_feature_set_rank (GST_PLUGIN_FEATURE (factory), GST_RANK_PRIMARY + 1);
149     }
150     else {
151         gst_plugin_feature_set_rank (GST_PLUGIN_FEATURE (factory), GST_RANK_NONE);
152     }
153
154     gst_registry_add_feature (registry, GST_PLUGIN_FEATURE (factory));
155     return;
156 }
157 ```
158
159 The first parameter passed to this method is the name of the element to
160 modify, for example, `vaapidecode` or `fluvadec`.
161
162 The key method is `gst_plugin_feature_set_rank()`, which will set the
163 rank of the requested element factory to the desired level. For
164 convenience, ranks are divided in NONE, MARGINAL, SECONDARY and PRIMARY,
165 but any number will do. When enabling an element, we set it to
166 PRIMARY+1, so it has a higher rank than the rest of elements which
167 commonly have PRIMARY rank. Setting an element’s rank to NONE will make
168 the auto-plugging mechanism to never select it.
169
170 > ![warning] The GStreamer developers often rank hardware decoders lower than
171 > the software ones when they are defective. This should act as a warning.
172
173 ## Conclusion
174
175 This tutorial has shown a bit how GStreamer internally manages hardware
176 accelerated video decoding. Particularly,
177
178   - Applications do not need to do anything special to enable hardware
179     acceleration if a suitable API and the corresponding GStreamer
180     plugin are available.
181   - Hardware acceleration can be enabled or disabled by changing the
182     rank of the decoding element with `gst_plugin_feature_set_rank()`.
183
184 It has been a pleasure having you here, and see you soon!
185
186   [warning]: images/icons/emoticons/warning.png