1 | /* GStreamer |
2 | * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu> |
3 | * 2000,2004 Wim Taymans <wim@fluendo.com> |
4 | * |
5 | * gstelement.h: Header for GstElement |
6 | * |
7 | * This library is free software; you can redistribute it and/or |
8 | * modify it under the terms of the GNU Library General Public |
9 | * License as published by the Free Software Foundation; either |
10 | * version 2 of the License, or (at your option) any later version. |
11 | * |
12 | * This library is distributed in the hope that it will be useful, |
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
15 | * Library General Public License for more details. |
16 | * |
17 | * You should have received a copy of the GNU Library General Public |
18 | * License along with this library; if not, write to the |
19 | * Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
20 | * Boston, MA 02111-1307, USA. |
21 | */ |
22 | |
23 | |
24 | #ifndef __GST_ELEMENT_H__ |
25 | #define __GST_ELEMENT_H__ |
26 | |
27 | /* gstelement.h and gstelementfactory.h include eachother */ |
28 | typedef struct _GstElement GstElement; |
29 | typedef struct _GstElementClass GstElementClass; |
30 | |
31 | /* gstmessage.h needs State */ |
32 | /** |
33 | * GstState: |
34 | * @GST_STATE_VOID_PENDING: no pending state. |
35 | * @GST_STATE_NULL : the NULL state or initial state of an element. |
36 | * @GST_STATE_READY : the element is ready to go to PAUSED. |
37 | * @GST_STATE_PAUSED : the element is PAUSED, it is ready to accept and |
38 | * process data. Sink elements however only accept one |
39 | * buffer and then block. |
40 | * @GST_STATE_PLAYING : the element is PLAYING, the #GstClock is running and |
41 | * the data is flowing. |
42 | * |
43 | * The possible states an element can be in. States can be changed using |
44 | * gst_element_set_state() and checked using gst_element_get_state(). |
45 | */ |
46 | typedef enum { |
47 | GST_STATE_VOID_PENDING = 0, |
48 | GST_STATE_NULL = 1, |
49 | GST_STATE_READY = 2, |
50 | GST_STATE_PAUSED = 3, |
51 | GST_STATE_PLAYING = 4 |
52 | } GstState; |
53 | |
54 | |
55 | #include <gst/gstconfig.h> |
56 | #include <gst/gstobject.h> |
57 | #include <gst/gstpad.h> |
58 | #include <gst/gstbus.h> |
59 | #include <gst/gstclock.h> |
60 | #include <gst/gstelementfactory.h> |
61 | #include <gst/gstplugin.h> |
62 | #include <gst/gstpluginfeature.h> |
63 | #include <gst/gstindex.h> |
64 | #include <gst/gstindexfactory.h> |
65 | #include <gst/gstiterator.h> |
66 | #include <gst/gstmessage.h> |
67 | #include <gst/gsttaglist.h> |
68 | |
69 | G_BEGIN_DECLS |
70 | |
71 | #define GST_TYPE_ELEMENT (gst_element_get_type ()) |
72 | #define GST_IS_ELEMENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_ELEMENT)) |
73 | #define GST_IS_ELEMENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_ELEMENT)) |
74 | #define GST_ELEMENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_ELEMENT, GstElementClass)) |
75 | #define GST_ELEMENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_ELEMENT, GstElement)) |
76 | #define GST_ELEMENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_ELEMENT, GstElementClass)) |
77 | #define GST_ELEMENT_CAST(obj) ((GstElement*)(obj)) |
78 | |
79 | /** |
80 | * GstStateChangeReturn: |
81 | * @GST_STATE_CHANGE_FAILURE : the state change failed |
82 | * @GST_STATE_CHANGE_SUCCESS : the state change succeeded |
83 | * @GST_STATE_CHANGE_ASYNC : the state change will happen asynchronously |
84 | * @GST_STATE_CHANGE_NO_PREROLL: the state change succeeded but the element |
85 | * cannot produce data in %GST_STATE_PAUSED. |
86 | * This typically happens with live sources. |
87 | * |
88 | * The possible return values from a state change function such as |
89 | * gst_element_set_state(). Only @GST_STATE_CHANGE_FAILURE is a real failure. |
90 | */ |
91 | typedef enum { |
92 | GST_STATE_CHANGE_FAILURE = 0, |
93 | GST_STATE_CHANGE_SUCCESS = 1, |
94 | GST_STATE_CHANGE_ASYNC = 2, |
95 | GST_STATE_CHANGE_NO_PREROLL = 3 |
96 | } GstStateChangeReturn; |
97 | |
98 | /* NOTE: this probably should be done with an #ifdef to decide |
99 | * whether to safe-cast or to just do the non-checking cast. |
100 | */ |
101 | |
102 | /** |
103 | * GST_STATE: |
104 | * @elem: a #GstElement to return state for. |
105 | * |
106 | * This macro returns the current #GstState of the element. |
107 | */ |
108 | #define GST_STATE(elem) (GST_ELEMENT_CAST(elem)->current_state) |
109 | |
110 | /** |
111 | * GST_STATE_NEXT: |
112 | * @elem: a #GstElement to return the next state for. |
113 | * |
114 | * This macro returns the next #GstState of the element. |
115 | */ |
116 | #define GST_STATE_NEXT(elem) (GST_ELEMENT_CAST(elem)->next_state) |
117 | |
118 | /** |
119 | * GST_STATE_PENDING: |
120 | * @elem: a #GstElement to return the pending state for. |
121 | * |
122 | * This macro returns the currently pending #GstState of the element. |
123 | */ |
124 | #define GST_STATE_PENDING(elem) (GST_ELEMENT_CAST(elem)->pending_state) |
125 | |
126 | /** |
127 | * GST_STATE_TARGET: |
128 | * @elem: a #GstElement to return the target state for. |
129 | * |
130 | * This macro returns the target #GstState of the element. |
131 | * |
132 | * Since: 0.10.13 |
133 | */ |
134 | #define GST_STATE_TARGET(elem) (GST_ELEMENT_CAST(elem)->abidata.ABI.target_state) |
135 | |
136 | /** |
137 | * GST_STATE_RETURN: |
138 | * @elem: a #GstElement to return the last state result for. |
139 | * |
140 | * This macro returns the last #GstStateChangeReturn value. |
141 | */ |
142 | #define GST_STATE_RETURN(elem) (GST_ELEMENT_CAST(elem)->last_return) |
143 | |
144 | #define __GST_SIGN(val) ((val) < 0 ? -1 : ((val) > 0 ? 1 : 0)) |
145 | /** |
146 | * GST_STATE_GET_NEXT: |
147 | * @cur: A starting #GstState |
148 | * @pending: A target #GstState |
149 | * |
150 | * Given a current state @cur and a target state @pending, calculate the next (intermediate) |
151 | * #GstState. |
152 | */ |
153 | #define GST_STATE_GET_NEXT(cur,pending) ((GstState)((cur) + __GST_SIGN ((gint)(pending) - (gint)(cur)))) |
154 | /** |
155 | * GST_STATE_TRANSITION: |
156 | * @cur: A current state |
157 | * @next: A next state |
158 | * |
159 | * Given a current state @cur and a next state @next, calculate the associated |
160 | * #GstStateChange transition. |
161 | */ |
162 | #define GST_STATE_TRANSITION(cur,next) ((GstStateChange)(((cur)<<3)|(next))) |
163 | /** |
164 | * GST_STATE_TRANSITION_CURRENT: |
165 | * @trans: A #GstStateChange |
166 | * |
167 | * Given a state transition @trans, extract the current #GstState. |
168 | */ |
169 | #define GST_STATE_TRANSITION_CURRENT(trans) ((GstState)((trans)>>3)) |
170 | /** |
171 | * GST_STATE_TRANSITION_NEXT: |
172 | * @trans: A #GstStateChange |
173 | * |
174 | * Given a state transition @trans, extract the next #GstState. |
175 | */ |
176 | #define GST_STATE_TRANSITION_NEXT(trans) ((GstState)((trans)&0x7)) |
177 | |
178 | /** |
179 | * GstStateChange: |
180 | * @GST_STATE_CHANGE_NULL_TO_READY : state change from NULL to READY. |
181 | * <itemizedlist> |
182 | * <listitem><para> |
183 | * The element must check if the resources it needs are available. Device |
184 | * sinks and -sources typically try to probe the device to constrain their |
185 | * caps. |
186 | * </para></listitem> |
187 | * <listitem><para> |
188 | * The element opens the device (in case feature need to be probed). |
189 | * </para></listitem> |
190 | * </itemizedlist> |
191 | * @GST_STATE_CHANGE_READY_TO_PAUSED : state change from READY to PAUSED. |
192 | * <itemizedlist> |
193 | * <listitem><para> |
194 | * The element pads are activated in order to receive data in PAUSED. |
195 | * Streaming threads are started. |
196 | * </para></listitem> |
197 | * <listitem><para> |
198 | * Some elements might need to return %GST_STATE_CHANGE_ASYNC and complete |
199 | * the state change when they have enough information. It is a requirement |
200 | * for sinks to return %GST_STATE_CHANGE_ASYNC and complete the state change |
201 | * when they receive the first buffer or %GST_EVENT_EOS (preroll). |
202 | * Sinks also block the dataflow when in PAUSED. |
203 | * </para></listitem> |
204 | * <listitem><para> |
205 | * A pipeline resets the running_time to 0. |
206 | * </para></listitem> |
207 | * <listitem><para> |
208 | * Live sources return %GST_STATE_CHANGE_NO_PREROLL and don't generate data. |
209 | * </para></listitem> |
210 | * </itemizedlist> |
211 | * @GST_STATE_CHANGE_PAUSED_TO_PLAYING: state change from PAUSED to PLAYING. |
212 | * <itemizedlist> |
213 | * <listitem><para> |
214 | * Most elements ignore this state change. |
215 | * </para></listitem> |
216 | * <listitem><para> |
217 | * The pipeline selects a #GstClock and distributes this to all the children |
218 | * before setting them to PLAYING. This means that it is only alowed to |
219 | * synchronize on the #GstClock in the PLAYING state. |
220 | * </para></listitem> |
221 | * <listitem><para> |
222 | * The pipeline uses the #GstClock and the running_time to calculate the |
223 | * base_time. The base_time is distributed to all children when performing |
224 | * the state change. |
225 | * </para></listitem> |
226 | * <listitem><para> |
227 | * Sink elements stop blocking on the preroll buffer or event and start |
228 | * rendering the data. |
229 | * </para></listitem> |
230 | * <listitem><para> |
231 | * Sinks can post %GST_MESSAGE_EOS in the PLAYING state. It is not allowed |
232 | * to post %GST_MESSAGE_EOS when not in the PLAYING state. |
233 | * </para></listitem> |
234 | * <listitem><para> |
235 | * While streaming in PAUSED or PLAYING elements can create and remove |
236 | * sometimes pads. |
237 | * </para></listitem> |
238 | * <listitem><para> |
239 | * Live sources start generating data and return %GST_STATE_CHANGE_SUCCESS. |
240 | * </para></listitem> |
241 | * </itemizedlist> |
242 | * @GST_STATE_CHANGE_PLAYING_TO_PAUSED: state change from PLAYING to PAUSED. |
243 | * <itemizedlist> |
244 | * <listitem><para> |
245 | * Most elements ignore this state change. |
246 | * </para></listitem> |
247 | * <listitem><para> |
248 | * The pipeline calculates the running_time based on the last selected |
249 | * #GstClock and the base_time. It stores this information to continue |
250 | * playback when going back to the PLAYING state. |
251 | * </para></listitem> |
252 | * <listitem><para> |
253 | * Sinks unblock any #GstClock wait calls. |
254 | * </para></listitem> |
255 | * <listitem><para> |
256 | * When a sink does not have a pending buffer to play, it returns |
257 | * %GST_STATE_CHANGE_ASYNC from this state change and completes the state |
258 | * change when it receives a new buffer or an %GST_EVENT_EOS. |
259 | * </para></listitem> |
260 | * <listitem><para> |
261 | * Any queued %GST_MESSAGE_EOS items are removed since they will be reposted |
262 | * when going back to the PLAYING state. The EOS messages are queued in |
263 | * #GstBin containers. |
264 | * </para></listitem> |
265 | * <listitem><para> |
266 | * Live sources stop generating data and return %GST_STATE_CHANGE_NO_PREROLL. |
267 | * </para></listitem> |
268 | * </itemizedlist> |
269 | * @GST_STATE_CHANGE_PAUSED_TO_READY : state change from PAUSED to READY. |
270 | * <itemizedlist> |
271 | * <listitem><para> |
272 | * Sinks unblock any waits in the preroll. |
273 | * </para></listitem> |
274 | * <listitem><para> |
275 | * Elements unblock any waits on devices |
276 | * </para></listitem> |
277 | * <listitem><para> |
278 | * Chain or get_range functions return %GST_FLOW_WRONG_STATE. |
279 | * </para></listitem> |
280 | * <listitem><para> |
281 | * The element pads are deactivated so that streaming becomes impossible and |
282 | * all streaming threads are stopped. |
283 | * </para></listitem> |
284 | * <listitem><para> |
285 | * The sink forgets all negotiated formats |
286 | * </para></listitem> |
287 | * <listitem><para> |
288 | * Elements remove all sometimes pads |
289 | * </para></listitem> |
290 | * </itemizedlist> |
291 | * @GST_STATE_CHANGE_READY_TO_NULL : state change from READY to NULL. |
292 | * <itemizedlist> |
293 | * <listitem><para> |
294 | * Elements close devices |
295 | * </para></listitem> |
296 | * <listitem><para> |
297 | * Elements reset any internal state. |
298 | * </para></listitem> |
299 | * </itemizedlist> |
300 | * |
301 | * These are the different state changes an element goes through. |
302 | * %GST_STATE_NULL ⇒ %GST_STATE_PLAYING is called an upwards state change |
303 | * and %GST_STATE_PLAYING ⇒ %GST_STATE_NULL a downwards state change. |
304 | */ |
305 | typedef enum /*< flags=0 >*/ |
306 | { |
307 | GST_STATE_CHANGE_NULL_TO_READY = (GST_STATE_NULL<<3) | GST_STATE_READY, |
308 | GST_STATE_CHANGE_READY_TO_PAUSED = (GST_STATE_READY<<3) | GST_STATE_PAUSED, |
309 | GST_STATE_CHANGE_PAUSED_TO_PLAYING = (GST_STATE_PAUSED<<3) | GST_STATE_PLAYING, |
310 | GST_STATE_CHANGE_PLAYING_TO_PAUSED = (GST_STATE_PLAYING<<3) | GST_STATE_PAUSED, |
311 | GST_STATE_CHANGE_PAUSED_TO_READY = (GST_STATE_PAUSED<<3) | GST_STATE_READY, |
312 | GST_STATE_CHANGE_READY_TO_NULL = (GST_STATE_READY<<3) | GST_STATE_NULL |
313 | } GstStateChange; |
314 | |
315 | /** |
316 | * GstElementFlags: |
317 | * @GST_ELEMENT_LOCKED_STATE: ignore state changes from parent |
318 | * @GST_ELEMENT_IS_SINK: the element is a sink |
319 | * @GST_ELEMENT_UNPARENTING: Child is being removed from the parent bin. |
320 | * gst_bin_remove() on a child already being removed immediately returns FALSE |
321 | * @GST_ELEMENT_IS_SOURCE: the element is a source. Since 0.10.31 |
322 | * @GST_ELEMENT_FLAG_LAST: offset to define more flags |
323 | * |
324 | * The standard flags that an element may have. |
325 | */ |
326 | typedef enum |
327 | { |
328 | GST_ELEMENT_LOCKED_STATE = (GST_OBJECT_FLAG_LAST << 0), |
329 | GST_ELEMENT_IS_SINK = (GST_OBJECT_FLAG_LAST << 1), |
330 | GST_ELEMENT_UNPARENTING = (GST_OBJECT_FLAG_LAST << 2), |
331 | GST_ELEMENT_IS_SOURCE = (GST_OBJECT_FLAG_LAST << 3), |
332 | /* padding */ |
333 | GST_ELEMENT_FLAG_LAST = (GST_OBJECT_FLAG_LAST << 16) |
334 | } GstElementFlags; |
335 | |
336 | /** |
337 | * GST_ELEMENT_IS_LOCKED_STATE: |
338 | * @elem: A #GstElement to query |
339 | * |
340 | * Check if the element is in the locked state and therefore will ignore state |
341 | * changes from its parent object. |
342 | */ |
343 | #define GST_ELEMENT_IS_LOCKED_STATE(elem) (GST_OBJECT_FLAG_IS_SET(elem,GST_ELEMENT_LOCKED_STATE)) |
344 | |
345 | /** |
346 | * GST_ELEMENT_NAME: |
347 | * @elem: A #GstElement to query |
348 | * |
349 | * Gets the name of this element. Use only in core as this is not |
350 | * ABI-compatible. Others use gst_element_get_name() |
351 | */ |
352 | #define GST_ELEMENT_NAME(elem) (GST_OBJECT_NAME(elem)) |
353 | |
354 | /** |
355 | * GST_ELEMENT_PARENT: |
356 | * @elem: A #GstElement to query |
357 | * |
358 | * Get the parent object of this element. |
359 | */ |
360 | #define GST_ELEMENT_PARENT(elem) (GST_ELEMENT_CAST(GST_OBJECT_PARENT(elem))) |
361 | |
362 | /** |
363 | * GST_ELEMENT_BUS: |
364 | * @elem: A #GstElement to query |
365 | * |
366 | * Get the message bus of this element. |
367 | */ |
368 | #define GST_ELEMENT_BUS(elem) (GST_ELEMENT_CAST(elem)->bus) |
369 | |
370 | /** |
371 | * GST_ELEMENT_CLOCK: |
372 | * @elem: A #GstElement to query |
373 | * |
374 | * Get the clock of this element |
375 | */ |
376 | #define GST_ELEMENT_CLOCK(elem) (GST_ELEMENT_CAST(elem)->clock) |
377 | |
378 | /** |
379 | * GST_ELEMENT_PADS: |
380 | * @elem: A #GstElement to query |
381 | * |
382 | * Get the pads of this elements. |
383 | */ |
384 | #define GST_ELEMENT_PADS(elem) (GST_ELEMENT_CAST(elem)->pads) |
385 | |
386 | /** |
387 | * GST_ELEMENT_START_TIME: |
388 | * @elem: a #GstElement to return the start time for. |
389 | * |
390 | * This macro returns the start_time of the @elem. The start_time is the |
391 | * running_time of the pipeline when the element went to PAUSED. |
392 | * |
393 | * Since: 0.10.24 |
394 | */ |
395 | #define GST_ELEMENT_START_TIME(elem) (GST_ELEMENT_CAST(elem)->abidata.ABI.start_time) |
396 | |
397 | /** |
398 | * GST_ELEMENT_ERROR: |
399 | * @el: the element that generates the error |
400 | * @domain: like CORE, LIBRARY, RESOURCE or STREAM (see #gstreamer-GstGError) |
401 | * @code: error code defined for that domain (see #gstreamer-GstGError) |
402 | * @text: the message to display (format string and args enclosed in |
403 | parentheses) |
404 | * @debug: debugging information for the message (format string and args |
405 | enclosed in parentheses) |
406 | * |
407 | * Utility function that elements can use in case they encountered a fatal |
408 | * data processing error. The pipeline will post an error message and the |
409 | * application will be requested to stop further media processing. |
410 | */ |
411 | #define GST_ELEMENT_ERROR(el, domain, code, text, debug) \ |
412 | G_STMT_START { \ |
413 | gchar *__txt = _gst_element_error_printf text; \ |
414 | gchar *__dbg = _gst_element_error_printf debug; \ |
415 | if (__txt) \ |
416 | GST_WARNING_OBJECT (el, "error: %s", __txt); \ |
417 | if (__dbg) \ |
418 | GST_WARNING_OBJECT (el, "error: %s", __dbg); \ |
419 | gst_element_message_full (GST_ELEMENT(el), GST_MESSAGE_ERROR, \ |
420 | GST_ ## domain ## _ERROR, GST_ ## domain ## _ERROR_ ## code, \ |
421 | __txt, __dbg, __FILE__, GST_FUNCTION, __LINE__); \ |
422 | } G_STMT_END |
423 | |
424 | /** |
425 | * GST_ELEMENT_WARNING: |
426 | * @el: the element that generates the warning |
427 | * @domain: like CORE, LIBRARY, RESOURCE or STREAM (see #gstreamer-GstGError) |
428 | * @code: error code defined for that domain (see #gstreamer-GstGError) |
429 | * @text: the message to display (format string and args enclosed in |
430 | parentheses) |
431 | * @debug: debugging information for the message (format string and args |
432 | enclosed in parentheses) |
433 | * |
434 | * Utility function that elements can use in case they encountered a non-fatal |
435 | * data processing problem. The pipeline will post a warning message and the |
436 | * application will be informed. |
437 | */ |
438 | #define GST_ELEMENT_WARNING(el, domain, code, text, debug) \ |
439 | G_STMT_START { \ |
440 | gchar *__txt = _gst_element_error_printf text; \ |
441 | gchar *__dbg = _gst_element_error_printf debug; \ |
442 | if (__txt) \ |
443 | GST_WARNING_OBJECT (el, "warning: %s", __txt); \ |
444 | if (__dbg) \ |
445 | GST_WARNING_OBJECT (el, "warning: %s", __dbg); \ |
446 | gst_element_message_full (GST_ELEMENT(el), GST_MESSAGE_WARNING, \ |
447 | GST_ ## domain ## _ERROR, GST_ ## domain ## _ERROR_ ## code, \ |
448 | __txt, __dbg, __FILE__, GST_FUNCTION, __LINE__); \ |
449 | } G_STMT_END |
450 | |
451 | /** |
452 | * GST_ELEMENT_INFO: |
453 | * @el: the element that generates the information |
454 | * @domain: like CORE, LIBRARY, RESOURCE or STREAM (see #gstreamer-GstGError) |
455 | * @code: error code defined for that domain (see #gstreamer-GstGError) |
456 | * @text: the message to display (format string and args enclosed in |
457 | parentheses) |
458 | * @debug: debugging information for the message (format string and args |
459 | enclosed in parentheses) |
460 | * |
461 | * Utility function that elements can use in case they want to inform |
462 | * the application of something noteworthy that is not an error. |
463 | * The pipeline will post a info message and the |
464 | * application will be informed. |
465 | * |
466 | * Since: 0.10.12 |
467 | */ |
468 | #define GST_ELEMENT_INFO(el, domain, code, text, debug) \ |
469 | G_STMT_START { \ |
470 | gchar *__txt = _gst_element_error_printf text; \ |
471 | gchar *__dbg = _gst_element_error_printf debug; \ |
472 | if (__txt) \ |
473 | GST_INFO_OBJECT (el, "info: %s", __txt); \ |
474 | if (__dbg) \ |
475 | GST_INFO_OBJECT (el, "info: %s", __dbg); \ |
476 | gst_element_message_full (GST_ELEMENT(el), GST_MESSAGE_INFO, \ |
477 | GST_ ## domain ## _ERROR, GST_ ## domain ## _ERROR_ ## code, \ |
478 | __txt, __dbg, __FILE__, GST_FUNCTION, __LINE__); \ |
479 | } G_STMT_END |
480 | |
481 | /* the state change mutexes and conds */ |
482 | /** |
483 | * GST_STATE_GET_LOCK: |
484 | * @elem: a #GstElement |
485 | * |
486 | * Get a reference to the state lock of @elem. |
487 | * This lock is used by the core. It is taken while getting or setting |
488 | * the state, during state changes, and while finalizing. |
489 | */ |
490 | #define GST_STATE_GET_LOCK(elem) (GST_ELEMENT_CAST(elem)->state_lock) |
491 | /** |
492 | * GST_STATE_GET_COND: |
493 | * @elem: a #GstElement |
494 | * |
495 | * Get the conditional used to signal the completion of a state change. |
496 | */ |
497 | #define GST_STATE_GET_COND(elem) (GST_ELEMENT_CAST(elem)->state_cond) |
498 | |
499 | #define GST_STATE_LOCK(elem) g_static_rec_mutex_lock(GST_STATE_GET_LOCK(elem)) |
500 | #define GST_STATE_TRYLOCK(elem) g_static_rec_mutex_trylock(GST_STATE_GET_LOCK(elem)) |
501 | #define GST_STATE_UNLOCK(elem) g_static_rec_mutex_unlock(GST_STATE_GET_LOCK(elem)) |
502 | #define GST_STATE_UNLOCK_FULL(elem) g_static_rec_mutex_unlock_full(GST_STATE_GET_LOCK(elem)) |
503 | #define GST_STATE_LOCK_FULL(elem,t) g_static_rec_mutex_lock_full(GST_STATE_GET_LOCK(elem), t) |
504 | #define GST_STATE_WAIT(elem) g_cond_wait (GST_STATE_GET_COND (elem), \ |
505 | GST_OBJECT_GET_LOCK (elem)) |
506 | #define GST_STATE_TIMED_WAIT(elem, timeval) g_cond_timed_wait (GST_STATE_GET_COND (elem), \ |
507 | GST_OBJECT_GET_LOCK (elem), timeval) |
508 | #define GST_STATE_SIGNAL(elem) g_cond_signal (GST_STATE_GET_COND (elem)); |
509 | #define GST_STATE_BROADCAST(elem) g_cond_broadcast (GST_STATE_GET_COND (elem)); |
510 | |
511 | /** |
512 | * GstElement: |
513 | * @state_lock: Used to serialize execution of gst_element_set_state() |
514 | * @state_cond: Used to signal completion of a state change |
515 | * @state_cookie: Used to detect concurrent execution of |
516 | * gst_element_set_state() and gst_element_get_state() |
517 | * @current_state: the current state of an element |
518 | * @next_state: the next state of an element, can be #GST_STATE_VOID_PENDING if |
519 | * the element is in the correct state. |
520 | * @pending_state: the final state the element should go to, can be |
521 | * #GST_STATE_VOID_PENDING if the element is in the correct state |
522 | * @last_return: the last return value of an element state change |
523 | * @bus: the bus of the element. This bus is provided to the element by the |
524 | * parent element or the application. A #GstPipeline has a bus of its own. |
525 | * @clock: the clock of the element. This clock is usually provided to the |
526 | * element by the toplevel #GstPipeline. |
527 | * @base_time: the time of the clock right before the element is set to |
528 | * PLAYING. Subtracting @base_time from the current clock time in the PLAYING |
529 | * state will yield the running_time against the clock. |
530 | * @numpads: number of pads of the element, includes both source and sink pads. |
531 | * @pads: list of pads |
532 | * @numsrcpads: number of source pads of the element. |
533 | * @srcpads: list of source pads |
534 | * @numsinkpads: number of sink pads of the element. |
535 | * @sinkpads: list of sink pads |
536 | * @pads_cookie: updated whenever the a pad is added or removed |
537 | * |
538 | * GStreamer element abstract base class. |
539 | */ |
540 | struct _GstElement |
541 | { |
542 | GstObject object; |
543 | |
544 | /*< public >*/ /* with LOCK */ |
545 | GStaticRecMutex *state_lock; |
546 | |
547 | /* element state */ |
548 | GCond *state_cond; |
549 | guint32 state_cookie; |
550 | GstState current_state; |
551 | GstState next_state; |
552 | GstState pending_state; |
553 | GstStateChangeReturn last_return; |
554 | |
555 | GstBus *bus; |
556 | |
557 | /* allocated clock */ |
558 | GstClock *clock; |
559 | GstClockTimeDiff base_time; /* NULL/READY: 0 - PAUSED: current time - PLAYING: difference to clock */ |
560 | |
561 | /* element pads, these lists can only be iterated while holding |
562 | * the LOCK or checking the cookie after each LOCK. */ |
563 | guint16 numpads; |
564 | GList *pads; |
565 | guint16 numsrcpads; |
566 | GList *srcpads; |
567 | guint16 numsinkpads; |
568 | GList *sinkpads; |
569 | guint32 pads_cookie; |
570 | |
571 | /*< private >*/ |
572 | union { |
573 | struct { |
574 | /* state set by application */ |
575 | GstState target_state; |
576 | /* running time of the last PAUSED state */ |
577 | GstClockTime start_time; |
578 | } ABI; |
579 | /* adding + 0 to mark ABI change to be undone later */ |
580 | gpointer _gst_reserved[GST_PADDING + 0]; |
581 | } abidata; |
582 | }; |
583 | |
584 | /** |
585 | * GstElementClass: |
586 | * @parent_class: the parent class structure |
587 | * @details: #GstElementDetails for elements of this class |
588 | * @elementfactory: the #GstElementFactory that creates these elements |
589 | * @padtemplates: a #GList of #GstPadTemplate |
590 | * @numpadtemplates: the number of padtemplates |
591 | * @pad_templ_cookie: changed whenever the padtemplates change |
592 | * @request_new_pad: called when a new pad is requested |
593 | * @release_pad: called when a request pad is to be released |
594 | * @get_state: get the state of the element |
595 | * @set_state: set a new state on the element |
596 | * @change_state: called by @set_state to perform an incremental state change |
597 | * @set_bus: set a #GstBus on the element |
598 | * @provide_clock: gets the #GstClock provided by the element |
599 | * @set_clock: set the #GstClock on the element |
600 | * @get_index: set a #GstIndex on the element |
601 | * @set_index: get the #GstIndex of an element |
602 | * @send_event: send a #GstEvent to the element |
603 | * @get_query_types: get the supported #GstQueryType of this element |
604 | * @query: perform a #GstQuery on the element |
605 | * @request_new_pad_full: called when a new pad is requested. Since: 0.10.32. |
606 | * @state_changed: called immediately after a new state was set. Since: 0.10.36. |
607 | * @post_message: called when a message is posted on the element. Chain up to |
608 | * the parent class' handler to have it posted on the bus. Since: 0.10.37. |
609 | * |
610 | * GStreamer element class. Override the vmethods to implement the element |
611 | * functionality. |
612 | */ |
613 | struct _GstElementClass |
614 | { |
615 | GstObjectClass parent_class; |
616 | |
617 | /*< public >*/ |
618 | /* the element details */ |
619 | /* FIXME-0.11: deprecate this in favour of meta_data */ |
620 | GstElementDetails details; |
621 | |
622 | /* factory that the element was created from */ |
623 | GstElementFactory *elementfactory; |
624 | |
625 | /* templates for our pads */ |
626 | GList *padtemplates; |
627 | gint numpadtemplates; |
628 | guint32 pad_templ_cookie; |
629 | |
630 | /*< private >*/ |
631 | /* signal callbacks */ |
632 | void (*pad_added) (GstElement *element, GstPad *pad); |
633 | void (*pad_removed) (GstElement *element, GstPad *pad); |
634 | void (*no_more_pads) (GstElement *element); |
635 | |
636 | /*< public >*/ |
637 | /* virtual methods for subclasses */ |
638 | |
639 | /* request/release pads */ |
640 | GstPad* (*request_new_pad) (GstElement *element, GstPadTemplate *templ, const gchar* name); |
641 | void (*release_pad) (GstElement *element, GstPad *pad); |
642 | |
643 | /* state changes */ |
644 | GstStateChangeReturn (*get_state) (GstElement * element, GstState * state, |
645 | GstState * pending, GstClockTime timeout); |
646 | GstStateChangeReturn (*set_state) (GstElement *element, GstState state); |
647 | GstStateChangeReturn (*change_state) (GstElement *element, GstStateChange transition); |
648 | |
649 | /* bus */ |
650 | void (*set_bus) (GstElement * element, GstBus * bus); |
651 | |
652 | /* set/get clocks */ |
653 | GstClock* (*provide_clock) (GstElement *element); |
654 | gboolean (*set_clock) (GstElement *element, GstClock *clock); |
655 | |
656 | /* index */ |
657 | GstIndex* (*get_index) (GstElement *element); |
658 | void (*set_index) (GstElement *element, GstIndex *index); |
659 | |
660 | /* query functions */ |
661 | gboolean (*send_event) (GstElement *element, GstEvent *event); |
662 | |
663 | const GstQueryType* (*get_query_types) (GstElement *element); |
664 | gboolean (*query) (GstElement *element, GstQuery *query); |
665 | |
666 | /*< private >*/ |
667 | /* FIXME-0.11: move up and replace details */ |
668 | gpointer meta_data; |
669 | |
670 | /*< public >*/ |
671 | /* Virtual method for subclasses (additions) */ |
672 | /* FIXME-0.11 Make this the default behaviour */ |
673 | GstPad* (*request_new_pad_full) (GstElement *element, GstPadTemplate *templ, |
674 | const gchar* name, const GstCaps *caps); |
675 | |
676 | void (*state_changed) (GstElement *element, GstState oldstate, |
677 | GstState newstate, GstState pending); |
678 | |
679 | gboolean (*post_message) (GstElement *element, GstMessage *message); |
680 | }; |
681 | |
682 | /* element class pad templates */ |
683 | void gst_element_class_add_pad_template (GstElementClass *klass, GstPadTemplate *templ); |
684 | void gst_element_class_add_static_pad_template (GstElementClass *klass, GstStaticPadTemplate *templ); |
685 | GstPadTemplate* gst_element_class_get_pad_template (GstElementClass *element_class, const gchar *name); |
686 | GList* gst_element_class_get_pad_template_list (GstElementClass *element_class); |
687 | |
688 | /* element class meta data */ |
689 | void gst_element_class_set_documentation_uri (GstElementClass * klass, const gchar *uri); |
690 | void gst_element_class_set_icon_name (GstElementClass * klass, const gchar *name); |
691 | #ifndef GST_DISABLE_DEPRECATED |
692 | void gst_element_class_set_details (GstElementClass *klass, const GstElementDetails *details); |
693 | #endif |
694 | void gst_element_class_set_details_simple (GstElementClass *klass, |
695 | const gchar *longname, |
696 | const gchar *classification, |
697 | const gchar *description, |
698 | const gchar *author); |
699 | |
700 | /* element instance */ |
701 | GType gst_element_get_type (void); |
702 | |
703 | /* basic name and parentage stuff from GstObject */ |
704 | |
705 | /** |
706 | * gst_element_get_name: |
707 | * @elem: a #GstElement to get the name of @elem. |
708 | * |
709 | * Returns a copy of the name of @elem. |
710 | * Caller should g_free() the return value after usage. |
711 | * For a nameless element, this returns NULL, which you can safely g_free() |
712 | * as well. |
713 | * |
714 | * Returns: (transfer full): the name of @elem. g_free() after usage. MT safe. |
715 | * |
716 | */ |
717 | #define gst_element_get_name(elem) gst_object_get_name(GST_OBJECT_CAST(elem)) |
718 | |
719 | /** |
720 | * gst_element_set_name: |
721 | * @elem: a #GstElement to set the name of. |
722 | * @name: the new name |
723 | * |
724 | * Sets the name of the element, getting rid of the old name if there was one. |
725 | */ |
726 | #define gst_element_set_name(elem,name) gst_object_set_name(GST_OBJECT_CAST(elem),name) |
727 | |
728 | /** |
729 | * gst_element_get_parent: |
730 | * @elem: a #GstElement to get the parent of. |
731 | * |
732 | * Get the parent of an element. |
733 | * |
734 | * Returns: (transfer full): the parent of an element. |
735 | */ |
736 | #define gst_element_get_parent(elem) gst_object_get_parent(GST_OBJECT_CAST(elem)) |
737 | |
738 | /** |
739 | * gst_element_set_parent: |
740 | * @elem: a #GstElement to set the parent of. |
741 | * @parent: the new parent #GstObject of the element. |
742 | * |
743 | * Sets the parent of an element. |
744 | */ |
745 | #define gst_element_set_parent(elem,parent) gst_object_set_parent(GST_OBJECT_CAST(elem),parent) |
746 | |
747 | /* clocking */ |
748 | gboolean gst_element_requires_clock (GstElement *element); |
749 | gboolean gst_element_provides_clock (GstElement *element); |
750 | GstClock* gst_element_provide_clock (GstElement *element); |
751 | GstClock* gst_element_get_clock (GstElement *element); |
752 | gboolean gst_element_set_clock (GstElement *element, GstClock *clock); |
753 | void gst_element_set_base_time (GstElement *element, GstClockTime time); |
754 | GstClockTime gst_element_get_base_time (GstElement *element); |
755 | void gst_element_set_start_time (GstElement *element, GstClockTime time); |
756 | GstClockTime gst_element_get_start_time (GstElement *element); |
757 | |
758 | /* indexes */ |
759 | gboolean gst_element_is_indexable (GstElement *element); |
760 | void gst_element_set_index (GstElement *element, GstIndex *index); |
761 | GstIndex* gst_element_get_index (GstElement *element); |
762 | |
763 | /* bus */ |
764 | void gst_element_set_bus (GstElement * element, GstBus * bus); |
765 | GstBus * gst_element_get_bus (GstElement * element); |
766 | |
767 | /* pad management */ |
768 | gboolean gst_element_add_pad (GstElement *element, GstPad *pad); |
769 | gboolean gst_element_remove_pad (GstElement *element, GstPad *pad); |
770 | void gst_element_no_more_pads (GstElement *element); |
771 | |
772 | #ifndef GST_DISABLE_DEPRECATED |
773 | GstPad* gst_element_get_pad (GstElement *element, const gchar *name); |
774 | #endif /* GST_DISABLE_DEPRECATED */ |
775 | GstPad* gst_element_get_static_pad (GstElement *element, const gchar *name); |
776 | GstPad* gst_element_get_request_pad (GstElement *element, const gchar *name); |
777 | GstPad* gst_element_request_pad (GstElement *element, |
778 | GstPadTemplate *templ, |
779 | const gchar * name, const GstCaps *caps); |
780 | void gst_element_release_request_pad (GstElement *element, GstPad *pad); |
781 | |
782 | GstIterator * gst_element_iterate_pads (GstElement * element); |
783 | GstIterator * gst_element_iterate_src_pads (GstElement * element); |
784 | GstIterator * gst_element_iterate_sink_pads (GstElement * element); |
785 | |
786 | /* event/query/format stuff */ |
787 | gboolean gst_element_send_event (GstElement *element, GstEvent *event); |
788 | gboolean gst_element_seek (GstElement *element, gdouble rate, |
789 | GstFormat format, GstSeekFlags flags, |
790 | GstSeekType cur_type, gint64 cur, |
791 | GstSeekType stop_type, gint64 stop); |
792 | const GstQueryType* gst_element_get_query_types (GstElement *element); |
793 | gboolean gst_element_query (GstElement *element, GstQuery *query); |
794 | |
795 | /* messages */ |
796 | gboolean gst_element_post_message (GstElement * element, GstMessage * message); |
797 | |
798 | /* error handling */ |
799 | /* gcc versions < 3.3 warn about NULL being passed as format to printf */ |
800 | #if (defined(GST_USING_PRINTF_EXTENSION) || !defined(__GNUC__) || (__GNUC__ < 3) || (__GNUC__ == 3 && __GNUC_MINOR__ < 3)) |
801 | gchar * _gst_element_error_printf (const gchar *format, ...); |
802 | #else |
803 | gchar * _gst_element_error_printf (const gchar *format, ...) G_GNUC_PRINTF (1, 2); |
804 | #endif |
805 | void gst_element_message_full (GstElement * element, GstMessageType type, |
806 | GQuark domain, gint code, gchar * text, |
807 | gchar * debug, const gchar * file, |
808 | const gchar * function, gint line); |
809 | |
810 | /* state management */ |
811 | gboolean gst_element_is_locked_state (GstElement *element); |
812 | gboolean gst_element_set_locked_state (GstElement *element, gboolean locked_state); |
813 | gboolean gst_element_sync_state_with_parent (GstElement *element); |
814 | |
815 | GstStateChangeReturn gst_element_get_state (GstElement * element, |
816 | GstState * state, |
817 | GstState * pending, |
818 | GstClockTime timeout); |
819 | GstStateChangeReturn gst_element_set_state (GstElement *element, GstState state); |
820 | |
821 | void gst_element_abort_state (GstElement * element); |
822 | GstStateChangeReturn gst_element_change_state (GstElement * element, |
823 | GstStateChange transition); |
824 | GstStateChangeReturn gst_element_continue_state (GstElement * element, |
825 | GstStateChangeReturn ret); |
826 | void gst_element_lost_state (GstElement * element); |
827 | void gst_element_lost_state_full (GstElement * element, gboolean new_base_time); |
828 | |
829 | /* factory management */ |
830 | GstElementFactory* gst_element_get_factory (GstElement *element); |
831 | |
832 | G_END_DECLS |
833 | |
834 | #endif /* __GST_ELEMENT_H__ */ |
835 | |