Added a quick hack to allow loop based elements to finish intead of looping till infinity.

Original commit message from CVS:
Added a quick hack to allow loop based elements to finish intead of
looping till infinity.
Added compile time i386 or plain C getbits implementation selection.
The vorbis decoder now is our first loop based element!
This commit is contained in:
Wim Taymans 2000-09-16 10:58:23 +00:00
parent 11e8ef9074
commit ff99ee6132
11 changed files with 68 additions and 59 deletions

View file

@ -28,3 +28,5 @@ gst_fdsink_get_type
gst_pipefilter_get_type
gst_identity_get_type
gst_queue_get_type

View file

@ -8,19 +8,21 @@
#include <unistd.h>
#include <sys/mman.h>
//#define DEBUG_ENABLED
#include "gst/gst.h"
#include "cothreads.h"
#include "gstarch.h"
#include "gst/gstarch.h"
pthread_key_t _cothread_key = -1;
cothread_state *cothread_create(cothread_context *ctx) {
cothread_state *s;
printf("pthread_self() %ld\n",pthread_self());
DEBUG("cothread: pthread_self() %ld\n",pthread_self());
//if (pthread_self() == 0) {
if (0) {
s = (cothread_state *)malloc(sizeof(int) * COTHREAD_STACKSIZE);
printf("new stack at %p\n",s);
DEBUG("cothread: new stack at %p\n",s);
} else {
char *sp = CURRENT_STACK_FRAME;
unsigned long *stack_end = (unsigned long *)((unsigned long)sp &
@ -42,7 +44,7 @@ cothread_state *cothread_create(cothread_context *ctx) {
ctx->threads[ctx->nthreads++] = s;
printf("created cothread at %p %p\n",s, s->sp);
DEBUG("cothread: created cothread at %p %p\n",s, s->sp);
return s;
}
@ -77,7 +79,7 @@ cothread_context *cothread_init() {
ctx->threads[0]->sp = (int *)CURRENT_STACK_FRAME;
ctx->threads[0]->pc = 0;
fprintf(stderr,"0th thread is at %p %p\n",ctx->threads[0], ctx->threads[0]->sp);
DEBUG("cothread: 0th thread is at %p %p\n",ctx->threads[0], ctx->threads[0]->sp);
// we consider the initiating process to be cothread 0
ctx->nthreads = 1;
@ -95,19 +97,20 @@ void cothread_stub() {
cothread_context *ctx = pthread_getspecific(_cothread_key);
register cothread_state *thread = ctx->threads[ctx->current];
printf("cothread_stub() entered\n");
DEBUG("cothread: cothread_stub() entered\n");
thread->flags |= COTHREAD_STARTED;
if (thread->func)
thread->func(thread->argc,thread->argv);
thread->flags &= ~COTHREAD_STARTED;
thread->pc = 0;
DEBUG("cothread: cothread_stub() exit\n");
//printf("uh, yeah, we shouldn't be here, but we should deal anyway\n");
}
void cothread_switch(cothread_state *thread) {
cothread_context *ctx;
cothread_state *current;
int enter = 0;
int enter;
// int i;
if (thread == NULL)
@ -117,36 +120,40 @@ void cothread_switch(cothread_state *thread) {
current = ctx->threads[ctx->current];
if (current == NULL) {
fprintf(stderr,"there's no current thread, help!\n");
g_print("cothread: there's no current thread, help!\n");
exit(2);
}
if (current == thread) {
fprintf(stderr,"trying to switch to same thread, legal but not necessary\n");
g_print("cothread: trying to switch to same thread, legal but not necessary\n");
return;
}
// find the number of the thread to switch to
ctx->current = thread->threadnum;
fprintf(stderr,"about to switch to thread #%d\n",ctx->current);
DEBUG("cothread: about to switch to thread #%d\n",ctx->current);
/* save the current stack pointer, frame pointer, and pc */
GET_SP(current->sp);
enter = setjmp(current->jmp);
if (enter != 0)
DEBUG("cothread: after thread #%d %d\n",ctx->current, enter);
if (enter != 0) {
return;
}
enter = 1;
fprintf(stderr,"set stack to %p\n", thread->sp);
DEBUG("cothread: set stack to %p\n", thread->sp);
/* restore stack pointer and other stuff of new cothread */
if (thread->flags & COTHREAD_STARTED) {
fprintf(stderr,"in thread \n");
DEBUG("cothread: in thread \n");
SET_SP(thread->sp);
// switch to it
longjmp(thread->jmp,1);
} else {
SET_SP(thread->sp);
DEBUG("cothread: exit thread \n");
SET_SP(thread->sp);
// start it
JUMP(cothread_stub);
//JUMP(cothread_stub);
cothread_stub();
}
}

View file

@ -55,6 +55,8 @@ static void gst_disksrc_init(GstDiskSrc *disksrc);
static void gst_disksrc_set_arg(GtkObject *object,GtkArg *arg,guint id);
static void gst_disksrc_get_arg(GtkObject *object,GtkArg *arg,guint id);
static void gst_disksrc_close_file(GstDiskSrc *src);
static void gst_disksrc_push(GstSrc *src);
//static void gst_disksrc_push_region(GstSrc *src,gulong offset,gulong size);
static GstElementStateReturn gst_disksrc_change_state(GstElement *element);
@ -219,6 +221,8 @@ void gst_disksrc_push(GstSrc *src) {
else if (readbytes == 0) {
gst_src_signal_eos(GST_SRC(disksrc));
gst_buffer_unref(buf);
gst_disksrc_close_file(disksrc);
GST_STATE(src) = GST_STATE_NULL;
return;
}

View file

@ -55,7 +55,6 @@ static void gst_queue_class_init(GstQueueClass *klass);
static void gst_queue_init(GstQueue *queue);
static void gst_queue_set_arg(GtkObject *object,GtkArg *arg,guint id);
static void gst_queue_get_arg(GtkObject *object,GtkArg *arg,guint id);
static GstBuffer *gst_queue_pull(GstPad *pad);
void gst_queue_push(GstConnection *connection);
void gst_queue_chain(GstPad *pad,GstBuffer *buf);
@ -107,7 +106,6 @@ static void gst_queue_init(GstQueue *queue) {
queue->sinkpad = gst_pad_new("sink",GST_PAD_SINK);
gst_element_add_pad(GST_ELEMENT(queue),queue->sinkpad);
gst_pad_set_chain_function(queue->sinkpad,gst_queue_chain);
gst_pad_set_pull_function(queue->sinkpad,gst_queue_pull);
queue->srcpad = gst_pad_new("src",GST_PAD_SRC);
gst_element_add_pad(GST_ELEMENT(queue),queue->srcpad);
@ -132,18 +130,6 @@ GstElement *gst_queue_new(gchar *name) {
return queue;
}
static GstBuffer *gst_queue_pull(GstPad *pad) {
GstQueue *queue;
GstBuffer *buf;
queue = GST_QUEUE(pad->parent);
if (GST_PAD_CAN_PULL(queue->srcpad) && (buf = gst_pad_pull(queue->srcpad)) != NULL) {
return buf;
}
else return NULL;
}
static void gst_queue_cleanup_buffers(gpointer data, gpointer user_data)
{
DEBUG("queue: %s cleaning buffer %p\n", (gchar *)user_data, data);

View file

@ -432,15 +432,17 @@ static int gst_bin_loopfunc_wrapper(int argc,char *argv[]) {
// 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) {
DEBUG("** gst_bin_loopfunc_wrapper(): element has loop function, calling it\n");
(element->loopfunc)(element);
DEBUG("** gst_bin_loopfunc_wrapper(): element ended loop function\n");
}
} else {
// g_print("** gst_bin_loopfunc_wrapper(): element is chain-based, calling in infinite loop\n");
DEBUG("** 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");
//while (1) {
while (GST_STATE(element) != GST_STATE_NULL) {
DEBUG("** gst_bin_loopfunc_wrapper(): calling push function of source\n");
gst_src_push(GST_SRC(element));
}
} else {
@ -449,9 +451,9 @@ static int gst_bin_loopfunc_wrapper(int argc,char *argv[]) {
while (pads) {
pad = GST_PAD(pads->data);
if (pad->direction == GST_PAD_SINK) {
// g_print("** gst_bin_loopfunc_wrapper(): pulling a buffer\n");
DEBUG("** gst_bin_loopfunc_wrapper(): pulling a buffer\n");
buf = gst_pad_pull(pad);
// g_print("** gst_bin_loopfunc_wrapper(): calling chain function\n");
DEBUG("** gst_bin_loopfunc_wrapper(): calling chain function\n");
(pad->chainfunc)(pad,buf);
}
pads = g_list_next(pads);
@ -459,18 +461,23 @@ static int gst_bin_loopfunc_wrapper(int argc,char *argv[]) {
}
}
}
return 0;
}
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)));
DEBUG("** in gst_bin_pullfunc_wrapper()============================= %s\n",
gst_element_get_name(GST_ELEMENT(pad->parent)));
cothread_switch(GST_ELEMENT(pad->parent)->threadstate);
DEBUG("** out gst_bin_pullfunc_wrapper()============================= %s\n",
gst_element_get_name(GST_ELEMENT(pad->parent)));
}
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)));
DEBUG("** in gst_bin_pushfunc_wrapper()============================= %s\n",
gst_element_get_name(GST_ELEMENT(pad->parent)));
cothread_switch(GST_ELEMENT(pad->parent)->threadstate);
DEBUG("** out gst_bin_pushfunc_wrapper()============================= %s\n",
gst_element_get_name(GST_ELEMENT(pad->parent)));
}
static void gst_bin_create_plan_func(GstBin *bin) {
@ -491,13 +498,13 @@ static void gst_bin_create_plan_func(GstBin *bin) {
g_print("gstbin: found element \"%s\" in bin \"%s\"\n", gst_element_get_name(element), gst_element_get_name(GST_ELEMENT(bin)));
// if it's a loop-based element, use cothreads
if (element->loopfunc != NULL) {
g_print("gstbin: loop based elenemt \"%s\" in bin \"%s\"\n", gst_element_get_name(element), gst_element_get_name(GST_ELEMENT(bin)));
g_print("gstbin: loop based element \"%s\" in bin \"%s\"\n", gst_element_get_name(element), gst_element_get_name(GST_ELEMENT(bin)));
bin->need_cothreads = TRUE;
break;
}
// if it's a complex element, use cothreads
if (GST_ELEMENT_IS_MULTI_IN(element)) {
g_print("gstbin: complex elenemt \"%s\" in bin \"%s\"\n", gst_element_get_name(element), gst_element_get_name(GST_ELEMENT(bin)));
g_print("gstbin: complex element \"%s\" in bin \"%s\"\n", gst_element_get_name(element), gst_element_get_name(GST_ELEMENT(bin)));
bin->need_cothreads = TRUE;
break;
}
@ -511,7 +518,7 @@ static void gst_bin_create_plan_func(GstBin *bin) {
pads = g_list_next(pads);
}
if (sink_pads > 1) {
g_print("gstbin: more than 1 sinkpad for elenemt \"%s\" in bin \"%s\"\n", gst_element_get_name(element), gst_element_get_name(GST_ELEMENT(bin)));
g_print("gstbin: more than 1 sinkpad for element \"%s\" in bin \"%s\"\n", gst_element_get_name(element), gst_element_get_name(GST_ELEMENT(bin)));
bin->need_cothreads = TRUE;
break;
}

View file

@ -23,7 +23,7 @@
static guint32 _gst_cpu_flags;
#ifdef __i386__
#ifdef HAVE_CPU_I386
void gst_cpuid_i386(int,long *,long *,long *,long *);
#define gst_cpuid gst_cpuid_i386

View file

@ -160,7 +160,7 @@ void gst_pad_set_pull_function(GstPad *pad,GstPadPullFunction pull) {
g_return_if_fail(pad != NULL);
g_return_if_fail(GST_IS_PAD(pad));
fprintf(stderr, "pad setting pull function\n");
g_print("gstpad: pad setting pull function\n");
pad->pullfunc = pull;
}

View file

@ -322,7 +322,7 @@ static GList *construct_path (gst_type_node *rgnNodes, gint chNode)
GstType *type;
GList *converters;
g_print("gsttype: constructed pad ");
g_print("gsttype: constructed mime path ");
while (current != MAX_COST)
{
type = gst_type_find_by_id(current);

View file

@ -293,6 +293,7 @@ void gst_getbits_init(gst_getbits_t *gb, GstGetbitsCallback callback, void *data
gb->backbits = _gst_getbits_back_int;
}
else {
#ifdef HAVE_CPU_I386
gb->get1bit = _gst_get1bit_i386;
gb->getbits = _gst_getbits_i386;
gb->getbits_fast = _gst_getbits_fast_i386;
@ -301,6 +302,18 @@ void gst_getbits_init(gst_getbits_t *gb, GstGetbitsCallback callback, void *data
gb->showbits = _gst_showbits_i386;
gb->flushbits = _gst_flushbits_i386;
gb->backbits = _gst_getbits_back_i386;
printf("gstgetbits: using intel optimized versions\n");
#else
gb->get1bit = _gst_get1bit_int;
gb->getbits = _gst_getbits_int;
gb->getbits_fast = _gst_getbits_fast_int;
gb->getbyte = _gst_getbyte;
gb->show1bit = _gst_showbits_int;
gb->showbits = _gst_showbits_int;
gb->flushbits = _gst_flushbits_int;
gb->backbits = _gst_getbits_back_int;
printf("gstgetbits: using normal versions\n");
#endif
}
}
}

View file

@ -55,6 +55,8 @@ static void gst_disksrc_init(GstDiskSrc *disksrc);
static void gst_disksrc_set_arg(GtkObject *object,GtkArg *arg,guint id);
static void gst_disksrc_get_arg(GtkObject *object,GtkArg *arg,guint id);
static void gst_disksrc_close_file(GstDiskSrc *src);
static void gst_disksrc_push(GstSrc *src);
//static void gst_disksrc_push_region(GstSrc *src,gulong offset,gulong size);
static GstElementStateReturn gst_disksrc_change_state(GstElement *element);
@ -219,6 +221,8 @@ void gst_disksrc_push(GstSrc *src) {
else if (readbytes == 0) {
gst_src_signal_eos(GST_SRC(disksrc));
gst_buffer_unref(buf);
gst_disksrc_close_file(disksrc);
GST_STATE(src) = GST_STATE_NULL;
return;
}

View file

@ -55,7 +55,6 @@ static void gst_queue_class_init(GstQueueClass *klass);
static void gst_queue_init(GstQueue *queue);
static void gst_queue_set_arg(GtkObject *object,GtkArg *arg,guint id);
static void gst_queue_get_arg(GtkObject *object,GtkArg *arg,guint id);
static GstBuffer *gst_queue_pull(GstPad *pad);
void gst_queue_push(GstConnection *connection);
void gst_queue_chain(GstPad *pad,GstBuffer *buf);
@ -107,7 +106,6 @@ static void gst_queue_init(GstQueue *queue) {
queue->sinkpad = gst_pad_new("sink",GST_PAD_SINK);
gst_element_add_pad(GST_ELEMENT(queue),queue->sinkpad);
gst_pad_set_chain_function(queue->sinkpad,gst_queue_chain);
gst_pad_set_pull_function(queue->sinkpad,gst_queue_pull);
queue->srcpad = gst_pad_new("src",GST_PAD_SRC);
gst_element_add_pad(GST_ELEMENT(queue),queue->srcpad);
@ -132,18 +130,6 @@ GstElement *gst_queue_new(gchar *name) {
return queue;
}
static GstBuffer *gst_queue_pull(GstPad *pad) {
GstQueue *queue;
GstBuffer *buf;
queue = GST_QUEUE(pad->parent);
if (GST_PAD_CAN_PULL(queue->srcpad) && (buf = gst_pad_pull(queue->srcpad)) != NULL) {
return buf;
}
else return NULL;
}
static void gst_queue_cleanup_buffers(gpointer data, gpointer user_data)
{
DEBUG("queue: %s cleaning buffer %p\n", (gchar *)user_data, data);