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!
gst_pipefilter_get_type
gst_identity_get_type
gst_queue_get_type
gst_pipefilter_get_type
gst_identity_get_type
gst_queue_get_type
#include <unistd.h>
#include <sys/mman.h>
#include <unistd.h>
#include <sys/mman.h>
+//#define DEBUG_ENABLED
+#include "gst/gst.h"
+#include "gst/gstarch.h"
pthread_key_t _cothread_key = -1;
cothread_state *cothread_create(cothread_context *ctx) {
cothread_state *s;
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);
//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 &
} else {
char *sp = CURRENT_STACK_FRAME;
unsigned long *stack_end = (unsigned long *)((unsigned long)sp &
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);
ctx->threads[0]->sp = (int *)CURRENT_STACK_FRAME;
ctx->threads[0]->pc = 0;
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;
// we consider the initiating process to be cothread 0
ctx->nthreads = 1;
cothread_context *ctx = pthread_getspecific(_cothread_key);
register cothread_state *thread = ctx->threads[ctx->current];
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;
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;
//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 i;
if (thread == NULL)
// int i;
if (thread == NULL)
current = ctx->threads[ctx->current];
if (current == NULL) {
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) {
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;
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);
/* save the current stack pointer, frame pointer, and pc */
GET_SP(current->sp);
enter = setjmp(current->jmp);
+ DEBUG("cothread: after thread #%d %d\n",ctx->current, enter);
+ if (enter != 0) {
- 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) {
/* 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);
// switch to it
longjmp(thread->jmp,1);
} else {
+ DEBUG("cothread: exit thread \n");
+ SET_SP(thread->sp);
+ //JUMP(cothread_stub);
+ cothread_stub();
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_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);
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);
else if (readbytes == 0) {
gst_src_signal_eos(GST_SRC(disksrc));
gst_buffer_unref(buf);
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;
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 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);
void gst_queue_push(GstConnection *connection);
void gst_queue_chain(GstPad *pad,GstBuffer *buf);
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);
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);
queue->srcpad = gst_pad_new("src",GST_PAD_SRC);
gst_element_add_pad(GST_ELEMENT(queue),queue->srcpad);
-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);
static void gst_queue_cleanup_buffers(gpointer data, gpointer user_data)
{
DEBUG("queue: %s cleaning buffer %p\n", (gchar *)user_data, data);
// argc,gst_element_get_name(element));
if (element->loopfunc != NULL) {
// argc,gst_element_get_name(element));
if (element->loopfunc != NULL) {
-// g_print("** gst_bin_loopfunc_wrapper(): element has loop function, calling it\n");
+ 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");
-// 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) {
-// 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 {
gst_src_push(GST_SRC(element));
}
} else {
while (pads) {
pad = GST_PAD(pads->data);
if (pad->direction == GST_PAD_SINK) {
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");
-// 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);
(pad->chainfunc)(pad,buf);
}
pads = g_list_next(pads);
}
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",
-// 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);
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",
-// 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);
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) {
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: 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)) {
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;
}
bin->need_cothreads = TRUE;
break;
}
pads = g_list_next(pads);
}
if (sink_pads > 1) {
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;
}
bin->need_cothreads = TRUE;
break;
}
static guint32 _gst_cpu_flags;
static guint32 _gst_cpu_flags;
void gst_cpuid_i386(int,long *,long *,long *,long *);
#define gst_cpuid gst_cpuid_i386
void gst_cpuid_i386(int,long *,long *,long *,long *);
#define gst_cpuid gst_cpuid_i386
g_return_if_fail(pad != NULL);
g_return_if_fail(GST_IS_PAD(pad));
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");
GstType *type;
GList *converters;
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);
while (current != MAX_COST)
{
type = gst_type_find_by_id(current);
gb->backbits = _gst_getbits_back_int;
}
else {
gb->backbits = _gst_getbits_back_int;
}
else {
gb->get1bit = _gst_get1bit_i386;
gb->getbits = _gst_getbits_i386;
gb->getbits_fast = _gst_getbits_fast_i386;
gb->get1bit = _gst_get1bit_i386;
gb->getbits = _gst_getbits_i386;
gb->getbits_fast = _gst_getbits_fast_i386;
gb->showbits = _gst_showbits_i386;
gb->flushbits = _gst_flushbits_i386;
gb->backbits = _gst_getbits_back_i386;
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
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_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);
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);
else if (readbytes == 0) {
gst_src_signal_eos(GST_SRC(disksrc));
gst_buffer_unref(buf);
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;
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 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);
void gst_queue_push(GstConnection *connection);
void gst_queue_chain(GstPad *pad,GstBuffer *buf);
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);
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);
queue->srcpad = gst_pad_new("src",GST_PAD_SRC);
gst_element_add_pad(GST_ELEMENT(queue),queue->srcpad);
-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);
static void gst_queue_cleanup_buffers(gpointer data, gpointer user_data)
{
DEBUG("queue: %s cleaning buffer %p\n", (gchar *)user_data, data);