Faster and modular getbits implementation.
authorWim Taymans <wim.taymans@gmail.com>
Thu, 7 Sep 2000 20:35:15 +0000 (20:35 +0000)
committerWim Taymans <wim.taymans@gmail.com>
Thu, 7 Sep 2000 20:35:15 +0000 (20:35 +0000)
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.

14 files changed:
gst/Makefile.am
gst/cothreads.c
gst/elements/gstaudiosink.c
gst/gstbin.c
libs/getbits/.gitignore
libs/getbits/Makefile.am
libs/getbits/gbtest.c [new file with mode: 0644]
libs/getbits/gstgetbits.c
libs/getbits/gstgetbits.h
libs/getbits/gstgetbits_i386.s [new file with mode: 0644]
libs/getbits/gstgetbits_inl.h
plugins/elements/gstaudiosink.c
test/cothreads/cothreads.c
test/cothreads/test.c

index 42ab6b5..3ee474c 100644 (file)
@@ -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)
index 894b404..4d57fe0 100644 (file)
@@ -1,10 +1,10 @@
+#include <pthread.h>
 #include <sys/time.h>
 #include <linux/linkage.h>
 #include <stdio.h>   
 #include <stdlib.h>
 #include <signal.h>   
 #include <setjmp.h>
-#include <pthread.h>
 #include <unistd.h>
 #include <sys/mman.h>
 
@@ -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));
   }
index 1c1eea8..fc09a75 100644 (file)
@@ -25,6 +25,8 @@
 #include <sys/soundcard.h>
 #include <unistd.h>
 
+//#define DEBUG_ENABLED
+
 #include <gstaudiosink.h>
 #include <gst/meta/audioraw.h>
 
@@ -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;
   }
index 11da06f..f0b2230 100644 (file)
@@ -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;
index 08f5ed3..64cdc3b 100644 (file)
@@ -5,3 +5,4 @@ Makefile.in
 *.la
 .deps
 .libs
+gbtest
index 5a5422c..7c926ff 100644 (file)
@@ -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 (file)
index 0000000..0d1f629
--- /dev/null
@@ -0,0 +1,94 @@
+#include <stdlib.h>
+#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<size;i++) {
+    if (bits & (1<<i))
+      ret[(size-1)-i] = '1';
+    else
+      ret[(size-1)-i] = '0';
+  }
+  return ret;
+}
+
+static unsigned char testbuffer[] = 
+{
+  0x11, 0x22, 0x44, 0x88, 0xCC, 0xEE,0xFF,0x11
+};
+
+void empty(gst_getbits_t *gb, void *data) {
+  printf("buffer empty\n");
+
+  gst_getbits_newbuf(gb,(unsigned char *)testbuffer, 7);
+}
+
+int main(int argc,char *argv[]) {
+  gst_getbits_t gb;
+  int i, j;
+  int bits;
+
+  gst_getbits_init(&gb, NULL, NULL);
+  gst_getbits_newbuf(&gb,(unsigned char *)testbuffer, 7);
+
+  for (i=0;i<7;i++) {
+    for (j=0;j<8;j++) {
+      printf("%lu",gst_getbits2(&gb));
+      gst_backbitsn(&gb, 1);
+    }
+    printf(" = %01x\n", testbuffer[i]);
+  }
+
+  gst_getbits_newbuf(&gb,(unsigned char *)testbuffer, 7);
+
+  bits = gst_getbits8(&gb);
+  printf("%08x <-> 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;
+}
index 56f1aff..fa6125d 100644 (file)
@@ -1,6 +1,38 @@
-#include <byteswap.h>
+#include <glib.h>
+
 #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;
+}
+
+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;
 }
 
-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_getbyte(gst_getbits_t *gb, unsigned long bits) {
+  return *gb->ptr++;
 }
 
-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_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 */
index e64c653..259bffa 100644 (file)
@@ -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 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 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_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 (file)
index 0000000..512378e
--- /dev/null
@@ -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
+
index ca894a2..2e025c7 100644 (file)
@@ -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)                            \
 {                                                                      \
index 1c1eea8..fc09a75 100644 (file)
@@ -25,6 +25,8 @@
 #include <sys/soundcard.h>
 #include <unistd.h>
 
+//#define DEBUG_ENABLED
+
 #include <gstaudiosink.h>
 #include <gst/meta/audioraw.h>
 
@@ -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;
   }
index 8b12b67..4d57fe0 100644 (file)
@@ -1,10 +1,10 @@
+#include <pthread.h>
 #include <sys/time.h>
 #include <linux/linkage.h>
 #include <stdio.h>   
 #include <stdlib.h>
 #include <signal.h>   
 #include <setjmp.h>
-#include <pthread.h>
 #include <unistd.h>
 #include <sys/mman.h>
 
@@ -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));
   }
index 42934ac..c8c8976 100644 (file)
@@ -1,17 +1,22 @@
 #include <stdio.h>
 
+#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);
 }