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_pipefilter_get_type
gst_identity_get_type gst_identity_get_type
gst_queue_get_type gst_queue_get_type

View file

@ -8,19 +8,21 @@
#include <unistd.h> #include <unistd.h>
#include <sys/mman.h> #include <sys/mman.h>
//#define DEBUG_ENABLED
#include "gst/gst.h"
#include "cothreads.h" #include "cothreads.h"
#include "gstarch.h" #include "gst/gstarch.h"
pthread_key_t _cothread_key = -1; pthread_key_t _cothread_key = -1;
cothread_state *cothread_create(cothread_context *ctx) { cothread_state *cothread_create(cothread_context *ctx) {
cothread_state *s; cothread_state *s;
printf("pthread_self() %ld\n",pthread_self()); DEBUG("cothread: pthread_self() %ld\n",pthread_self());
//if (pthread_self() == 0) { //if (pthread_self() == 0) {
if (0) { if (0) {
s = (cothread_state *)malloc(sizeof(int) * COTHREAD_STACKSIZE); s = (cothread_state *)malloc(sizeof(int) * COTHREAD_STACKSIZE);
printf("new stack at %p\n",s); DEBUG("cothread: new stack at %p\n",s);
} else { } else {
char *sp = CURRENT_STACK_FRAME; char *sp = CURRENT_STACK_FRAME;
unsigned long *stack_end = (unsigned long *)((unsigned long)sp & 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; 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; return s;
} }
@ -77,7 +79,7 @@ cothread_context *cothread_init() {
ctx->threads[0]->sp = (int *)CURRENT_STACK_FRAME; ctx->threads[0]->sp = (int *)CURRENT_STACK_FRAME;
ctx->threads[0]->pc = 0; 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 // we consider the initiating process to be cothread 0
ctx->nthreads = 1; ctx->nthreads = 1;
@ -95,19 +97,20 @@ void cothread_stub() {
cothread_context *ctx = pthread_getspecific(_cothread_key); cothread_context *ctx = pthread_getspecific(_cothread_key);
register cothread_state *thread = ctx->threads[ctx->current]; register cothread_state *thread = ctx->threads[ctx->current];
printf("cothread_stub() entered\n"); DEBUG("cothread: cothread_stub() entered\n");
thread->flags |= COTHREAD_STARTED; thread->flags |= COTHREAD_STARTED;
if (thread->func) if (thread->func)
thread->func(thread->argc,thread->argv); thread->func(thread->argc,thread->argv);
thread->flags &= ~COTHREAD_STARTED; thread->flags &= ~COTHREAD_STARTED;
thread->pc = 0; thread->pc = 0;
DEBUG("cothread: cothread_stub() exit\n");
//printf("uh, yeah, we shouldn't be here, but we should deal anyway\n"); //printf("uh, yeah, we shouldn't be here, but we should deal anyway\n");
} }
void cothread_switch(cothread_state *thread) { void cothread_switch(cothread_state *thread) {
cothread_context *ctx; cothread_context *ctx;
cothread_state *current; cothread_state *current;
int enter = 0; int enter;
// int i; // int i;
if (thread == NULL) if (thread == NULL)
@ -117,36 +120,40 @@ void cothread_switch(cothread_state *thread) {
current = ctx->threads[ctx->current]; current = ctx->threads[ctx->current];
if (current == NULL) { if (current == NULL) {
fprintf(stderr,"there's no current thread, help!\n"); g_print("cothread: there's no current thread, help!\n");
exit(2); exit(2);
} }
if (current == thread) { 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; return;
} }
// find the number of the thread to switch to // find the number of the thread to switch to
ctx->current = thread->threadnum; 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 */ /* save the current stack pointer, frame pointer, and pc */
GET_SP(current->sp); GET_SP(current->sp);
enter = setjmp(current->jmp); enter = setjmp(current->jmp);
if (enter != 0) DEBUG("cothread: after thread #%d %d\n",ctx->current, enter);
if (enter != 0) {
return; return;
}
enter = 1; 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 */ /* restore stack pointer and other stuff of new cothread */
if (thread->flags & COTHREAD_STARTED) { if (thread->flags & COTHREAD_STARTED) {
fprintf(stderr,"in thread \n"); DEBUG("cothread: in thread \n");
SET_SP(thread->sp); SET_SP(thread->sp);
// switch to it // switch to it
longjmp(thread->jmp,1); longjmp(thread->jmp,1);
} else { } else {
SET_SP(thread->sp); DEBUG("cothread: exit thread \n");
SET_SP(thread->sp);
// start it // 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_set_arg(GtkObject *object,GtkArg *arg,guint id);
static void gst_disksrc_get_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(GstSrc *src);
//static void gst_disksrc_push_region(GstSrc *src,gulong offset,gulong size); //static void gst_disksrc_push_region(GstSrc *src,gulong offset,gulong size);
static GstElementStateReturn gst_disksrc_change_state(GstElement *element); static GstElementStateReturn gst_disksrc_change_state(GstElement *element);
@ -219,6 +221,8 @@ void gst_disksrc_push(GstSrc *src) {
else if (readbytes == 0) { else if (readbytes == 0) {
gst_src_signal_eos(GST_SRC(disksrc)); gst_src_signal_eos(GST_SRC(disksrc));
gst_buffer_unref(buf); gst_buffer_unref(buf);
gst_disksrc_close_file(disksrc);
GST_STATE(src) = GST_STATE_NULL;
return; 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_init(GstQueue *queue);
static void gst_queue_set_arg(GtkObject *object,GtkArg *arg,guint id); 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 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_push(GstConnection *connection);
void gst_queue_chain(GstPad *pad,GstBuffer *buf); 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); queue->sinkpad = gst_pad_new("sink",GST_PAD_SINK);
gst_element_add_pad(GST_ELEMENT(queue),queue->sinkpad); gst_element_add_pad(GST_ELEMENT(queue),queue->sinkpad);
gst_pad_set_chain_function(queue->sinkpad,gst_queue_chain); 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); queue->srcpad = gst_pad_new("src",GST_PAD_SRC);
gst_element_add_pad(GST_ELEMENT(queue),queue->srcpad); gst_element_add_pad(GST_ELEMENT(queue),queue->srcpad);
@ -132,18 +130,6 @@ GstElement *gst_queue_new(gchar *name) {
return queue; 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) static void gst_queue_cleanup_buffers(gpointer data, gpointer user_data)
{ {
DEBUG("queue: %s cleaning buffer %p\n", (gchar *)user_data, 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)); // argc,gst_element_get_name(element));
if (element->loopfunc != NULL) { if (element->loopfunc != NULL) {
// g_print("** gst_bin_loopfunc_wrapper(): element has loop function, calling it\n");
while (1) { while (1) {
DEBUG("** gst_bin_loopfunc_wrapper(): element has loop function, calling it\n");
(element->loopfunc)(element); (element->loopfunc)(element);
DEBUG("** gst_bin_loopfunc_wrapper(): element ended loop function\n");
} }
} else { } 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)) { if (GST_IS_SRC(element)) {
while (1) { //while (1) {
// g_print("** gst_bin_loopfunc_wrapper(): calling push function of source\n"); while (GST_STATE(element) != GST_STATE_NULL) {
DEBUG("** gst_bin_loopfunc_wrapper(): calling push function of source\n");
gst_src_push(GST_SRC(element)); gst_src_push(GST_SRC(element));
} }
} else { } else {
@ -449,9 +451,9 @@ static int gst_bin_loopfunc_wrapper(int argc,char *argv[]) {
while (pads) { while (pads) {
pad = GST_PAD(pads->data); pad = GST_PAD(pads->data);
if (pad->direction == GST_PAD_SINK) { 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); 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); (pad->chainfunc)(pad,buf);
} }
pads = g_list_next(pads); 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) { static void gst_bin_pullfunc_wrapper(GstPad *pad) {
// g_print("** in gst_bin_pullfunc_wrapper()============================= %s\n", DEBUG("** in gst_bin_pullfunc_wrapper()============================= %s\n",
// gst_element_get_name(GST_ELEMENT(pad->parent))); gst_element_get_name(GST_ELEMENT(pad->parent)));
cothread_switch(GST_ELEMENT(pad->parent)->threadstate); 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) { static void gst_bin_pushfunc_wrapper(GstPad *pad) {
// g_print("** in gst_bin_pushfunc_wrapper()============================= %s\n", DEBUG("** in gst_bin_pushfunc_wrapper()============================= %s\n",
// gst_element_get_name(GST_ELEMENT(pad->parent))); gst_element_get_name(GST_ELEMENT(pad->parent)));
cothread_switch(GST_ELEMENT(pad->parent)->threadstate); 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) { 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))); 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 it's a loop-based element, use cothreads
if (element->loopfunc != NULL) { 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; bin->need_cothreads = TRUE;
break; break;
} }
// if it's a complex element, use cothreads // if it's a complex element, use cothreads
if (GST_ELEMENT_IS_MULTI_IN(element)) { 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; bin->need_cothreads = TRUE;
break; break;
} }
@ -511,7 +518,7 @@ static void gst_bin_create_plan_func(GstBin *bin) {
pads = g_list_next(pads); pads = g_list_next(pads);
} }
if (sink_pads > 1) { 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; bin->need_cothreads = TRUE;
break; break;
} }

View file

@ -23,7 +23,7 @@
static guint32 _gst_cpu_flags; static guint32 _gst_cpu_flags;
#ifdef __i386__ #ifdef HAVE_CPU_I386
void gst_cpuid_i386(int,long *,long *,long *,long *); void gst_cpuid_i386(int,long *,long *,long *,long *);
#define gst_cpuid gst_cpuid_i386 #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(pad != NULL);
g_return_if_fail(GST_IS_PAD(pad)); 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; pad->pullfunc = pull;
} }

View file

@ -322,7 +322,7 @@ static GList *construct_path (gst_type_node *rgnNodes, gint chNode)
GstType *type; GstType *type;
GList *converters; GList *converters;
g_print("gsttype: constructed pad "); g_print("gsttype: constructed mime path ");
while (current != MAX_COST) while (current != MAX_COST)
{ {
type = gst_type_find_by_id(current); 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; gb->backbits = _gst_getbits_back_int;
} }
else { else {
#ifdef HAVE_CPU_I386
gb->get1bit = _gst_get1bit_i386; gb->get1bit = _gst_get1bit_i386;
gb->getbits = _gst_getbits_i386; gb->getbits = _gst_getbits_i386;
gb->getbits_fast = _gst_getbits_fast_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->showbits = _gst_showbits_i386;
gb->flushbits = _gst_flushbits_i386; gb->flushbits = _gst_flushbits_i386;
gb->backbits = _gst_getbits_back_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_set_arg(GtkObject *object,GtkArg *arg,guint id);
static void gst_disksrc_get_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(GstSrc *src);
//static void gst_disksrc_push_region(GstSrc *src,gulong offset,gulong size); //static void gst_disksrc_push_region(GstSrc *src,gulong offset,gulong size);
static GstElementStateReturn gst_disksrc_change_state(GstElement *element); static GstElementStateReturn gst_disksrc_change_state(GstElement *element);
@ -219,6 +221,8 @@ void gst_disksrc_push(GstSrc *src) {
else if (readbytes == 0) { else if (readbytes == 0) {
gst_src_signal_eos(GST_SRC(disksrc)); gst_src_signal_eos(GST_SRC(disksrc));
gst_buffer_unref(buf); gst_buffer_unref(buf);
gst_disksrc_close_file(disksrc);
GST_STATE(src) = GST_STATE_NULL;
return; 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_init(GstQueue *queue);
static void gst_queue_set_arg(GtkObject *object,GtkArg *arg,guint id); 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 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_push(GstConnection *connection);
void gst_queue_chain(GstPad *pad,GstBuffer *buf); 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); queue->sinkpad = gst_pad_new("sink",GST_PAD_SINK);
gst_element_add_pad(GST_ELEMENT(queue),queue->sinkpad); gst_element_add_pad(GST_ELEMENT(queue),queue->sinkpad);
gst_pad_set_chain_function(queue->sinkpad,gst_queue_chain); 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); queue->srcpad = gst_pad_new("src",GST_PAD_SRC);
gst_element_add_pad(GST_ELEMENT(queue),queue->srcpad); gst_element_add_pad(GST_ELEMENT(queue),queue->srcpad);
@ -132,18 +130,6 @@ GstElement *gst_queue_new(gchar *name) {
return queue; 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) static void gst_queue_cleanup_buffers(gpointer data, gpointer user_data)
{ {
DEBUG("queue: %s cleaning buffer %p\n", (gchar *)user_data, data); DEBUG("queue: %s cleaning buffer %p\n", (gchar *)user_data, data);