71 * |
71 * |
72 * Note that clock slection and distribution is normally handled by the |
72 * Note that clock slection and distribution is normally handled by the |
73 * toplevel #GstPipeline so the clock functions are only to be used in very |
73 * toplevel #GstPipeline so the clock functions are only to be used in very |
74 * specific situations. |
74 * specific situations. |
75 * |
75 * |
76 * Last reviewed on 2009-05-29 (0.10.24) |
76 * Last reviewed on 2006-03-12 (0.10.5) |
77 */ |
77 */ |
78 |
78 |
79 #include "gst_private.h" |
79 #include "gst_private.h" |
80 #include <glib.h> |
80 #include <glib.h> |
81 #include <stdarg.h> |
81 #include <stdarg.h> |
110 { |
109 { |
111 ARG_0 |
110 ARG_0 |
112 /* FILL ME */ |
111 /* FILL ME */ |
113 }; |
112 }; |
114 |
113 |
115 IMPORT_C extern void __gst_element_details_clear (GstElementDetails * dp); |
114 extern void __gst_element_details_clear (GstElementDetails * dp); |
116 |
115 extern void __gst_element_details_copy (GstElementDetails * dest, |
117 IMPORT_C extern void __gst_element_details_copy (GstElementDetails * dest, |
|
118 const GstElementDetails * src); |
116 const GstElementDetails * src); |
119 |
117 |
120 static void gst_element_class_init (GstElementClass * klass); |
118 static void gst_element_class_init (GstElementClass * klass); |
121 static void gst_element_init (GstElement * element); |
119 static void gst_element_init (GstElement * element); |
122 static void gst_element_base_class_init (gpointer g_class); |
120 static void gst_element_base_class_init (gpointer g_class); |
148 static void gst_element_restore_thyself (GstObject * parent, xmlNodePtr self); |
146 static void gst_element_restore_thyself (GstObject * parent, xmlNodePtr self); |
149 #endif |
147 #endif |
150 |
148 |
151 static GstObjectClass *parent_class = NULL; |
149 static GstObjectClass *parent_class = NULL; |
152 static guint gst_element_signals[LAST_SIGNAL] = { 0 }; |
150 static guint gst_element_signals[LAST_SIGNAL] = { 0 }; |
153 |
|
154 /* this is used in gstelementfactory.c:gst_element_register() */ |
|
155 GQuark _gst_elementclass_factory = 0; |
|
156 #ifdef __SYMBIAN32__ |
151 #ifdef __SYMBIAN32__ |
157 EXPORT_C |
152 EXPORT_C |
158 #endif |
153 #endif |
159 |
154 |
160 |
155 |
161 GType |
156 GType |
162 gst_element_get_type (void) |
157 gst_element_get_type (void) |
163 { |
158 { |
164 static volatile gsize gst_element_type = 0; |
159 static GType gst_element_type = 0; |
165 |
160 |
166 if (g_once_init_enter (&gst_element_type)) { |
161 if (G_UNLIKELY (gst_element_type == 0)) { |
167 GType _type; |
|
168 static const GTypeInfo element_info = { |
162 static const GTypeInfo element_info = { |
169 sizeof (GstElementClass), |
163 sizeof (GstElementClass), |
170 gst_element_base_class_init, |
164 gst_element_base_class_init, |
171 gst_element_base_class_finalize, |
165 gst_element_base_class_finalize, |
172 (GClassInitFunc) gst_element_class_init, |
166 (GClassInitFunc) gst_element_class_init, |
176 0, |
170 0, |
177 (GInstanceInitFunc) gst_element_init, |
171 (GInstanceInitFunc) gst_element_init, |
178 NULL |
172 NULL |
179 }; |
173 }; |
180 |
174 |
181 _type = g_type_register_static (GST_TYPE_OBJECT, "GstElement", |
175 gst_element_type = g_type_register_static (GST_TYPE_OBJECT, "GstElement", |
182 &element_info, G_TYPE_FLAG_ABSTRACT); |
176 &element_info, G_TYPE_FLAG_ABSTRACT); |
183 |
|
184 _gst_elementclass_factory = |
|
185 g_quark_from_static_string ("GST_ELEMENTCLASS_FACTORY"); |
|
186 g_once_init_leave (&gst_element_type, _type); |
|
187 } |
177 } |
188 return gst_element_type; |
178 return gst_element_type; |
189 } |
179 } |
190 |
180 |
191 static void |
181 static void |
266 * of doing things. |
256 * of doing things. |
267 * See http://bugzilla.gnome.org/show_bug.cgi?id=491501 |
257 * See http://bugzilla.gnome.org/show_bug.cgi?id=491501 |
268 */ |
258 */ |
269 memset (&element_class->details, 0, sizeof (GstElementDetails)); |
259 memset (&element_class->details, 0, sizeof (GstElementDetails)); |
270 element_class->padtemplates = NULL; |
260 element_class->padtemplates = NULL; |
271 |
|
272 /* set the factory, see gst_element_register() */ |
|
273 element_class->elementfactory = |
|
274 g_type_get_qdata (G_TYPE_FROM_CLASS (element_class), |
|
275 _gst_elementclass_factory); |
|
276 GST_DEBUG ("type %s : factory %p", G_OBJECT_CLASS_NAME (element_class), |
|
277 element_class->elementfactory); |
|
278 } |
261 } |
279 |
262 |
280 static void |
263 static void |
281 gst_element_base_class_finalize (gpointer g_class) |
264 gst_element_base_class_finalize (gpointer g_class) |
282 { |
265 { |
337 * @element: a #GstElement to release the request pad of. |
320 * @element: a #GstElement to release the request pad of. |
338 * @pad: the #GstPad to release. |
321 * @pad: the #GstPad to release. |
339 * |
322 * |
340 * Makes the element free the previously requested pad as obtained |
323 * Makes the element free the previously requested pad as obtained |
341 * with gst_element_get_request_pad(). |
324 * with gst_element_get_request_pad(). |
342 * |
|
343 * This does not unref the pad. If the pad was created by using |
|
344 * gst_element_get_request_pad(), gst_element_release_request_pad() needs to be |
|
345 * followed by gst_object_unref() to free the @pad. |
|
346 * |
325 * |
347 * MT safe. |
326 * MT safe. |
348 */ |
327 */ |
349 #ifdef __SYMBIAN32__ |
328 #ifdef __SYMBIAN32__ |
350 EXPORT_C |
329 EXPORT_C |
567 * @element: a #GstElement. |
546 * @element: a #GstElement. |
568 * |
547 * |
569 * Returns the base time of the element. The base time is the |
548 * Returns the base time of the element. The base time is the |
570 * absolute time of the clock when this element was last put to |
549 * absolute time of the clock when this element was last put to |
571 * PLAYING. Subtracting the base time from the clock time gives |
550 * PLAYING. Subtracting the base time from the clock time gives |
572 * the running time of the element. |
551 * the stream time of the element. |
573 * |
552 * |
574 * Returns: the base time of the element. |
553 * Returns: the base time of the element. |
575 * |
554 * |
576 * MT safe. |
555 * MT safe. |
577 */ |
556 */ |
591 GST_OBJECT_UNLOCK (element); |
570 GST_OBJECT_UNLOCK (element); |
592 |
571 |
593 return result; |
572 return result; |
594 } |
573 } |
595 |
574 |
596 /** |
575 #ifndef GST_DISABLE_INDEX |
597 * gst_element_set_start_time: |
|
598 * @element: a #GstElement. |
|
599 * @time: the base time to set. |
|
600 * |
|
601 * Set the start time of an element. The start time of the element is the |
|
602 * running time of the element when it last went to the PAUSED state. In READY |
|
603 * or after a flushing seek, it is set to 0. |
|
604 * |
|
605 * Toplevel elements like #GstPipeline will manage the start_time and |
|
606 * base_time on its children. Setting the start_time to #GST_CLOCK_TIME_NONE |
|
607 * on such a toplevel element will disable the distribution of the base_time to |
|
608 * the children and can be useful if the application manages the base_time |
|
609 * itself, for example if you want to synchronize capture from multiple |
|
610 * pipelines, and you can also ensure that the pipelines have the same clock. |
|
611 * |
|
612 * MT safe. |
|
613 * |
|
614 * Since: 0.10.24 |
|
615 */ |
|
616 #ifdef __SYMBIAN32__ |
|
617 EXPORT_C |
|
618 #endif |
|
619 |
|
620 void |
|
621 gst_element_set_start_time (GstElement * element, GstClockTime time) |
|
622 { |
|
623 GstClockTime old; |
|
624 |
|
625 g_return_if_fail (GST_IS_ELEMENT (element)); |
|
626 |
|
627 GST_OBJECT_LOCK (element); |
|
628 old = GST_ELEMENT_START_TIME (element); |
|
629 GST_ELEMENT_START_TIME (element) = time; |
|
630 GST_OBJECT_UNLOCK (element); |
|
631 |
|
632 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, element, |
|
633 "set start_time=%" GST_TIME_FORMAT ", old %" GST_TIME_FORMAT, |
|
634 GST_TIME_ARGS (time), GST_TIME_ARGS (old)); |
|
635 } |
|
636 |
|
637 /** |
|
638 * gst_element_get_start_time: |
|
639 * @element: a #GstElement. |
|
640 * |
|
641 * Returns the start time of the element. The start time is the |
|
642 * running time of the clock when this element was last put to PAUSED. |
|
643 * |
|
644 * Usually the start_time is managed by a toplevel element such as |
|
645 * #GstPipeline. |
|
646 * |
|
647 * MT safe. |
|
648 * |
|
649 * Returns: the start time of the element. |
|
650 * |
|
651 * Since: 0.10.24 |
|
652 */ |
|
653 #ifdef __SYMBIAN32__ |
|
654 EXPORT_C |
|
655 #endif |
|
656 |
|
657 GstClockTime |
|
658 gst_element_get_start_time (GstElement * element) |
|
659 { |
|
660 GstClockTime result; |
|
661 |
|
662 g_return_val_if_fail (GST_IS_ELEMENT (element), GST_CLOCK_TIME_NONE); |
|
663 |
|
664 GST_OBJECT_LOCK (element); |
|
665 result = GST_ELEMENT_START_TIME (element); |
|
666 GST_OBJECT_UNLOCK (element); |
|
667 |
|
668 return result; |
|
669 } |
|
670 |
|
671 /** |
576 /** |
672 * gst_element_is_indexable: |
577 * gst_element_is_indexable: |
673 * @element: a #GstElement. |
578 * @element: a #GstElement. |
674 * |
579 * |
675 * Queries if the element can be indexed. |
580 * Queries if the element can be indexed. |
750 if (oclass->get_index) |
655 if (oclass->get_index) |
751 result = oclass->get_index (element); |
656 result = oclass->get_index (element); |
752 |
657 |
753 return result; |
658 return result; |
754 } |
659 } |
|
660 #endif |
755 |
661 |
756 /** |
662 /** |
757 * gst_element_add_pad: |
663 * gst_element_add_pad: |
758 * @element: a #GstElement to add the pad to. |
664 * @element: a #GstElement to add the pad to. |
759 * @pad: the #GstPad to add to the element. |
665 * @pad: the #GstPad to add to the element. |
1175 * @name: the name of the pad to retrieve. |
1081 * @name: the name of the pad to retrieve. |
1176 * |
1082 * |
1177 * Retrieves a pad from @element by name. Tries gst_element_get_static_pad() |
1083 * Retrieves a pad from @element by name. Tries gst_element_get_static_pad() |
1178 * first, then gst_element_get_request_pad(). |
1084 * first, then gst_element_get_request_pad(). |
1179 * |
1085 * |
1180 * Deprecated: This function is deprecated as it's unclear if the reference |
1086 * <note>Usage of this function is not recommended as it is unclear if the reference |
1181 * to the result pad should be released with gst_object_unref() in case of a static pad |
1087 * to the result pad should be released with gst_object_unref() in case of a static pad |
1182 * or gst_element_release_request_pad() in case of a request pad. |
1088 * or gst_element_release_request_pad() in case of a request pad.</note> |
1183 * Use gst_element_get_static_pad() or gst_element_get_request_pad() instead. |
|
1184 * |
1089 * |
1185 * Returns: the #GstPad if found, otherwise %NULL. Unref or Release after usage, |
1090 * Returns: the #GstPad if found, otherwise %NULL. Unref or Release after usage, |
1186 * depending on the type of the pad. |
1091 * depending on the type of the pad. |
1187 */ |
1092 */ |
1188 #ifndef GST_REMOVE_DEPRECATED |
1093 #ifdef __SYMBIAN32__ |
1189 #ifdef __SYMBIAN32__ |
1094 EXPORT_C |
1190 EXPORT_C |
1095 #endif |
1191 #endif |
1096 |
1192 GstPad * |
1097 GstPad * |
1193 gst_element_get_pad (GstElement * element, const gchar * name) |
1098 gst_element_get_pad (GstElement * element, const gchar * name) |
1194 { |
1099 { |
1195 GstPad *pad; |
1100 GstPad *pad; |
1196 |
1101 |
1201 if (!pad) |
1106 if (!pad) |
1202 pad = gst_element_get_request_pad (element, name); |
1107 pad = gst_element_get_request_pad (element, name); |
1203 |
1108 |
1204 return pad; |
1109 return pad; |
1205 } |
1110 } |
1206 #endif /* GST_REMOVE_DEPRECATED */ |
|
1207 |
1111 |
1208 static GstIteratorItem |
1112 static GstIteratorItem |
1209 iterate_pad (GstIterator * it, GstPad * pad) |
1113 iterate_pad (GstIterator * it, GstPad * pad) |
1210 { |
1114 { |
1211 gst_object_ref (pad); |
1115 gst_object_ref (pad); |
1887 gchar *sent_debug; |
1791 gchar *sent_debug; |
1888 gboolean has_debug = TRUE; |
1792 gboolean has_debug = TRUE; |
1889 GstMessage *message = NULL; |
1793 GstMessage *message = NULL; |
1890 |
1794 |
1891 /* checks */ |
1795 /* checks */ |
1892 GST_CAT_DEBUG_OBJECT (GST_CAT_MESSAGE, element, "start"); |
1796 GST_DEBUG_OBJECT (element, "start"); |
1893 g_return_if_fail (GST_IS_ELEMENT (element)); |
1797 g_return_if_fail (GST_IS_ELEMENT (element)); |
1894 g_return_if_fail ((type == GST_MESSAGE_ERROR) || |
1798 g_return_if_fail ((type == GST_MESSAGE_ERROR) || |
1895 (type == GST_MESSAGE_WARNING) || (type == GST_MESSAGE_INFO)); |
1799 (type == GST_MESSAGE_WARNING) || (type == GST_MESSAGE_INFO)); |
1896 |
1800 |
1897 /* check if we send the given text or the default error text */ |
1801 /* check if we send the given text or the default error text */ |
2149 g_time_val_add (&abstimeout, add); |
2052 g_time_val_add (&abstimeout, add); |
2150 timeval = &abstimeout; |
2053 timeval = &abstimeout; |
2151 } else { |
2054 } else { |
2152 timeval = NULL; |
2055 timeval = NULL; |
2153 } |
2056 } |
2154 /* get cookie to detect state changes during waiting */ |
2057 /* get cookie to dected state change during waiting */ |
2155 cookie = element->state_cookie; |
2058 cookie = element->state_cookie; |
2156 |
2059 |
2157 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, |
2060 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, |
2158 "waiting for element to commit state"); |
2061 "waiting for element to commit state"); |
2159 |
2062 |
2387 /* mark busy */ |
2290 /* mark busy */ |
2388 GST_STATE_RETURN (element) = GST_STATE_CHANGE_ASYNC; |
2291 GST_STATE_RETURN (element) = GST_STATE_CHANGE_ASYNC; |
2389 GST_OBJECT_UNLOCK (element); |
2292 GST_OBJECT_UNLOCK (element); |
2390 |
2293 |
2391 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, |
2294 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, |
2392 "committing state from %s to %s, pending %s, next %s", |
2295 "committing state from %s to %s, pending %s", |
2393 gst_element_state_get_name (old_state), |
2296 gst_element_state_get_name (old_state), |
2394 gst_element_state_get_name (old_next), |
2297 gst_element_state_get_name (old_next), |
2395 gst_element_state_get_name (pending), gst_element_state_get_name (next)); |
2298 gst_element_state_get_name (pending)); |
2396 |
2299 |
2397 message = gst_message_new_state_changed (GST_OBJECT_CAST (element), |
2300 message = gst_message_new_state_changed (GST_OBJECT_CAST (element), |
2398 old_state, old_next, pending); |
2301 old_state, old_next, pending); |
2399 gst_element_post_message (element, message); |
2302 gst_element_post_message (element, message); |
2400 |
2303 |
2444 return ret; |
2347 return ret; |
2445 } |
2348 } |
2446 } |
2349 } |
2447 |
2350 |
2448 /** |
2351 /** |
2449 * gst_element_lost_state_full: |
2352 * gst_element_lost_state: |
2450 * @element: a #GstElement the state is lost of |
2353 * @element: a #GstElement the state is lost of |
2451 * @new_base_time: if a new base time should be distributed |
|
2452 * |
2354 * |
2453 * Brings the element to the lost state. The current state of the |
2355 * Brings the element to the lost state. The current state of the |
2454 * element is copied to the pending state so that any call to |
2356 * element is copied to the pending state so that any call to |
2455 * gst_element_get_state() will return %GST_STATE_CHANGE_ASYNC. |
2357 * gst_element_get_state() will return %GST_STATE_CHANGE_ASYNC. |
2456 * |
2358 * |
2457 * An ASYNC_START message is posted with indication to distribute a new |
2359 * An ASYNC_START message is posted with an indication to distribute a new |
2458 * base_time to the element when @new_base_time is %TRUE. |
2360 * base_time to the element. |
2459 * If the element was PLAYING, it will go to PAUSED. The element |
2361 * If the element was PLAYING, it will go to PAUSED. The element |
2460 * will be restored to its PLAYING state by the parent pipeline when it |
2362 * will be restored to its PLAYING state by the parent pipeline when it |
2461 * prerolls again. |
2363 * prerolls again. |
2462 * |
2364 * |
2463 * This is mostly used for elements that lost their preroll buffer |
2365 * This is mostly used for elements that lost their preroll buffer |
2468 * |
2370 * |
2469 * This function is used internally and should normally not be called from |
2371 * This function is used internally and should normally not be called from |
2470 * plugins or applications. |
2372 * plugins or applications. |
2471 * |
2373 * |
2472 * MT safe. |
2374 * MT safe. |
2473 * |
|
2474 * Since: 0.10.24 |
|
2475 */ |
2375 */ |
2476 #ifdef __SYMBIAN32__ |
2376 #ifdef __SYMBIAN32__ |
2477 EXPORT_C |
2377 EXPORT_C |
2478 #endif |
2378 #endif |
2479 |
2379 |
2480 void |
2380 void |
2481 gst_element_lost_state_full (GstElement * element, gboolean new_base_time) |
2381 gst_element_lost_state (GstElement * element) |
2482 { |
2382 { |
2483 GstState old_state, new_state; |
2383 GstState old_state, new_state; |
2484 GstMessage *message; |
2384 GstMessage *message; |
2485 |
2385 |
2486 g_return_if_fail (GST_IS_ELEMENT (element)); |
2386 g_return_if_fail (GST_IS_ELEMENT (element)); |
2487 |
2387 |
2488 GST_OBJECT_LOCK (element); |
2388 GST_OBJECT_LOCK (element); |
2489 if (GST_STATE_RETURN (element) == GST_STATE_CHANGE_FAILURE) |
2389 if (GST_STATE_PENDING (element) != GST_STATE_VOID_PENDING || |
|
2390 GST_STATE_RETURN (element) == GST_STATE_CHANGE_FAILURE) |
2490 goto nothing_lost; |
2391 goto nothing_lost; |
2491 |
|
2492 if (GST_STATE_PENDING (element) != GST_STATE_VOID_PENDING) |
|
2493 goto only_async_start; |
|
2494 |
2392 |
2495 old_state = GST_STATE (element); |
2393 old_state = GST_STATE (element); |
2496 |
2394 |
2497 /* when we were PLAYING, the new state is PAUSED. We will also not |
2395 /* when we were PLAYING, the new state is PAUSED. We will also not |
2498 * automatically go to PLAYING but let the parent bin(s) set us to PLAYING |
2396 * automatically go to PLAYING but let the parent bin(s) set us to PLAYING |
2508 |
2406 |
2509 GST_STATE (element) = new_state; |
2407 GST_STATE (element) = new_state; |
2510 GST_STATE_NEXT (element) = new_state; |
2408 GST_STATE_NEXT (element) = new_state; |
2511 GST_STATE_PENDING (element) = new_state; |
2409 GST_STATE_PENDING (element) = new_state; |
2512 GST_STATE_RETURN (element) = GST_STATE_CHANGE_ASYNC; |
2410 GST_STATE_RETURN (element) = GST_STATE_CHANGE_ASYNC; |
2513 if (new_base_time) |
|
2514 GST_ELEMENT_START_TIME (element) = 0; |
|
2515 GST_OBJECT_UNLOCK (element); |
2411 GST_OBJECT_UNLOCK (element); |
2516 |
2412 |
2517 message = gst_message_new_state_changed (GST_OBJECT_CAST (element), |
2413 message = gst_message_new_state_changed (GST_OBJECT_CAST (element), |
2518 new_state, new_state, new_state); |
2414 new_state, new_state, new_state); |
2519 gst_element_post_message (element, message); |
2415 gst_element_post_message (element, message); |
2520 |
2416 |
2521 message = |
2417 message = gst_message_new_async_start (GST_OBJECT_CAST (element), TRUE); |
2522 gst_message_new_async_start (GST_OBJECT_CAST (element), new_base_time); |
|
2523 gst_element_post_message (element, message); |
2418 gst_element_post_message (element, message); |
2524 |
2419 |
2525 return; |
2420 return; |
2526 |
2421 |
2527 nothing_lost: |
2422 nothing_lost: |
2528 { |
2423 { |
2529 GST_OBJECT_UNLOCK (element); |
2424 GST_OBJECT_UNLOCK (element); |
2530 return; |
2425 return; |
2531 } |
2426 } |
2532 only_async_start: |
|
2533 { |
|
2534 GST_OBJECT_UNLOCK (element); |
|
2535 |
|
2536 message = gst_message_new_async_start (GST_OBJECT_CAST (element), TRUE); |
|
2537 gst_element_post_message (element, message); |
|
2538 return; |
|
2539 } |
|
2540 } |
|
2541 |
|
2542 /** |
|
2543 * gst_element_lost_state: |
|
2544 * @element: a #GstElement the state is lost of |
|
2545 * |
|
2546 * Brings the element to the lost state. This function calls |
|
2547 * gst_element_lost_state_full() with the new_base_time set to %TRUE. |
|
2548 * |
|
2549 * This function is used internally and should normally not be called from |
|
2550 * plugins or applications. |
|
2551 * |
|
2552 * MT safe. |
|
2553 */ |
|
2554 #ifdef __SYMBIAN32__ |
|
2555 EXPORT_C |
|
2556 #endif |
|
2557 |
|
2558 void |
|
2559 gst_element_lost_state (GstElement * element) |
|
2560 { |
|
2561 gst_element_lost_state_full (element, TRUE); |
|
2562 } |
2427 } |
2563 |
2428 |
2564 /** |
2429 /** |
2565 * gst_element_set_state: |
2430 * gst_element_set_state: |
2566 * @element: a #GstElement to change state of. |
2431 * @element: a #GstElement to change state of. |
2573 * This function can return #GST_STATE_CHANGE_ASYNC, in which case the |
2438 * This function can return #GST_STATE_CHANGE_ASYNC, in which case the |
2574 * element will perform the remainder of the state change asynchronously in |
2439 * element will perform the remainder of the state change asynchronously in |
2575 * another thread. |
2440 * another thread. |
2576 * An application can use gst_element_get_state() to wait for the completion |
2441 * An application can use gst_element_get_state() to wait for the completion |
2577 * of the state change or it can wait for a state change message on the bus. |
2442 * of the state change or it can wait for a state change message on the bus. |
2578 * |
|
2579 * State changes to %GST_STATE_READY or %GST_STATE_NULL never return |
|
2580 * #GST_STATE_CHANGE_ASYNC. |
|
2581 * |
2443 * |
2582 * Returns: Result of the state change using #GstStateChangeReturn. |
2444 * Returns: Result of the state change using #GstStateChangeReturn. |
2583 * |
2445 * |
2584 * MT safe. |
2446 * MT safe. |
2585 */ |
2447 */ |
2640 old_pending = GST_STATE_PENDING (element); |
2502 old_pending = GST_STATE_PENDING (element); |
2641 |
2503 |
2642 /* this is the (new) state we should go to. TARGET is the last state we set on |
2504 /* this is the (new) state we should go to. TARGET is the last state we set on |
2643 * the element. */ |
2505 * the element. */ |
2644 if (state != GST_STATE_TARGET (element)) { |
2506 if (state != GST_STATE_TARGET (element)) { |
2645 GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element, |
|
2646 "setting target state to %s", gst_element_state_get_name (state)); |
|
2647 GST_STATE_TARGET (element) = state; |
2507 GST_STATE_TARGET (element) = state; |
2648 /* increment state cookie so that we can track each state change. We only do |
2508 /* increment state cookie so that we can track each state change. We only do |
2649 * this if this is actually a new state change. */ |
2509 * this if this is actually a new state change. */ |
2650 element->state_cookie++; |
2510 element->state_cookie++; |
2651 } |
2511 } |
2738 GstStateChangeReturn |
2598 GstStateChangeReturn |
2739 gst_element_change_state (GstElement * element, GstStateChange transition) |
2599 gst_element_change_state (GstElement * element, GstStateChange transition) |
2740 { |
2600 { |
2741 GstElementClass *oclass; |
2601 GstElementClass *oclass; |
2742 GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS; |
2602 GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS; |
|
2603 GstState current; |
|
2604 GstState next; |
2743 |
2605 |
2744 oclass = GST_ELEMENT_GET_CLASS (element); |
2606 oclass = GST_ELEMENT_GET_CLASS (element); |
|
2607 |
|
2608 /* start with the current state. */ |
|
2609 current = (GstState) GST_STATE_TRANSITION_CURRENT (transition); |
|
2610 next = GST_STATE_TRANSITION_NEXT (transition); |
2745 |
2611 |
2746 /* call the state change function so it can set the state */ |
2612 /* call the state change function so it can set the state */ |
2747 if (oclass->change_state) |
2613 if (oclass->change_state) |
2748 ret = (oclass->change_state) (element, transition); |
2614 ret = (oclass->change_state) (element, transition); |
2749 else |
2615 else |
2929 return TRUE; |
2795 return TRUE; |
2930 |
2796 |
2931 /* ERRORS */ |
2797 /* ERRORS */ |
2932 src_failed: |
2798 src_failed: |
2933 { |
2799 { |
2934 GST_CAT_DEBUG_OBJECT (GST_CAT_ELEMENT_PADS, element, |
2800 GST_DEBUG_OBJECT (element, "source pads_activate failed"); |
2935 "source pads_activate failed"); |
|
2936 return FALSE; |
2801 return FALSE; |
2937 } |
2802 } |
2938 sink_failed: |
2803 sink_failed: |
2939 { |
2804 { |
2940 GST_CAT_DEBUG_OBJECT (GST_CAT_ELEMENT_PADS, element, |
2805 GST_DEBUG_OBJECT (element, "sink pads_activate failed"); |
2941 "sink pads_activate failed"); |
|
2942 return FALSE; |
2806 return FALSE; |
2943 } |
2807 } |
2944 caps_failed: |
2808 caps_failed: |
2945 { |
2809 { |
2946 GST_CAT_DEBUG_OBJECT (GST_CAT_ELEMENT_PADS, element, |
2810 GST_DEBUG_OBJECT (element, "failed to clear caps on pads"); |
2947 "failed to clear caps on pads"); |
|
2948 return FALSE; |
2811 return FALSE; |
2949 } |
2812 } |
2950 } |
2813 } |
2951 |
2814 |
2952 /* is called with STATE_LOCK */ |
2815 /* is called with STATE_LOCK */ |
2953 static GstStateChangeReturn |
2816 static GstStateChangeReturn |
2954 gst_element_change_state_func (GstElement * element, GstStateChange transition) |
2817 gst_element_change_state_func (GstElement * element, GstStateChange transition) |
2955 { |
2818 { |
2956 GstState state, next; |
2819 GstState state, next; |
2957 GstStateChangeReturn result = GST_STATE_CHANGE_SUCCESS; |
2820 GstStateChangeReturn result = GST_STATE_CHANGE_SUCCESS; |
2958 GstClock **clock_p; |
|
2959 |
2821 |
2960 g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_CHANGE_FAILURE); |
2822 g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_CHANGE_FAILURE); |
2961 |
2823 |
2962 state = (GstState) GST_STATE_TRANSITION_CURRENT (transition); |
2824 state = (GstState) GST_STATE_TRANSITION_CURRENT (transition); |
2963 next = GST_STATE_TRANSITION_NEXT (transition); |
2825 next = GST_STATE_TRANSITION_NEXT (transition); |
2990 if (!gst_element_pads_activate (element, FALSE)) { |
2852 if (!gst_element_pads_activate (element, FALSE)) { |
2991 result = GST_STATE_CHANGE_FAILURE; |
2853 result = GST_STATE_CHANGE_FAILURE; |
2992 } else { |
2854 } else { |
2993 gst_element_set_base_time (element, 0); |
2855 gst_element_set_base_time (element, 0); |
2994 } |
2856 } |
2995 |
|
2996 /* In null state release the reference to the clock */ |
|
2997 GST_OBJECT_LOCK (element); |
|
2998 clock_p = &element->clock; |
|
2999 gst_object_replace ((GstObject **) clock_p, NULL); |
|
3000 GST_OBJECT_UNLOCK (element); |
|
3001 break; |
2857 break; |
3002 default: |
2858 default: |
3003 /* this will catch real but unhandled state changes; |
2859 /* this will catch real but unhandled state changes; |
3004 * can only be caused by: |
2860 * can only be caused by: |
3005 * - a new state was added |
2861 * - a new state was added |
3173 else if (G_IS_PARAM_SPEC_ENUM (spec)) |
3029 else if (G_IS_PARAM_SPEC_ENUM (spec)) |
3174 contents = g_strdup_printf ("%d", g_value_get_enum (&value)); |
3030 contents = g_strdup_printf ("%d", g_value_get_enum (&value)); |
3175 else if (G_IS_PARAM_SPEC_INT64 (spec)) |
3031 else if (G_IS_PARAM_SPEC_INT64 (spec)) |
3176 contents = g_strdup_printf ("%" G_GINT64_FORMAT, |
3032 contents = g_strdup_printf ("%" G_GINT64_FORMAT, |
3177 g_value_get_int64 (&value)); |
3033 g_value_get_int64 (&value)); |
3178 else if (GST_VALUE_HOLDS_STRUCTURE (&value)) { |
3034 else |
3179 if (g_value_get_boxed (&value) != NULL) { |
|
3180 contents = g_strdup_value_contents (&value); |
|
3181 } else { |
|
3182 contents = g_strdup ("NULL"); |
|
3183 } |
|
3184 } else |
|
3185 contents = g_strdup_value_contents (&value); |
3035 contents = g_strdup_value_contents (&value); |
3186 |
3036 |
3187 xmlNewChild (param, NULL, (xmlChar *) "value", (xmlChar *) contents); |
3037 xmlNewChild (param, NULL, (xmlChar *) "value", (xmlChar *) contents); |
3188 g_free (contents); |
3038 g_free (contents); |
3189 |
3039 |
3191 } |
3041 } |
3192 } |
3042 } |
3193 |
3043 |
3194 g_free (specs); |
3044 g_free (specs); |
3195 |
3045 |
3196 pads = g_list_last (GST_ELEMENT_PADS (element)); |
3046 pads = GST_ELEMENT_PADS (element); |
3197 |
3047 |
3198 while (pads) { |
3048 while (pads) { |
3199 GstPad *pad = GST_PAD_CAST (pads->data); |
3049 GstPad *pad = GST_PAD_CAST (pads->data); |
3200 |
3050 |
3201 /* figure out if it's a direct pad or a ghostpad */ |
3051 /* figure out if it's a direct pad or a ghostpad */ |
3202 if (GST_ELEMENT (GST_OBJECT_PARENT (pad)) == element) { |
3052 if (GST_ELEMENT (GST_OBJECT_PARENT (pad)) == element) { |
3203 xmlNodePtr padtag = xmlNewChild (parent, NULL, (xmlChar *) "pad", NULL); |
3053 xmlNodePtr padtag = xmlNewChild (parent, NULL, (xmlChar *) "pad", NULL); |
3204 |
3054 |
3205 gst_object_save_thyself (GST_OBJECT_CAST (pad), padtag); |
3055 gst_object_save_thyself (GST_OBJECT_CAST (pad), padtag); |
3206 } |
3056 } |
3207 pads = g_list_previous (pads); |
3057 pads = g_list_next (pads); |
3208 } |
3058 } |
3209 |
3059 |
3210 return parent; |
3060 return parent; |
3211 } |
3061 } |
3212 |
3062 |