mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-03-26 19:12:57 +00:00
Megapatch, changes which states are available, how they're used, and how they're set. Also modifies the scheduling s...
Original commit message from CVS: Megapatch, changes which states are available, how they're used, and how they're set. Also modifies the scheduling system, breaking pulled buffers. Check mail archives for more details.
This commit is contained in:
parent
5effd6fe5d
commit
b6d31c1c72
30 changed files with 657 additions and 450 deletions
|
@ -1,4 +1,4 @@
|
|||
SUBDIRS = gst plugins test editor tools docs libs
|
||||
SUBDIRS = gst libs plugins test editor tools docs tests
|
||||
|
||||
bin_SCRIPTS = gstreamer-config
|
||||
|
||||
|
|
|
@ -61,7 +61,7 @@ for dir in `find * -name autogen.sh -print | grep -v '^autogen.sh$' | \
|
|||
popd > /dev/null
|
||||
done
|
||||
|
||||
./configure --enable-maintainer-mode "$@"
|
||||
./configure --enable-maintainer-mode --enable-debug "$@"
|
||||
|
||||
echo
|
||||
echo "Now type 'make' to compile $package."
|
||||
|
|
|
@ -51,7 +51,7 @@ AM_PATH_GLIB(1.2.0,,
|
|||
glib gmodule gthread)
|
||||
dnl Put the glib flags into $LIBS and $CFLAGS since we always use them
|
||||
LIBS="$LIBS $GLIB_LIBS"
|
||||
CFLAGS="$FLAGS $GLIB_CFLAGS"
|
||||
CFLAGS="$CFLAGS $GLIB_CFLAGS"
|
||||
|
||||
dnl Check for libxml
|
||||
AC_PATH_PROG(XML_CONFIG, xml-config, no)
|
||||
|
@ -306,7 +306,7 @@ AM_CONDITIONAL(HAVE_LIBMMX, test "x$USE_LIBMMX" = "xyes")
|
|||
AM_CONDITIONAL(HAVE_ATOMIC_H, test "x$USE_ATOMIC_H" = "xyes")
|
||||
AM_CONDITIONAL(HAVE_XAUDIO, test "x$HAVE_XAUDIO" = "xyes")
|
||||
AM_CONDITIONAL(HAVE_CSSAUTH, test "x$HAVE_CSSAUTH" = "xyes")
|
||||
AM_CONDITIONAL(HAVE_GTK_DOC, $HAVE_GTK_DOC)
|
||||
AM_CONDITIONAL(HAVE_GTK_DOC, test "x$HAVE_GTK_DOC" = "xyes")
|
||||
|
||||
|
||||
dnl FIXME: having to AC_SUBST these is messy. Not sure if CPPFLAGS and LDFLAGS
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
SUBDIRS =
|
||||
if HAVE_GTK_DOC
|
||||
SUBDIRS += gst
|
||||
SUBDIRS += gst manual
|
||||
endif
|
||||
|
||||
DIST_SUBDIRS = gst
|
||||
DIST_SUBDIRS = gst manual
|
||||
|
||||
EXTRA_DIST = random slides
|
||||
|
|
|
@ -136,25 +136,6 @@ struct GstBin {
|
|||
cothread_context *threadcontext;
|
||||
};
|
||||
</STRUCT>
|
||||
<STRUCT>
|
||||
<NAME>GstBinClass</NAME>
|
||||
struct GstBinClass {
|
||||
GstElementClass parent_class;
|
||||
|
||||
void (*object_added) (GstObject *object,GstObject *child);
|
||||
|
||||
/* change the state of elements of the given type */
|
||||
gboolean (*change_state_type) (GstBin *bin,
|
||||
GstElementState state,
|
||||
GtkType type);
|
||||
|
||||
/* create a plan for the execution of the bin */
|
||||
void (*create_plan) (GstBin *bin);
|
||||
|
||||
/* run a full iteration of operation */
|
||||
void (*iterate) (GstBin *bin);
|
||||
};
|
||||
</STRUCT>
|
||||
<FUNCTION>
|
||||
<NAME>gst_bin_get_type</NAME>
|
||||
<RETURNS>GtkType </RETURNS>
|
||||
|
@ -359,64 +340,6 @@ GstBuffer *buffer
|
|||
<RETURNS>void </RETURNS>
|
||||
GstBuffer *buffer,GstMeta *meta
|
||||
</FUNCTION>
|
||||
<TYPEDEF>
|
||||
<NAME>GstClockTime</NAME>
|
||||
typedef guint64 GstClockTime;
|
||||
</TYPEDEF>
|
||||
<TYPEDEF>
|
||||
<NAME>GstClockTimeDiff</NAME>
|
||||
typedef gint64 GstClockTimeDiff;
|
||||
</TYPEDEF>
|
||||
<MACRO>
|
||||
<NAME>GST_CLOCK_DIFF</NAME>
|
||||
#define GST_CLOCK_DIFF(s, e) (GstClockTimeDiff)((s)-(e))
|
||||
</MACRO>
|
||||
<STRUCT>
|
||||
<NAME>GstClock</NAME>
|
||||
</STRUCT>
|
||||
<STRUCT>
|
||||
<NAME>GstClock</NAME>
|
||||
struct GstClock {
|
||||
gchar *name;
|
||||
GstClockTime start_time;
|
||||
GstClockTime current_time;
|
||||
GstClockTimeDiff adjust;
|
||||
gboolean locking;
|
||||
GList *sinkobjects;
|
||||
GMutex *sinkmutex;
|
||||
GMutex *lock;
|
||||
};
|
||||
</STRUCT>
|
||||
<FUNCTION>
|
||||
<NAME>gst_clock_new</NAME>
|
||||
<RETURNS>GstClock *</RETURNS>
|
||||
gchar *name
|
||||
</FUNCTION>
|
||||
<FUNCTION>
|
||||
<NAME>gst_clock_get_system</NAME>
|
||||
<RETURNS>GstClock *</RETURNS>
|
||||
void
|
||||
</FUNCTION>
|
||||
<FUNCTION>
|
||||
<NAME>gst_clock_register</NAME>
|
||||
<RETURNS>void </RETURNS>
|
||||
GstClock *clock, GstObject *obj
|
||||
</FUNCTION>
|
||||
<FUNCTION>
|
||||
<NAME>gst_clock_set</NAME>
|
||||
<RETURNS>void </RETURNS>
|
||||
GstClock *clock, GstClockTime time
|
||||
</FUNCTION>
|
||||
<FUNCTION>
|
||||
<NAME>gst_clock_reset</NAME>
|
||||
<RETURNS>void </RETURNS>
|
||||
GstClock *clock
|
||||
</FUNCTION>
|
||||
<FUNCTION>
|
||||
<NAME>gst_clock_wait</NAME>
|
||||
<RETURNS>void </RETURNS>
|
||||
GstClock *clock, GstClockTime time, GstObject *obj
|
||||
</FUNCTION>
|
||||
<MACRO>
|
||||
<NAME>GST_TYPE_CONNECTION</NAME>
|
||||
#define GST_TYPE_CONNECTION \
|
||||
|
@ -454,15 +377,6 @@ struct GstConnection {
|
|||
GstElement element;
|
||||
};
|
||||
</STRUCT>
|
||||
<STRUCT>
|
||||
<NAME>GstConnectionClass</NAME>
|
||||
struct GstConnectionClass {
|
||||
GstElementClass parent_class;
|
||||
|
||||
/* push function */
|
||||
void (*push) (GstConnection *connection);
|
||||
};
|
||||
</STRUCT>
|
||||
<FUNCTION>
|
||||
<NAME>gst_connection_get_type</NAME>
|
||||
<RETURNS>GtkType </RETURNS>
|
||||
|
@ -504,14 +418,16 @@ typedef enum {
|
|||
<NAME>GST_STATE_SET</NAME>
|
||||
#define GST_STATE_SET(obj,flag) \
|
||||
G_STMT_START{ (GST_STATE (obj) |= (flag)); \
|
||||
gst_info("set '%s' state %d\n",gst_element_get_name(obj),flag); \
|
||||
gst_info("set '%s' state %d(%s)\n",gst_element_get_name(obj),flag, \
|
||||
_gst_print_statename(flag)); \
|
||||
}G_STMT_END
|
||||
</MACRO>
|
||||
<MACRO>
|
||||
<NAME>GST_STATE_UNSET</NAME>
|
||||
#define GST_STATE_UNSET(obj,flag) \
|
||||
G_STMT_START{ (GST_STATE (obj) &= ~(flag)); \
|
||||
gst_info("unset '%s' state %d\n",gst_element_get_name(obj),flag); \
|
||||
gst_info("unset '%s' state %d(%s)\n",gst_element_get_name(obj),flag, \
|
||||
_gst_print_statename(flag)); \
|
||||
}G_STMT_END
|
||||
</MACRO>
|
||||
<MACRO>
|
||||
|
@ -539,6 +455,16 @@ gst_info("unset '%s' state %d\n",gst_element_get_name(obj),flag); \
|
|||
#define GST_IS_ELEMENT_CLASS(obj) \
|
||||
(GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_ELEMENT))
|
||||
</MACRO>
|
||||
<ENUM>
|
||||
<NAME>GstElementFlags</NAME>
|
||||
typedef enum {
|
||||
GST_ELEMENT_MULTI_OUT = (1 << 16),
|
||||
} GstElementFlags;
|
||||
</ENUM>
|
||||
<MACRO>
|
||||
<NAME>GST_ELEMENT_IS_MULTI_OUT</NAME>
|
||||
#define GST_ELEMENT_IS_MULTI_OUT(obj) ((GST_FLAGS(obj) & GST_ELEMENT_MULTI_OUT)
|
||||
</MACRO>
|
||||
<STRUCT>
|
||||
<NAME>GstElement</NAME>
|
||||
</STRUCT>
|
||||
|
@ -575,32 +501,6 @@ struct GstElement {
|
|||
};
|
||||
</STRUCT>
|
||||
<STRUCT>
|
||||
<NAME>GstElementClass</NAME>
|
||||
struct GstElementClass {
|
||||
GstObjectClass parent_class;
|
||||
|
||||
/* the elementfactory that created us */
|
||||
GstElementFactory *elementfactory;
|
||||
|
||||
/* signal callbacks */
|
||||
void (*state_change) (GstElement *element,GstElementState state);
|
||||
void (*new_pad) (GstElement *element,GstPad *pad);
|
||||
void (*new_ghost_pad) (GstElement *element,GstPad *pad);
|
||||
void (*error) (GstElement *element,gchar *error);
|
||||
|
||||
/* events */
|
||||
gboolean (*start) (GstElement *element,GstElementState state);
|
||||
gboolean (*stop) (GstElement *element);
|
||||
|
||||
/* change the element state */
|
||||
gboolean (*change_state) (GstElement *element,GstElementState state);
|
||||
|
||||
/* create or read XML representation of self */
|
||||
xmlNodePtr (*save_thyself)(GstElement *element,xmlNodePtr parent);
|
||||
void (*restore_thyself)(GstElement *element,xmlNodePtr *self);
|
||||
};
|
||||
</STRUCT>
|
||||
<STRUCT>
|
||||
<NAME>GstElementDetails</NAME>
|
||||
struct GstElementDetails {
|
||||
gchar *longname; /* long, english name */
|
||||
|
@ -776,12 +676,6 @@ struct GstFilter {
|
|||
GstElement element;
|
||||
};
|
||||
</STRUCT>
|
||||
<STRUCT>
|
||||
<NAME>GstFilterClass</NAME>
|
||||
struct GstFilterClass {
|
||||
GstElementClass parent_class;
|
||||
};
|
||||
</STRUCT>
|
||||
<FUNCTION>
|
||||
<NAME>gst_filter_get_type</NAME>
|
||||
<RETURNS>GtkType </RETURNS>
|
||||
|
@ -926,17 +820,6 @@ struct GstObject {
|
|||
GstObject *parent;
|
||||
};
|
||||
</STRUCT>
|
||||
<STRUCT>
|
||||
<NAME>GstObjectClass</NAME>
|
||||
struct GstObjectClass {
|
||||
GtkObjectClass parent_class;
|
||||
|
||||
/* signals */
|
||||
void (*parent_set) (GstObject *object,GstObject *parent);
|
||||
|
||||
/* functions go here */
|
||||
};
|
||||
</STRUCT>
|
||||
<MACRO>
|
||||
<NAME>GST_FLAGS</NAME>
|
||||
#define GST_FLAGS(obj) GTK_OBJECT_FLAGS(obj)
|
||||
|
@ -1028,13 +911,11 @@ GstObject *object
|
|||
</MACRO>
|
||||
<MACRO>
|
||||
<NAME>GST_PAD_CONNECTED</NAME>
|
||||
#define GST_PAD_CONNECTED(pad) \
|
||||
((pad)->peer != NULL)
|
||||
#define GST_PAD_CONNECTED(pad) ((pad)->peer != NULL)
|
||||
</MACRO>
|
||||
<MACRO>
|
||||
<NAME>GST_PAD_CAN_PULL</NAME>
|
||||
#define GST_PAD_CAN_PULL(pad) \
|
||||
((pad)->pull != NULL)
|
||||
#define GST_PAD_CAN_PULL(pad) ((pad)->pullfunc != NULL)
|
||||
</MACRO>
|
||||
<STRUCT>
|
||||
<NAME>GstPad</NAME>
|
||||
|
@ -1049,7 +930,7 @@ GstPad *pad,GstBuffer *buf
|
|||
</USER_FUNCTION>
|
||||
<USER_FUNCTION>
|
||||
<NAME>GstPadPullFunction</NAME>
|
||||
<RETURNS>GstBuffer *</RETURNS>
|
||||
<RETURNS>void </RETURNS>
|
||||
GstPad *pad
|
||||
</USER_FUNCTION>
|
||||
<USER_FUNCTION>
|
||||
|
@ -1079,19 +960,14 @@ struct GstPad {
|
|||
|
||||
GstBuffer *bufpen;
|
||||
|
||||
GstPadChainFunction chain;
|
||||
GstPadPullFunction pull;
|
||||
GstPadChainFunction chainfunc;
|
||||
GstPadPullFunction pullfunc;
|
||||
GstPadPushFunction pushfunc;
|
||||
|
||||
GstObject *parent;
|
||||
GList *ghostparents;
|
||||
};
|
||||
</STRUCT>
|
||||
<STRUCT>
|
||||
<NAME>GstPadClass</NAME>
|
||||
struct GstPadClass {
|
||||
GstObjectClass parent_class;
|
||||
};
|
||||
</STRUCT>
|
||||
<FUNCTION>
|
||||
<NAME>gst_pad_get_type</NAME>
|
||||
<RETURNS>GtkType </RETURNS>
|
||||
|
@ -1233,12 +1109,6 @@ struct GstPipeline {
|
|||
GstBin bin;
|
||||
};
|
||||
</STRUCT>
|
||||
<STRUCT>
|
||||
<NAME>GstPipelineClass</NAME>
|
||||
struct GstPipelineClass {
|
||||
GstBinClass parent_class;
|
||||
};
|
||||
</STRUCT>
|
||||
<FUNCTION>
|
||||
<NAME>gst_pipeline_get_type</NAME>
|
||||
<RETURNS>GtkType </RETURNS>
|
||||
|
@ -1368,12 +1238,6 @@ struct GstSink {
|
|||
GstElement element;
|
||||
};
|
||||
</STRUCT>
|
||||
<STRUCT>
|
||||
<NAME>GstSinkClass</NAME>
|
||||
struct GstSinkClass {
|
||||
GstElementClass parent_class;
|
||||
};
|
||||
</STRUCT>
|
||||
<FUNCTION>
|
||||
<NAME>gst_sink_get_type</NAME>
|
||||
<RETURNS>GtkType </RETURNS>
|
||||
|
@ -1438,19 +1302,6 @@ struct GstSrc {
|
|||
gint32 flags;
|
||||
};
|
||||
</STRUCT>
|
||||
<STRUCT>
|
||||
<NAME>GstSrcClass</NAME>
|
||||
struct GstSrcClass {
|
||||
GstElementClass parent_class;
|
||||
|
||||
/* subclass functions */
|
||||
void (*push) (GstSrc *src);
|
||||
void (*push_region) (GstSrc *src,gulong offset,gulong size);
|
||||
|
||||
/* signals */
|
||||
void (*eos) (GstSrc *src);
|
||||
};
|
||||
</STRUCT>
|
||||
<MACRO>
|
||||
<NAME>GST_SRC_SET_FLAGS</NAME>
|
||||
#define GST_SRC_SET_FLAGS(src,flag) \
|
||||
|
@ -1523,12 +1374,6 @@ struct GstTee {
|
|||
GSList *srcpads;
|
||||
};
|
||||
</STRUCT>
|
||||
<STRUCT>
|
||||
<NAME>GstTeeClass</NAME>
|
||||
struct GstTeeClass {
|
||||
GstFilterClass parent_class;
|
||||
};
|
||||
</STRUCT>
|
||||
<FUNCTION>
|
||||
<NAME>gst_tee_get_type</NAME>
|
||||
<RETURNS>GtkType </RETURNS>
|
||||
|
@ -1593,20 +1438,11 @@ typedef enum {
|
|||
struct GstThread {
|
||||
GstBin bin;
|
||||
|
||||
GList *entries; /* used to determine iterate behavior */
|
||||
gint numentries; /* number of above entry points */
|
||||
|
||||
pthread_t thread_id; /* id of the thread, if any */
|
||||
GMutex *lock; /* thread lock/condititon pair... */
|
||||
GCond *cond; /* used to control the thread */
|
||||
};
|
||||
</STRUCT>
|
||||
<STRUCT>
|
||||
<NAME>GstThreadClass</NAME>
|
||||
struct GstThreadClass {
|
||||
GstBinClass parent_class;
|
||||
};
|
||||
</STRUCT>
|
||||
<FUNCTION>
|
||||
<NAME>gst_thread_get_type</NAME>
|
||||
<RETURNS>GtkType </RETURNS>
|
||||
|
@ -1825,6 +1661,64 @@ GtkObject *object,guchar *argname
|
|||
<RETURNS>xmlDocPtr </RETURNS>
|
||||
GstElement *element
|
||||
</FUNCTION>
|
||||
<TYPEDEF>
|
||||
<NAME>GstClockTime</NAME>
|
||||
typedef guint64 GstClockTime;
|
||||
</TYPEDEF>
|
||||
<TYPEDEF>
|
||||
<NAME>GstClockTimeDiff</NAME>
|
||||
typedef gint64 GstClockTimeDiff;
|
||||
</TYPEDEF>
|
||||
<MACRO>
|
||||
<NAME>GST_CLOCK_DIFF</NAME>
|
||||
#define GST_CLOCK_DIFF(s, e) (GstClockTimeDiff)((s)-(e))
|
||||
</MACRO>
|
||||
<STRUCT>
|
||||
<NAME>GstClock</NAME>
|
||||
</STRUCT>
|
||||
<STRUCT>
|
||||
<NAME>GstClock</NAME>
|
||||
struct GstClock {
|
||||
gchar *name;
|
||||
GstClockTime start_time;
|
||||
GstClockTime current_time;
|
||||
GstClockTimeDiff adjust;
|
||||
gboolean locking;
|
||||
GList *sinkobjects;
|
||||
GMutex *sinkmutex;
|
||||
GMutex *lock;
|
||||
};
|
||||
</STRUCT>
|
||||
<FUNCTION>
|
||||
<NAME>gst_clock_new</NAME>
|
||||
<RETURNS>GstClock *</RETURNS>
|
||||
gchar *name
|
||||
</FUNCTION>
|
||||
<FUNCTION>
|
||||
<NAME>gst_clock_get_system</NAME>
|
||||
<RETURNS>GstClock *</RETURNS>
|
||||
void
|
||||
</FUNCTION>
|
||||
<FUNCTION>
|
||||
<NAME>gst_clock_register</NAME>
|
||||
<RETURNS>void </RETURNS>
|
||||
GstClock *clock, GstObject *obj
|
||||
</FUNCTION>
|
||||
<FUNCTION>
|
||||
<NAME>gst_clock_set</NAME>
|
||||
<RETURNS>void </RETURNS>
|
||||
GstClock *clock, GstClockTime time
|
||||
</FUNCTION>
|
||||
<FUNCTION>
|
||||
<NAME>gst_clock_reset</NAME>
|
||||
<RETURNS>void </RETURNS>
|
||||
GstClock *clock
|
||||
</FUNCTION>
|
||||
<FUNCTION>
|
||||
<NAME>gst_clock_wait</NAME>
|
||||
<RETURNS>void </RETURNS>
|
||||
GstClock *clock, GstClockTime time, GstObject *obj
|
||||
</FUNCTION>
|
||||
<MACRO>
|
||||
<NAME>GST_TYPE_ASYNCDISKSRC</NAME>
|
||||
#define GST_TYPE_ASYNCDISKSRC \
|
||||
|
@ -1885,12 +1779,6 @@ struct GstAsyncDiskSrc {
|
|||
gulong seq; /* buffer sequence number */
|
||||
};
|
||||
</STRUCT>
|
||||
<STRUCT>
|
||||
<NAME>GstAsyncDiskSrcClass</NAME>
|
||||
struct GstAsyncDiskSrcClass {
|
||||
GstSrcClass parent_class;
|
||||
};
|
||||
</STRUCT>
|
||||
<FUNCTION>
|
||||
<NAME>gst_asyncdisksrc_get_type</NAME>
|
||||
<RETURNS>GtkType </RETURNS>
|
||||
|
@ -1944,15 +1832,6 @@ struct GstAudioSink {
|
|||
gint frequency;
|
||||
};
|
||||
</STRUCT>
|
||||
<STRUCT>
|
||||
<NAME>GstAudioSinkClass</NAME>
|
||||
struct GstAudioSinkClass {
|
||||
GstSinkClass parent_class;
|
||||
|
||||
/* signals */
|
||||
void (*handoff) (GstElement *element,GstPad *pad);
|
||||
};
|
||||
</STRUCT>
|
||||
<FUNCTION>
|
||||
<NAME>gst_audiosink_get_type</NAME>
|
||||
<RETURNS>GtkType </RETURNS>
|
||||
|
@ -2014,12 +1893,6 @@ struct GstAudioSrc {
|
|||
MetaAudioRaw *meta;
|
||||
};
|
||||
</STRUCT>
|
||||
<STRUCT>
|
||||
<NAME>GstAudioSrcClass</NAME>
|
||||
struct GstAudioSrcClass {
|
||||
GstSrcClass parent_class;
|
||||
};
|
||||
</STRUCT>
|
||||
<FUNCTION>
|
||||
<NAME>gst_audiosrc_get_type</NAME>
|
||||
<RETURNS>GtkType </RETURNS>
|
||||
|
@ -2080,12 +1953,6 @@ struct GstDiskSrc {
|
|||
gulong seq; /* buffer sequence number */
|
||||
};
|
||||
</STRUCT>
|
||||
<STRUCT>
|
||||
<NAME>GstDiskSrcClass</NAME>
|
||||
struct GstDiskSrcClass {
|
||||
GstSrcClass parent_class;
|
||||
};
|
||||
</STRUCT>
|
||||
<FUNCTION>
|
||||
<NAME>gst_disksrc_get_type</NAME>
|
||||
<RETURNS>GtkType </RETURNS>
|
||||
|
@ -2137,15 +2004,6 @@ struct GstEsdSink {
|
|||
gint frequency;
|
||||
};
|
||||
</STRUCT>
|
||||
<STRUCT>
|
||||
<NAME>GstEsdSinkClass</NAME>
|
||||
struct GstEsdSinkClass {
|
||||
GstFilterClass parent_class;
|
||||
|
||||
/* signals */
|
||||
void (*handoff) (GstElement *element,GstPad *pad);
|
||||
};
|
||||
</STRUCT>
|
||||
<FUNCTION>
|
||||
<NAME>gst_esdsink_get_type</NAME>
|
||||
<RETURNS>GtkType </RETURNS>
|
||||
|
@ -2190,12 +2048,6 @@ struct GstFakeSink {
|
|||
GstPad *sinkpad;
|
||||
};
|
||||
</STRUCT>
|
||||
<STRUCT>
|
||||
<NAME>GstFakeSinkClass</NAME>
|
||||
struct GstFakeSinkClass {
|
||||
GstSinkClass parent_class;
|
||||
};
|
||||
</STRUCT>
|
||||
<FUNCTION>
|
||||
<NAME>gst_fakesink_get_type</NAME>
|
||||
<RETURNS>GtkType </RETURNS>
|
||||
|
@ -2240,12 +2092,6 @@ struct GstFakeSrc {
|
|||
GstPad *srcpad;
|
||||
};
|
||||
</STRUCT>
|
||||
<STRUCT>
|
||||
<NAME>GstFakeSrcClass</NAME>
|
||||
struct GstFakeSrcClass {
|
||||
GstSrcClass parent_class;
|
||||
};
|
||||
</STRUCT>
|
||||
<FUNCTION>
|
||||
<NAME>gst_fakesrc_get_type</NAME>
|
||||
<RETURNS>GtkType </RETURNS>
|
||||
|
@ -2292,12 +2138,6 @@ struct GstFdSink {
|
|||
int fd;
|
||||
};
|
||||
</STRUCT>
|
||||
<STRUCT>
|
||||
<NAME>GstFdSinkClass</NAME>
|
||||
struct GstFdSinkClass {
|
||||
GstSinkClass parent_class;
|
||||
};
|
||||
</STRUCT>
|
||||
<FUNCTION>
|
||||
<NAME>gst_fdsink_get_type</NAME>
|
||||
<RETURNS>GtkType </RETURNS>
|
||||
|
@ -2350,12 +2190,6 @@ struct GstFdSrc {
|
|||
gulong seq; /* buffer sequence number */
|
||||
};
|
||||
</STRUCT>
|
||||
<STRUCT>
|
||||
<NAME>GstFdSrcClass</NAME>
|
||||
struct GstFdSrcClass {
|
||||
GstSrcClass parent_class;
|
||||
};
|
||||
</STRUCT>
|
||||
<FUNCTION>
|
||||
<NAME>gst_fdsrc_get_type</NAME>
|
||||
<RETURNS>GtkType </RETURNS>
|
||||
|
@ -2407,12 +2241,6 @@ struct GstHttpSrc {
|
|||
gulong bytes_per_read; /* bytes per read */
|
||||
};
|
||||
</STRUCT>
|
||||
<STRUCT>
|
||||
<NAME>GstHttpSrcClass</NAME>
|
||||
struct GstHttpSrcClass {
|
||||
GstSrcClass parent_class;
|
||||
};
|
||||
</STRUCT>
|
||||
<FUNCTION>
|
||||
<NAME>gst_httpsrc_get_type</NAME>
|
||||
<RETURNS>GtkType </RETURNS>
|
||||
|
@ -2460,12 +2288,6 @@ struct GstIdentity {
|
|||
gint control;
|
||||
};
|
||||
</STRUCT>
|
||||
<STRUCT>
|
||||
<NAME>GstIdentityClass</NAME>
|
||||
struct GstIdentityClass {
|
||||
GstFilterClass parent_class;
|
||||
};
|
||||
</STRUCT>
|
||||
<FUNCTION>
|
||||
<NAME>gst_identity_get_type</NAME>
|
||||
<RETURNS>GtkType </RETURNS>
|
||||
|
@ -2526,12 +2348,6 @@ struct GstQueue {
|
|||
GCond *fullcond;
|
||||
};
|
||||
</STRUCT>
|
||||
<STRUCT>
|
||||
<NAME>GstQueueClass</NAME>
|
||||
struct GstQueueClass {
|
||||
GstConnectionClass parent_class;
|
||||
};
|
||||
</STRUCT>
|
||||
<FUNCTION>
|
||||
<NAME>gst_queue_get_type</NAME>
|
||||
<RETURNS>GtkType </RETURNS>
|
||||
|
@ -2585,18 +2401,15 @@ struct GstSineSrc {
|
|||
gint channels;
|
||||
gint frequency;
|
||||
|
||||
/* state */
|
||||
double mTheta;
|
||||
|
||||
gulong seq;
|
||||
|
||||
MetaAudioRaw meta;
|
||||
gboolean sentmeta;
|
||||
};
|
||||
</STRUCT>
|
||||
<STRUCT>
|
||||
<NAME>GstSineSrcClass</NAME>
|
||||
struct GstSineSrcClass {
|
||||
GstSrcClass parent_class;
|
||||
};
|
||||
</STRUCT>
|
||||
<FUNCTION>
|
||||
<NAME>gst_sinesrc_get_type</NAME>
|
||||
<RETURNS>GtkType </RETURNS>
|
||||
|
|
|
@ -58,6 +58,9 @@ libgstinclude_HEADERS = \
|
|||
cothreads.h
|
||||
|
||||
CFLAGS += -O2 -Wall
|
||||
#if USE_DEBUG
|
||||
CFLAGS += -g
|
||||
#endif
|
||||
|
||||
libgst_la_LIBADD = $(GLIB_LIBS) $(GTK_LIBS) $(XML_LIBS)
|
||||
libgst_la_LDFLAGS = -version-info $(STREAMER_CURRENT):$(STREAMER_REVISION):$(STREAMER_AGE)
|
||||
|
|
|
@ -45,13 +45,13 @@ struct _elements_entry {
|
|||
};
|
||||
|
||||
struct _elements_entry _elements[] = {
|
||||
{ "fakesrc", gst_fakesrc_get_type, &gst_fakesrc_details },
|
||||
{ "fakesink", gst_fakesink_get_type, &gst_fakesink_details },
|
||||
{ "asyncdisksrc", gst_asyncdisksrc_get_type, &gst_asyncdisksrc_details },
|
||||
{ "audiosink", gst_audiosink_get_type, &gst_audiosink_details },
|
||||
{ "audiosrc", gst_audiosrc_get_type, &gst_audiosrc_details },
|
||||
{ "disksrc", gst_disksrc_get_type, &gst_disksrc_details },
|
||||
{ "identity", gst_identity_get_type, &gst_identity_details },
|
||||
{ "fakesink", gst_fakesink_get_type, &gst_fakesink_details },
|
||||
{ "fakesrc", gst_fakesrc_get_type, &gst_fakesrc_details },
|
||||
{ "fdsink", gst_fdsink_get_type, &gst_fdsink_details },
|
||||
{ "fdsrc", gst_fdsrc_get_type, &gst_fdsrc_details },
|
||||
#if HAVE_LIBGHTTP
|
||||
|
|
|
@ -86,8 +86,8 @@ static void gst_fakesink_init(GstFakeSink *fakesink) {
|
|||
gst_element_add_pad(GST_ELEMENT(fakesink),fakesink->sinkpad);
|
||||
gst_pad_set_chain_function(fakesink->sinkpad,gst_fakesink_chain);
|
||||
|
||||
// we're already complete, since we don't have any args...
|
||||
gst_element_set_state(GST_ELEMENT(fakesink),GST_STATE_COMPLETE);
|
||||
// we're ready right away, since we don't have any args...
|
||||
// gst_element_set_state(GST_ELEMENT(fakesink),GST_STATE_READY);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -120,8 +120,8 @@ void gst_fakesink_chain(GstPad *pad,GstBuffer *buf) {
|
|||
g_return_if_fail(buf != NULL);
|
||||
|
||||
fakesink = GST_FAKESINK(pad->parent);
|
||||
// g_print("gst_fakesink_chain: got buffer of %d bytes in '%s'\n",
|
||||
// buf->datasize,gst_element_get_name(GST_ELEMENT(fakesink)));
|
||||
// g_print("gst_fakesink_chain: got buffer in '%s'\n",
|
||||
// gst_element_get_name(GST_ELEMENT(fakesink)));
|
||||
g_print("<");
|
||||
gst_buffer_unref(buf);
|
||||
}
|
||||
|
|
|
@ -87,8 +87,8 @@ static void gst_fakesrc_init(GstFakeSrc *fakesrc) {
|
|||
fakesrc->srcpad = gst_pad_new("src",GST_PAD_SRC);
|
||||
gst_element_add_pad(GST_ELEMENT(fakesrc),fakesrc->srcpad);
|
||||
|
||||
// we're already complete, since we don't have any args...
|
||||
gst_element_set_state(GST_ELEMENT(fakesrc),GST_STATE_COMPLETE);
|
||||
// we're ready right away, since we don't have any args...
|
||||
// gst_element_set_state(GST_ELEMENT(fakesrc),GST_STATE_READY);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
280
gst/gstbin.c
280
gst/gstbin.c
|
@ -31,13 +31,11 @@ GstElementDetails gst_bin_details = {
|
|||
|
||||
void gst_bin_real_destroy(GtkObject *object);
|
||||
|
||||
static gboolean gst_bin_change_state(GstElement *element,
|
||||
GstElementState state);
|
||||
static GstElementStateReturn gst_bin_change_state(GstElement *element);
|
||||
static GstElementStateReturn gst_bin_change_state_norecurse(GstBin *bin);
|
||||
static gboolean gst_bin_change_state_type(GstBin *bin,
|
||||
GstElementState state,
|
||||
GtkType type);
|
||||
static gboolean gst_bin_change_state_norecurse(GstElement *element,
|
||||
GstElementState state);
|
||||
|
||||
static void gst_bin_create_plan_func(GstBin *bin);
|
||||
static void gst_bin_iterate_func(GstBin *bin);
|
||||
|
@ -143,28 +141,38 @@ void gst_bin_add(GstBin *bin,GstElement *element) {
|
|||
g_return_if_fail(element != NULL);
|
||||
g_return_if_fail(GST_IS_ELEMENT(element));
|
||||
|
||||
// must be NULL or PAUSED state in order to modify bin
|
||||
g_return_if_fail((GST_STATE(bin) == GST_STATE_NULL) ||
|
||||
(GST_STATE(bin) == GST_STATE_PAUSED));
|
||||
|
||||
bin->children = g_list_append(bin->children,element);
|
||||
bin->numchildren++;
|
||||
gst_object_set_parent(GST_OBJECT(element),GST_OBJECT(bin));
|
||||
|
||||
#ifdef OLDSTATE
|
||||
/* FIXME: this isn't right, the bin should be complete whether or not
|
||||
the children are, I think. */
|
||||
// if (GST_STATE_IS_SET(element,GST_STATE_COMPLETE)) {
|
||||
if (!GST_STATE_IS_SET(bin,GST_STATE_COMPLETE)) {
|
||||
g_print("GstBin: adding complete element - \n");
|
||||
gst_bin_change_state_norecurse(GST_ELEMENT(bin),GST_STATE_COMPLETE);
|
||||
g_print("GstBin: adding complete element - ");
|
||||
gst_bin_change_state_norecurse(GST_ELEMENT(bin));
|
||||
}
|
||||
// } else {
|
||||
// g_print("GstBin: adding element - ");
|
||||
// gst_bin_change_state_norecurse(GST_ELEMENT(bin),~GST_STATE_COMPLETE);
|
||||
// }
|
||||
#else
|
||||
/* we know we have at least one child, we just added one... */
|
||||
// if (GST_STATE(element) < GST_STATE_READY)
|
||||
// gst_bin_change_state_norecurse(bin,GST_STATE_READY);
|
||||
#endif
|
||||
|
||||
gtk_signal_emit(GTK_OBJECT(bin),gst_bin_signals[OBJECT_ADDED],element);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_bin_remove:
|
||||
* @bin: #Gstbin to remove element from
|
||||
* @bin: #GstBin to remove element from
|
||||
* @element: #GstElement to remove
|
||||
*
|
||||
* Remove the element from its associated bin, unparenting as well.
|
||||
|
@ -176,57 +184,74 @@ void gst_bin_remove(GstBin *bin,GstElement *element) {
|
|||
g_return_if_fail(GST_IS_ELEMENT(element));
|
||||
g_return_if_fail(bin->children != NULL);
|
||||
|
||||
// must be NULL or PAUSED state in order to modify bin
|
||||
g_return_if_fail((GST_STATE(bin) == GST_STATE_NULL) ||
|
||||
(GST_STATE(bin) == GST_STATE_PAUSED));
|
||||
|
||||
gst_object_unparent(GST_OBJECT(element));
|
||||
bin->children = g_list_remove(bin->children,element);
|
||||
bin->numchildren--;
|
||||
|
||||
/* if we're down to zero children, force state to NULL */
|
||||
if (bin->numchildren == 0)
|
||||
gst_element_set_state(GST_ELEMENT(bin),GST_STATE_NULL);
|
||||
}
|
||||
|
||||
|
||||
static gboolean gst_bin_change_state(GstElement *element,
|
||||
GstElementState state) {
|
||||
static GstElementStateReturn gst_bin_change_state(GstElement *element) {
|
||||
GstBin *bin;
|
||||
GList *children;
|
||||
GstElement *child;
|
||||
|
||||
// g_print("gst_bin_change_state(\"%s\",%d);\n",
|
||||
// gst_object_get_name(GST_OBJECT(bin)),state);
|
||||
|
||||
g_return_val_if_fail(GST_IS_BIN(element), FALSE);
|
||||
g_return_val_if_fail(GST_IS_BIN(element), GST_STATE_FAILURE);
|
||||
bin = GST_BIN(element);
|
||||
g_return_val_if_fail(bin->numchildren != 0, FALSE);
|
||||
|
||||
g_print("gst_bin_change_state(\"%s\"): currently %d(%s), %d(%s) pending\n",
|
||||
gst_element_get_name(element),GST_STATE(element),
|
||||
_gst_print_statename(GST_STATE(element)),GST_STATE_PENDING(element),
|
||||
_gst_print_statename(GST_STATE_PENDING(element)));
|
||||
|
||||
// g_return_val_if_fail(bin->numchildren != 0, GST_STATE_FAILURE);
|
||||
|
||||
// g_print("-->\n");
|
||||
children = bin->children;
|
||||
while (children) {
|
||||
child = GST_ELEMENT(children->data);
|
||||
//g_print("gst_bin_change_state setting state on \"%s\"\n",
|
||||
// gst_element_get_name(GST_ELEMENT(child)));
|
||||
if (!gst_element_set_state(child,state)) {
|
||||
g_print("GstBin: child %p failed to set state 0x%08x\n",child,state);
|
||||
return FALSE;
|
||||
g_print("gst_bin_change_state: setting state on '%s'\n",
|
||||
gst_element_get_name(child));
|
||||
switch (gst_element_set_state(child,GST_STATE_PENDING(element))) {
|
||||
case GST_STATE_FAILURE:
|
||||
GST_STATE_PENDING(element) = GST_STATE_NONE_PENDING;
|
||||
g_print("child '%s' failed to go to state %d(%s)\n",gst_element_get_name(child),
|
||||
GST_STATE_PENDING(element),_gst_print_statename(GST_STATE_PENDING(element)));
|
||||
return GST_STATE_FAILURE;
|
||||
break;
|
||||
case GST_STATE_ASYNC:
|
||||
g_print("child '%s' is changing state asynchronously\n",gst_element_get_name(child));
|
||||
break;
|
||||
}
|
||||
// g_print("\n");
|
||||
children = g_list_next(children);
|
||||
}
|
||||
// g_print("<-- \"%s\"\n",gst_object_get_name(GST_OBJECT(bin)));
|
||||
|
||||
if (GST_ELEMENT_CLASS(parent_class)->change_state)
|
||||
return GST_ELEMENT_CLASS(parent_class)->change_state(element,state);
|
||||
return TRUE;
|
||||
// if (GST_STATE_PENDING(element),
|
||||
|
||||
return gst_bin_change_state_norecurse(bin);
|
||||
}
|
||||
|
||||
|
||||
static gboolean gst_bin_change_state_norecurse(GstElement *element,
|
||||
GstElementState state) {
|
||||
GstBin *bin;
|
||||
|
||||
g_return_val_if_fail(GST_IS_BIN(element), FALSE);
|
||||
bin = GST_BIN(element);
|
||||
g_return_val_if_fail(bin->numchildren != 0, FALSE);
|
||||
static GstElementStateReturn gst_bin_change_state_norecurse(GstBin *bin) {
|
||||
/*
|
||||
if ((state == GST_STATE_READY) && (GST_STATE(bin) < GST_STATE_READY)) {
|
||||
// gst_bin_create_plan(
|
||||
}
|
||||
*/
|
||||
|
||||
if (GST_ELEMENT_CLASS(parent_class)->change_state)
|
||||
return GST_ELEMENT_CLASS(parent_class)->change_state(element,state);
|
||||
return TRUE;
|
||||
return GST_ELEMENT_CLASS(parent_class)->change_state(bin);
|
||||
else
|
||||
return GST_STATE_FAILURE;
|
||||
}
|
||||
|
||||
static gboolean gst_bin_change_state_type(GstBin *bin,
|
||||
|
@ -371,6 +396,7 @@ void gst_bin_iterate(GstBin *bin) {
|
|||
|
||||
oclass = GST_BIN_CLASS(GTK_OBJECT(bin)->klass);
|
||||
|
||||
g_print("gst_bin_iterate()\n");
|
||||
if (oclass->iterate)
|
||||
(oclass->iterate)(bin);
|
||||
}
|
||||
|
@ -384,6 +410,7 @@ void gst_bin_create_plan(GstBin *bin) {
|
|||
(oclass->create_plan)(bin);
|
||||
}
|
||||
|
||||
#ifdef OLD_STUFF
|
||||
static void gst_bin_create_plan_func(GstBin *bin) {
|
||||
GList *elements;
|
||||
GstElement *element;
|
||||
|
@ -400,7 +427,8 @@ static void gst_bin_create_plan_func(GstBin *bin) {
|
|||
while (elements) {
|
||||
element = GST_ELEMENT(elements->data);
|
||||
|
||||
// have to use cothreads if any elements use loop functions
|
||||
// have to use cothreads if any elements use loop functions, or if any
|
||||
// of them have nontrivial chain functions
|
||||
if (element->loopfunc != NULL) {
|
||||
if (bin->threadcontext == NULL) {
|
||||
g_print("GstBin: initializing cothread context\n");
|
||||
|
@ -414,14 +442,14 @@ static void gst_bin_create_plan_func(GstBin *bin) {
|
|||
}
|
||||
}
|
||||
|
||||
/* we need to find all the entry points into the bin */
|
||||
// we need to find all the entry points into the bin
|
||||
if (GST_IS_SRC(element)) {
|
||||
g_print("GstBin: element '%s' is a source entry point for the bin\n",
|
||||
gst_element_get_name(GST_ELEMENT(element)));
|
||||
bin->entries = g_list_prepend(bin->entries,element);
|
||||
bin->numentries++;
|
||||
} else {
|
||||
/* go through the list of pads to see if there's a Connection */
|
||||
// go through the list of pads to see if there's a Connection
|
||||
pads = gst_element_get_pad_list(element);
|
||||
while (pads) {
|
||||
pad = GST_PAD(pads->data);
|
||||
|
@ -449,31 +477,187 @@ for internal element '%s'\n",
|
|||
}
|
||||
elements = g_list_next(elements);
|
||||
}
|
||||
g_print("GstBin: have %d entries into bin\n",bin->numentries);
|
||||
g_print("have %d entries into bin\n",bin->numentries);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int gst_bin_loopfunc_wrapper(int argc,char *argv[]) {
|
||||
GstElement *element = GST_ELEMENT(argv);
|
||||
GList *pads;
|
||||
GstPad *pad;
|
||||
GstBuffer *buf;
|
||||
|
||||
// g_print("** gst_bin_loopfunc_wrapper(%d,\"%s\")\n",
|
||||
// argc,gst_element_get_name(element));
|
||||
|
||||
if (element->loopfunc != NULL) {
|
||||
// g_print("** gst_bin_loopfunc_wrapper(): element has loop function, calling it\n");
|
||||
while (1) {
|
||||
(element->loopfunc)(element);
|
||||
}
|
||||
} else {
|
||||
// g_print("** gst_bin_loopfunc_wrapper(): element is chain-based, calling in infinite loop\n");
|
||||
if (GST_IS_SRC(element)) {
|
||||
while (1) {
|
||||
// g_print("** gst_bin_loopfunc_wrapper(): calling push function of source\n");
|
||||
gst_src_push(GST_SRC(element));
|
||||
}
|
||||
} else {
|
||||
while (1) {
|
||||
pads = element->pads;
|
||||
while (pads) {
|
||||
pad = GST_PAD(pads->data);
|
||||
if (pad->direction == GST_PAD_SINK) {
|
||||
// g_print("** gst_bin_loopfunc_wrapper(): pulling a buffer\n");
|
||||
buf = gst_pad_pull(pad);
|
||||
// g_print("** gst_bin_loopfunc_wrapper(): calling chain function\n");
|
||||
(pad->chainfunc)(pad,buf);
|
||||
}
|
||||
pads = g_list_next(pads);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void gst_bin_pullfunc_wrapper(GstPad *pad) {
|
||||
// g_print("** in gst_bin_pullfunc_wrapper()============================= %s\n",
|
||||
// gst_element_get_name(GST_ELEMENT(pad->parent)));
|
||||
cothread_switch(GST_ELEMENT(pad->parent)->threadstate);
|
||||
}
|
||||
|
||||
static void gst_bin_pushfunc_wrapper(GstPad *pad) {
|
||||
// g_print("** in gst_bin_pushfunc_wrapper()============================= %s\n",
|
||||
// gst_element_get_name(GST_ELEMENT(pad->parent)));
|
||||
cothread_switch(GST_ELEMENT(pad->parent)->threadstate);
|
||||
}
|
||||
|
||||
static void gst_bin_create_plan_func(GstBin *bin) {
|
||||
GList *elements;
|
||||
GstElement *element;
|
||||
int sink_pads;
|
||||
GList *pads;
|
||||
GstPad *pad, *peer;
|
||||
GstElement *outside;
|
||||
|
||||
g_print("creating plan for bin\n");
|
||||
|
||||
// first loop through all children to see if we need cothreads
|
||||
// we break immediately when we find we need to, why keep searching?
|
||||
elements = bin->children;
|
||||
while (elements) {
|
||||
element = GST_ELEMENT(elements->data);
|
||||
// if it's a loop-based element, use cothreads
|
||||
if (element->loopfunc != NULL) {
|
||||
bin->need_cothreads = TRUE;
|
||||
break;
|
||||
}
|
||||
// if it's a complex element, use cothreads
|
||||
if (GST_ELEMENT_IS_MULTI_IN(element)) {
|
||||
bin->need_cothreads = TRUE;
|
||||
break;
|
||||
}
|
||||
// if it has more than one input pad, use cothreads
|
||||
sink_pads = 0;
|
||||
pads = gst_element_get_pad_list(element);
|
||||
while (pads) {
|
||||
pad = GST_PAD(pads->data);
|
||||
if (pad->direction == GST_PAD_SINK)
|
||||
sink_pads++;
|
||||
pads = g_list_next(pads);
|
||||
}
|
||||
if (sink_pads > 1) {
|
||||
bin->need_cothreads = TRUE;
|
||||
break;
|
||||
}
|
||||
elements = g_list_next(elements);
|
||||
}
|
||||
|
||||
if (bin->need_cothreads) {
|
||||
g_print("BIN: need cothreads\n");
|
||||
|
||||
// first create thread context
|
||||
if (bin->threadcontext == NULL) {
|
||||
bin->threadcontext = cothread_init();
|
||||
g_print("initialized cothread context\n");
|
||||
}
|
||||
|
||||
// walk through all the children
|
||||
elements = bin->children;
|
||||
while (elements) {
|
||||
element = GST_ELEMENT(elements->data);
|
||||
|
||||
// start by creating thread state for the element
|
||||
if (element->threadstate == NULL) {
|
||||
element->threadstate = cothread_create(bin->threadcontext);
|
||||
cothread_setfunc(element->threadstate,gst_bin_loopfunc_wrapper,
|
||||
0,(char **)element);
|
||||
}
|
||||
|
||||
pads = gst_element_get_pad_list(element);
|
||||
while (pads) {
|
||||
pad = GST_PAD(pads->data);
|
||||
g_print("setting push&pull handlers for %s:%s\n",
|
||||
gst_element_get_name(element),gst_pad_get_name(pad));
|
||||
// if (pad->direction == GST_PAD_SRC)
|
||||
pad->pushfunc = gst_bin_pushfunc_wrapper;
|
||||
// else
|
||||
pad->pullfunc = gst_bin_pullfunc_wrapper;
|
||||
pads = g_list_next(pads);
|
||||
}
|
||||
elements = g_list_next(elements);
|
||||
}
|
||||
} else {
|
||||
g_print("BIN: don't need cothreads, looking for entry points\n");
|
||||
// clear previous plan state
|
||||
g_list_free(bin->entries);
|
||||
bin->numentries = 0;
|
||||
// we have to find which elements will drive an iteration
|
||||
elements = bin->children;
|
||||
while (elements) {
|
||||
element = GST_ELEMENT(elements->data);
|
||||
if (GST_IS_SRC(element)) {
|
||||
g_print("adding '%s' as entry point\n",gst_element_get_name(element));
|
||||
bin->entries = g_list_prepend(bin->entries,element);
|
||||
bin->numentries++;
|
||||
}
|
||||
elements = g_list_next(elements);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void gst_bin_iterate_func(GstBin *bin) {
|
||||
GList *entries;
|
||||
GstElement *entry;
|
||||
|
||||
|
||||
g_print("gst_bin_iterate_func()\n");
|
||||
|
||||
g_return_if_fail(bin != NULL);
|
||||
g_return_if_fail(GST_IS_BIN(bin));
|
||||
// g_return_if_fail(GST_FLAG_IS_SET(thread,GST_STATE_RUNNING));
|
||||
g_return_if_fail(GST_STATE(bin) == GST_STATE_PLAYING);
|
||||
g_return_if_fail(bin->numentries > 0);
|
||||
|
||||
entries = bin->entries;
|
||||
|
||||
g_print("GstBin: iterating\n");
|
||||
|
||||
while (entries) {
|
||||
entry = GST_ELEMENT(entries->data);
|
||||
if (GST_IS_SRC(entry))
|
||||
gst_src_push(GST_SRC(entry));
|
||||
else if (GST_IS_CONNECTION(entry))
|
||||
gst_connection_push(GST_CONNECTION(entry));
|
||||
else
|
||||
g_assert_not_reached();
|
||||
entries = g_list_next(entries);
|
||||
if (bin->need_cothreads) {
|
||||
// all we really have to do is switch to the first child
|
||||
// FIXME this should be lots more intelligent about where to start
|
||||
// g_print("** in gst_bin_iterate_func()==================================%s\n",
|
||||
// gst_element_get_name(GST_ELEMENT(bin->children->data)));
|
||||
cothread_switch(GST_ELEMENT(bin->children->data)->threadstate);
|
||||
} else {
|
||||
entries = bin->entries;
|
||||
|
||||
while (entries) {
|
||||
entry = GST_ELEMENT(entries->data);
|
||||
if (GST_IS_SRC(entry))
|
||||
gst_src_push(GST_SRC(entry));
|
||||
else if (GST_IS_CONNECTION(entry))
|
||||
gst_connection_push(GST_CONNECTION(entry));
|
||||
else
|
||||
g_assert_not_reached();
|
||||
entries = g_list_next(entries);
|
||||
}
|
||||
}
|
||||
// g_print(",");
|
||||
}
|
||||
|
|
|
@ -52,9 +52,12 @@ typedef struct _GstBinClass GstBinClass;
|
|||
struct _GstBin {
|
||||
GstElement element;
|
||||
|
||||
// our children
|
||||
gint numchildren;
|
||||
GList *children;
|
||||
|
||||
// iteration state
|
||||
gboolean need_cothreads;
|
||||
GList *entries;
|
||||
gint numentries;
|
||||
|
||||
|
|
|
@ -105,7 +105,6 @@ void gst_clock_wait(GstClock *clock, GstClockTime time, GstObject *obj) {
|
|||
struct timeval tfnow;
|
||||
GstClockTime now;
|
||||
GstClockTimeDiff diff;
|
||||
GList *elements;
|
||||
|
||||
//DEBUG("gst_clock: requesting clock object 0x%p %08llu %08llu\n", obj, time, clock->current_time);
|
||||
|
||||
|
|
|
@ -39,6 +39,9 @@ static void gst_element_class_init(GstElementClass *klass);
|
|||
static void gst_element_init(GstElement *element);
|
||||
static void gst_element_real_destroy(GtkObject *object);
|
||||
|
||||
GstElementStateReturn gst_element_change_state(GstElement *element);
|
||||
|
||||
|
||||
static GstObjectClass *parent_class = NULL;
|
||||
static guint gst_element_signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
|
@ -92,15 +95,14 @@ static void gst_element_class_init(GstElementClass *klass) {
|
|||
|
||||
gtk_object_class_add_signals(gtkobject_class,gst_element_signals,LAST_SIGNAL);
|
||||
|
||||
klass->start = NULL;
|
||||
klass->stop = NULL;
|
||||
klass->change_state = gst_element_change_state;
|
||||
|
||||
gtkobject_class->destroy = gst_element_real_destroy;
|
||||
}
|
||||
|
||||
static void gst_element_init(GstElement *element) {
|
||||
element->state = 0;
|
||||
element->current_state = GST_STATE_NULL;
|
||||
element->pending_state = -1;
|
||||
element->numpads = 0;
|
||||
element->pads = NULL;
|
||||
element->loopfunc = NULL;
|
||||
|
@ -282,37 +284,31 @@ void gst_element_error(GstElement *element,gchar *error) {
|
|||
*
|
||||
* Returns: whether or not the state was successfully set.
|
||||
*/
|
||||
gboolean gst_element_set_state(GstElement *element,GstElementState state) {
|
||||
gint gst_element_set_state(GstElement *element,GstElementState state) {
|
||||
GstElementClass *oclass;
|
||||
gboolean stateset = FALSE;
|
||||
GstElementStateReturn return_val = GST_STATE_SUCCESS;
|
||||
|
||||
// g_print("gst_element_set_state(\"%s\",%08lx)\n",
|
||||
// element->name,state);
|
||||
|
||||
g_return_val_if_fail(element != NULL, FALSE);
|
||||
g_return_val_if_fail(GST_IS_ELEMENT(element), FALSE);
|
||||
g_return_val_if_fail(element != NULL, GST_STATE_FAILURE);
|
||||
g_return_val_if_fail(GST_IS_ELEMENT(element), GST_STATE_FAILURE);
|
||||
|
||||
// first we set the pending state variable
|
||||
// FIXME should probably check to see that we don't already have one
|
||||
GST_STATE_PENDING(element) = state;
|
||||
|
||||
// now we call the state change function so it can set the state
|
||||
oclass = GST_ELEMENT_CLASS(GTK_OBJECT(element)->klass);
|
||||
|
||||
if (oclass->change_state)
|
||||
stateset = (oclass->change_state)(element,state);
|
||||
return_val = (oclass->change_state)(element);
|
||||
|
||||
/* if a state *set* failed, unset it immediately */
|
||||
/*
|
||||
if (!(state & GST_STATE_MAX) && !stateset) {
|
||||
g_print("set state failed miserably, forcing unset\n");
|
||||
if (oclass->change_state)
|
||||
stateset = (oclass->change_state)(element,~state);
|
||||
return FALSE;
|
||||
}*/
|
||||
|
||||
return stateset;
|
||||
return return_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_element_change_state:
|
||||
* @element: element to change state of
|
||||
* @state: new element state
|
||||
*
|
||||
* Changes the state of the element, but more importantly fires off a signal
|
||||
* indicating the new state. You can clear state by simply prefixing the
|
||||
|
@ -321,14 +317,14 @@ gboolean gst_element_set_state(GstElement *element,GstElementState state) {
|
|||
*
|
||||
* Returns: whether or not the state change was successfully set.
|
||||
*/
|
||||
gboolean gst_element_change_state(GstElement *element,
|
||||
GstElementState state) {
|
||||
g_return_val_if_fail(element != NULL, FALSE);
|
||||
g_return_val_if_fail(GST_IS_ELEMENT(element), FALSE);
|
||||
GstElementStateReturn gst_element_change_state(GstElement *element) {
|
||||
g_return_val_if_fail(element != NULL, GST_STATE_FAILURE);
|
||||
g_return_val_if_fail(GST_IS_ELEMENT(element), GST_STATE_FAILURE);
|
||||
|
||||
// g_print("gst_element_change_state(\"%s\",%d)\n",
|
||||
// element->name,state);
|
||||
|
||||
#ifdef OLDSTATE
|
||||
/* deal with the inverted state */
|
||||
//g_print("changing element state, was %08lx\n",GST_STATE(element));
|
||||
if (state & GST_STATE_MAX)
|
||||
|
@ -336,8 +332,12 @@ gboolean gst_element_change_state(GstElement *element,
|
|||
else
|
||||
GST_STATE_SET(element,state);
|
||||
// g_print(", is now %08lx\n",GST_STATE(element));
|
||||
#else
|
||||
GST_STATE(element) = GST_STATE_PENDING(element);
|
||||
GST_STATE_PENDING(element) = GST_STATE_NONE_PENDING;
|
||||
#endif
|
||||
gtk_signal_emit(GTK_OBJECT(element),gst_element_signals[STATE_CHANGE],
|
||||
state);
|
||||
GST_STATE(element));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -541,6 +541,7 @@ GstElement *gst_element_get_manager(GstElement *element) {
|
|||
int gst_element_loopfunc_wrapper(int argc,char **argv) {
|
||||
GstElement *element = GST_ELEMENT(argv);
|
||||
element->loopfunc(element);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -35,6 +35,7 @@ extern "C" {
|
|||
#endif /* __cplusplus */
|
||||
|
||||
|
||||
#ifdef OLDSTATES
|
||||
typedef enum {
|
||||
GST_STATE_COMPLETE = (1 << 0),
|
||||
GST_STATE_RUNNING = (1 << 1),
|
||||
|
@ -47,17 +48,55 @@ typedef enum {
|
|||
GST_STATE_MAX = (1 << 15),
|
||||
} GstElementState;
|
||||
|
||||
typedef enum {
|
||||
GST_STATE_FAILURE = 0,
|
||||
GST_STATE_SUCCESS = 1,
|
||||
GST_STATE_ASYNC = 2,
|
||||
};
|
||||
#else
|
||||
typedef enum {
|
||||
GST_STATE_NONE_PENDING = -1,
|
||||
GST_STATE_NULL = 0,
|
||||
GST_STATE_READY = 1,
|
||||
GST_STATE_PLAYING = 2,
|
||||
GST_STATE_PAUSED = 3,
|
||||
} GstElementState;
|
||||
|
||||
#define GST_STATE(obj) (GST_ELEMENT(obj)->state)
|
||||
typedef enum {
|
||||
GST_STATE_FAILURE = 0,
|
||||
GST_STATE_SUCCESS = 1,
|
||||
GST_STATE_ASYNC = 2,
|
||||
} GstElementStateReturn;
|
||||
#endif
|
||||
|
||||
static inline char *_gst_print_statename(int state) {
|
||||
switch (state) {
|
||||
case -1: return "none pending";break;
|
||||
case 0: return "null";break;
|
||||
case 1: return "ready";break;
|
||||
case 2: return "playing";break;
|
||||
case 3: return "paused";break;
|
||||
default: return "";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
#define GST_STATE(obj) (GST_ELEMENT(obj)->current_state)
|
||||
#define GST_STATE_PENDING(obj) (GST_ELEMENT(obj)->pending_state)
|
||||
|
||||
#ifdef OLDSTATE
|
||||
#define GST_STATE_IS_SET(obj,flag) (GST_STATE (obj) & (flag))
|
||||
#define GST_STATE_SET(obj,flag) \
|
||||
G_STMT_START{ (GST_STATE (obj) |= (flag)); \
|
||||
gst_info("GstElement: set '%s' state %d\n",gst_element_get_name(obj),flag); \
|
||||
gst_info("GstElement: set '%s' state %d(%s)\n",gst_element_get_name(obj),flag, \
|
||||
_gst_print_statename(flag)); \
|
||||
}G_STMT_END
|
||||
#define GST_STATE_UNSET(obj,flag) \
|
||||
G_STMT_START{ (GST_STATE (obj) &= ~(flag)); \
|
||||
gst_info("GstElement: unset '%s' state %d\n",gst_element_get_name(obj),flag); \
|
||||
gst_info("GstElement: unset '%s' state %d(%s)\n",gst_element_get_name(obj),flag, \
|
||||
_gst_print_statename(flag)); \
|
||||
}G_STMT_END
|
||||
#endif
|
||||
|
||||
|
||||
#define GST_TYPE_ELEMENT \
|
||||
|
@ -71,6 +110,13 @@ gst_info("GstElement: unset '%s' state %d\n",gst_element_get_name(obj),flag); \
|
|||
#define GST_IS_ELEMENT_CLASS(obj) \
|
||||
(GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_ELEMENT))
|
||||
|
||||
typedef enum {
|
||||
GST_ELEMENT_MULTI_IN = (1 << 16),
|
||||
} GstElementFlags;
|
||||
|
||||
#define GST_ELEMENT_IS_MULTI_IN(obj) (GST_FLAGS(obj) & GST_ELEMENT_MULTI_IN)
|
||||
|
||||
|
||||
typedef struct _GstElement GstElement;
|
||||
typedef struct _GstElementClass GstElementClass;
|
||||
typedef struct _GstElementDetails GstElementDetails;
|
||||
|
@ -83,7 +129,8 @@ struct _GstElement {
|
|||
|
||||
gchar *name;
|
||||
|
||||
guint16 state;
|
||||
guint8 current_state;
|
||||
guint8 pending_state;
|
||||
|
||||
GstElementLoopFunction loopfunc;
|
||||
cothread_state *threadstate;
|
||||
|
@ -107,11 +154,11 @@ struct _GstElementClass {
|
|||
void (*error) (GstElement *element,gchar *error);
|
||||
|
||||
/* events */
|
||||
gboolean (*start) (GstElement *element,GstElementState state);
|
||||
gboolean (*stop) (GstElement *element);
|
||||
// gboolean (*start) (GstElement *element,GstElementState state);
|
||||
// gboolean (*stop) (GstElement *element);
|
||||
|
||||
/* change the element state */
|
||||
gboolean (*change_state) (GstElement *element,GstElementState state);
|
||||
GstElementStateReturn (*change_state) (GstElement *element);
|
||||
|
||||
/* create or read XML representation of self */
|
||||
xmlNodePtr (*save_thyself)(GstElement *element,xmlNodePtr parent);
|
||||
|
@ -156,14 +203,10 @@ void gst_element_connect(GstElement *src,gchar *srcpadname,
|
|||
GstElement *dest,gchar *destpadname);
|
||||
|
||||
/* called by the app to set the state of the element */
|
||||
gboolean gst_element_set_state(GstElement *element,GstElementState state);
|
||||
gint gst_element_set_state(GstElement *element,GstElementState state);
|
||||
|
||||
void gst_element_error(GstElement *element,gchar *error);
|
||||
|
||||
/* callback to actually set the state */
|
||||
gboolean gst_element_change_state(GstElement *element,
|
||||
GstElementState state);
|
||||
|
||||
#define gst_element_destroy(element) gst_object_destroy(GST_OBJECT(element))
|
||||
|
||||
/* XML write and read */
|
||||
|
|
105
gst/gstpad.c
105
gst/gstpad.c
|
@ -80,9 +80,10 @@ static void gst_pad_init(GstPad *pad) {
|
|||
pad->type = 0;
|
||||
pad->direction = GST_PAD_UNKNOWN;
|
||||
pad->peer = NULL;
|
||||
pad->chain = NULL;
|
||||
pad->pull = NULL;
|
||||
pad->qos = NULL;
|
||||
pad->chainfunc = NULL;
|
||||
pad->pullfunc = NULL;
|
||||
pad->pushfunc = NULL;
|
||||
pad->qosfunc = NULL;
|
||||
pad->parent = NULL;
|
||||
pad->ghostparents = NULL;
|
||||
}
|
||||
|
@ -158,35 +159,60 @@ gchar *gst_pad_get_name(GstPad *pad) {
|
|||
void gst_pad_set_pull_function(GstPad *pad,GstPadPullFunction pull) {
|
||||
g_return_if_fail(pad != NULL);
|
||||
g_return_if_fail(GST_IS_PAD(pad));
|
||||
|
||||
pad->pull = pull;
|
||||
|
||||
fprintf(stderr, "pad setting pull function\n");
|
||||
|
||||
pad->pullfunc = pull;
|
||||
}
|
||||
|
||||
void gst_pad_set_chain_function(GstPad *pad,GstPadChainFunction chain) {
|
||||
g_return_if_fail(pad != NULL);
|
||||
g_return_if_fail(GST_IS_PAD(pad));
|
||||
|
||||
pad->chain = chain;
|
||||
pad->chainfunc = chain;
|
||||
}
|
||||
|
||||
void gst_pad_set_qos_function(GstPad *pad,GstPadQoSFunction qos) {
|
||||
g_return_if_fail(pad != NULL);
|
||||
g_return_if_fail(GST_IS_PAD(pad));
|
||||
|
||||
pad->qos = qos;
|
||||
pad->qosfunc = qos;
|
||||
}
|
||||
|
||||
/* gst_pad_push is handed the src pad and the buffer to push */
|
||||
void gst_pad_push(GstPad *pad,GstBuffer *buffer) {
|
||||
g_return_if_fail(pad != NULL);
|
||||
g_return_if_fail(GST_IS_PAD(pad));
|
||||
g_return_if_fail(GST_PAD_CONNECTED(pad));
|
||||
// g_return_if_fail(GST_PAD_CONNECTED(pad));
|
||||
g_return_if_fail(buffer != NULL);
|
||||
|
||||
gst_trace_add_entry(NULL,0,buffer,"push buffer");
|
||||
|
||||
// FIXME we should probably make some noise here...
|
||||
if (!GST_PAD_CONNECTED(pad)) return;
|
||||
|
||||
// g_return_if_fail(pad->pushfunc != NULL);
|
||||
|
||||
// first check to see if there's a push handler
|
||||
if (pad->pushfunc != NULL) {
|
||||
// g_print("-- gst_pad_push(): putting buffer in pen and calling push handler\n");
|
||||
// put the buffer in peer's holding pen
|
||||
pad->peer->bufpen = buffer;
|
||||
// now inform the handler that the peer pad has something
|
||||
(pad->pushfunc)(pad->peer);
|
||||
// otherwise we assume we're chaining directly
|
||||
} else if (pad->chainfunc != NULL) {
|
||||
(pad->chainfunc)(pad->peer,buffer);
|
||||
// else we squawk
|
||||
} else {
|
||||
// g_print("-- gst_pad_push(): houston, we have a problem, no way of talking to peer\n");
|
||||
}
|
||||
|
||||
#ifdef OLD_STUFF
|
||||
// if the chain function exists for the pad, call it directly
|
||||
if (pad->chain)
|
||||
(pad->chain)(pad->peer,buffer);
|
||||
// else we're likely going to have to coroutine it
|
||||
// else we're likely going to have to cothread it
|
||||
else {
|
||||
pad->peer->bufpen = buffer;
|
||||
g_print("GstPad: would switch to a coroutine here...\n");
|
||||
|
@ -195,22 +221,51 @@ void gst_pad_push(GstPad *pad,GstBuffer *buffer) {
|
|||
if (GST_ELEMENT(pad->peer->parent)->threadstate != NULL)
|
||||
cothread_switch(GST_ELEMENT(pad->peer->parent)->threadstate);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* gst_pad_pull() is given the sink pad */
|
||||
GstBuffer *gst_pad_pull(GstPad *pad) {
|
||||
GstBuffer *buf;
|
||||
GstElement *peerparent;
|
||||
cothread_state *state;
|
||||
// GstElement *peerparent;
|
||||
// cothread_state *state;
|
||||
|
||||
g_return_val_if_fail(pad != NULL, NULL);
|
||||
g_return_val_if_fail(GST_IS_PAD(pad), NULL);
|
||||
|
||||
// g_print("-- gst_pad_pull(): attempting to pull buffer\n");
|
||||
|
||||
// g_return_val_if_fail(pad->pullfunc != NULL, NULL);
|
||||
|
||||
// if no buffer in pen and there's a pull handler, fire it
|
||||
if (pad->bufpen == NULL) {
|
||||
if (pad->pullfunc != NULL) {
|
||||
// g_print("-- gst_pad_pull(): calling pull handler\n");
|
||||
(pad->pullfunc)(pad->peer);
|
||||
} else {
|
||||
// g_print("-- gst_pad_pull(): no buffer in pen, and no handler to get one there!!!\n");
|
||||
}
|
||||
}
|
||||
|
||||
// if there's a buffer in the holding pen, use it
|
||||
if (pad->bufpen != NULL) {
|
||||
// g_print("-- gst_pad_pull(): buffer available, pulling\n");
|
||||
buf = pad->bufpen;
|
||||
pad->bufpen = NULL;
|
||||
return buf;
|
||||
// else we have a big problem...
|
||||
} else {
|
||||
// g_print("-- gst_pad_pull(): uh, nothing in pen and no handler\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef OLD_STUFF
|
||||
// if the pull function exists for the pad, call it directly
|
||||
if (pad->pull) {
|
||||
return (pad->pull)(pad->peer);
|
||||
// else we're likely going to have to coroutine it
|
||||
// else we're likely going to have to cothread it
|
||||
} else if (pad->bufpen == NULL) {
|
||||
g_print("GstPad: no buffer available, will have to do something about it\n");
|
||||
g_print("no buffer available, will have to do something about it\n");
|
||||
peerparent = GST_ELEMENT(pad->peer->parent);
|
||||
// if they're a cothread too, we can just switch to them
|
||||
if (peerparent->threadstate != NULL) {
|
||||
|
@ -227,19 +282,22 @@ GstBuffer *gst_pad_pull(GstPad *pad) {
|
|||
pad->bufpen = NULL;
|
||||
return buf;
|
||||
}
|
||||
return NULL;
|
||||
#endif
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void gst_pad_chain(GstPad *pad) {
|
||||
g_return_if_fail(pad != NULL);
|
||||
g_return_if_fail(GST_IS_PAD(pad));
|
||||
g_return_if_fail(pad->peer != NULL);
|
||||
g_return_if_fail(pad->chain != NULL);
|
||||
g_return_if_fail(pad->chainfunc != NULL);
|
||||
|
||||
if (pad->bufpen)
|
||||
(pad->chain)(pad,pad->bufpen);
|
||||
if (pad->bufpen && pad->chainfunc)
|
||||
(pad->chainfunc)(pad,pad->bufpen);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* gst_pad_handle_qos:
|
||||
* @element: element to change state of
|
||||
|
@ -255,8 +313,8 @@ void gst_pad_handle_qos(GstPad *pad,
|
|||
|
||||
DEBUG("gst_pad_handle_qos(\"%s\",%08ld)\n", GST_ELEMENT(pad->parent)->name,qos_message);
|
||||
|
||||
if (pad->qos) {
|
||||
(pad->qos)(pad,qos_message);
|
||||
if (pad->qosfunc) {
|
||||
(pad->qosfunc)(pad,qos_message);
|
||||
}
|
||||
else {
|
||||
element = GST_ELEMENT(pad->peer->parent);
|
||||
|
@ -292,9 +350,8 @@ void gst_pad_disconnect(GstPad *srcpad,GstPad *sinkpad) {
|
|||
srcpad->peer = NULL;
|
||||
sinkpad->peer = NULL;
|
||||
|
||||
srcpad->chain = NULL;
|
||||
srcpad->pull = NULL;
|
||||
|
||||
srcpad->chainfunc = NULL;
|
||||
srcpad->pullfunc = NULL;
|
||||
}
|
||||
|
||||
void gst_pad_connect(GstPad *srcpad,GstPad *sinkpad) {
|
||||
|
@ -324,9 +381,9 @@ void gst_pad_connect(GstPad *srcpad,GstPad *sinkpad) {
|
|||
sinkpad->peer = srcpad;
|
||||
|
||||
/* now copy the chain pointer from sink to src */
|
||||
srcpad->chain = sinkpad->chain;
|
||||
srcpad->chainfunc = sinkpad->chainfunc;
|
||||
/* and the pull function */
|
||||
srcpad->pull = sinkpad->pull;
|
||||
srcpad->pullfunc = sinkpad->pullfunc;
|
||||
|
||||
/* set the connected flag */
|
||||
/* FIXME: set connected flag */
|
||||
|
|
15
gst/gstpad.h
15
gst/gstpad.h
|
@ -39,10 +39,8 @@ extern "C" {
|
|||
#define GST_IS_PAD_CLASS(obj) (GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_PAD))
|
||||
|
||||
// quick test to see if the pad is connected
|
||||
#define GST_PAD_CONNECTED(pad) \
|
||||
((pad)->peer != NULL)
|
||||
#define GST_PAD_CAN_PULL(pad) \
|
||||
((pad)->pull != NULL)
|
||||
#define GST_PAD_CONNECTED(pad) ((pad)->peer != NULL)
|
||||
#define GST_PAD_CAN_PULL(pad) ((pad)->pullfunc != NULL)
|
||||
|
||||
typedef struct _GstPad GstPad;
|
||||
typedef struct _GstPadClass GstPadClass;
|
||||
|
@ -51,7 +49,7 @@ typedef struct _GstPadClass GstPadClass;
|
|||
* pad is the sink pad (so the same chain function can be used for N pads)
|
||||
* buf is the buffer being passed */
|
||||
typedef void (*GstPadChainFunction) (GstPad *pad,GstBuffer *buf);
|
||||
typedef GstBuffer *(*GstPadPullFunction) (GstPad *pad);
|
||||
typedef void (*GstPadPullFunction) (GstPad *pad);
|
||||
typedef void (*GstPadPushFunction) (GstPad *pad);
|
||||
typedef void (*GstPadQoSFunction) (GstPad *pad, glong qos_message);
|
||||
|
||||
|
@ -76,9 +74,10 @@ struct _GstPad {
|
|||
|
||||
GstBuffer *bufpen;
|
||||
|
||||
GstPadChainFunction chain;
|
||||
GstPadPullFunction pull;
|
||||
GstPadQoSFunction qos;
|
||||
GstPadChainFunction chainfunc;
|
||||
GstPadPullFunction pullfunc;
|
||||
GstPadPushFunction pushfunc;
|
||||
GstPadQoSFunction qosfunc;
|
||||
|
||||
GstObject *parent;
|
||||
GList *ghostparents;
|
||||
|
|
|
@ -44,8 +44,7 @@ enum {
|
|||
static void gst_pipeline_class_init(GstPipelineClass *klass);
|
||||
static void gst_pipeline_init(GstPipeline *pipeline);
|
||||
|
||||
static gboolean gst_pipeline_change_state(GstElement *element,
|
||||
GstElementState state);
|
||||
static GstElementStateReturn gst_pipeline_change_state(GstElement *element);
|
||||
|
||||
static void gst_pipeline_prepare(GstPipeline *pipeline);
|
||||
|
||||
|
@ -109,31 +108,33 @@ static void gst_pipeline_prepare(GstPipeline *pipeline) {
|
|||
}
|
||||
|
||||
|
||||
static gboolean gst_pipeline_change_state(GstElement *element,
|
||||
GstElementState state) {
|
||||
static GstElementStateReturn gst_pipeline_change_state(GstElement *element) {
|
||||
GstPipeline *pipeline;
|
||||
|
||||
/*
|
||||
g_return_val_if_fail(GST_IS_PIPELINE(element), FALSE);
|
||||
pipeline = GST_PIPELINE(element);
|
||||
|
||||
switch (state) {
|
||||
case GST_STATE_RUNNING:
|
||||
/* we need to set up internal state */
|
||||
g_print("GstPipeline: preparing pipeline \"%s\" for iterations:\n",
|
||||
case GST_STATE_READY:
|
||||
// we need to set up internal state
|
||||
g_print("preparing pipeline \"%s\" for iterations:\n",
|
||||
gst_element_get_name(GST_ELEMENT(element)));
|
||||
gst_pipeline_prepare(pipeline);
|
||||
break;
|
||||
#if OLDSTATE
|
||||
case ~GST_STATE_RUNNING:
|
||||
/* tear down the internal state */
|
||||
g_print("GstPipeline: tearing down pipelines's \"%s\" iteration state\n",
|
||||
gst_element_get_name(GST_ELEMENT(element)));
|
||||
// tear down the internal state
|
||||
g_print("tearing down pipelines's iteration state\n");
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (GST_ELEMENT_CLASS(parent_class)->change_state)
|
||||
return GST_ELEMENT_CLASS(parent_class)->change_state(element,state);
|
||||
*/
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -47,8 +47,7 @@ static void gst_thread_init(GstThread *thread);
|
|||
|
||||
static void gst_thread_set_arg(GtkObject *object,GtkArg *arg,guint id);
|
||||
static void gst_thread_get_arg(GtkObject *object,GtkArg *arg,guint id);
|
||||
static gboolean gst_thread_change_state(GstElement *element,
|
||||
GstElementState state);
|
||||
static GstElementStateReturn gst_thread_change_state(GstElement *element);
|
||||
|
||||
static xmlNodePtr gst_thread_save_thyself(GstElement *element,xmlNodePtr parent);
|
||||
|
||||
|
@ -104,8 +103,8 @@ gst_thread_class_init(GstThreadClass *klass) {
|
|||
static void gst_thread_init(GstThread *thread) {
|
||||
GST_FLAG_SET(thread,GST_THREAD_CREATE);
|
||||
|
||||
thread->entries = NULL;
|
||||
thread->numentries = 0;
|
||||
// thread->entries = NULL;
|
||||
// thread->numentries = 0;
|
||||
|
||||
thread->lock = g_mutex_new();
|
||||
thread->cond = g_cond_new();
|
||||
|
@ -145,6 +144,7 @@ static void gst_thread_get_arg(GtkObject *object,GtkArg *arg,guint id) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* gst_thread_new:
|
||||
* @name: the name of the thread
|
||||
|
@ -162,6 +162,7 @@ GstElement *gst_thread_new(guchar *name) {
|
|||
}
|
||||
|
||||
|
||||
#ifdef OLD_STUFF
|
||||
static void gst_thread_prepare(GstThread *thread) {
|
||||
GList *elements;
|
||||
GstElement *element;
|
||||
|
@ -211,13 +212,14 @@ for internal element \"%s\"\n",
|
|||
}
|
||||
gst_info("gstthread: have %d entries into thread\n",thread->numentries);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static gboolean gst_thread_change_state(GstElement *element,
|
||||
GstElementState state) {
|
||||
static GstElementStateReturn gst_thread_change_state(GstElement *element) {
|
||||
GstThread *thread;
|
||||
gboolean stateset = TRUE;
|
||||
|
||||
/*
|
||||
g_return_val_if_fail(GST_IS_THREAD(element), FALSE);
|
||||
thread = GST_THREAD(element);
|
||||
|
||||
|
@ -225,18 +227,19 @@ static gboolean gst_thread_change_state(GstElement *element,
|
|||
stateset = GST_ELEMENT_CLASS(parent_class)->change_state(element,state);
|
||||
|
||||
switch (state) {
|
||||
case GST_STATE_RUNNING:
|
||||
case GST_STATE_READY:
|
||||
if (!stateset) return FALSE;
|
||||
/* we want to prepare our internal state for doing the iterations */
|
||||
gst_info("gstthread: preparing thread \"%s\" for iterations:\n",
|
||||
// we want to prepare our internal state for doing the iterations
|
||||
gst_info("preparing thread \"%s\" for iterations:\n",
|
||||
gst_element_get_name(GST_ELEMENT(element)));
|
||||
gst_thread_prepare(thread);
|
||||
if (thread->numentries == 0)
|
||||
return FALSE;
|
||||
/* set the state to idle */
|
||||
// gst_thread_prepare(thread);
|
||||
gst_bin_create_plan(GST_BIN(thread));
|
||||
// if (thread->numentries == 0)
|
||||
// return FALSE;
|
||||
// set the state to idle
|
||||
GST_FLAG_UNSET(thread,GST_THREAD_STATE_SPINNING);
|
||||
/* create the thread if that's what we're supposed to do */
|
||||
gst_info("gstthread: flags are 0x%08x\n",GST_FLAGS(thread));
|
||||
// create the thread if that's what we're supposed to do
|
||||
gst_info("flags are 0x%08x\n",GST_FLAGS(thread));
|
||||
if (GST_FLAG_IS_SET(thread,GST_THREAD_CREATE)) {
|
||||
gst_info("gstthread: starting thread \"%s\"\n",
|
||||
gst_element_get_name(GST_ELEMENT(element)));
|
||||
|
@ -248,17 +251,18 @@ static gboolean gst_thread_change_state(GstElement *element,
|
|||
}
|
||||
return TRUE;
|
||||
break;
|
||||
#if OLDSTATE
|
||||
case ~GST_STATE_RUNNING:
|
||||
/* stop, reap, and join the thread */
|
||||
// stop, reap, and join the thread
|
||||
GST_FLAG_UNSET(thread,GST_THREAD_STATE_SPINNING);
|
||||
GST_FLAG_SET(thread,GST_THREAD_STATE_REAPING);
|
||||
gst_thread_signal_thread(thread);
|
||||
//pthread_join(thread->thread_id,0);
|
||||
/* tear down the internal state */
|
||||
gst_info("gstthread: tearing down thread's \"%s\" iteration state\n",
|
||||
gst_element_get_name(GST_ELEMENT(element)));
|
||||
/* FIXME do stuff */
|
||||
pthread_join(thread->thread_id,0);
|
||||
// tear down the internal state
|
||||
gst_info("tearing down thread's iteration state\n");
|
||||
// FIXME do stuff
|
||||
break;
|
||||
#endif
|
||||
case GST_STATE_PLAYING:
|
||||
if (!stateset) return FALSE;
|
||||
gst_info("gstthread: starting thread \"%s\"\n",
|
||||
|
@ -276,6 +280,7 @@ static gboolean gst_thread_change_state(GstElement *element,
|
|||
default:
|
||||
break;
|
||||
}
|
||||
*/
|
||||
|
||||
return stateset;
|
||||
}
|
||||
|
@ -295,7 +300,7 @@ void *gst_thread_main_loop(void *arg) {
|
|||
|
||||
while(!GST_FLAG_IS_SET(thread,GST_THREAD_STATE_REAPING)) {
|
||||
if (GST_FLAG_IS_SET(thread,GST_THREAD_STATE_SPINNING))
|
||||
gst_thread_iterate(thread);
|
||||
gst_bin_iterate(GST_BIN(thread));
|
||||
else {
|
||||
g_mutex_lock(thread->lock);
|
||||
g_cond_wait(thread->cond,thread->lock);
|
||||
|
@ -311,6 +316,7 @@ void *gst_thread_main_loop(void *arg) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef OLD_STUFF
|
||||
/**
|
||||
* gst_thread_iterate:
|
||||
* @thread: the thread to iterate
|
||||
|
@ -343,6 +349,7 @@ void gst_thread_iterate(GstThread *thread) {
|
|||
DEBUG("gstthread: %s: thread iterate done\n", gst_element_get_name(GST_ELEMENT(thread)));
|
||||
//g_print(",");
|
||||
}
|
||||
#endif
|
||||
|
||||
static void gst_thread_signal_thread(GstThread *thread) {
|
||||
g_mutex_lock(thread->lock);
|
||||
|
|
|
@ -57,9 +57,6 @@ typedef struct _GstThreadClass GstThreadClass;
|
|||
struct _GstThread {
|
||||
GstBin bin;
|
||||
|
||||
GList *entries; /* used to determine iterate behavior */
|
||||
gint numentries; /* number of above entry points */
|
||||
|
||||
pthread_t thread_id; /* id of the thread, if any */
|
||||
GMutex *lock; /* thread lock/condititon pair... */
|
||||
GCond *cond; /* used to control the thread */
|
||||
|
|
|
@ -45,13 +45,13 @@ struct _elements_entry {
|
|||
};
|
||||
|
||||
struct _elements_entry _elements[] = {
|
||||
{ "fakesrc", gst_fakesrc_get_type, &gst_fakesrc_details },
|
||||
{ "fakesink", gst_fakesink_get_type, &gst_fakesink_details },
|
||||
{ "asyncdisksrc", gst_asyncdisksrc_get_type, &gst_asyncdisksrc_details },
|
||||
{ "audiosink", gst_audiosink_get_type, &gst_audiosink_details },
|
||||
{ "audiosrc", gst_audiosrc_get_type, &gst_audiosrc_details },
|
||||
{ "disksrc", gst_disksrc_get_type, &gst_disksrc_details },
|
||||
{ "identity", gst_identity_get_type, &gst_identity_details },
|
||||
{ "fakesink", gst_fakesink_get_type, &gst_fakesink_details },
|
||||
{ "fakesrc", gst_fakesrc_get_type, &gst_fakesrc_details },
|
||||
{ "fdsink", gst_fdsink_get_type, &gst_fdsink_details },
|
||||
{ "fdsrc", gst_fdsrc_get_type, &gst_fdsrc_details },
|
||||
#if HAVE_LIBGHTTP
|
||||
|
|
|
@ -86,8 +86,8 @@ static void gst_fakesink_init(GstFakeSink *fakesink) {
|
|||
gst_element_add_pad(GST_ELEMENT(fakesink),fakesink->sinkpad);
|
||||
gst_pad_set_chain_function(fakesink->sinkpad,gst_fakesink_chain);
|
||||
|
||||
// we're already complete, since we don't have any args...
|
||||
gst_element_set_state(GST_ELEMENT(fakesink),GST_STATE_COMPLETE);
|
||||
// we're ready right away, since we don't have any args...
|
||||
// gst_element_set_state(GST_ELEMENT(fakesink),GST_STATE_READY);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -120,8 +120,8 @@ void gst_fakesink_chain(GstPad *pad,GstBuffer *buf) {
|
|||
g_return_if_fail(buf != NULL);
|
||||
|
||||
fakesink = GST_FAKESINK(pad->parent);
|
||||
// g_print("gst_fakesink_chain: got buffer of %d bytes in '%s'\n",
|
||||
// buf->datasize,gst_element_get_name(GST_ELEMENT(fakesink)));
|
||||
// g_print("gst_fakesink_chain: got buffer in '%s'\n",
|
||||
// gst_element_get_name(GST_ELEMENT(fakesink)));
|
||||
g_print("<");
|
||||
gst_buffer_unref(buf);
|
||||
}
|
||||
|
|
|
@ -87,8 +87,8 @@ static void gst_fakesrc_init(GstFakeSrc *fakesrc) {
|
|||
fakesrc->srcpad = gst_pad_new("src",GST_PAD_SRC);
|
||||
gst_element_add_pad(GST_ELEMENT(fakesrc),fakesrc->srcpad);
|
||||
|
||||
// we're already complete, since we don't have any args...
|
||||
gst_element_set_state(GST_ELEMENT(fakesrc),GST_STATE_COMPLETE);
|
||||
// we're ready right away, since we don't have any args...
|
||||
// gst_element_set_state(GST_ELEMENT(fakesrc),GST_STATE_READY);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
19
test/fake.c
19
test/fake.c
|
@ -3,15 +3,15 @@
|
|||
extern gboolean _gst_plugin_spew;
|
||||
|
||||
int main(int argc,char *argv[]) {
|
||||
GstPipeline *pipeline;
|
||||
GstBin *bin;
|
||||
GstElement *src, *sink;
|
||||
GstPad *srcpad, *sinkpad;
|
||||
|
||||
// _gst_plugin_spew = TRUE;
|
||||
gst_init(&argc,&argv);
|
||||
|
||||
pipeline = gst_pipeline_new("pipeline");
|
||||
g_return_if_fail(pipeline != NULL);
|
||||
bin = gst_bin_new("bin");
|
||||
g_return_if_fail(bin != NULL);
|
||||
|
||||
g_print("--- creating src and sink elements\n");
|
||||
src = gst_elementfactory_make("fakesrc","src");
|
||||
|
@ -19,9 +19,9 @@ int main(int argc,char *argv[]) {
|
|||
sink = gst_elementfactory_make("fakesink","sink");
|
||||
g_return_if_fail(sink != NULL);
|
||||
|
||||
g_print("--- about to add the elements to the pipeline\n");
|
||||
gst_bin_add(GST_BIN(pipeline),GST_ELEMENT(src));
|
||||
gst_bin_add(GST_BIN(pipeline),GST_ELEMENT(sink));
|
||||
g_print("--- about to add the elements to the bin\n");
|
||||
gst_bin_add(bin,GST_ELEMENT(src));
|
||||
gst_bin_add(bin,GST_ELEMENT(sink));
|
||||
|
||||
g_print("--- getting pads\n");
|
||||
srcpad = gst_element_get_pad(src,"src");
|
||||
|
@ -33,5 +33,10 @@ int main(int argc,char *argv[]) {
|
|||
gst_pad_connect(srcpad,sinkpad);
|
||||
|
||||
g_print("--- setting up\n");
|
||||
gst_pipeline_iterate(pipeline);
|
||||
gst_element_set_state(GST_ELEMENT(bin),GST_STATE_READY);
|
||||
|
||||
g_print("--- creating plan\n");
|
||||
gst_bin_create_plan(bin);
|
||||
g_print("--- iterating\n");
|
||||
gst_bin_iterate(bin);
|
||||
}
|
||||
|
|
12
tests/.gitignore
vendored
Normal file
12
tests/.gitignore
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
Makefile
|
||||
Makefile.in
|
||||
*.o
|
||||
*.lo
|
||||
*.la
|
||||
.deps
|
||||
.libs
|
||||
*.xml
|
||||
init
|
||||
loadall
|
||||
simplefake
|
||||
states
|
7
tests/Makefile.am
Normal file
7
tests/Makefile.am
Normal file
|
@ -0,0 +1,7 @@
|
|||
noinst_PROGRAMS = init loadall simplefake states
|
||||
|
||||
LDADD = $(GLIB_LIBS) $(GTK_LIBS) $(top_builddir)/gst/libgst.la
|
||||
|
||||
INCLUDES = $(GLIB_CFLAGS) $(GTK_CFLAGS) -I$(top_srcdir)
|
||||
|
||||
EXTRA_DIST = README
|
2
tests/README
Normal file
2
tests/README
Normal file
|
@ -0,0 +1,2 @@
|
|||
This directory contains various tests designed to verify GStreamer
|
||||
behavior. If any of them exit with a non-zero value, something's wrong.
|
5
tests/init.c
Normal file
5
tests/init.c
Normal file
|
@ -0,0 +1,5 @@
|
|||
#include <gst/gst.h>
|
||||
|
||||
int main(int argc,char *argv[]) {
|
||||
gst_init(&argc,&argv);
|
||||
}
|
6
tests/loadall.c
Normal file
6
tests/loadall.c
Normal file
|
@ -0,0 +1,6 @@
|
|||
#include <gst/gst.h>
|
||||
|
||||
int main(int argc,char *argv[]) {
|
||||
gst_init(&argc,&argv);
|
||||
gst_plugin_load_all();
|
||||
}
|
17
tests/simplefake.c
Normal file
17
tests/simplefake.c
Normal file
|
@ -0,0 +1,17 @@
|
|||
#include <gst/gst.h>
|
||||
|
||||
int main(int argc,char *argv[]) {
|
||||
GstPipeline *pipeline;
|
||||
GstElement *src,*sink;
|
||||
|
||||
gst_init(&argc,&argv);
|
||||
|
||||
pipeline = gst_pipeline_new("fakepipeline");
|
||||
src = gst_elementfactory_make("fakesrc","fakesrc");
|
||||
g_return_val_if_fail(1,src != NULL);
|
||||
sink = gst_elementfactory_make("fakesink","fakesink");
|
||||
g_return_val_if_fail(1,sink != NULL);
|
||||
|
||||
gst_bin_add(GST_BIN(pipeline),src);
|
||||
gst_bin_add(GST_BIN(pipeline),sink);
|
||||
}
|
46
tests/states.c
Normal file
46
tests/states.c
Normal file
|
@ -0,0 +1,46 @@
|
|||
#include <gst/gst.h>
|
||||
|
||||
gboolean state_change(GstElement *element,GstElementState state) {
|
||||
g_print("state_change: element '%s' state set to %d(%s)\n",
|
||||
gst_element_get_name(element),state,_gst_print_statename(state));
|
||||
g_print("state_change: element state is actually %d\n",GST_STATE(element));
|
||||
}
|
||||
|
||||
int main(int argc,char *argv[]) {
|
||||
GstElement *bin;
|
||||
GstElement *src,*sink;
|
||||
|
||||
gst_init(&argc,&argv);
|
||||
|
||||
src = gst_elementfactory_make("fakesrc","src");
|
||||
g_return_val_if_fail(1,src != NULL);
|
||||
sink = gst_elementfactory_make("fakesink","sink");
|
||||
g_return_val_if_fail(1,sink != NULL);
|
||||
bin = gst_bin_new("bin");
|
||||
g_return_val_if_fail(1,bin != NULL);
|
||||
|
||||
gtk_signal_connect(GTK_OBJECT(src),"state_change",
|
||||
GTK_SIGNAL_FUNC(state_change),NULL);
|
||||
gtk_signal_connect(GTK_OBJECT(sink),"state_change",
|
||||
GTK_SIGNAL_FUNC(state_change),NULL);
|
||||
gtk_signal_connect(GTK_OBJECT(bin),"state_change",
|
||||
GTK_SIGNAL_FUNC(state_change),NULL);
|
||||
|
||||
g_print("element '%s' starts at state %d(%s)\n",gst_element_get_name(src),
|
||||
GST_STATE(src),_gst_print_statename(GST_STATE(src)));
|
||||
g_print("element '%s' starts at state %d(%s)\n",gst_element_get_name(sink),
|
||||
GST_STATE(sink),_gst_print_statename(GST_STATE(sink)));
|
||||
g_print("element '%s' starts at state %d(%s)\n",gst_element_get_name(bin),
|
||||
GST_STATE(bin),_gst_print_statename(GST_STATE(bin)));
|
||||
|
||||
gst_bin_add(GST_BIN(bin),src);
|
||||
gst_bin_add(GST_BIN(bin),sink);
|
||||
|
||||
gst_pad_connect(gst_element_get_pad(src,"src"),
|
||||
gst_element_get_pad(sink,"sink"));
|
||||
|
||||
gst_bin_create_plan(bin);
|
||||
gst_element_set_state(bin,GST_STATE_PLAYING);
|
||||
|
||||
gst_bin_iterate(bin);
|
||||
}
|
Loading…
Reference in a new issue