Policy element integration
[profile/ivi/gst-plugins-base.git] / gst-libs / gst / policy / gstpolicy.c
1 /* GStreamer
2  * Copyright (C) <2012> Intel Corporation
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20
21 /**
22  * SECTION:gstpolicy
23  * @short_description: Simple base class for platform-specific policy implementations
24  * @see_also: autopolicy
25  *
26  * Any platform-specific policy element should be implemented by subclassing
27  * #GstPolicy. Applications should be using #autopolicy element that finds and 
28  * and wraps an appropriate policy element, or just #playbin element which 
29  * encapsulates autopolicy element.
30  *
31  * #GstPolicy provides an unlimited number of request sink pads. You can obtain 
32  * the corresponding source pad by listening to a "pad-added" signal while 
33  * requesting the sink pad.
34  * </refsect2>
35  */
36 #ifdef HAVE_CONFIG_H
37 #  include <config.h>
38 #endif
39
40 #include <gst/gst.h>
41
42 #include "gstpolicy.h"
43
44 GST_DEBUG_CATEGORY_STATIC (gst_policy_debug);
45 #define GST_CAT_DEFAULT gst_policy_debug
46
47 enum
48 {
49   LAST_SIGNAL
50 };
51
52 enum
53 {
54   PROP_0,
55   PROP_ROLE
56 };
57
58 static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink_%d",
59     GST_PAD_SINK,
60     GST_PAD_REQUEST,
61     GST_STATIC_CAPS ("ANY")
62     );
63
64 static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src_%d",
65     GST_PAD_SRC,
66     GST_PAD_SOMETIMES,
67     GST_STATIC_CAPS ("ANY")
68     );
69
70 GST_BOILERPLATE(GstPolicy, gst_policy, GstElement, GST_TYPE_ELEMENT);
71
72 static void gst_policy_set_property (GObject * object, guint prop_id,
73     const GValue * value, GParamSpec * pspec);
74 static void gst_policy_get_property (GObject * object, guint prop_id,
75     GValue * value, GParamSpec * pspec);
76 static void gst_policy_finalize (GObject * object);
77
78 static GstPad *gst_policy_request_new_pad (GstElement * element,
79     GstPadTemplate * templ, const gchar * name);
80 static void gst_policy_release_pad (GstElement * element, GstPad * pad);
81
82 static gboolean gst_policy_sink_event (GstPad * pad, GstEvent * event);
83 static gboolean gst_policy_src_event (GstPad * pad, GstEvent * event);
84 static GstFlowReturn gst_policy_chain (GstPad * pad, GstBuffer * buf);
85
86 static GstIterator *gst_policy_iterate_internal_links (GstPad *
87     pad, GstObject * parent);
88
89 static void
90 gst_policy_class_init (GstPolicyClass * klass)
91 {
92   GObjectClass *gobject_class;
93   GstElementClass *gstelement_class;
94
95   gobject_class = (GObjectClass *) klass;
96   gstelement_class = (GstElementClass *) klass;
97
98   GST_DEBUG_CATEGORY_INIT (gst_policy_debug, "policy", 0, "Policy debugging");
99
100   gobject_class->set_property = gst_policy_set_property;
101   gobject_class->get_property = gst_policy_get_property;
102   gobject_class->finalize = gst_policy_finalize;
103
104   /**
105    * GstPolicy:role
106    *
107    * Set the role of the stream. This property can be used by the platform policy subsystem
108    * to make policy decisions that affect the stream (for example routing and enforced 
109    * pause/playback).
110    */
111   g_object_class_install_property (gobject_class, PROP_ROLE,
112       g_param_spec_string ("role", "Stream role",
113           "Stream role for the platform policy sybsystem", NULL,
114           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
115
116   // element class methods
117   gstelement_class->request_new_pad = gst_policy_request_new_pad;
118   gstelement_class->release_pad = gst_policy_release_pad;
119 }
120
121 static void
122 gst_policy_init (GstPolicy * policy, GstPolicyClass *klass)
123 {
124   GST_DEBUG_CATEGORY_INIT (gst_policy_debug, "policy", 0, "Policy");
125
126   policy->role = NULL;
127 }
128
129 static void
130 gst_policy_base_init (gpointer klass) 
131 {
132   GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
133
134   gst_element_class_add_pad_template (gstelement_class,
135       gst_static_pad_template_get (&src_factory));
136   gst_element_class_add_pad_template (gstelement_class,
137       gst_static_pad_template_get (&sink_factory));
138
139 }
140
141 static void
142 gst_policy_finalize (GObject * object)
143 {
144   GstPolicy *policy;
145
146   policy = GST_POLICY (object);
147
148   g_free (policy->role);
149   policy->role = NULL;
150
151   G_OBJECT_CLASS (parent_class)->finalize (object);
152 }
153
154 static void
155 gst_policy_set_property (GObject * object, guint prop_id,
156     const GValue * value, GParamSpec * pspec)
157 {
158   GstPolicy *policy = GST_POLICY (object);
159
160   switch (prop_id) {
161     case PROP_ROLE:
162       g_free (policy->role);
163       policy->role = g_strdup (g_value_get_string (value));
164       GST_DEBUG_OBJECT (policy, "Setting stream role to %s", policy->role);
165       break;
166     default:
167       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
168       break;
169   }
170 }
171
172 static void
173 gst_policy_get_property (GObject * object, guint prop_id,
174     GValue * value, GParamSpec * pspec)
175 {
176   GstPolicy *policy = GST_POLICY (object);
177
178   switch (prop_id) {
179     case PROP_ROLE:
180       GST_DEBUG_OBJECT (policy, "Getting stream role: %s", policy->role);
181       g_value_set_string (value, policy->role);
182       break;
183     default:
184       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
185       break;
186   }
187 }
188 static void
189 gst_policy_release_pad (GstElement * element, GstPad * pad)
190 {
191   GstPolicy *self = GST_POLICY (element);
192   GstPad *srcpad = gst_pad_get_element_private (pad);
193
194   gst_pad_set_element_private (pad, NULL);
195   gst_pad_set_element_private (srcpad, NULL);
196
197   gst_element_remove_pad (GST_ELEMENT_CAST (self), srcpad);
198   gst_element_remove_pad (GST_ELEMENT_CAST (self), pad);
199 }
200
201 static GstIterator *
202 gst_policy_iterate_internal_links (GstPad * pad, GstObject * parent)
203 {
204   GstIterator *it = NULL;
205   GstPad *opad;
206
207   opad = gst_pad_get_element_private (pad);
208   if (opad) {
209     it = gst_iterator_new_single (GST_TYPE_PAD, (gpointer)opad, 
210              (GstCopyFunction)gst_object_ref, 
211              (GFreeFunc)gst_object_unref);
212   }
213
214   return it;
215 }
216
217 static gboolean
218 gst_policy_sink_event (GstPad * pad, GstEvent * event)
219 {
220   gboolean ret;
221
222   switch (GST_EVENT_TYPE (event)) {
223     default:
224       ret = gst_pad_event_default (pad, event);
225       break;
226   }
227   return ret;
228 }
229
230 static gboolean
231 gst_policy_src_event (GstPad * pad, GstEvent * event)
232 {
233   gboolean ret;
234
235   switch (GST_EVENT_TYPE (event)) {
236     default:
237       ret = gst_pad_event_default (pad, event);
238       break;
239   }
240   return ret;
241 }
242
243 static GstFlowReturn
244 gst_policy_chain (GstPad * pad, GstBuffer * buf)
245 {
246   /* just push out the incoming buffer without touching it */
247   return gst_pad_push (gst_pad_get_element_private (pad), buf);
248 }
249
250 static GstPad *
251 gst_policy_request_new_pad (GstElement * element,
252     GstPadTemplate * templ, const gchar * name)
253 {
254   GstPad *srcpad;
255   GstPad *sinkpad;
256   GstPolicy *self = GST_POLICY (element);
257
258   sinkpad = gst_pad_new_from_template (templ, name);
259   srcpad = gst_pad_new_from_static_template (&src_factory, NULL);
260
261   gst_pad_set_element_private (sinkpad, srcpad);
262   gst_pad_set_element_private (srcpad, sinkpad);
263
264   gst_pad_set_chain_function (sinkpad, 
265       GST_DEBUG_FUNCPTR (gst_policy_chain));
266   gst_pad_set_iterate_internal_links_function (sinkpad,
267       (GstPadIterIntLinkFunction)gst_policy_iterate_internal_links);
268   gst_pad_set_event_function (sinkpad, 
269       GST_DEBUG_FUNCPTR (gst_policy_sink_event));
270
271   gst_pad_set_iterate_internal_links_function (srcpad,
272       (GstPadIterIntLinkFunction)gst_policy_iterate_internal_links);
273   gst_pad_set_event_function (srcpad, 
274       GST_DEBUG_FUNCPTR (gst_policy_src_event));
275
276   gst_pad_set_active (srcpad, TRUE);
277   gst_pad_set_active (sinkpad, TRUE);
278
279   gst_element_add_pad (GST_ELEMENT (self), sinkpad);
280   gst_element_add_pad (GST_ELEMENT (self), srcpad);
281
282   return sinkpad;
283 }
284