|
1 /* |
|
2 * GStreamer |
|
3 * Copyright (C) 2008 Nokia Corporation <multimedia@maemo.org> |
|
4 * |
|
5 * This library is free software; you can redistribute it and/or |
|
6 * modify it under the terms of the GNU Library General Public |
|
7 * License as published by the Free Software Foundation; either |
|
8 * version 2 of the License, or (at your option) any later version. |
|
9 * |
|
10 * This library is distributed in the hope that it will be useful, |
|
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
13 * Library General Public License for more details. |
|
14 * |
|
15 * You should have received a copy of the GNU Library General Public |
|
16 * License along with this library; if not, write to the |
|
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
|
18 * Boston, MA 02111-1307, USA. |
|
19 */ |
|
20 |
|
21 /** |
|
22 * SECTION:camerabingeneral |
|
23 * @short_description: helper functions for #GstCameraBin and it's modules |
|
24 * |
|
25 * Common helper functions for #GstCameraBin, #GstCameraBinImage and |
|
26 * #GstCameraBinVideo. |
|
27 * |
|
28 */ |
|
29 |
|
30 #include "camerabingeneral.h" |
|
31 #include <glib.h> |
|
32 |
|
33 GST_DEBUG_CATEGORY (gst_camerabin_debug); |
|
34 |
|
35 static gboolean |
|
36 camerabin_general_dbg_have_event (GstPad * pad, GstEvent * event, |
|
37 gpointer u_data) |
|
38 { |
|
39 switch (GST_EVENT_TYPE (event)) { |
|
40 case GST_EVENT_NEWSEGMENT: |
|
41 { |
|
42 GstElement *elem = (GstElement *) u_data; |
|
43 gchar *elem_name = gst_element_get_name (elem); |
|
44 gchar *pad_name = gst_pad_get_name (pad); |
|
45 |
|
46 gboolean update; |
|
47 gdouble rate; |
|
48 GstFormat format; |
|
49 gint64 start, stop, pos; |
|
50 gst_event_parse_new_segment (event, &update, &rate, &format, &start, |
|
51 &stop, &pos); |
|
52 |
|
53 GST_DEBUG ("element %s, pad %s, new_seg_start =%" GST_TIME_FORMAT |
|
54 ", new_seg_stop =%" GST_TIME_FORMAT |
|
55 ", new_seg_pos =%" GST_TIME_FORMAT "\n", elem_name, pad_name, |
|
56 GST_TIME_ARGS (start), GST_TIME_ARGS (stop), GST_TIME_ARGS (pos)); |
|
57 |
|
58 g_free (pad_name); |
|
59 g_free (elem_name); |
|
60 } |
|
61 break; |
|
62 default: |
|
63 break; |
|
64 } |
|
65 |
|
66 return TRUE; |
|
67 } |
|
68 |
|
69 static gboolean |
|
70 camerabin_general_dbg_have_buffer (GstPad * pad, GstBuffer * buffer, |
|
71 gpointer u_data) |
|
72 { |
|
73 GstElement *elem = (GstElement *) u_data; |
|
74 gchar *elem_name = gst_element_get_name (elem); |
|
75 gchar *pad_name = gst_pad_get_name (pad); |
|
76 |
|
77 GST_DEBUG ("element %s, pad %s, buf_ts =%" GST_TIME_FORMAT "\n", elem_name, |
|
78 pad_name, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer))); |
|
79 |
|
80 g_free (pad_name); |
|
81 g_free (elem_name); |
|
82 |
|
83 return TRUE; |
|
84 |
|
85 } |
|
86 |
|
87 void |
|
88 camerabin_general_dbg_set_probe (GstElement * elem, gchar * pad_name, |
|
89 gboolean buf, gboolean evt) |
|
90 { |
|
91 GstPad *pad = gst_element_get_static_pad (elem, pad_name); |
|
92 |
|
93 if (buf) |
|
94 gst_pad_add_buffer_probe (pad, |
|
95 G_CALLBACK (camerabin_general_dbg_have_buffer), elem); |
|
96 if (evt) |
|
97 gst_pad_add_event_probe (pad, |
|
98 G_CALLBACK (camerabin_general_dbg_have_event), elem); |
|
99 |
|
100 gst_object_unref (pad); |
|
101 } |
|
102 |
|
103 /** |
|
104 * gst_camerabin_add_element: |
|
105 * @bin: add an element to this bin |
|
106 * @new_elem: new element to be added |
|
107 * |
|
108 * Adds given element to given @bin. Looks for an unconnected src pad |
|
109 * from the @bin and links the element to it. Raises an error if adding |
|
110 * or linking failed. |
|
111 * |
|
112 * Returns: %TRUE if adding and linking succeeded, %FALSE otherwise. |
|
113 */ |
|
114 gboolean |
|
115 gst_camerabin_add_element (GstBin * bin, GstElement * new_elem) |
|
116 { |
|
117 gboolean ret = FALSE; |
|
118 |
|
119 ret = gst_camerabin_try_add_element (bin, new_elem); |
|
120 |
|
121 if (!ret) { |
|
122 gchar *elem_name = gst_element_get_name (new_elem); |
|
123 GST_ELEMENT_ERROR (bin, CORE, NEGOTIATION, (NULL), |
|
124 ("linking %s failed", elem_name)); |
|
125 g_free (elem_name); |
|
126 } |
|
127 |
|
128 return ret; |
|
129 } |
|
130 |
|
131 /** |
|
132 * gst_camerabin_try_add_element: |
|
133 * @bin: tries adding an element to this bin |
|
134 * @new_elem: new element to be added |
|
135 * |
|
136 * Adds given element to given @bin. Looks for an unconnected src pad |
|
137 * from the @bin and links the element to it. |
|
138 * |
|
139 * Returns: %TRUE if adding and linking succeeded, %FALSE otherwise. |
|
140 */ |
|
141 gboolean |
|
142 gst_camerabin_try_add_element (GstBin * bin, GstElement * new_elem) |
|
143 { |
|
144 GstPad *bin_pad; |
|
145 GstElement *bin_elem; |
|
146 gboolean ret = TRUE; |
|
147 |
|
148 if (!bin || !new_elem) { |
|
149 return FALSE; |
|
150 } |
|
151 |
|
152 /* Get pads for linking */ |
|
153 GST_DEBUG ("finding unconnected src pad"); |
|
154 //bin_pad = gst_bin_find_unlinked_pad (bin, GST_PAD_SRC); |
|
155 bin_pad = gst_bin_find_unconnected_pad (bin, GST_PAD_SRC); |
|
156 GST_DEBUG ("unconnected pad %s:%s", GST_DEBUG_PAD_NAME (bin_pad)); |
|
157 /* Add to bin */ |
|
158 gst_bin_add (GST_BIN (bin), new_elem); |
|
159 /* Link, if unconnected pad was found, otherwise just add it to bin */ |
|
160 if (bin_pad) { |
|
161 bin_elem = gst_pad_get_parent_element (bin_pad); |
|
162 gst_object_unref (bin_pad); |
|
163 if (!gst_element_link (bin_elem, new_elem)) { |
|
164 gst_bin_remove (bin, new_elem); |
|
165 ret = FALSE; |
|
166 } |
|
167 gst_object_unref (bin_elem); |
|
168 } |
|
169 |
|
170 return ret; |
|
171 } |
|
172 |
|
173 /** |
|
174 * gst_camerabin_create_and_add_element: |
|
175 * @bin: tries adding an element to this bin |
|
176 * @elem_name: name of the element to be created |
|
177 * |
|
178 * Creates an element according to given name and |
|
179 * adds it to given @bin. Looks for an unconnected src pad |
|
180 * from the @bin and links the element to it. |
|
181 * |
|
182 * Returns: pointer to the new element if successful, NULL otherwise. |
|
183 */ |
|
184 GstElement * |
|
185 gst_camerabin_create_and_add_element (GstBin * bin, const gchar * elem_name) |
|
186 { |
|
187 GstElement *new_elem = NULL; |
|
188 |
|
189 GST_DEBUG ("adding %s", elem_name); |
|
190 new_elem = gst_element_factory_make (elem_name, NULL); |
|
191 if (!new_elem) { |
|
192 GST_ELEMENT_ERROR (bin, CORE, MISSING_PLUGIN, (NULL), |
|
193 ("could not create \"%s\" element.", elem_name)); |
|
194 } else if (!gst_camerabin_add_element (bin, new_elem)) { |
|
195 new_elem = NULL; |
|
196 } |
|
197 |
|
198 return new_elem; |
|
199 } |
|
200 |
|
201 /** |
|
202 * gst_camerabin_remove_elements_from_bin: |
|
203 * @bin: removes all elements from this bin |
|
204 * |
|
205 * Removes all elements from this @bin. |
|
206 */ |
|
207 void |
|
208 gst_camerabin_remove_elements_from_bin (GstBin * bin) |
|
209 { |
|
210 GstIterator *iter = NULL; |
|
211 gpointer data = NULL; |
|
212 GstElement *elem = NULL; |
|
213 gboolean done = FALSE; |
|
214 |
|
215 iter = gst_bin_iterate_elements (bin); |
|
216 while (!done) { |
|
217 switch (gst_iterator_next (iter, &data)) { |
|
218 case GST_ITERATOR_OK: |
|
219 elem = GST_ELEMENT (data); |
|
220 gst_bin_remove (bin, elem); |
|
221 /* Iterator increased the element refcount, so unref */ |
|
222 gst_object_unref (elem); |
|
223 break; |
|
224 case GST_ITERATOR_RESYNC: |
|
225 gst_iterator_resync (iter); |
|
226 break; |
|
227 case GST_ITERATOR_ERROR: |
|
228 GST_WARNING_OBJECT (bin, "error in iterating elements"); |
|
229 done = TRUE; |
|
230 break; |
|
231 case GST_ITERATOR_DONE: |
|
232 done = TRUE; |
|
233 break; |
|
234 } |
|
235 } |
|
236 gst_iterator_free (iter); |
|
237 } |
|
238 |
|
239 /** |
|
240 * gst_camerabin_drop_eos_probe: |
|
241 * @pad: pad receiving the event |
|
242 * @event: received event |
|
243 * @u_data: not used |
|
244 * |
|
245 * Event probe that drop all eos events. |
|
246 * |
|
247 * Returns: FALSE to drop the event, TRUE otherwise |
|
248 */ |
|
249 gboolean |
|
250 gst_camerabin_drop_eos_probe (GstPad * pad, GstEvent * event, gpointer u_data) |
|
251 { |
|
252 gboolean ret = TRUE; |
|
253 |
|
254 switch (GST_EVENT_TYPE (event)) { |
|
255 case GST_EVENT_EOS: |
|
256 GST_DEBUG ("dropping eos in %s:%s", GST_DEBUG_PAD_NAME (pad)); |
|
257 ret = FALSE; |
|
258 break; |
|
259 default: |
|
260 break; |
|
261 } |
|
262 return ret; |
|
263 } |