mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-23 23:58:17 +00:00
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:
parent
11e8ef9074
commit
ff99ee6132
11 changed files with 68 additions and 59 deletions
|
@ -28,3 +28,5 @@ gst_fdsink_get_type
|
|||
gst_pipefilter_get_type
|
||||
gst_identity_get_type
|
||||
gst_queue_get_type
|
||||
|
||||
|
||||
|
|
|
@ -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 {
|
||||
DEBUG("cothread: exit thread \n");
|
||||
SET_SP(thread->sp);
|
||||
// start it
|
||||
JUMP(cothread_stub);
|
||||
//JUMP(cothread_stub);
|
||||
cothread_stub();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
33
gst/gstbin.c
33
gst/gstbin.c
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue