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