mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-06-05 06:58:56 +00:00
Rearranged cothreads sources a bit, added some API docs.
Original commit message from CVS: Rearranged cothreads sources a bit, added some API docs. Added some functions needed for gstreamer-inspect. Added num_sources to fakesink.
This commit is contained in:
parent
e318439f64
commit
759d83e487
9 changed files with 208 additions and 70 deletions
|
@ -42,6 +42,50 @@ pthread_key_t _cothread_key = -1;
|
|||
* cothread_switch. This likely will speed things up fractionally */
|
||||
#define COTHREAD_PARANOID
|
||||
|
||||
/**
|
||||
* cothread_init:
|
||||
*
|
||||
* create and initialize a new cotread context
|
||||
*
|
||||
* Returns: the new cothread context
|
||||
*/
|
||||
cothread_context*
|
||||
cothread_init (void)
|
||||
{
|
||||
cothread_context *ctx = (cothread_context *)malloc(sizeof(cothread_context));
|
||||
|
||||
GST_INFO (GST_CAT_COTHREADS,"initializing cothreads");
|
||||
|
||||
if (_cothread_key == -1) {
|
||||
if (pthread_key_create (&_cothread_key,NULL) != 0) {
|
||||
perror ("pthread_key_create");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
pthread_setspecific (_cothread_key,ctx);
|
||||
|
||||
memset (ctx->threads,0,sizeof(ctx->threads));
|
||||
|
||||
ctx->threads[0] = (cothread_state *)malloc(sizeof(cothread_state));
|
||||
ctx->threads[0]->ctx = ctx;
|
||||
ctx->threads[0]->threadnum = 0;
|
||||
ctx->threads[0]->func = NULL;
|
||||
ctx->threads[0]->argc = 0;
|
||||
ctx->threads[0]->argv = NULL;
|
||||
ctx->threads[0]->flags = COTHREAD_STARTED;
|
||||
ctx->threads[0]->sp = (int *)CURRENT_STACK_FRAME;
|
||||
ctx->threads[0]->pc = 0;
|
||||
|
||||
GST_INFO (GST_CAT_COTHREADS,"0th thread is %p at sp:%p",ctx->threads[0], ctx->threads[0]->sp);
|
||||
|
||||
// we consider the initiating process to be cothread 0
|
||||
ctx->nthreads = 1;
|
||||
ctx->current = 0;
|
||||
ctx->data = g_hash_table_new(g_str_hash, g_str_equal);
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
/**
|
||||
* cothread_create:
|
||||
* @ctx: the cothread context
|
||||
|
@ -109,64 +153,14 @@ cothread_setfunc (cothread_state *thread,
|
|||
thread->pc = (int *)func;
|
||||
}
|
||||
|
||||
/**
|
||||
* cothread_init:
|
||||
*
|
||||
* create and initialize a new cotread context
|
||||
*
|
||||
* Returns: the new cothread context
|
||||
*/
|
||||
cothread_context*
|
||||
cothread_init (void)
|
||||
{
|
||||
cothread_context *ctx = (cothread_context *)malloc(sizeof(cothread_context));
|
||||
|
||||
GST_INFO (GST_CAT_COTHREADS,"initializing cothreads");
|
||||
|
||||
if (_cothread_key == -1) {
|
||||
if (pthread_key_create (&_cothread_key,NULL) != 0) {
|
||||
perror ("pthread_key_create");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
pthread_setspecific (_cothread_key,ctx);
|
||||
|
||||
memset (ctx->threads,0,sizeof(ctx->threads));
|
||||
|
||||
ctx->threads[0] = (cothread_state *)malloc(sizeof(cothread_state));
|
||||
ctx->threads[0]->ctx = ctx;
|
||||
ctx->threads[0]->threadnum = 0;
|
||||
ctx->threads[0]->func = NULL;
|
||||
ctx->threads[0]->argc = 0;
|
||||
ctx->threads[0]->argv = NULL;
|
||||
ctx->threads[0]->flags = COTHREAD_STARTED;
|
||||
ctx->threads[0]->sp = (int *)CURRENT_STACK_FRAME;
|
||||
ctx->threads[0]->pc = 0;
|
||||
|
||||
GST_INFO (GST_CAT_COTHREADS,"0th thread is %p at sp:%p",ctx->threads[0], ctx->threads[0]->sp);
|
||||
|
||||
// we consider the initiating process to be cothread 0
|
||||
ctx->nthreads = 1;
|
||||
ctx->current = 0;
|
||||
ctx->data = g_hash_table_new(g_str_hash, g_str_equal);
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
/**
|
||||
* cothread_main:
|
||||
* @ctx: the cothread context
|
||||
*
|
||||
* Returns: the new cothread state
|
||||
*/
|
||||
cothread_state*
|
||||
static cothread_state*
|
||||
cothread_main(cothread_context *ctx)
|
||||
{
|
||||
GST_DEBUG (0,"returning %p, the 0th cothread\n",ctx->threads[0]);
|
||||
return ctx->threads[0];
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
cothread_stub (void)
|
||||
{
|
||||
cothread_context *ctx = pthread_getspecific(_cothread_key);
|
||||
|
|
|
@ -43,14 +43,17 @@ enum {
|
|||
|
||||
enum {
|
||||
ARG_0,
|
||||
/* FILL ME */
|
||||
ARG_NUM_SOURCES,
|
||||
};
|
||||
|
||||
|
||||
static void gst_fakesink_class_init(GstFakeSinkClass *klass);
|
||||
static void gst_fakesink_init(GstFakeSink *fakesink);
|
||||
static void gst_fakesink_class_init (GstFakeSinkClass *klass);
|
||||
static void gst_fakesink_init (GstFakeSink *fakesink);
|
||||
|
||||
static void gst_fakesink_chain(GstPad *pad,GstBuffer *buf);
|
||||
static void gst_fakesink_set_arg (GtkObject *object, GtkArg *arg, guint id);
|
||||
static void gst_fakesink_get_arg (GtkObject *object, GtkArg *arg, guint id);
|
||||
|
||||
static void gst_fakesink_chain (GstPad *pad,GstBuffer *buf);
|
||||
|
||||
static GstElementClass *parent_class = NULL;
|
||||
static guint gst_fakesink_signals[LAST_SIGNAL] = { 0 };
|
||||
|
@ -83,6 +86,11 @@ gst_fakesink_class_init (GstFakeSinkClass *klass)
|
|||
|
||||
gtkobject_class = (GtkObjectClass*)klass;
|
||||
|
||||
parent_class = gtk_type_class (GST_TYPE_ELEMENT);
|
||||
|
||||
gtk_object_add_arg_type ("GstFakeSink::num_sources", GTK_TYPE_INT,
|
||||
GTK_ARG_READWRITE, ARG_NUM_SOURCES);
|
||||
|
||||
gst_fakesink_signals[SIGNAL_HANDOFF] =
|
||||
gtk_signal_new ("handoff", GTK_RUN_LAST, gtkobject_class->type,
|
||||
GTK_SIGNAL_OFFSET (GstFakeSinkClass, handoff),
|
||||
|
@ -91,20 +99,70 @@ gst_fakesink_class_init (GstFakeSinkClass *klass)
|
|||
gtk_object_class_add_signals (gtkobject_class, gst_fakesink_signals,
|
||||
LAST_SIGNAL);
|
||||
|
||||
parent_class = gtk_type_class (GST_TYPE_ELEMENT);
|
||||
gtkobject_class->set_arg = gst_fakesink_set_arg;
|
||||
gtkobject_class->get_arg = gst_fakesink_get_arg;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_fakesink_init (GstFakeSink *fakesink)
|
||||
{
|
||||
fakesink->sinkpad = gst_pad_new ("sink", GST_PAD_SINK);
|
||||
gst_element_add_pad (GST_ELEMENT (fakesink), fakesink->sinkpad);
|
||||
gst_pad_set_chain_function (fakesink->sinkpad, gst_fakesink_chain);
|
||||
GstPad *pad;
|
||||
pad = gst_pad_new ("sink", GST_PAD_SINK);
|
||||
gst_element_add_pad (GST_ELEMENT (fakesink), pad);
|
||||
gst_pad_set_chain_function (pad, gst_fakesink_chain);
|
||||
fakesink->sinkpads = g_slist_prepend (NULL, pad);
|
||||
fakesink->numsinkpads = 1;
|
||||
|
||||
// we're ready right away, since we don't have any args...
|
||||
// gst_element_set_state(GST_ELEMENT(fakesink),GST_STATE_READY);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_fakesink_set_arg (GtkObject *object, GtkArg *arg, guint id)
|
||||
{
|
||||
GstFakeSink *sink;
|
||||
gint new_numsinks;
|
||||
GstPad *pad;
|
||||
|
||||
/* it's not null if we got it, but it might not be ours */
|
||||
sink = GST_FAKESINK (object);
|
||||
|
||||
switch(id) {
|
||||
case ARG_NUM_SOURCES:
|
||||
new_numsinks = GTK_VALUE_INT (*arg);
|
||||
while (sink->numsinkpads < new_numsinks) {
|
||||
pad = gst_pad_new (g_strdup_printf ("sink%d", sink->numsinkpads), GST_PAD_SINK);
|
||||
gst_pad_set_chain_function (pad, gst_fakesink_chain);
|
||||
gst_element_add_pad (GST_ELEMENT (sink), pad);
|
||||
sink->sinkpads = g_slist_append (sink->sinkpads, pad);
|
||||
sink->numsinkpads++;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_fakesink_get_arg (GtkObject *object, GtkArg *arg, guint id)
|
||||
{
|
||||
GstFakeSink *sink;
|
||||
|
||||
/* it's not null if we got it, but it might not be ours */
|
||||
g_return_if_fail (GST_IS_FAKESINK (object));
|
||||
|
||||
sink = GST_FAKESINK (object);
|
||||
|
||||
switch (id) {
|
||||
case ARG_NUM_SOURCES:
|
||||
GTK_VALUE_INT (*arg) = sink->numsinkpads;
|
||||
break;
|
||||
default:
|
||||
arg->type = GTK_TYPE_INVALID;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_fakesink_chain:
|
||||
* @pad: the pad this faksink is connected to
|
||||
|
|
|
@ -54,7 +54,8 @@ typedef struct _GstFakeSinkClass GstFakeSinkClass;
|
|||
struct _GstFakeSink {
|
||||
GstElement element;
|
||||
|
||||
GstPad *sinkpad;
|
||||
GSList *sinkpads;
|
||||
gint numsinkpads;
|
||||
};
|
||||
|
||||
struct _GstFakeSinkClass {
|
||||
|
|
16
gst/gstpad.c
16
gst/gstpad.c
|
@ -1105,3 +1105,19 @@ gst_pad_set_eos(GstPad *pad)
|
|||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
GstPad *
|
||||
gst_pad_select(GstPad *nextpad, ...) {
|
||||
va_list args;
|
||||
GstPad *pad;
|
||||
GSList *pads = NULL;
|
||||
|
||||
// construct the list of pads
|
||||
va_start (args, nextpad);
|
||||
while ((pad = va_arg (args, GstPad*)))
|
||||
pads = g_slist_prepend (pads, pad);
|
||||
va_end (args);
|
||||
|
||||
// now switch to the nextpad
|
||||
*/
|
||||
|
|
|
@ -210,6 +210,8 @@ GstBuffer* gst_pad_pull_region (GstPad *pad, gulong offset, gulong size);
|
|||
(((pad)->peer->pullregionfunc) ? ((pad)->peer->pullregionfunc)((pad)->peer,(offset),(size)) : NULL)
|
||||
#endif
|
||||
|
||||
GstPad * gst_pad_select (GstPad *nextpad, ...);
|
||||
|
||||
#define gst_pad_eos(pad) ((pad)->peer->eosfunc((pad)->peer))
|
||||
gboolean gst_pad_set_eos (GstPad *pad);
|
||||
|
||||
|
|
|
@ -648,3 +648,10 @@ gst_plugin_load_thyself (xmlNodePtr parent)
|
|||
GST_INFO (GST_CAT_PLUGIN_LOADING,"added %d registered factories and %d types",elementcount,typecount);
|
||||
}
|
||||
|
||||
|
||||
GList*
|
||||
gst_plugin_get_factory_list (GstPlugin *plugin)
|
||||
{
|
||||
return plugin->elements;
|
||||
}
|
||||
|
||||
|
|
|
@ -62,6 +62,7 @@ gboolean gst_library_load (gchar *name);
|
|||
|
||||
void gst_plugin_add_factory (GstPlugin *plugin, GstElementFactory *factory);
|
||||
void gst_plugin_add_type (GstPlugin *plugin, GstTypeFactory *factory);
|
||||
GList* gst_plugin_get_factory_list (GstPlugin *plugin);
|
||||
|
||||
GstPlugin* gst_plugin_find (const gchar *name);
|
||||
GList* gst_plugin_get_list (void);
|
||||
|
|
|
@ -43,14 +43,17 @@ enum {
|
|||
|
||||
enum {
|
||||
ARG_0,
|
||||
/* FILL ME */
|
||||
ARG_NUM_SOURCES,
|
||||
};
|
||||
|
||||
|
||||
static void gst_fakesink_class_init(GstFakeSinkClass *klass);
|
||||
static void gst_fakesink_init(GstFakeSink *fakesink);
|
||||
static void gst_fakesink_class_init (GstFakeSinkClass *klass);
|
||||
static void gst_fakesink_init (GstFakeSink *fakesink);
|
||||
|
||||
static void gst_fakesink_chain(GstPad *pad,GstBuffer *buf);
|
||||
static void gst_fakesink_set_arg (GtkObject *object, GtkArg *arg, guint id);
|
||||
static void gst_fakesink_get_arg (GtkObject *object, GtkArg *arg, guint id);
|
||||
|
||||
static void gst_fakesink_chain (GstPad *pad,GstBuffer *buf);
|
||||
|
||||
static GstElementClass *parent_class = NULL;
|
||||
static guint gst_fakesink_signals[LAST_SIGNAL] = { 0 };
|
||||
|
@ -83,6 +86,11 @@ gst_fakesink_class_init (GstFakeSinkClass *klass)
|
|||
|
||||
gtkobject_class = (GtkObjectClass*)klass;
|
||||
|
||||
parent_class = gtk_type_class (GST_TYPE_ELEMENT);
|
||||
|
||||
gtk_object_add_arg_type ("GstFakeSink::num_sources", GTK_TYPE_INT,
|
||||
GTK_ARG_READWRITE, ARG_NUM_SOURCES);
|
||||
|
||||
gst_fakesink_signals[SIGNAL_HANDOFF] =
|
||||
gtk_signal_new ("handoff", GTK_RUN_LAST, gtkobject_class->type,
|
||||
GTK_SIGNAL_OFFSET (GstFakeSinkClass, handoff),
|
||||
|
@ -91,20 +99,70 @@ gst_fakesink_class_init (GstFakeSinkClass *klass)
|
|||
gtk_object_class_add_signals (gtkobject_class, gst_fakesink_signals,
|
||||
LAST_SIGNAL);
|
||||
|
||||
parent_class = gtk_type_class (GST_TYPE_ELEMENT);
|
||||
gtkobject_class->set_arg = gst_fakesink_set_arg;
|
||||
gtkobject_class->get_arg = gst_fakesink_get_arg;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_fakesink_init (GstFakeSink *fakesink)
|
||||
{
|
||||
fakesink->sinkpad = gst_pad_new ("sink", GST_PAD_SINK);
|
||||
gst_element_add_pad (GST_ELEMENT (fakesink), fakesink->sinkpad);
|
||||
gst_pad_set_chain_function (fakesink->sinkpad, gst_fakesink_chain);
|
||||
GstPad *pad;
|
||||
pad = gst_pad_new ("sink", GST_PAD_SINK);
|
||||
gst_element_add_pad (GST_ELEMENT (fakesink), pad);
|
||||
gst_pad_set_chain_function (pad, gst_fakesink_chain);
|
||||
fakesink->sinkpads = g_slist_prepend (NULL, pad);
|
||||
fakesink->numsinkpads = 1;
|
||||
|
||||
// we're ready right away, since we don't have any args...
|
||||
// gst_element_set_state(GST_ELEMENT(fakesink),GST_STATE_READY);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_fakesink_set_arg (GtkObject *object, GtkArg *arg, guint id)
|
||||
{
|
||||
GstFakeSink *sink;
|
||||
gint new_numsinks;
|
||||
GstPad *pad;
|
||||
|
||||
/* it's not null if we got it, but it might not be ours */
|
||||
sink = GST_FAKESINK (object);
|
||||
|
||||
switch(id) {
|
||||
case ARG_NUM_SOURCES:
|
||||
new_numsinks = GTK_VALUE_INT (*arg);
|
||||
while (sink->numsinkpads < new_numsinks) {
|
||||
pad = gst_pad_new (g_strdup_printf ("sink%d", sink->numsinkpads), GST_PAD_SINK);
|
||||
gst_pad_set_chain_function (pad, gst_fakesink_chain);
|
||||
gst_element_add_pad (GST_ELEMENT (sink), pad);
|
||||
sink->sinkpads = g_slist_append (sink->sinkpads, pad);
|
||||
sink->numsinkpads++;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_fakesink_get_arg (GtkObject *object, GtkArg *arg, guint id)
|
||||
{
|
||||
GstFakeSink *sink;
|
||||
|
||||
/* it's not null if we got it, but it might not be ours */
|
||||
g_return_if_fail (GST_IS_FAKESINK (object));
|
||||
|
||||
sink = GST_FAKESINK (object);
|
||||
|
||||
switch (id) {
|
||||
case ARG_NUM_SOURCES:
|
||||
GTK_VALUE_INT (*arg) = sink->numsinkpads;
|
||||
break;
|
||||
default:
|
||||
arg->type = GTK_TYPE_INVALID;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_fakesink_chain:
|
||||
* @pad: the pad this faksink is connected to
|
||||
|
|
|
@ -54,7 +54,8 @@ typedef struct _GstFakeSinkClass GstFakeSinkClass;
|
|||
struct _GstFakeSink {
|
||||
GstElement element;
|
||||
|
||||
GstPad *sinkpad;
|
||||
GSList *sinkpads;
|
||||
gint numsinkpads;
|
||||
};
|
||||
|
||||
struct _GstFakeSinkClass {
|
||||
|
|
Loading…
Reference in a new issue