From 23540ccc524685fe1fc1f1ce90e2b229612685ae Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Thu, 7 Sep 2000 20:35:15 +0000 Subject: [PATCH] Faster and modular getbits implementation. Original commit message from CVS: Faster and modular getbits implementation. Fixed a bug in the audiosink that could lock up your box on bad MB. Modified the plugins to use the new getbits functions. --- gst/Makefile.am | 2 +- gst/cothreads.c | 28 ++-- gst/elements/gstaudiosink.c | 11 +- gst/gstbin.c | 4 +- libs/getbits/.gitignore | 1 + libs/getbits/Makefile.am | 9 +- libs/getbits/gbtest.c | 94 +++++++++++++ libs/getbits/gstgetbits.c | 239 ++++++++++++++++++++------------ libs/getbits/gstgetbits.h | 106 ++++++++++++-- libs/getbits/gstgetbits_i386.s | 115 +++++++++++++++ libs/getbits/gstgetbits_inl.h | 2 +- plugins/elements/gstaudiosink.c | 11 +- test/cothreads/cothreads.c | 30 ++-- test/cothreads/test.c | 9 +- 14 files changed, 531 insertions(+), 130 deletions(-) create mode 100644 libs/getbits/gbtest.c create mode 100644 libs/getbits/gstgetbits_i386.s diff --git a/gst/Makefile.am b/gst/Makefile.am index 42ab6b570d..3ee474cff8 100644 --- a/gst/Makefile.am +++ b/gst/Makefile.am @@ -59,7 +59,7 @@ libgstinclude_HEADERS = \ gstxml.h \ cothreads.h -CFLAGS += -O2 -Wall +CFLAGS += -g -O2 -Wall libgst_la_LIBADD = $(GLIB_LIBS) $(GTK_LIBS) $(XML_LIBS) libgst_la_LDFLAGS = -version-info $(STREAMER_CURRENT):$(STREAMER_REVISION):$(STREAMER_AGE) diff --git a/gst/cothreads.c b/gst/cothreads.c index 894b404a1b..4d57fe0cdd 100644 --- a/gst/cothreads.c +++ b/gst/cothreads.c @@ -1,10 +1,10 @@ +#include #include #include #include #include #include #include -#include #include #include @@ -15,8 +15,11 @@ pthread_key_t _cothread_key = -1; cothread_state *cothread_create(cothread_context *ctx) { cothread_state *s; - if (pthread_self() == 0) { + printf("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); } else { char *sp = CURRENT_STACK_FRAME; unsigned long *stack_end = (unsigned long *)((unsigned long)sp & @@ -34,11 +37,11 @@ cothread_state *cothread_create(cothread_context *ctx) { s->ctx = ctx; s->threadnum = ctx->nthreads; s->flags = 0; - s->sp = (int *)(s + COTHREAD_STACKSIZE); + s->sp = ((int *)s + COTHREAD_STACKSIZE); ctx->threads[ctx->nthreads++] = s; -// printf("created cothread at %p\n",s); + printf("created cothread at %p %p\n",s, s->sp); return s; } @@ -70,10 +73,10 @@ cothread_context *cothread_init() { ctx->threads[0]->argc = 0; ctx->threads[0]->argv = NULL; ctx->threads[0]->flags = COTHREAD_STARTED; - ctx->threads[0]->sp = CURRENT_STACK_FRAME; + ctx->threads[0]->sp = (int *)CURRENT_STACK_FRAME; ctx->threads[0]->pc = 0; -// fprintf(stderr,"0th thread is at %p\n",ctx->threads[0]); + fprintf(stderr,"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; @@ -91,11 +94,13 @@ void cothread_stub() { cothread_context *ctx = pthread_getspecific(_cothread_key); register cothread_state *thread = ctx->threads[ctx->current]; + printf("cothread_stub() entered\n"); thread->flags |= COTHREAD_STARTED; - thread->func(thread->argc,thread->argv); + if (thread->func) + thread->func(thread->argc,thread->argv); thread->flags &= ~COTHREAD_STARTED; thread->pc = 0; -// 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) { @@ -122,7 +127,7 @@ void cothread_switch(cothread_state *thread) { // find the number of the thread to switch to ctx->current = thread->threadnum; -// fprintf(stderr,"about to switch to thread #%d\n",ctx->current); + fprintf(stderr,"about to switch to thread #%d\n",ctx->current); /* save the current stack pointer, frame pointer, and pc */ __asm__("movl %%esp, %0" : "=m"(current->sp) : : "esp", "ebp"); @@ -131,12 +136,15 @@ void cothread_switch(cothread_state *thread) { return; enter = 1; + fprintf(stderr,"set stack to %p\n", thread->sp); /* restore stack pointer and other stuff of new cothread */ - __asm__("movl %0, %%esp\n" : "=m"(thread->sp)); if (thread->flags & COTHREAD_STARTED) { + fprintf(stderr,"in thread \n"); + __asm__("movl %0, %%esp\n" : "=m"(thread->sp)); // switch to it longjmp(thread->jmp,1); } else { + __asm__("movl %0, %%esp\n" : "=m"(thread->sp)); // start it __asm__("jmp " SYMBOL_NAME_STR(cothread_stub)); } diff --git a/gst/elements/gstaudiosink.c b/gst/elements/gstaudiosink.c index 1c1eea8e70..fc09a75803 100644 --- a/gst/elements/gstaudiosink.c +++ b/gst/elements/gstaudiosink.c @@ -25,6 +25,8 @@ #include #include +//#define DEBUG_ENABLED + #include #include @@ -184,6 +186,7 @@ void gst_audiosink_chain(GstPad *pad,GstBuffer *buf) { g_return_if_fail(GST_IS_PAD(pad)); g_return_if_fail(buf != NULL); + /* this has to be an audio buffer */ // g_return_if_fail(((GstMeta *)buf->meta)->type != //gst_audiosink_type_audio); @@ -212,6 +215,7 @@ void gst_audiosink_chain(GstPad *pad,GstBuffer *buf) { gtk_signal_emit(GTK_OBJECT(audiosink),gst_audiosink_signals[SIGNAL_HANDOFF], audiosink); + if (GST_BUFFER_DATA(buf) != NULL) { gst_trace_add_entry(NULL,0,buf,"audiosink: writing to soundcard"); //g_print("audiosink: writing to soundcard\n"); @@ -219,8 +223,9 @@ void gst_audiosink_chain(GstPad *pad,GstBuffer *buf) { if (!audiosink->mute) { gst_clock_wait(audiosink->clock, GST_BUFFER_TIMESTAMP(buf), GST_OBJECT(audiosink)); ioctl(audiosink->fd,SNDCTL_DSP_GETOSPACE,&ospace); - DEBUG("audiosink: (%d bytes buffer)\n", ospace.bytes); + DEBUG("audiosink: (%d bytes buffer) %d %p %d\n", ospace.bytes, audiosink->fd, GST_BUFFER_DATA(buf), GST_BUFFER_SIZE(buf)); write(audiosink->fd,GST_BUFFER_DATA(buf),GST_BUFFER_SIZE(buf)); + //write(STDOUT_FILENO,GST_BUFFER_DATA(buf),GST_BUFFER_SIZE(buf)); } } } @@ -288,7 +293,7 @@ static gboolean gst_audiosink_open_audio(GstAudioSink *sink) { g_print("audiosink: attempting to open sound device\n"); /* first try to open the sound card */ - sink->fd = open("/dev/dsp",O_RDWR); + sink->fd = open("/dev/dsp",O_WRONLY); /* if we have it, set the default parameters and go have fun */ if (sink->fd > 0) { @@ -306,7 +311,7 @@ static gboolean gst_audiosink_open_audio(GstAudioSink *sink) { if (sink->caps & DSP_CAP_COPROC) g_print("audiosink: Has coprocessor\n"); if (sink->caps & DSP_CAP_TRIGGER) g_print("audiosink: Trigger\n"); if (sink->caps & DSP_CAP_MMAP) g_print("audiosink: Direct access\n"); - g_print("audiosink: opened audio\n"); + g_print("audiosink: opened audio with fd=%d\n", sink->fd); GST_FLAG_SET(sink,GST_AUDIOSINK_OPEN); return TRUE; } diff --git a/gst/gstbin.c b/gst/gstbin.c index 11da06fd70..f0b2230465 100644 --- a/gst/gstbin.c +++ b/gst/gstbin.c @@ -603,8 +603,8 @@ void gst_bin_iterate_func(GstBin *bin) { if (bin->need_cothreads) { // all we really have to do is switch to the first child // FIXME this should be lots more intelligent about where to start -// g_print("** in gst_bin_iterate_func()==================================%s\n", -// gst_element_get_name(GST_ELEMENT(bin->children->data))); + //g_print("** in gst_bin_iterate_func()==================================%s\n", + // gst_element_get_name(GST_ELEMENT(bin->children->data))); cothread_switch(GST_ELEMENT(bin->children->data)->threadstate); } else { entries = bin->entries; diff --git a/libs/getbits/.gitignore b/libs/getbits/.gitignore index 08f5ed37d8..64cdc3b97b 100644 --- a/libs/getbits/.gitignore +++ b/libs/getbits/.gitignore @@ -5,3 +5,4 @@ Makefile.in *.la .deps .libs +gbtest diff --git a/libs/getbits/Makefile.am b/libs/getbits/Makefile.am index 5a5422cada..7c926fff20 100644 --- a/libs/getbits/Makefile.am +++ b/libs/getbits/Makefile.am @@ -2,14 +2,19 @@ filterdir = $(libdir)/gst filter_LTLIBRARIES = libgstgetbits.la -libgstgetbits_la_SOURCES = gstgetbits.c gstgetbits_inl.h +libgstgetbits_la_SOURCES = gstgetbits.c gstgetbits_inl.h gstgetbits_i386.s libgstgetbitsincludedir = $(includedir)/gst/libs/gstgetbits libgstgetbitsinclude_HEADERS = gstgetbits.h noinst_HEADERS = gstgetbits.h gstgetbits_inl.h -CFLAGS += -Wall -O2 -fomit-frame-pointer -funroll-all-loops -finline-functions -ffast-math +bin_PROGRAMS = gbtest + +gbtest_SOURCES = gbtest.c +gbtest_LDADD = libgstgetbits.la + +CFLAGS += -Wall -O2 -fomit-frame-pointer -funroll-all-loops -finline-functions -ffast-math INCLUDES = $(GLIB_CFLAGS) $(GTK_CFLAGS) -I$(top_srcdir) -I$(top_srcdir)/include LDADD = $(GLIB_LIBS) $(GTK_LIBS) $(top_srcdir)/gst/libgst.la diff --git a/libs/getbits/gbtest.c b/libs/getbits/gbtest.c new file mode 100644 index 0000000000..0d1f629f6e --- /dev/null +++ b/libs/getbits/gbtest.c @@ -0,0 +1,94 @@ +#include +#include "gstgetbits.h" + +char *print_bits(unsigned long bits,int size) { + char *ret = (char *)malloc(size+1); + int i; + ret[size] = 0; + for (i=0;i 00000011 %lu\n",bits, gb.bits); + bits = gst_getbits8(&gb); + printf("%08x <-> 00000022 %lu\n",bits, gb.bits); + bits = gst_getbits8(&gb); + printf("%08x <-> 00000044 %lu\n",bits, gb.bits); + bits = gst_getbits8(&gb); + printf("%08x <-> 00000088 %lu\n",bits, gb.bits); + bits = gst_getbits6(&gb); + printf("%08x <-> 00000033 %lu\n",bits, gb.bits); + + gst_backbitsn(&gb, 16); + + bits = gst_getbits10(&gb); + printf("%08x <-> 00000088 \n",bits); + + gst_getbits_newbuf(&gb,(unsigned char *)testbuffer, 7); + + bits = gst_getbits8(&gb); + printf("%08x <-> 00000011 \n",bits); + bits = gst_getbits8(&gb); + printf("%08x <-> 00000022 \n",bits); + bits = gst_getbits8(&gb); + printf("%08x <-> 00000044 \n",bits); + + bits = gst_getbits6(&gb); + printf("%08x <-> 00000022 \n",bits); + + gst_backbitsn(&gb, 19); + + bits = gst_getbits19(&gb); + printf("%08x <-> 00009122 \n",bits); + + bits = gst_getbits10(&gb); + printf("%08x <-> 000000cc \n",bits); + + gst_backbitsn(&gb, 8); + + gst_backbitsn(&gb, 19); + + gst_backbitsn(&gb, 8); + + bits = gst_getbits19(&gb); + printf("%08x <-> 00012244 \n",bits); + bits = gst_getbits8(&gb); + printf("%08x <-> 00000088 \n",bits); + + return 0; +} diff --git a/libs/getbits/gstgetbits.c b/libs/getbits/gstgetbits.c index 56f1aff456..fa6125da21 100644 --- a/libs/getbits/gstgetbits.c +++ b/libs/getbits/gstgetbits.c @@ -1,6 +1,38 @@ -#include +#include + #include "gstgetbits.h" +extern unsigned long _gst_get1bit_i386(gst_getbits_t *gb, unsigned long bits); +extern unsigned long _gst_getbits_i386(gst_getbits_t *gb, unsigned long bits); +extern unsigned long _gst_getbits_fast_i386(gst_getbits_t *gb, unsigned long bits); +extern unsigned long _gst_showbits_i386(gst_getbits_t *gb, unsigned long bits); +extern void _gst_flushbits_i386(gst_getbits_t *gb, unsigned long bits); +extern void _gst_getbits_back_i386(gst_getbits_t *gb, unsigned long bits); + +//#define DEBUG_ENABLED +#ifdef DEBUG_ENABLED +#define DEBUG(format, args...) g_print("DEBUG:(%d) " format, getpid() , ##args) +#else +#define DEBUG(format, args...) +#endif + +#ifdef WORDS_BIGENDIAN +# define swab32(x) (x) +#else +# if defined (__i386__) +# define swab32(x) __i386_swab32(x) + static inline const guint32 __i386_swab32(guint32 x) + { + __asm__("bswap %0" : "=r" (x) : "0" (x)); + return x; + } +# else +# define swab32(x)\ + ((((guint8*)&x)[0] << 24) | (((guint8*)&x)[1] << 16) | \ + (((guint8*)&x)[2] << 8) | (((guint8*)&x)[3])) +# endif +#endif + unsigned long gst_getbits_nBitMask[] = { 0x00000000, 0x80000000, 0xc0000000, 0xe0000000, 0xf0000000, 0xf8000000, 0xfc000000, 0xfe000000, @@ -35,7 +67,7 @@ unsigned long _getbits_64_minus_index[] = { this isn't as cycle-efficient, due to the simple fact that I must call emms() at the end. all state must be kept in *gb, not in registers */ -unsigned long getbits_mmx(gst_getbits_t *gb,unsigned long bits) { +unsigned long _gst_getbits_mmx(gst_getbits_t *gb,unsigned long bits) { signed long remaining; unsigned long result; @@ -63,9 +95,9 @@ unsigned long getbits_mmx(gst_getbits_t *gb,unsigned long bits) { remaining += 64; /* grab the first 32 bits from the buffer and swap them around */ - dword1 = bswap_32(*(gb->ptr-8)); + dword1 = swab32(*(gb->ptr-8)); /* grab the second 32 bits, swap */ - dword2 = bswap_32(*(gb->ptr-4)); + dword2 = swab32(*(gb->ptr-4)); /* put second dword in mm4 */ movd_m2r(dword2,mm4); @@ -130,96 +162,121 @@ unsigned long getbits_mmx(gst_getbits_t *gb,unsigned long bits) { } #endif /* HAVE_LIBMMX */ -unsigned long getbits_int(gst_getbits_t *gb,unsigned long bits) { - int remaining; - int result = 0; +unsigned long _gst_getbits_int_cb(gst_getbits_t *gb, unsigned long bits) { + int result; + int bitsleft; - if (bits == 0) { -// fprintf(stderr,"getbits(0) = 0\n"); - return 0; - } + //printf("gst_getbits%lu %ld %p %08x\n", bits, gb->bits, gb->ptr, gb->dword); - remaining = gb->bits - bits; - if (remaining < 0) { - /* how many bits are left to get? */ - remaining = -remaining; -// printf("have to get %d more bits from next dword\n",remaining); - /* move what's left over to accomodate the new stuff */ - result = gb->dword >> (32 - bits); -// printf("have \t\t%s from previous dword\n",print_bits(result)); - /* get the new word into the buffer */ -// fprintf(stderr,"getbits: incrementing %p by 4\n",gb->ptr); + if (!bits) return 0; + + gb->bits -= bits; + result = gb->dword >> (32-bits); + + if (gb->bits < 0) { + gb->ptr += 4; - gb->dword = bswap_32(*((unsigned long *)(gb->ptr))); -// gb->dword = *((unsigned char *)(gb->ptr)) << 24 | -// *((unsigned char *)(gb->ptr)+1) << 16 | -// *((unsigned char *)(gb->ptr)+2) << 8 | -// *((unsigned char *)(gb->ptr)+3); -// gb->dword = *((unsigned long *)(gb->ptr)); - gb->bits = 32; -// fprintf(stderr,"got new dword %08x\n",gb->dword); - /* & in the right number of bits */ - result |= (gb->dword >> (32 - remaining)); - /* shift the buffer over */ - gb->dword <<= remaining; - /* record how many bits are left */ - gb->bits -= remaining; - } else { - result = gb->dword >> (32 - bits); - gb->dword <<= bits; - gb->bits -= bits; -// printf("have %d bits left\n",gb->bits); + + bitsleft = (gb->endptr - gb->ptr)*8; + bits = -gb->bits; + gb->bits += (bitsleft>32? 32 : bitsleft); + + if (gb->endptr <= gb->ptr) { + (gb->callback)(gb, gb->data); + gb->bits -= bits; + } + gb->dword = swab32(*((unsigned long *)(gb->ptr))); + + result |= (gb->dword >> (32-bits)); } -// printf("have \t\t%s left\n",print_bits(gb->dword)); -// fprintf(stderr,"getbits.c:getbits(%ld) = %d\n",bits,result); + gb->dword <<= bits; + return result; } -void getbits_back_int(gst_getbits_t *gb,unsigned long bits) { - fprintf(stderr,"getbits.c:getbits_back(%lu)\n",bits); - // moving within the same dword... - if ((bits + gb->bits) <= 32) { - fprintf(stderr,"moving back %lu bits in the same dword\n",bits); - gb->bits += bits; - // otherwise we're going to have move the pointer (ick) - } else { - // rare case where we're moving a multiple of 32 bits... - if ((bits % 32) == 0) { - fprintf(stderr,"moving back exactly %lu dwords\n",bits/32); - gb->ptr -= (bits / 8); - // we have to both shift bits and the pointer (NOOOOOOO!) - } else { - // strip off the first dword - bits -= (32 - gb->bits); - gb->ptr -= 4; - // now strip off as many others as necessary - gb->ptr -= 4 * (bits/32); - // and set the bits to what's left - gb->bits = bits % 32; - fprintf(stderr,"moved back %lu bytes to %p\n",4 * ((bits/32)+1),gb->ptr); - } - } - gb->dword = bswap_32(*((unsigned long *)(gb->ptr))); - fprintf(stderr,"orignal new loaded word is %08lx\n",gb->dword); - gb->dword <<= (32 - gb->bits); - fprintf(stderr,"shifted (by %lu) word is %08lx\n",gb->bits,gb->dword); +void _gst_getbits_back_int(gst_getbits_t *gb, unsigned long bits) { + gb->bits -= bits; + gb->ptr += (gb->bits>>3); + gb->bits &= 0x7; } -void getbits_byteback_int(gst_getbits_t *gb,unsigned long bytes) { - fprintf(stderr,"getbits.c:getbits_byteback(%lu)\n",bytes); - getbits_back_int(gb,bytes*8); - gb->bits = gb->bits & ~0x07; +unsigned long _gst_showbits_int(gst_getbits_t *gb, unsigned long bits) { + unsigned long rval; + + if (bits == 0) return 0; + + rval = swab32(*((unsigned long *)(gb->ptr))); + rval <<= gb->bits; + rval >>= (32-bits); + + DEBUG("showbits%d, %08x\n", bits, rval); + return rval; } -int getbits_offset(gst_getbits_t *gb) { - fprintf(stderr,"getbits.c:getbits_offset() = %lu\n",gb->bits % 8); - return gb->bits % 8; +unsigned long _gst_getbyte(gst_getbits_t *gb, unsigned long bits) { + return *gb->ptr++; +} + +unsigned long _gst_get1bit_int(gst_getbits_t *gb, unsigned long bits) { + unsigned char rval; + + rval = *gb->ptr << gb->bits; + + gb->bits++; + gb->ptr += (gb->bits>>3); + gb->bits &= 0x7; + + DEBUG("getbits%d, %08x\n", bits, rval); + return rval>>7; +} + +unsigned long _gst_getbits_fast_int(gst_getbits_t *gb, unsigned long bits) { + unsigned long rval; + + rval = (unsigned char) (gb->ptr[0] << gb->bits); + rval |= ((unsigned int) gb->ptr[1] << gb->bits)>>8; + rval <<= bits; + rval >>= 8; + + gb->bits += bits; + gb->ptr += (gb->bits>>3); + gb->bits &= 0x7; + + DEBUG("getbits%d, %08x\n", bits, rval); + return rval; +} + +unsigned long _gst_getbits_int(gst_getbits_t *gb, unsigned long bits) { + unsigned long rval; + + if (bits == 0) return 0; + + rval = swab32(*((unsigned long *)(gb->ptr))); + rval <<= gb->bits; + + gb->bits += bits; + + rval >>= (32-bits); + gb->ptr += (gb->bits>>3); + gb->bits &= 0x7; + + DEBUG("getbits%d, %08x\n", bits, rval); + return rval; +} + +void _gst_flushbits_int(gst_getbits_t *gb, unsigned long bits) { + gb->bits += bits; + gb->ptr += (gb->bits>>3); + gb->bits &= 0x7; + DEBUG("flushbits%d\n", bits); } /* initialize the getbits structure with the proper getbits func */ -void getbits_init(gst_getbits_t *gb) { +void gst_getbits_init(gst_getbits_t *gb, GstGetbitsCallback callback, void *data) { gb->ptr = NULL; gb->bits = 0; + gb->callback = callback; + gb->data = data; #ifdef HAVE_LIBMMX if (1) { @@ -229,18 +286,30 @@ void getbits_init(gst_getbits_t *gb) { } else #endif /* HAVE_LIBMMX */ { - gb->getbits = getbits_int; - gb->backbits = getbits_back_int; - gb->backbytes = getbits_byteback_int; + if (gb->callback) { + gb->getbits = _gst_getbits_int_cb; + gb->showbits = _gst_showbits_int; + gb->flushbits = _gst_flushbits_int; + 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->getbyte = _gst_getbyte; + gb->show1bit = _gst_showbits_i386; + gb->showbits = _gst_showbits_i386; + gb->flushbits = _gst_flushbits_i386; + gb->backbits = _gst_getbits_back_i386; + } } } /* set up the getbits structure with a new buffer */ -void getbits_newbuf(gst_getbits_t *gb,unsigned char *buffer) { - gb->ptr = buffer - 4; -// fprintf(stderr,"setting ptr to %p\n",gb->ptr); +void gst_getbits_newbuf(gst_getbits_t *gb,unsigned char *buffer, unsigned long len) { + gb->ptr = buffer; + gb->endptr = buffer+len; gb->bits = 0; - gb->dword = 0; #ifdef HAVE_LIBMMX // gb->qword = 0; #endif /* HAVE_LIBMMX */ diff --git a/libs/getbits/gstgetbits.h b/libs/getbits/gstgetbits.h index e64c65318c..259bffa557 100644 --- a/libs/getbits/gstgetbits.h +++ b/libs/getbits/gstgetbits.h @@ -16,6 +16,7 @@ #endif /* HAVE_LIBSSE */ typedef struct _gst_getbits_t gst_getbits_t; +typedef void (*GstGetbitsCallback) (gst_getbits_t *gb, void *data); /* breaks in structure show alignment on quadword boundaries */ /* FIXME: need to find out how to force GCC to align this to octwords */ @@ -28,9 +29,17 @@ struct _gst_getbits_t { unsigned long dword; unsigned long temp; - unsigned long (*getbits)(gst_getbits_t *gb,unsigned long bits); /* dword */ - void (*backbits)(gst_getbits_t *gb,unsigned long bits); /* dword */ - void (*backbytes)(gst_getbits_t *gb,unsigned long bytes); /* dword */ + GstGetbitsCallback callback; + void *data; + + unsigned long (*get1bit)(gst_getbits_t *gb, unsigned long bits); + unsigned long (*getbits)(gst_getbits_t *gb, unsigned long bits); + unsigned long (*getbits_fast)(gst_getbits_t *gb, unsigned long bits); + unsigned long (*getbyte)(gst_getbits_t *gb, unsigned long bits); + unsigned long (*show1bit)(gst_getbits_t *gb, unsigned long bits); + unsigned long (*showbits)(gst_getbits_t *gb, unsigned long bits); + void (*flushbits)(gst_getbits_t *gb, unsigned long bits); + void (*backbits)(gst_getbits_t *gb, unsigned long bits); #ifdef HAVE_LIBMMX mmx_t qword; /* qword */ @@ -42,18 +51,95 @@ struct _gst_getbits_t { }; -#define GST_GETBITS_INLINE - #ifdef GST_GETBITS_INLINE #include "gstgetbits_inl.h" #else -void gst_getbits_init(gst_getbits_t *gb); -void gst_getbits_newbuf(gst_getbits_t *gb,unsigned char *buffer); +void gst_getbits_init(gst_getbits_t *gb, GstGetbitsCallback callback, void *data); +void gst_getbits_newbuf(gst_getbits_t *gb, unsigned char *buffer, unsigned long len); -#define getbits(gb,bits) (((gb)->getbits)(gb,bits)) -#define getbits_back(gb,bits) (((gb)->backbits)(gb,bits)) -#define getbits_back_bytes(gb,bytes) (((gb)->backbytes)(gb,bytes)) +#define gst_getbits_bitoffset(gb) \ +( \ + (-(gb)->bits)&0x7 \ +) + +#define gst_getbits_align_byte(gb) + +#define gst_getbits_bufferpos(gb) ((gb)->ptr) + +#define gst_getbits_bytesleft(gb) ((gb)->endptr - (gb)->ptr) + +#define gst_getbits_bitsleft(gb) (((gb)->endptr - (gb)->ptr)*8 - ((-(gb)->bits)&0x7)) + +#define gst_get1bit(gb) (((gb)->get1bit)(gb, 1)) +#define gst_getbitsX(gb,bits) (((gb)->getbits)(gb,bits)) +#define gst_getbits_fastX(gb,bits) (((gb)->getbits_fast)(gb,bits)) +#define gst_show1bit(gb,bits) (((gb)->show1bit)(gb,bits)) +#define gst_showbitsX(gb,bits) (((gb)->showbits)(gb,bits)) +#define gst_flushbitsX(gb,bits) (((gb)->flushbits)(gb,bits)) +#define gst_backbitsX(gb,bits) (((gb)->backbits)(gb,bits)) + +#define gst_getbyte(gb) (((gb)->getbyte)(gb,8)) + +#define gst_getbits_fastn(gb,n) gst_getbits_fastX(gb, n) + +#define gst_getbitsn(gb,n) gst_getbitsX(gb, n) +#define gst_getbits1(gb) gst_get1bit(gb) +#define gst_getbits2(gb) gst_getbits_fastX(gb, 2) +#define gst_getbits3(gb) gst_getbits_fastX(gb, 3) +#define gst_getbits4(gb) gst_getbits_fastX(gb, 4) +#define gst_getbits5(gb) gst_getbits_fastX(gb, 5) +#define gst_getbits6(gb) gst_getbits_fastX(gb, 6) +#define gst_getbits7(gb) gst_getbits_fastX(gb, 7) +#define gst_getbits8(gb) gst_getbits_fastX(gb, 8) +#define gst_getbits9(gb) gst_getbits_fastX(gb, 9) +#define gst_getbits10(gb) gst_getbitsX(gb, 10) +#define gst_getbits11(gb) gst_getbitsX(gb, 11) +#define gst_getbits12(gb) gst_getbitsX(gb, 12) +#define gst_getbits13(gb) gst_getbitsX(gb, 13) +#define gst_getbits14(gb) gst_getbitsX(gb, 14) +#define gst_getbits15(gb) gst_getbitsX(gb, 15) +#define gst_getbits16(gb) gst_getbitsX(gb, 16) +#define gst_getbits17(gb) gst_getbitsX(gb, 17) +#define gst_getbits18(gb) gst_getbitsX(gb, 18) +#define gst_getbits19(gb) gst_getbitsX(gb, 19) +#define gst_getbits20(gb) gst_getbitsX(gb, 20) +#define gst_getbits21(gb) gst_getbitsX(gb, 21) +#define gst_getbits22(gb) gst_getbitsX(gb, 22) +#define gst_getbits23(gb) gst_getbitsX(gb, 23) + +#define gst_showbitsn(gb,n) gst_showbitsX(gb, n) +#define gst_showbits1(gb) gst_show1bit(gb, 1) +#define gst_showbits2(gb) gst_showbitsX(gb, 2) +#define gst_showbits3(gb) gst_showbitsX(gb, 3) +#define gst_showbits4(gb) gst_showbitsX(gb, 4) +#define gst_showbits5(gb) gst_showbitsX(gb, 5) +#define gst_showbits6(gb) gst_showbitsX(gb, 6) +#define gst_showbits7(gb) gst_showbitsX(gb, 7) +#define gst_showbits8(gb) gst_showbitsX(gb, 8) +#define gst_showbits9(gb) gst_showbitsX(gb, 9) +#define gst_showbits10(gb) gst_showbitsX(gb, 10) +#define gst_showbits11(gb) gst_showbitsX(gb, 11) +#define gst_showbits12(gb) gst_showbitsX(gb, 12) +#define gst_showbits13(gb) gst_showbitsX(gb, 13) +#define gst_showbits14(gb) gst_showbitsX(gb, 14) +#define gst_showbits15(gb) gst_showbitsX(gb, 15) +#define gst_showbits16(gb) gst_showbitsX(gb, 16) +#define gst_showbits17(gb) gst_showbitsX(gb, 17) +#define gst_showbits18(gb) gst_showbitsX(gb, 18) +#define gst_showbits19(gb) gst_showbitsX(gb, 19) +#define gst_showbits20(gb) gst_showbitsX(gb, 20) +#define gst_showbits21(gb) gst_showbitsX(gb, 21) +#define gst_showbits22(gb) gst_showbitsX(gb, 22) +#define gst_showbits23(gb) gst_showbitsX(gb, 23) +#define gst_showbits24(gb) gst_showbitsX(gb, 24) +#define gst_showbits32(gb) gst_showbitsX(gb, 32) + +#define gst_flushbitsn(gb,n) gst_flushbitsX(gb, n) +#define gst_flushbits32(gb) gst_flushbitsX(gb, 32) + +#define gst_backbitsn(gb,n) gst_backbitsX(gb, n) +#define gst_backbits24(gb) gst_backbitsX(gb, 24) #endif #endif /* __GST_GETBITS_H__ */ diff --git a/libs/getbits/gstgetbits_i386.s b/libs/getbits/gstgetbits_i386.s new file mode 100644 index 0000000000..512378e459 --- /dev/null +++ b/libs/getbits/gstgetbits_i386.s @@ -0,0 +1,115 @@ + .p2align 4,,7 +.globl _gst_getbits_i386 + .type _gst_getbits_i386,@function +_gst_getbits_i386: + cmpl $0,8(%esp) + jne .L39 + xorl %eax,%eax + ret +.L39: + movl 4(%esp),%edx + movl (%edx),%ecx + movl (%ecx),%eax + bswap %eax + movl 16(%edx),%ecx + shll %cl, %eax + movl 8(%esp),%ecx + addl %ecx, 16(%edx) + negl %ecx + addl $32,%ecx + shrl %cl, %eax + movl 16(%edx),%ecx + sarl $3,%ecx + addl %ecx,(%edx) + andl $7,16(%edx) + ret + + .p2align 4,,7 +.globl _gst_getbits_fast_i386 + .type _gst_getbits_fast_i386,@function +_gst_getbits_fast_i386: + movl 4(%esp),%edx + movl (%edx),%ecx + movzbl 1(%ecx),%eax + movb (%ecx), %ah + movl 16(%edx),%ecx + shlw %cl, %ax + movl 8(%esp),%ecx + addl %ecx, 16(%edx) + negl %ecx + addl $16,%ecx + shrl %cl, %eax + movl 16(%edx),%ecx + sarl $3,%ecx + addl %ecx,(%edx) + andl $7,16(%edx) + ret + + .p2align 4,,7 +.globl _gst_get1bit_i386 + .type _gst_get1bit_i386,@function +_gst_get1bit_i386: + movl 4(%esp),%edx + movl (%edx),%ecx + movzbl (%ecx),%eax + movl 16(%edx),%ecx + incl %ecx + rolb %cl, %al + andb $1, %al + movl %ecx, 16(%edx) + andl $7,16(%edx) + sarl $3,%ecx + addl %ecx,(%edx) + ret + + .p2align 4,,7 +.globl _gst_showbits_i386 + .type _gst_showbits_i386,@function +_gst_showbits_i386: + cmpl $0,8(%esp) + jne .L40 + xorl %eax,%eax + ret +.L40: + movl 4(%esp),%edx + movl (%edx),%ecx + movl (%ecx), %eax + bswap %eax + movl 16(%edx),%ecx + shll %cl, %eax + movl 8(%esp),%ecx + negl %ecx + addl $32,%ecx + shrl %cl, %eax + ret + + + .p2align 4,,7 +.globl _gst_flushbits_i386 + .type _gst_flushbits_i386,@function +_gst_flushbits_i386: + movl 4(%esp),%ecx + movl 16(%ecx),%eax + addl 8(%esp),%eax + movl %eax, %edx + sarl $3,%eax + addl %eax,(%ecx) + andl $7, %edx + movl %edx, 16(%ecx) + ret + + + .p2align 4,,7 +.globl _gst_getbits_back_i386 + .type _gst_getbits_back_i386,@function +_gst_getbits_back_i386: + movl 4(%esp),%edx + movl 16(%edx),%ecx + subl 8(%esp),%ecx + movl %ecx, %eax + sarl $3,%ecx + addl %ecx,(%edx) + andl $7,%eax + movl %eax, 16(%edx) + ret + diff --git a/libs/getbits/gstgetbits_inl.h b/libs/getbits/gstgetbits_inl.h index ca894a241b..2e025c7aaa 100644 --- a/libs/getbits/gstgetbits_inl.h +++ b/libs/getbits/gstgetbits_inl.h @@ -93,7 +93,7 @@ /* External declarations for bitstream i/o operations. */ extern unsigned long gst_getbits_nBitMask[]; -#define gst_getbits_init(gb) +#define gst_getbits_init(gb, callback, data) #define gst_getbits_newbuf(gb, buffer, len) \ { \ diff --git a/plugins/elements/gstaudiosink.c b/plugins/elements/gstaudiosink.c index 1c1eea8e70..fc09a75803 100644 --- a/plugins/elements/gstaudiosink.c +++ b/plugins/elements/gstaudiosink.c @@ -25,6 +25,8 @@ #include #include +//#define DEBUG_ENABLED + #include #include @@ -184,6 +186,7 @@ void gst_audiosink_chain(GstPad *pad,GstBuffer *buf) { g_return_if_fail(GST_IS_PAD(pad)); g_return_if_fail(buf != NULL); + /* this has to be an audio buffer */ // g_return_if_fail(((GstMeta *)buf->meta)->type != //gst_audiosink_type_audio); @@ -212,6 +215,7 @@ void gst_audiosink_chain(GstPad *pad,GstBuffer *buf) { gtk_signal_emit(GTK_OBJECT(audiosink),gst_audiosink_signals[SIGNAL_HANDOFF], audiosink); + if (GST_BUFFER_DATA(buf) != NULL) { gst_trace_add_entry(NULL,0,buf,"audiosink: writing to soundcard"); //g_print("audiosink: writing to soundcard\n"); @@ -219,8 +223,9 @@ void gst_audiosink_chain(GstPad *pad,GstBuffer *buf) { if (!audiosink->mute) { gst_clock_wait(audiosink->clock, GST_BUFFER_TIMESTAMP(buf), GST_OBJECT(audiosink)); ioctl(audiosink->fd,SNDCTL_DSP_GETOSPACE,&ospace); - DEBUG("audiosink: (%d bytes buffer)\n", ospace.bytes); + DEBUG("audiosink: (%d bytes buffer) %d %p %d\n", ospace.bytes, audiosink->fd, GST_BUFFER_DATA(buf), GST_BUFFER_SIZE(buf)); write(audiosink->fd,GST_BUFFER_DATA(buf),GST_BUFFER_SIZE(buf)); + //write(STDOUT_FILENO,GST_BUFFER_DATA(buf),GST_BUFFER_SIZE(buf)); } } } @@ -288,7 +293,7 @@ static gboolean gst_audiosink_open_audio(GstAudioSink *sink) { g_print("audiosink: attempting to open sound device\n"); /* first try to open the sound card */ - sink->fd = open("/dev/dsp",O_RDWR); + sink->fd = open("/dev/dsp",O_WRONLY); /* if we have it, set the default parameters and go have fun */ if (sink->fd > 0) { @@ -306,7 +311,7 @@ static gboolean gst_audiosink_open_audio(GstAudioSink *sink) { if (sink->caps & DSP_CAP_COPROC) g_print("audiosink: Has coprocessor\n"); if (sink->caps & DSP_CAP_TRIGGER) g_print("audiosink: Trigger\n"); if (sink->caps & DSP_CAP_MMAP) g_print("audiosink: Direct access\n"); - g_print("audiosink: opened audio\n"); + g_print("audiosink: opened audio with fd=%d\n", sink->fd); GST_FLAG_SET(sink,GST_AUDIOSINK_OPEN); return TRUE; } diff --git a/test/cothreads/cothreads.c b/test/cothreads/cothreads.c index 8b12b67083..4d57fe0cdd 100644 --- a/test/cothreads/cothreads.c +++ b/test/cothreads/cothreads.c @@ -1,10 +1,10 @@ +#include #include #include #include #include #include #include -#include #include #include @@ -15,8 +15,11 @@ pthread_key_t _cothread_key = -1; cothread_state *cothread_create(cothread_context *ctx) { cothread_state *s; - if (pthread_self() == 0) { + printf("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); } else { char *sp = CURRENT_STACK_FRAME; unsigned long *stack_end = (unsigned long *)((unsigned long)sp & @@ -34,11 +37,11 @@ cothread_state *cothread_create(cothread_context *ctx) { s->ctx = ctx; s->threadnum = ctx->nthreads; s->flags = 0; - s->sp = (int *)(s + COTHREAD_STACKSIZE); + s->sp = ((int *)s + COTHREAD_STACKSIZE); ctx->threads[ctx->nthreads++] = s; -// printf("created cothread at %p\n",s); + printf("created cothread at %p %p\n",s, s->sp); return s; } @@ -56,7 +59,7 @@ cothread_context *cothread_init() { if (_cothread_key == -1) { if (pthread_key_create(&_cothread_key,NULL) != 0) { perror("pthread_key_create"); - return; + return NULL; } } pthread_setspecific(_cothread_key,ctx); @@ -70,10 +73,10 @@ cothread_context *cothread_init() { ctx->threads[0]->argc = 0; ctx->threads[0]->argv = NULL; ctx->threads[0]->flags = COTHREAD_STARTED; - ctx->threads[0]->sp = CURRENT_STACK_FRAME; + ctx->threads[0]->sp = (int *)CURRENT_STACK_FRAME; ctx->threads[0]->pc = 0; -// fprintf(stderr,"0th thread is at %p\n",ctx->threads[0]); + fprintf(stderr,"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; @@ -91,11 +94,13 @@ void cothread_stub() { cothread_context *ctx = pthread_getspecific(_cothread_key); register cothread_state *thread = ctx->threads[ctx->current]; + printf("cothread_stub() entered\n"); thread->flags |= COTHREAD_STARTED; - thread->func(thread->argc,thread->argv); + if (thread->func) + thread->func(thread->argc,thread->argv); thread->flags &= ~COTHREAD_STARTED; thread->pc = 0; -// 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) { @@ -122,7 +127,7 @@ void cothread_switch(cothread_state *thread) { // find the number of the thread to switch to ctx->current = thread->threadnum; -// fprintf(stderr,"about to switch to thread #%d\n",ctx->current); + fprintf(stderr,"about to switch to thread #%d\n",ctx->current); /* save the current stack pointer, frame pointer, and pc */ __asm__("movl %%esp, %0" : "=m"(current->sp) : : "esp", "ebp"); @@ -131,12 +136,15 @@ void cothread_switch(cothread_state *thread) { return; enter = 1; + fprintf(stderr,"set stack to %p\n", thread->sp); /* restore stack pointer and other stuff of new cothread */ - __asm__("movl %0, %%esp\n" : "=m"(thread->sp)); if (thread->flags & COTHREAD_STARTED) { + fprintf(stderr,"in thread \n"); + __asm__("movl %0, %%esp\n" : "=m"(thread->sp)); // switch to it longjmp(thread->jmp,1); } else { + __asm__("movl %0, %%esp\n" : "=m"(thread->sp)); // start it __asm__("jmp " SYMBOL_NAME_STR(cothread_stub)); } diff --git a/test/cothreads/test.c b/test/cothreads/test.c index 42934ac0b3..c8c8976331 100644 --- a/test/cothreads/test.c +++ b/test/cothreads/test.c @@ -1,17 +1,22 @@ #include +#include "glib.h" #include "cothreads.h" #include "object.h" #include "looper.h" +cothread_context *ctx; + int main(int argc,char *argv[]) { - cothread_context *ctx = cothread_init(); looper *l1,*l2; + ctx = cothread_init(); + l1 = looper_create("looperone",1,ctx); l2 = looper_create("loopertwo",0,ctx); object_setpeer(OBJECT(l1),OBJECT(l2)); fprintf(stderr,"about to start l1\n\n"); - object_start(l1); + while (1) + object_start(l1); }