gstreamer_core/gst/gstelement.c
branchRCL_3
changeset 30 7e817e7e631c
parent 29 567bb019e3e3
equal deleted inserted replaced
29:567bb019e3e3 30:7e817e7e631c
    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>
    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"
       
    93 #include "gst-i18n-lib.h"
    92 #include "gst-i18n-lib.h"
    94 
    93 
    95 #ifdef __SYMBIAN32__
    94 #ifdef __SYMBIAN32__
    96 #include <glib_global.h>
    95 #include <glib_global.h>
    97 #endif
    96 #endif
   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 */
  2026 
  1930 
  2027   return TRUE;
  1931   return TRUE;
  2028 
  1932 
  2029 was_ok:
  1933 was_ok:
  2030   {
  1934   {
  2031     GST_CAT_DEBUG (GST_CAT_STATES, "elements %s was already in locked state %d",
  1935     GST_CAT_DEBUG (GST_CAT_STATES, "elements %s was in locked state %d",
  2032         GST_ELEMENT_NAME (element), old);
  1936         GST_ELEMENT_NAME (element), old);
  2033     GST_OBJECT_UNLOCK (element);
  1937     GST_OBJECT_UNLOCK (element);
  2034 
  1938 
  2035     return FALSE;
  1939     return FALSE;
  2036   }
  1940   }
  2098 failed:
  2002 failed:
  2099   {
  2003   {
  2100     GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
  2004     GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
  2101         "syncing state failed (%s)",
  2005         "syncing state failed (%s)",
  2102         gst_element_state_change_return_get_name (ret));
  2006         gst_element_state_change_return_get_name (ret));
  2103     gst_object_unref (parent);
       
  2104     return FALSE;
  2007     return FALSE;
  2105   }
  2008   }
  2106 }
  2009 }
  2107 
  2010 
  2108 /* MT safe */
  2011 /* MT safe */
  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