Split out documentation into subfolders.
[platform/upstream/gstreamer.git] / markdown / pwg / advanced / interfaces.md
1 ---
2 title: Interfaces
3 ...
4
5 # Interfaces
6
7 Previously, in the chapter [Adding
8 Properties](pwg/building/args.md), we have introduced the concept of
9 GObject properties of controlling an element's behaviour. This is very
10 powerful, but it has two big disadvantages: first of all, it is too
11 generic, and second, it isn't dynamic.
12
13 The first disadvantage is related to the customizability of the end-user
14 interface that will be built to control the element. Some properties are
15 more important than others. Some integer properties are better shown in
16 a spin-button widget, whereas others would be better represented by a
17 slider widget. Such things are not possible because the UI has no actual
18 meaning in the application. A UI widget that represents a bitrate
19 property is the same as a UI widget that represents the size of a video,
20 as long as both are of the same `GParamSpec` type. Another problem, is
21 that things like parameter grouping, function grouping, or parameter
22 coupling are not really possible.
23
24 The second problem with parameters are that they are not dynamic. In
25 many cases, the allowed values for a property are not fixed, but depend
26 on things that can only be detected at runtime. The names of inputs for
27 a TV card in a video4linux source element, for example, can only be
28 retrieved from the kernel driver when we've opened the device; this only
29 happens when the element goes into the READY state. This means that we
30 cannot create an enum property type to show this to the user.
31
32 The solution to those problems is to create very specialized types of
33 controls for certain often-used controls. We use the concept of
34 interfaces to achieve this. The basis of this all is the glib
35 `GTypeInterface` type. For each case where we think it's useful, we've
36 created interfaces which can be implemented by elements at their own
37 will.
38
39 One important note: interfaces do *not* replace properties. Rather,
40 interfaces should be built *next to* properties. There are two important
41 reasons for this. First of all, properties can be more easily
42 introspected. Second, properties can be specified on the commandline
43 (`gst-launch`).
44
45 ## How to Implement Interfaces
46
47 Implementing interfaces is initiated in the `_get_type ()` of your
48 element. You can register one or more interfaces after having registered
49 the type itself. Some interfaces have dependencies on other interfaces
50 or can only be registered by certain types of elements. You will be
51 notified of doing that wrongly when using the element: it will quit with
52 failed assertions, which will explain what went wrong. If it does, you
53 need to register support for *that* interface before registering support
54 for the interface that you're wanting to support. The example below
55 explains how to add support for a simple interface with no further
56 dependencies.
57
58 ``` c
59 static void gst_my_filter_some_interface_init   (GstSomeInterface *iface);
60
61 GType
62 gst_my_filter_get_type (void)
63 {
64   static GType my_filter_type = 0;
65
66   if (!my_filter_type) {
67     static const GTypeInfo my_filter_info = {
68       sizeof (GstMyFilterClass),
69       NULL,
70       NULL,
71       (GClassInitFunc) gst_my_filter_class_init,
72       NULL,
73       NULL,
74       sizeof (GstMyFilter),
75       0,
76       (GInstanceInitFunc) gst_my_filter_init
77     };
78     static const GInterfaceInfo some_interface_info = {
79       (GInterfaceInitFunc) gst_my_filter_some_interface_init,
80       NULL,
81       NULL
82     };
83
84     my_filter_type =
85     g_type_register_static (GST_TYPE_ELEMENT,
86                 "GstMyFilter",
87                 &my_filter_info, 0);
88     g_type_add_interface_static (my_filter_type,
89                  GST_TYPE_SOME_INTERFACE,
90                                  &some_interface_info);
91   }
92
93   return my_filter_type;
94 }
95
96 static void
97 gst_my_filter_some_interface_init (GstSomeInterface *iface)
98 {
99   /* here, you would set virtual function pointers in the interface */
100 }
101
102 ```
103
104 Or more
105 conveniently:
106
107 ``` c
108 static void gst_my_filter_some_interface_init   (GstSomeInterface *iface);
109
110 G_DEFINE_TYPE_WITH_CODE (GstMyFilter, gst_my_filter,GST_TYPE_ELEMENT,
111      G_IMPLEMENT_INTERFACE (GST_TYPE_SOME_INTERFACE,
112             gst_my_filter_some_interface_init));
113
114
115 ```
116
117 ## URI interface
118
119 WRITEME
120
121 ## Color Balance Interface
122
123 WRITEME
124
125 ## Video Overlay Interface
126
127 The \#GstVideoOverlay interface is used for 2 main purposes :
128
129   - To get a grab on the Window where the video sink element is going to
130     render. This is achieved by either being informed about the Window
131     identifier that the video sink element generated, or by forcing the
132     video sink element to use a specific Window identifier for
133     rendering.
134
135   - To force a redrawing of the latest video frame the video sink
136     element displayed on the Window. Indeed if the \#GstPipeline is in
137     \#GST\_STATE\_PAUSED state, moving the Window around will damage its
138     content. Application developers will want to handle the Expose
139     events themselves and force the video sink element to refresh the
140     Window's content.
141
142 A plugin drawing video output in a video window will need to have that
143 window at one stage or another. Passive mode simply means that no window
144 has been given to the plugin before that stage, so the plugin created
145 the window by itself. In that case the plugin is responsible of
146 destroying that window when it's not needed any more and it has to tell
147 the applications that a window has been created so that the application
148 can use it. This is done using the `have-window-handle` message that can
149 be posted from the plugin with the `gst_video_overlay_got_window_handle`
150 method.
151
152 As you probably guessed already active mode just means sending a video
153 window to the plugin so that video output goes there. This is done using
154 the `gst_video_overlay_set_window_handle` method.
155
156 It is possible to switch from one mode to another at any moment, so the
157 plugin implementing this interface has to handle all cases. There are
158 only 2 methods that plugins writers have to implement and they most
159 probably look like that :
160
161 ``` c
162 static void
163 gst_my_filter_set_window_handle (GstVideoOverlay *overlay, guintptr handle)
164 {
165   GstMyFilter *my_filter = GST_MY_FILTER (overlay);
166
167   if (my_filter->window)
168     gst_my_filter_destroy_window (my_filter->window);
169
170   my_filter->window = handle;
171 }
172
173 static void
174 gst_my_filter_xoverlay_init (GstVideoOverlayClass *iface)
175 {
176   iface->set_window_handle = gst_my_filter_set_window_handle;
177 }
178
179 ```
180
181 You will also need to use the interface methods to post messages when
182 needed such as when receiving a CAPS event where you will know the video
183 geometry and maybe create the window.
184
185 ``` c
186 static MyFilterWindow *
187 gst_my_filter_window_create (GstMyFilter *my_filter, gint width, gint height)
188 {
189   MyFilterWindow *window = g_new (MyFilterWindow, 1);
190   ...
191   gst_video_overlay_got_window_handle (GST_VIDEO_OVERLAY (my_filter), window->win);
192 }
193
194 /* called from the event handler for CAPS events */
195 static gboolean
196 gst_my_filter_sink_set_caps (GstMyFilter *my_filter, GstCaps *caps)
197 {
198   gint width, height;
199   gboolean ret;
200   ...
201   ret = gst_structure_get_int (structure, "width", &width);
202   ret &= gst_structure_get_int (structure, "height", &height);
203   if (!ret) return FALSE;
204
205   gst_video_overlay_prepare_window_handle (GST_VIDEO_OVERLAY (my_filter));
206
207   if (!my_filter->window)
208     my_filter->window = gst_my_filter_create_window (my_filter, width, height);
209
210   ...
211 }
212
213 ```
214
215 ## Navigation Interface
216
217 WRITEME