mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-12 03:16:33 +00:00
cothreads.c: added a comment on one of the tests gstbin.h: added the GST_BIN_SELF_SCHEDULABLE flag gstelement.c: clea...
Original commit message from CVS: cothreads.c: added a comment on one of the tests gstbin.h: added the GST_BIN_SELF_SCHEDULABLE flag gstelement.c: cleaned up the _change_state function a little gstobject.c: improved the refcounting DEBUGs gstpad.c: moved the connected signal to after capsnego, added the caps_nego_failed signal gstpad.h: added the caps_nego_failed signal funcptr gstscheduler.c: added the GST_BIN_SELF_SCHEDULABLE exception gsttypefind.c: added check code around signal_emit to deal with the case where the signal's handler shuts down the element gstautoplugcache.c: added the first_buffer signal and caps_proxy arg gstautoplugger.c: significant rework, it functions quite nicely actually
This commit is contained in:
parent
dbbd2077d0
commit
ed06327f06
10 changed files with 248 additions and 42 deletions
|
@ -49,6 +49,8 @@ struct _GstAutoplugCache {
|
|||
|
||||
GstPad *sinkpad, *srcpad;
|
||||
|
||||
gboolean caps_proxy;
|
||||
|
||||
GList *cache;
|
||||
GList *cache_start;
|
||||
gint buffer_count;
|
||||
|
@ -59,12 +61,14 @@ struct _GstAutoplugCache {
|
|||
struct _GstAutoplugCacheClass {
|
||||
GstElementClass parent_class;
|
||||
|
||||
void (*first_buffer) (GstElement *element, GstBuffer *buf);
|
||||
void (*cache_empty) (GstElement *element);
|
||||
};
|
||||
|
||||
|
||||
/* Cache signals and args */
|
||||
enum {
|
||||
FIRST_BUFFER,
|
||||
CACHE_EMPTY,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
@ -72,6 +76,7 @@ enum {
|
|||
enum {
|
||||
ARG_0,
|
||||
ARG_BUFFER_COUNT,
|
||||
ARG_CAPS_PROXY,
|
||||
ARG_RESET
|
||||
};
|
||||
|
||||
|
@ -123,6 +128,11 @@ gst_autoplugcache_class_init (GstAutoplugCacheClass *klass)
|
|||
|
||||
parent_class = gtk_type_class (GST_TYPE_ELEMENT);
|
||||
|
||||
gst_autoplugcache_signals[FIRST_BUFFER] =
|
||||
gtk_signal_new ("first_buffer", GTK_RUN_LAST, gtkobject_class->type,
|
||||
GTK_SIGNAL_OFFSET (GstAutoplugCacheClass, first_buffer),
|
||||
gtk_marshal_NONE__POINTER, GTK_TYPE_NONE, 1,
|
||||
GTK_TYPE_POINTER);
|
||||
gst_autoplugcache_signals[CACHE_EMPTY] =
|
||||
gtk_signal_new ("cache_empty", GTK_RUN_LAST, gtkobject_class->type,
|
||||
GTK_SIGNAL_OFFSET (GstAutoplugCacheClass, cache_empty),
|
||||
|
@ -131,6 +141,8 @@ gst_autoplugcache_class_init (GstAutoplugCacheClass *klass)
|
|||
|
||||
gtk_object_add_arg_type ("GstAutoplugCache::buffer_count", GTK_TYPE_INT,
|
||||
GTK_ARG_READABLE, ARG_BUFFER_COUNT);
|
||||
gtk_object_add_arg_type ("GstAutoplugCache::caps_proxy", GTK_TYPE_BOOL,
|
||||
GTK_ARG_READWRITE, ARG_CAPS_PROXY);
|
||||
gtk_object_add_arg_type ("GstAutoplugCache::reset", GTK_TYPE_BOOL,
|
||||
GTK_ARG_WRITABLE, ARG_RESET);
|
||||
|
||||
|
@ -146,13 +158,15 @@ gst_autoplugcache_init (GstAutoplugCache *cache)
|
|||
gst_element_set_loop_function(GST_ELEMENT(cache), GST_DEBUG_FUNCPTR(gst_autoplugcache_loop));
|
||||
|
||||
cache->sinkpad = gst_pad_new ("sink", GST_PAD_SINK);
|
||||
gst_pad_set_negotiate_function (cache->sinkpad, gst_autoplugcache_nego_sink);
|
||||
// gst_pad_set_negotiate_function (cache->sinkpad, gst_autoplugcache_nego_sink);
|
||||
gst_element_add_pad (GST_ELEMENT(cache), cache->sinkpad);
|
||||
|
||||
cache->srcpad = gst_pad_new ("src", GST_PAD_SRC);
|
||||
gst_pad_set_negotiate_function (cache->sinkpad, gst_autoplugcache_nego_src);
|
||||
// gst_pad_set_negotiate_function (cache->srcpad, gst_autoplugcache_nego_src);
|
||||
gst_element_add_pad (GST_ELEMENT(cache), cache->srcpad);
|
||||
|
||||
cache->caps_proxy = FALSE;
|
||||
|
||||
// provide a zero basis for the cache
|
||||
cache->cache = g_list_prepend(NULL, NULL);
|
||||
cache->cache_start = cache->cache;
|
||||
|
@ -196,6 +210,8 @@ gst_autoplugcache_loop (GstElement *element)
|
|||
// set the current_playout pointer
|
||||
cache->current_playout = cache->cache;
|
||||
|
||||
gtk_signal_emit (GTK_OBJECT(cache), gst_autoplugcache_signals[FIRST_BUFFER], buf);
|
||||
|
||||
// send the buffer on its way
|
||||
gst_pad_push (cache->srcpad, buf);
|
||||
}
|
||||
|
@ -275,6 +291,16 @@ gst_autoplugcache_set_arg (GtkObject *object, GtkArg *arg, guint id)
|
|||
cache = GST_AUTOPLUGCACHE (object);
|
||||
|
||||
switch (id) {
|
||||
case ARG_CAPS_PROXY:
|
||||
cache->caps_proxy = GTK_VALUE_BOOL(*arg);
|
||||
if (cache->caps_proxy) {
|
||||
gst_pad_set_negotiate_function (cache->sinkpad, gst_autoplugcache_nego_sink);
|
||||
gst_pad_set_negotiate_function (cache->srcpad, gst_autoplugcache_nego_src);
|
||||
} else {
|
||||
gst_pad_set_negotiate_function (cache->sinkpad, NULL);
|
||||
gst_pad_set_negotiate_function (cache->srcpad, NULL);
|
||||
}
|
||||
break;
|
||||
case ARG_RESET:
|
||||
// no idea why anyone would set this to FALSE, but just in case ;-)
|
||||
if (GTK_VALUE_BOOL(*arg)) {
|
||||
|
@ -301,6 +327,8 @@ gst_autoplugcache_get_arg (GtkObject *object, GtkArg *arg, guint id)
|
|||
case ARG_BUFFER_COUNT:
|
||||
GTK_VALUE_INT(*arg) = cache->buffer_count;
|
||||
break;
|
||||
case ARG_CAPS_PROXY:
|
||||
GTK_VALUE_BOOL(*arg) = cache->caps_proxy;
|
||||
default:
|
||||
arg->type = GTK_TYPE_INVALID;
|
||||
break;
|
||||
|
|
|
@ -47,9 +47,14 @@ typedef struct _GstAutopluggerClass GstAutopluggerClass;
|
|||
struct _GstAutoplugger {
|
||||
GstBin bin;
|
||||
|
||||
GstGhostPad *srcghost, *sinkghost;
|
||||
GstElement *cache;
|
||||
GstPad *cache_sinkpad, *cache_srcpad;
|
||||
|
||||
GstElement *cache, *typefind;
|
||||
GstElement *typefind;
|
||||
GstPad *typefind_sinkpad;
|
||||
|
||||
GstPad *sinkpadpeer, *srcpadpeer;
|
||||
GstCaps *sinkcaps, *srccaps;
|
||||
};
|
||||
|
||||
struct _GstAutopluggerClass {
|
||||
|
@ -67,7 +72,7 @@ enum {
|
|||
};
|
||||
|
||||
|
||||
static void gst_autoplugger_class_init (GstAutopluggerClass *klass);
|
||||
static void gst_autoplugger_class_init (GstAutopluggerClass *klass);
|
||||
static void gst_autoplugger_init (GstAutoplugger *queue);
|
||||
|
||||
static void gst_autoplugger_set_arg (GtkObject *object, GtkArg *arg, guint id);
|
||||
|
@ -79,6 +84,12 @@ static void gst_autoplugger_get_arg (GtkObject *object, GtkArg *arg, guint id
|
|||
static void gst_autoplugger_external_sink_caps_changed (GstPad *pad, GstCaps *caps, GstAutoplugger *autoplugger);
|
||||
static void gst_autoplugger_external_src_caps_changed (GstPad *pad, GstCaps *caps, GstAutoplugger *autoplugger);
|
||||
|
||||
static void gst_autoplugger_external_sink_connected (GstPad *pad, GstPad *peerpad, GstAutoplugger *autoplugger);
|
||||
static void gst_autoplugger_external_src_connected (GstPad *pad, GstPad *peerpad, GstAutoplugger *autoplugger);
|
||||
|
||||
static void gst_autoplugger_typefind_have_type (GstElement *element, GstCaps *caps, GstAutoplugger *autoplugger);
|
||||
static void gst_autoplugger_cache_first_buffer (GstElement *element,GstBuffer *buf,GstAutoplugger *autoplugger);
|
||||
|
||||
static GstElementClass *parent_class = NULL;
|
||||
//static guint gst_autoplugger_signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
|
@ -137,30 +148,36 @@ gst_autoplugger_class_init (GstAutopluggerClass *klass)
|
|||
static void
|
||||
gst_autoplugger_init (GstAutoplugger *autoplugger)
|
||||
{
|
||||
GstPad *srcpad, *sinkpad;
|
||||
|
||||
// create the autoplugger cache, which is the fundamental unit of the autopluggerger
|
||||
// FIXME we need to find a way to set element's name before _init
|
||||
// FIXME ... so we can name the subelements uniquely
|
||||
autoplugger->cache = gst_elementfactory_make("autoplugcache", "unnamed_autoplugcache");
|
||||
g_return_if_fail (autoplugger->cache != NULL);
|
||||
|
||||
// attach signals to the cache
|
||||
gtk_signal_connect (GTK_OBJECT (autoplugger->cache), "first_buffer",
|
||||
GTK_SIGNAL_FUNC (gst_autoplugger_cache_first_buffer), autoplugger);
|
||||
|
||||
// add the cache to self
|
||||
gst_bin_add (GST_BIN(autoplugger), autoplugger->cache);
|
||||
|
||||
// get the cache's pads so we can attach stuff to them
|
||||
sinkpad = gst_element_get_pad (autoplugger->cache, "sink");
|
||||
srcpad = gst_element_get_pad (autoplugger->cache, "src");
|
||||
autoplugger->cache_sinkpad = gst_element_get_pad (autoplugger->cache, "sink");
|
||||
autoplugger->cache_srcpad = gst_element_get_pad (autoplugger->cache, "src");
|
||||
|
||||
// attach handlers to the typefind pads
|
||||
gtk_signal_connect (GTK_OBJECT (sinkpad), "caps_changed",
|
||||
gtk_signal_connect (GTK_OBJECT (autoplugger->cache_sinkpad), "caps_changed",
|
||||
GTK_SIGNAL_FUNC (gst_autoplugger_external_sink_caps_changed), autoplugger);
|
||||
gtk_signal_connect (GTK_OBJECT (srcpad), "caps_changed",
|
||||
gtk_signal_connect (GTK_OBJECT (autoplugger->cache_srcpad), "caps_changed",
|
||||
GTK_SIGNAL_FUNC (gst_autoplugger_external_src_caps_changed), autoplugger);
|
||||
gtk_signal_connect (GTK_OBJECT (autoplugger->cache_sinkpad), "connected",
|
||||
GTK_SIGNAL_FUNC (gst_autoplugger_external_sink_connected), autoplugger);
|
||||
gtk_signal_connect (GTK_OBJECT (autoplugger->cache_srcpad), "connected",
|
||||
GTK_SIGNAL_FUNC (gst_autoplugger_external_src_connected), autoplugger);
|
||||
|
||||
// ghost both of these pads to the outside world
|
||||
gst_element_add_ghost_pad (GST_ELEMENT(autoplugger), sinkpad, "sink");
|
||||
gst_element_add_ghost_pad (GST_ELEMENT(autoplugger), srcpad, "src");
|
||||
gst_element_add_ghost_pad (GST_ELEMENT(autoplugger), autoplugger->cache_sinkpad, "sink");
|
||||
gst_element_add_ghost_pad (GST_ELEMENT(autoplugger), autoplugger->cache_srcpad, "src");
|
||||
}
|
||||
|
||||
|
||||
|
@ -168,12 +185,146 @@ static void
|
|||
gst_autoplugger_external_sink_caps_changed(GstPad *pad, GstCaps *caps, GstAutoplugger *autoplugger)
|
||||
{
|
||||
GST_INFO(GST_CAT_AUTOPLUG, "have cache:sink caps of %s\n",gst_caps_get_mime(caps));
|
||||
autoplugger->sinkcaps = caps;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_autoplugger_external_src_caps_changed(GstPad *pad, GstCaps *caps, GstAutoplugger *autoplugger)
|
||||
{
|
||||
GST_INFO(GST_CAT_AUTOPLUG, "have cache:src caps of %s\n",gst_caps_get_mime(caps));
|
||||
autoplugger->srccaps = caps;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_autoplugger_external_sink_connected(GstPad *pad, GstPad *peerpad, GstAutoplugger *autoplugger)
|
||||
{
|
||||
GstPadTemplate *peertemplate;
|
||||
GstCaps *peercaps, *peertemplatecaps;
|
||||
|
||||
GST_INFO(GST_CAT_AUTOPLUG, "have cache:sink connected\n");
|
||||
autoplugger->sinkpadpeer = peerpad;
|
||||
|
||||
if (autoplugger->sinkpadpeer) {
|
||||
peercaps = GST_PAD_CAPS(autoplugger->sinkpadpeer);
|
||||
if (peercaps)
|
||||
GST_INFO(GST_CAT_AUTOPLUG, "there are some caps on this pad's peer: %s\n",
|
||||
gst_caps_get_mime(peercaps));
|
||||
peertemplate = GST_PAD_PADTEMPLATE(autoplugger->sinkpadpeer);
|
||||
if (peertemplate) {
|
||||
peertemplatecaps = GST_PADTEMPLATE_CAPS(peertemplate);
|
||||
if (peertemplatecaps) {
|
||||
GST_INFO(GST_CAT_AUTOPLUG, "there are some caps on this pad's peer's padtemplate %s\n",
|
||||
gst_caps_get_mime(peertemplatecaps));
|
||||
GST_DEBUG(GST_CAT_AUTOPLUG, "turning on caps nego proxying in cache\n");
|
||||
gtk_object_set(GTK_OBJECT(autoplugger->cache),"caps_proxy",TRUE,NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_autoplugger_external_src_connected(GstPad *pad, GstPad *peerpad, GstAutoplugger *autoplugger)
|
||||
{
|
||||
GstPadTemplate *peertemplate;
|
||||
GstCaps *peercaps, *peertemplatecaps;
|
||||
|
||||
GST_INFO(GST_CAT_AUTOPLUG, "have cache:src connected\n");
|
||||
autoplugger->srcpadpeer = peerpad;
|
||||
|
||||
if (autoplugger->srcpadpeer) {
|
||||
peercaps = GST_PAD_CAPS(autoplugger->srcpadpeer);
|
||||
if (peercaps)
|
||||
GST_INFO(GST_CAT_AUTOPLUG, "there are some caps on this pad's peer: %s\n",
|
||||
gst_caps_get_mime(peercaps));
|
||||
peertemplate = GST_PAD_PADTEMPLATE(autoplugger->srcpadpeer);
|
||||
if (peertemplate) {
|
||||
peertemplatecaps = GST_PADTEMPLATE_CAPS(peertemplate);
|
||||
if (peertemplatecaps) {
|
||||
GST_INFO(GST_CAT_AUTOPLUG, "there are some caps on this pad's peer's padtemplate %s\n",
|
||||
gst_caps_get_mime(peertemplatecaps));
|
||||
GST_DEBUG(GST_CAT_AUTOPLUG, "turning on caps nego proxying in cache\n");
|
||||
gtk_object_set(GTK_OBJECT(autoplugger->cache),"caps_proxy",TRUE,NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_autoplugger_typefind_have_type(GstElement *element, GstCaps *caps, GstAutoplugger *autoplugger)
|
||||
{
|
||||
GST_INFO(GST_CAT_AUTOPLUG, "typefind claims to have a type: %s",gst_caps_get_mime(caps));
|
||||
|
||||
gst_schedule_show(GST_ELEMENT_SCHED(autoplugger));
|
||||
|
||||
// try to PAUSE the whole thing
|
||||
gst_element_set_state(GST_ELEMENT_SCHED(autoplugger)->parent,GST_STATE_PAUSED);
|
||||
|
||||
// first disconnect the typefind and shut it down
|
||||
GST_DEBUG(GST_CAT_AUTOPLUG, "disconnecting typefind from the cache\n");
|
||||
gst_element_disconnect(autoplugger->cache,"src",autoplugger->typefind,"sink");
|
||||
gst_bin_remove(GST_BIN(autoplugger),autoplugger->typefind);
|
||||
|
||||
// FIXME FIXME now we'd compare caps and see if we need to autoplug something in the middle, but for
|
||||
// now we're going to just reconnect where we left off
|
||||
|
||||
// re-attach the srcpad's original peer to the cache
|
||||
GST_DEBUG(GST_CAT_AUTOPLUG, "reconnecting the cache to the downstream peer\n");
|
||||
gst_pad_connect(autoplugger->cache_srcpad,autoplugger->srcpadpeer);
|
||||
|
||||
// now reset the autoplugcache
|
||||
GST_DEBUG(GST_CAT_AUTOPLUG, "resetting the cache to send first buffer(s) again\n");
|
||||
gtk_object_set(GTK_OBJECT(autoplugger->cache),"reset",TRUE,NULL);
|
||||
|
||||
// try to PLAY the whole thing
|
||||
gst_element_set_state(GST_ELEMENT_SCHED(autoplugger)->parent,GST_STATE_PLAYING);
|
||||
|
||||
GST_INFO(GST_CAT_AUTOPLUG, "typefind_have_type finished");
|
||||
gst_schedule_show(GST_ELEMENT_SCHED(autoplugger));
|
||||
}
|
||||
|
||||
static void
|
||||
gst_autoplugger_cache_first_buffer(GstElement *element,GstBuffer *buf,GstAutoplugger *autoplugger)
|
||||
{
|
||||
GST_INFO(GST_CAT_AUTOPLUG, "have first buffer through cache");
|
||||
|
||||
// if there are no established caps, worry
|
||||
if (!autoplugger->sinkcaps && !autoplugger->srccaps) {
|
||||
GST_INFO(GST_CAT_AUTOPLUG, "have no caps for the buffer, Danger Will Robinson!");
|
||||
|
||||
gst_schedule_show(GST_ELEMENT_SCHED(autoplugger));
|
||||
|
||||
// try to PAUSE the whole thing
|
||||
gst_element_set_state(GST_ELEMENT_SCHED(autoplugger)->parent,GST_STATE_PAUSED);
|
||||
|
||||
// detach the srcpad
|
||||
GST_DEBUG(GST_CAT_AUTOPLUG, "disconnecting cache from its downstream peer\n");
|
||||
gst_pad_disconnect(autoplugger->cache_srcpad,autoplugger->srcpadpeer);
|
||||
|
||||
// instantiate the typefind and set up the signal handlers
|
||||
if (!autoplugger->typefind) {
|
||||
GST_DEBUG(GST_CAT_AUTOPLUG, "creating typefind and setting signal handler\n");
|
||||
autoplugger->typefind = gst_elementfactory_make("typefind","unnamed_typefind");
|
||||
autoplugger->typefind_sinkpad = gst_element_get_pad(autoplugger->typefind,"sink");
|
||||
gtk_signal_connect(GTK_OBJECT(autoplugger->typefind),"have_type",
|
||||
GTK_SIGNAL_FUNC (gst_autoplugger_typefind_have_type), autoplugger);
|
||||
}
|
||||
// add it to self and attach it
|
||||
GST_DEBUG(GST_CAT_AUTOPLUG, "adding typefind to self and connecting to cache\n");
|
||||
gst_bin_add(GST_BIN(autoplugger),autoplugger->typefind);
|
||||
gst_pad_connect(autoplugger->cache_srcpad,autoplugger->typefind_sinkpad);
|
||||
|
||||
// bring the typefind into playing state
|
||||
GST_DEBUG(GST_CAT_AUTOPLUG, "setting typefind state to PLAYING\n");
|
||||
gst_element_set_state(autoplugger->cache,GST_STATE_PLAYING);
|
||||
|
||||
// try to PLAY the whole thing
|
||||
gst_element_set_state(GST_ELEMENT_SCHED(autoplugger)->parent,GST_STATE_PLAYING);
|
||||
|
||||
GST_INFO(GST_CAT_AUTOPLUG,"here we go into nothingness, hoping the typefind will return us to safety");
|
||||
gst_schedule_show(GST_ELEMENT_SCHED(autoplugger));
|
||||
} else {
|
||||
GST_INFO(GST_CAT_AUTOPLUG, "caps are set, nothing happening here, move along");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -108,7 +108,7 @@ cothread_create (cothread_context *ctx)
|
|||
|
||||
GST_DEBUG (0,"pthread_self() %ld\n",pthread_self());
|
||||
//if (0) {
|
||||
if (pthread_self() == 0) {
|
||||
if (pthread_self() == 0) { // FIXME uh, what does this test really do?
|
||||
s = (cothread_state *)malloc(sizeof(int) * COTHREAD_STACKSIZE);
|
||||
GST_DEBUG (0,"new stack (case 1) at %p\n",s);
|
||||
} else {
|
||||
|
|
|
@ -47,6 +47,8 @@ extern GstElementDetails gst_bin_details;
|
|||
typedef enum {
|
||||
/* this bin is a manager of child elements, i.e. a pipeline or thread */
|
||||
GST_BIN_FLAG_MANAGER = GST_ELEMENT_FLAG_LAST,
|
||||
/* this bin is actually a meta-bin, and may need to be scheduled */
|
||||
GST_BIN_SELF_SCHEDULABLE,
|
||||
|
||||
/* we prefer to have cothreads when its an option, over chain-based */
|
||||
GST_BIN_FLAG_PREFER_COTHREADS,
|
||||
|
|
|
@ -857,14 +857,16 @@ gst_element_change_state (GstElement *element)
|
|||
|
||||
if ((GST_STATE_TRANSITION(element) == GST_STATE_READY_TO_PLAYING) ||
|
||||
(GST_STATE_TRANSITION(element) == GST_STATE_PAUSED_TO_PLAYING)) {
|
||||
g_return_val_if_fail(GST_ELEMENT_SCHED(element), GST_STATE_FAILURE);
|
||||
if (GST_ELEMENT_PARENT(element))
|
||||
fprintf(stderr,"READY->PLAYING: element \"%s\" has parent \"%s\" and sched %p\n",
|
||||
fprintf(stderr,"PAUSED->PLAYING: element \"%s\" has parent \"%s\" and sched %p\n",
|
||||
GST_ELEMENT_NAME(element),GST_ELEMENT_NAME(GST_ELEMENT_PARENT(element)),GST_ELEMENT_SCHED(element));
|
||||
GST_SCHEDULE_ENABLE_ELEMENT (element->sched,element);
|
||||
}
|
||||
else if ((GST_STATE_TRANSITION(element) == GST_STATE_PLAYING_TO_READY) ||
|
||||
(GST_STATE_TRANSITION(element) == GST_STATE_PLAYING_TO_READY))
|
||||
(GST_STATE_TRANSITION(element) == GST_STATE_PLAYING_TO_PAUSED)) {
|
||||
GST_SCHEDULE_DISABLE_ELEMENT (element->sched,element);
|
||||
}
|
||||
|
||||
GST_STATE (element) = GST_STATE_PENDING (element);
|
||||
GST_STATE_PENDING (element) = GST_STATE_NONE_PENDING;
|
||||
|
@ -876,7 +878,7 @@ GST_ELEMENT_NAME(element),GST_ELEMENT_NAME(GST_ELEMENT_PARENT(element)),GST_ELEM
|
|||
// unlocks, then emits this.
|
||||
gtk_signal_emit (GTK_OBJECT (element), gst_element_signals[STATE_CHANGE],
|
||||
GST_STATE (element));
|
||||
return TRUE;
|
||||
return GST_STATE_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -158,7 +158,8 @@ gst_object_ref (GstObject *object)
|
|||
{
|
||||
g_return_val_if_fail (GST_IS_OBJECT (object), NULL);
|
||||
|
||||
GST_DEBUG (GST_CAT_REFCOUNTING, "ref\n");
|
||||
GST_DEBUG (GST_CAT_REFCOUNTING, "ref '%s' %d->%d\n",GST_OBJECT_NAME(object),
|
||||
GTK_OBJECT(object)->ref_count,GTK_OBJECT(object)->ref_count+1);
|
||||
|
||||
gtk_object_ref (GTK_OBJECT (object));
|
||||
|
||||
|
@ -178,7 +179,8 @@ gst_object_unref (GstObject *object)
|
|||
{
|
||||
g_return_if_fail (GST_IS_OBJECT (object));
|
||||
|
||||
GST_DEBUG (GST_CAT_REFCOUNTING, "unref\n");
|
||||
GST_DEBUG (GST_CAT_REFCOUNTING, "unref '%s' %d->%d\n",GST_OBJECT_NAME(object),
|
||||
GTK_OBJECT(object)->ref_count,GTK_OBJECT(object)->ref_count-1);
|
||||
|
||||
gtk_object_unref (GTK_OBJECT (object));
|
||||
}
|
||||
|
@ -198,7 +200,7 @@ gst_object_sink (GstObject *object)
|
|||
g_return_if_fail (object != NULL);
|
||||
g_return_if_fail (GST_IS_OBJECT (object));
|
||||
|
||||
GST_DEBUG (GST_CAT_REFCOUNTING, "sink\n");
|
||||
GST_DEBUG (GST_CAT_REFCOUNTING, "sink '%s'\n",GST_OBJECT_NAME(object));
|
||||
if (GST_OBJECT_FLOATING (object))
|
||||
{
|
||||
GST_FLAG_UNSET (object, GST_FLOATING);
|
||||
|
@ -212,7 +214,7 @@ gst_object_destroy (GstObject *object)
|
|||
g_return_if_fail (object != NULL);
|
||||
g_return_if_fail (GST_IS_OBJECT (object));
|
||||
|
||||
GST_DEBUG (GST_CAT_REFCOUNTING, "destroy\n");
|
||||
GST_DEBUG (GST_CAT_REFCOUNTING, "destroy '%s'\n",GST_OBJECT_NAME(object));
|
||||
if (!GST_OBJECT_DESTROYED (object))
|
||||
{
|
||||
/* need to hold a reference count around all class method
|
||||
|
@ -227,7 +229,7 @@ gst_object_destroy (GstObject *object)
|
|||
static void
|
||||
gst_object_shutdown (GtkObject *object)
|
||||
{
|
||||
GST_DEBUG (GST_CAT_REFCOUNTING, "shutdown\n");
|
||||
GST_DEBUG (GST_CAT_REFCOUNTING, "shutdown '%s'\n",GST_OBJECT_NAME(object));
|
||||
GST_FLAG_SET (GST_OBJECT (object), GST_DESTROYED);
|
||||
parent_class->shutdown (GTK_OBJECT (object));
|
||||
}
|
||||
|
@ -236,7 +238,7 @@ gst_object_shutdown (GtkObject *object)
|
|||
static void
|
||||
gst_object_real_destroy (GtkObject *gtk_object)
|
||||
{
|
||||
GST_DEBUG (GST_CAT_REFCOUNTING, "destroy\n");
|
||||
GST_DEBUG (GST_CAT_REFCOUNTING, "destroy '%s'\n",GST_OBJECT_NAME(gtk_object));
|
||||
|
||||
GST_OBJECT_PARENT (gtk_object) = NULL;
|
||||
|
||||
|
@ -251,7 +253,7 @@ gst_object_finalize (GtkObject *gtk_object)
|
|||
|
||||
object = GST_OBJECT (gtk_object);
|
||||
|
||||
GST_DEBUG (GST_CAT_REFCOUNTING, "finalize\n");
|
||||
GST_DEBUG (GST_CAT_REFCOUNTING, "finalize '%s'\n",GST_OBJECT_NAME(object));
|
||||
if (object->name != NULL)
|
||||
g_free (object->name);
|
||||
|
||||
|
|
34
gst/gstpad.c
34
gst/gstpad.c
|
@ -79,6 +79,7 @@ gst_pad_init (GstPad *pad)
|
|||
enum {
|
||||
REAL_SET_ACTIVE,
|
||||
REAL_CAPS_CHANGED,
|
||||
REAL_CAPS_NEGO_FAILED,
|
||||
REAL_CONNECTED,
|
||||
REAL_DISCONNECTED,
|
||||
/* FILL ME */
|
||||
|
@ -147,6 +148,10 @@ gst_real_pad_class_init (GstRealPadClass *klass)
|
|||
GTK_SIGNAL_OFFSET (GstRealPadClass, caps_changed),
|
||||
gtk_marshal_NONE__POINTER, GTK_TYPE_NONE, 1,
|
||||
GTK_TYPE_POINTER);
|
||||
gst_real_pad_signals[REAL_CAPS_NEGO_FAILED] =
|
||||
gtk_signal_new ("caps_nego_failed", GTK_RUN_LAST, gtkobject_class->type,
|
||||
GTK_SIGNAL_OFFSET (GstRealPadClass, caps_nego_failed),
|
||||
gtk_marshal_NONE__NONE, GTK_TYPE_NONE, 0);
|
||||
gst_real_pad_signals[REAL_CONNECTED] =
|
||||
gtk_signal_new ("connected", GTK_RUN_LAST, gtkobject_class->type,
|
||||
GTK_SIGNAL_OFFSET (GstRealPadClass, connected),
|
||||
|
@ -633,18 +638,6 @@ gst_pad_connect (GstPad *srcpad,
|
|||
GST_RPAD_PEER(realsrc) = realsink;
|
||||
GST_RPAD_PEER(realsink) = realsrc;
|
||||
|
||||
/* FIXME: set connected flag */
|
||||
|
||||
/* fire off a signal to each of the pads telling them that they've been connected */
|
||||
gtk_signal_emit(GTK_OBJECT(realsrc), gst_real_pad_signals[REAL_CONNECTED], realsink);
|
||||
gtk_signal_emit(GTK_OBJECT(realsink), gst_real_pad_signals[REAL_CONNECTED], realsrc);
|
||||
|
||||
// now tell the scheduler(s)
|
||||
if (realsrc->sched)
|
||||
GST_SCHEDULE_PAD_CONNECT (realsrc->sched, (GstPad *)realsrc, (GstPad *)realsink);
|
||||
else if (realsink->sched)
|
||||
GST_SCHEDULE_PAD_CONNECT (realsink->sched, (GstPad *)realsrc, (GstPad *)realsink);
|
||||
|
||||
if (GST_PAD_CAPS (srcpad)) {
|
||||
negotiated = gst_pad_renegotiate (srcpad);
|
||||
}
|
||||
|
@ -661,6 +654,16 @@ gst_pad_connect (GstPad *srcpad,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
/* fire off a signal to each of the pads telling them that they've been connected */
|
||||
gtk_signal_emit(GTK_OBJECT(realsrc), gst_real_pad_signals[REAL_CONNECTED], realsink);
|
||||
gtk_signal_emit(GTK_OBJECT(realsink), gst_real_pad_signals[REAL_CONNECTED], realsrc);
|
||||
|
||||
// now tell the scheduler(s)
|
||||
if (realsrc->sched)
|
||||
GST_SCHEDULE_PAD_CONNECT (realsrc->sched, (GstPad *)realsrc, (GstPad *)realsink);
|
||||
else if (realsink->sched)
|
||||
GST_SCHEDULE_PAD_CONNECT (realsink->sched, (GstPad *)realsrc, (GstPad *)realsink);
|
||||
|
||||
GST_INFO (GST_CAT_ELEMENT_PADS, "connected %s:%s and %s:%s",
|
||||
GST_DEBUG_PAD_NAME(srcpad), GST_DEBUG_PAD_NAME(sinkpad));
|
||||
return TRUE;
|
||||
|
@ -1272,6 +1275,13 @@ gst_pad_renegotiate (GstPad *pad)
|
|||
gst_real_pad_signals[REAL_CAPS_CHANGED],GST_PAD_CAPS(currentpad));
|
||||
gtk_signal_emit (GTK_OBJECT(otherpad),
|
||||
gst_real_pad_signals[REAL_CAPS_CHANGED],GST_PAD_CAPS(otherpad));
|
||||
} else {
|
||||
GST_DEBUG (GST_CAT_NEGOTIATION, "firing caps_nego_failed signal on %s:%s and %s:%s\n",
|
||||
GST_DEBUG_PAD_NAME(currentpad),GST_DEBUG_PAD_NAME(otherpad));
|
||||
gtk_signal_emit (GTK_OBJECT(currentpad),
|
||||
gst_real_pad_signals[REAL_CAPS_NEGO_FAILED]);
|
||||
gtk_signal_emit (GTK_OBJECT(otherpad),
|
||||
gst_real_pad_signals[REAL_CAPS_NEGO_FAILED]);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
|
11
gst/gstpad.h
11
gst/gstpad.h
|
@ -165,12 +165,13 @@ struct _GstRealPadClass {
|
|||
GstPadClass parent_class;
|
||||
|
||||
/* signal callbacks */
|
||||
void (*set_active) (GstPad *pad, gboolean active);
|
||||
void (*caps_changed) (GstPad *pad, GstCaps *newcaps);
|
||||
void (*connected) (GstPad *pad, GstPad *peer);
|
||||
void (*disconnected) (GstPad *pad, GstPad *peer);
|
||||
void (*set_active) (GstPad *pad, gboolean active);
|
||||
void (*caps_changed) (GstPad *pad, GstCaps *newcaps);
|
||||
void (*caps_nego_failed) (GstPad *pad);
|
||||
void (*connected) (GstPad *pad, GstPad *peer);
|
||||
void (*disconnected) (GstPad *pad, GstPad *peer);
|
||||
|
||||
void (*eos) (GstPad *pad);
|
||||
void (*eos) (GstPad *pad);
|
||||
};
|
||||
|
||||
struct _GstGhostPad {
|
||||
|
|
|
@ -1186,7 +1186,8 @@ gst_schedule_add_element (GstSchedule *sched, GstElement *element)
|
|||
GST_ELEMENT_SCHED(element) = sched;
|
||||
|
||||
// only deal with elements after this point, not bins
|
||||
if (GST_IS_BIN (element)) return;
|
||||
// exception is made for Bin's that are schedulable, like the autoplugger
|
||||
if (GST_IS_BIN (element) && !GST_FLAG_IS_SET(element, GST_BIN_SELF_SCHEDULABLE)) return;
|
||||
|
||||
// first add it to the list of elements that are to be scheduled
|
||||
sched->elements = g_list_prepend (sched->elements, element);
|
||||
|
|
|
@ -183,8 +183,17 @@ gst_typefind_chain (GstPad *pad, GstBuffer *buf)
|
|||
GST_DEBUG (0,"found type :%d \"%s\" \"%s\"\n", caps->id, type->mime,
|
||||
gst_caps_get_name (caps));
|
||||
typefind->caps = caps;
|
||||
|
||||
{
|
||||
int oldstate = GST_STATE(typefind);
|
||||
gtk_signal_emit (GTK_OBJECT (typefind), gst_typefind_signals[HAVE_TYPE],
|
||||
typefind->caps);
|
||||
if (GST_STATE(typefind) != oldstate) {
|
||||
GST_DEBUG(0, "state changed during signal, aborting\n");
|
||||
cothread_switch(cothread_current_main());
|
||||
}
|
||||
}
|
||||
|
||||
gst_pad_set_caps (pad, caps);
|
||||
goto end;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue