mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-25 11:11:08 +00:00
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.
This commit is contained in:
parent
7ccc2cf90b
commit
23540ccc52
14 changed files with 531 additions and 130 deletions
|
@ -59,7 +59,7 @@ libgstinclude_HEADERS = \
|
||||||
gstxml.h \
|
gstxml.h \
|
||||||
cothreads.h
|
cothreads.h
|
||||||
|
|
||||||
CFLAGS += -O2 -Wall
|
CFLAGS += -g -O2 -Wall
|
||||||
|
|
||||||
libgst_la_LIBADD = $(GLIB_LIBS) $(GTK_LIBS) $(XML_LIBS)
|
libgst_la_LIBADD = $(GLIB_LIBS) $(GTK_LIBS) $(XML_LIBS)
|
||||||
libgst_la_LDFLAGS = -version-info $(STREAMER_CURRENT):$(STREAMER_REVISION):$(STREAMER_AGE)
|
libgst_la_LDFLAGS = -version-info $(STREAMER_CURRENT):$(STREAMER_REVISION):$(STREAMER_AGE)
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
|
#include <pthread.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <linux/linkage.h>
|
#include <linux/linkage.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
#include <pthread.h>
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
|
|
||||||
|
@ -15,8 +15,11 @@ pthread_key_t _cothread_key = -1;
|
||||||
cothread_state *cothread_create(cothread_context *ctx) {
|
cothread_state *cothread_create(cothread_context *ctx) {
|
||||||
cothread_state *s;
|
cothread_state *s;
|
||||||
|
|
||||||
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);
|
s = (cothread_state *)malloc(sizeof(int) * COTHREAD_STACKSIZE);
|
||||||
|
printf("new stack at %p\n",s);
|
||||||
} else {
|
} else {
|
||||||
char *sp = CURRENT_STACK_FRAME;
|
char *sp = CURRENT_STACK_FRAME;
|
||||||
unsigned long *stack_end = (unsigned long *)((unsigned long)sp &
|
unsigned long *stack_end = (unsigned long *)((unsigned long)sp &
|
||||||
|
@ -34,11 +37,11 @@ cothread_state *cothread_create(cothread_context *ctx) {
|
||||||
s->ctx = ctx;
|
s->ctx = ctx;
|
||||||
s->threadnum = ctx->nthreads;
|
s->threadnum = ctx->nthreads;
|
||||||
s->flags = 0;
|
s->flags = 0;
|
||||||
s->sp = (int *)(s + COTHREAD_STACKSIZE);
|
s->sp = ((int *)s + COTHREAD_STACKSIZE);
|
||||||
|
|
||||||
ctx->threads[ctx->nthreads++] = s;
|
ctx->threads[ctx->nthreads++] = s;
|
||||||
|
|
||||||
// printf("created cothread at %p\n",s);
|
printf("created cothread at %p %p\n",s, s->sp);
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
@ -70,10 +73,10 @@ cothread_context *cothread_init() {
|
||||||
ctx->threads[0]->argc = 0;
|
ctx->threads[0]->argc = 0;
|
||||||
ctx->threads[0]->argv = NULL;
|
ctx->threads[0]->argv = NULL;
|
||||||
ctx->threads[0]->flags = COTHREAD_STARTED;
|
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;
|
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
|
// we consider the initiating process to be cothread 0
|
||||||
ctx->nthreads = 1;
|
ctx->nthreads = 1;
|
||||||
|
@ -91,11 +94,13 @@ void cothread_stub() {
|
||||||
cothread_context *ctx = pthread_getspecific(_cothread_key);
|
cothread_context *ctx = pthread_getspecific(_cothread_key);
|
||||||
register cothread_state *thread = ctx->threads[ctx->current];
|
register cothread_state *thread = ctx->threads[ctx->current];
|
||||||
|
|
||||||
|
printf("cothread_stub() entered\n");
|
||||||
thread->flags |= COTHREAD_STARTED;
|
thread->flags |= COTHREAD_STARTED;
|
||||||
thread->func(thread->argc,thread->argv);
|
if (thread->func)
|
||||||
|
thread->func(thread->argc,thread->argv);
|
||||||
thread->flags &= ~COTHREAD_STARTED;
|
thread->flags &= ~COTHREAD_STARTED;
|
||||||
thread->pc = 0;
|
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) {
|
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
|
// find the number of the thread to switch to
|
||||||
ctx->current = thread->threadnum;
|
ctx->current = thread->threadnum;
|
||||||
// fprintf(stderr,"about to switch to thread #%d\n",ctx->current);
|
fprintf(stderr,"about to switch to thread #%d\n",ctx->current);
|
||||||
|
|
||||||
/* save the current stack pointer, frame pointer, and pc */
|
/* save the current stack pointer, frame pointer, and pc */
|
||||||
__asm__("movl %%esp, %0" : "=m"(current->sp) : : "esp", "ebp");
|
__asm__("movl %%esp, %0" : "=m"(current->sp) : : "esp", "ebp");
|
||||||
|
@ -131,12 +136,15 @@ void cothread_switch(cothread_state *thread) {
|
||||||
return;
|
return;
|
||||||
enter = 1;
|
enter = 1;
|
||||||
|
|
||||||
|
fprintf(stderr,"set stack to %p\n", thread->sp);
|
||||||
/* restore stack pointer and other stuff of new cothread */
|
/* restore stack pointer and other stuff of new cothread */
|
||||||
__asm__("movl %0, %%esp\n" : "=m"(thread->sp));
|
|
||||||
if (thread->flags & COTHREAD_STARTED) {
|
if (thread->flags & COTHREAD_STARTED) {
|
||||||
|
fprintf(stderr,"in thread \n");
|
||||||
|
__asm__("movl %0, %%esp\n" : "=m"(thread->sp));
|
||||||
// switch to it
|
// switch to it
|
||||||
longjmp(thread->jmp,1);
|
longjmp(thread->jmp,1);
|
||||||
} else {
|
} else {
|
||||||
|
__asm__("movl %0, %%esp\n" : "=m"(thread->sp));
|
||||||
// start it
|
// start it
|
||||||
__asm__("jmp " SYMBOL_NAME_STR(cothread_stub));
|
__asm__("jmp " SYMBOL_NAME_STR(cothread_stub));
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,8 @@
|
||||||
#include <sys/soundcard.h>
|
#include <sys/soundcard.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
//#define DEBUG_ENABLED
|
||||||
|
|
||||||
#include <gstaudiosink.h>
|
#include <gstaudiosink.h>
|
||||||
#include <gst/meta/audioraw.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(GST_IS_PAD(pad));
|
||||||
g_return_if_fail(buf != NULL);
|
g_return_if_fail(buf != NULL);
|
||||||
|
|
||||||
|
|
||||||
/* this has to be an audio buffer */
|
/* this has to be an audio buffer */
|
||||||
// g_return_if_fail(((GstMeta *)buf->meta)->type !=
|
// g_return_if_fail(((GstMeta *)buf->meta)->type !=
|
||||||
//gst_audiosink_type_audio);
|
//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],
|
gtk_signal_emit(GTK_OBJECT(audiosink),gst_audiosink_signals[SIGNAL_HANDOFF],
|
||||||
audiosink);
|
audiosink);
|
||||||
|
|
||||||
if (GST_BUFFER_DATA(buf) != NULL) {
|
if (GST_BUFFER_DATA(buf) != NULL) {
|
||||||
gst_trace_add_entry(NULL,0,buf,"audiosink: writing to soundcard");
|
gst_trace_add_entry(NULL,0,buf,"audiosink: writing to soundcard");
|
||||||
//g_print("audiosink: writing to soundcard\n");
|
//g_print("audiosink: writing to soundcard\n");
|
||||||
|
@ -219,8 +223,9 @@ void gst_audiosink_chain(GstPad *pad,GstBuffer *buf) {
|
||||||
if (!audiosink->mute) {
|
if (!audiosink->mute) {
|
||||||
gst_clock_wait(audiosink->clock, GST_BUFFER_TIMESTAMP(buf), GST_OBJECT(audiosink));
|
gst_clock_wait(audiosink->clock, GST_BUFFER_TIMESTAMP(buf), GST_OBJECT(audiosink));
|
||||||
ioctl(audiosink->fd,SNDCTL_DSP_GETOSPACE,&ospace);
|
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(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");
|
g_print("audiosink: attempting to open sound device\n");
|
||||||
|
|
||||||
/* first try to open the sound card */
|
/* 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 we have it, set the default parameters and go have fun */
|
||||||
if (sink->fd > 0) {
|
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_COPROC) g_print("audiosink: Has coprocessor\n");
|
||||||
if (sink->caps & DSP_CAP_TRIGGER) g_print("audiosink: Trigger\n");
|
if (sink->caps & DSP_CAP_TRIGGER) g_print("audiosink: Trigger\n");
|
||||||
if (sink->caps & DSP_CAP_MMAP) g_print("audiosink: Direct access\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);
|
GST_FLAG_SET(sink,GST_AUDIOSINK_OPEN);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -603,8 +603,8 @@ void gst_bin_iterate_func(GstBin *bin) {
|
||||||
if (bin->need_cothreads) {
|
if (bin->need_cothreads) {
|
||||||
// all we really have to do is switch to the first child
|
// all we really have to do is switch to the first child
|
||||||
// FIXME this should be lots more intelligent about where to start
|
// FIXME this should be lots more intelligent about where to start
|
||||||
// g_print("** in gst_bin_iterate_func()==================================%s\n",
|
//g_print("** in gst_bin_iterate_func()==================================%s\n",
|
||||||
// gst_element_get_name(GST_ELEMENT(bin->children->data)));
|
// gst_element_get_name(GST_ELEMENT(bin->children->data)));
|
||||||
cothread_switch(GST_ELEMENT(bin->children->data)->threadstate);
|
cothread_switch(GST_ELEMENT(bin->children->data)->threadstate);
|
||||||
} else {
|
} else {
|
||||||
entries = bin->entries;
|
entries = bin->entries;
|
||||||
|
|
1
libs/getbits/.gitignore
vendored
1
libs/getbits/.gitignore
vendored
|
@ -5,3 +5,4 @@ Makefile.in
|
||||||
*.la
|
*.la
|
||||||
.deps
|
.deps
|
||||||
.libs
|
.libs
|
||||||
|
gbtest
|
||||||
|
|
|
@ -2,14 +2,19 @@ filterdir = $(libdir)/gst
|
||||||
|
|
||||||
filter_LTLIBRARIES = libgstgetbits.la
|
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
|
libgstgetbitsincludedir = $(includedir)/gst/libs/gstgetbits
|
||||||
libgstgetbitsinclude_HEADERS = gstgetbits.h
|
libgstgetbitsinclude_HEADERS = gstgetbits.h
|
||||||
|
|
||||||
noinst_HEADERS = gstgetbits.h gstgetbits_inl.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
|
INCLUDES = $(GLIB_CFLAGS) $(GTK_CFLAGS) -I$(top_srcdir) -I$(top_srcdir)/include
|
||||||
LDADD = $(GLIB_LIBS) $(GTK_LIBS) $(top_srcdir)/gst/libgst.la
|
LDADD = $(GLIB_LIBS) $(GTK_LIBS) $(top_srcdir)/gst/libgst.la
|
||||||
|
|
94
libs/getbits/gbtest.c
Normal file
94
libs/getbits/gbtest.c
Normal file
|
@ -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;
|
||||||
|
}
|
|
@ -1,6 +1,38 @@
|
||||||
#include <byteswap.h>
|
#include <glib.h>
|
||||||
|
|
||||||
#include "gstgetbits.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[] = {
|
unsigned long gst_getbits_nBitMask[] = {
|
||||||
0x00000000, 0x80000000, 0xc0000000, 0xe0000000,
|
0x00000000, 0x80000000, 0xc0000000, 0xe0000000,
|
||||||
0xf0000000, 0xf8000000, 0xfc000000, 0xfe000000,
|
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
|
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 */
|
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;
|
signed long remaining;
|
||||||
unsigned long result;
|
unsigned long result;
|
||||||
|
|
||||||
|
@ -63,9 +95,9 @@ unsigned long getbits_mmx(gst_getbits_t *gb,unsigned long bits) {
|
||||||
remaining += 64;
|
remaining += 64;
|
||||||
|
|
||||||
/* grab the first 32 bits from the buffer and swap them around */
|
/* 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 */
|
/* grab the second 32 bits, swap */
|
||||||
dword2 = bswap_32(*(gb->ptr-4));
|
dword2 = swab32(*(gb->ptr-4));
|
||||||
|
|
||||||
/* put second dword in mm4 */
|
/* put second dword in mm4 */
|
||||||
movd_m2r(dword2,mm4);
|
movd_m2r(dword2,mm4);
|
||||||
|
@ -130,96 +162,121 @@ unsigned long getbits_mmx(gst_getbits_t *gb,unsigned long bits) {
|
||||||
}
|
}
|
||||||
#endif /* HAVE_LIBMMX */
|
#endif /* HAVE_LIBMMX */
|
||||||
|
|
||||||
unsigned long getbits_int(gst_getbits_t *gb,unsigned long bits) {
|
unsigned long _gst_getbits_int_cb(gst_getbits_t *gb, unsigned long bits) {
|
||||||
int remaining;
|
int result;
|
||||||
int result = 0;
|
int bitsleft;
|
||||||
|
|
||||||
if (bits == 0) {
|
//printf("gst_getbits%lu %ld %p %08x\n", bits, gb->bits, gb->ptr, gb->dword);
|
||||||
// fprintf(stderr,"getbits(0) = 0\n");
|
|
||||||
return 0;
|
if (!bits) return 0;
|
||||||
}
|
|
||||||
|
gb->bits -= bits;
|
||||||
|
result = gb->dword >> (32-bits);
|
||||||
|
|
||||||
|
if (gb->bits < 0) {
|
||||||
|
|
||||||
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);
|
|
||||||
gb->ptr += 4;
|
gb->ptr += 4;
|
||||||
gb->dword = bswap_32(*((unsigned long *)(gb->ptr)));
|
|
||||||
// gb->dword = *((unsigned char *)(gb->ptr)) << 24 |
|
bitsleft = (gb->endptr - gb->ptr)*8;
|
||||||
// *((unsigned char *)(gb->ptr)+1) << 16 |
|
bits = -gb->bits;
|
||||||
// *((unsigned char *)(gb->ptr)+2) << 8 |
|
gb->bits += (bitsleft>32? 32 : bitsleft);
|
||||||
// *((unsigned char *)(gb->ptr)+3);
|
|
||||||
// gb->dword = *((unsigned long *)(gb->ptr));
|
if (gb->endptr <= gb->ptr) {
|
||||||
gb->bits = 32;
|
(gb->callback)(gb, gb->data);
|
||||||
// fprintf(stderr,"got new dword %08x\n",gb->dword);
|
gb->bits -= bits;
|
||||||
/* & in the right number of bits */
|
}
|
||||||
result |= (gb->dword >> (32 - remaining));
|
gb->dword = swab32(*((unsigned long *)(gb->ptr)));
|
||||||
/* shift the buffer over */
|
|
||||||
gb->dword <<= remaining;
|
result |= (gb->dword >> (32-bits));
|
||||||
/* 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);
|
|
||||||
}
|
}
|
||||||
// printf("have \t\t%s left\n",print_bits(gb->dword));
|
gb->dword <<= bits;
|
||||||
// fprintf(stderr,"getbits.c:getbits(%ld) = %d\n",bits,result);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void getbits_back_int(gst_getbits_t *gb,unsigned long bits) {
|
void _gst_getbits_back_int(gst_getbits_t *gb, unsigned long bits) {
|
||||||
fprintf(stderr,"getbits.c:getbits_back(%lu)\n",bits);
|
gb->bits -= bits;
|
||||||
// moving within the same dword...
|
gb->ptr += (gb->bits>>3);
|
||||||
if ((bits + gb->bits) <= 32) {
|
gb->bits &= 0x7;
|
||||||
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 getbits_byteback_int(gst_getbits_t *gb,unsigned long bytes) {
|
unsigned long _gst_showbits_int(gst_getbits_t *gb, unsigned long bits) {
|
||||||
fprintf(stderr,"getbits.c:getbits_byteback(%lu)\n",bytes);
|
unsigned long rval;
|
||||||
getbits_back_int(gb,bytes*8);
|
|
||||||
gb->bits = gb->bits & ~0x07;
|
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) {
|
unsigned long _gst_getbyte(gst_getbits_t *gb, unsigned long bits) {
|
||||||
fprintf(stderr,"getbits.c:getbits_offset() = %lu\n",gb->bits % 8);
|
return *gb->ptr++;
|
||||||
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 */
|
/* 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->ptr = NULL;
|
||||||
gb->bits = 0;
|
gb->bits = 0;
|
||||||
|
gb->callback = callback;
|
||||||
|
gb->data = data;
|
||||||
|
|
||||||
#ifdef HAVE_LIBMMX
|
#ifdef HAVE_LIBMMX
|
||||||
if (1) {
|
if (1) {
|
||||||
|
@ -229,18 +286,30 @@ void getbits_init(gst_getbits_t *gb) {
|
||||||
} else
|
} else
|
||||||
#endif /* HAVE_LIBMMX */
|
#endif /* HAVE_LIBMMX */
|
||||||
{
|
{
|
||||||
gb->getbits = getbits_int;
|
if (gb->callback) {
|
||||||
gb->backbits = getbits_back_int;
|
gb->getbits = _gst_getbits_int_cb;
|
||||||
gb->backbytes = getbits_byteback_int;
|
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 */
|
/* set up the getbits structure with a new buffer */
|
||||||
void getbits_newbuf(gst_getbits_t *gb,unsigned char *buffer) {
|
void gst_getbits_newbuf(gst_getbits_t *gb,unsigned char *buffer, unsigned long len) {
|
||||||
gb->ptr = buffer - 4;
|
gb->ptr = buffer;
|
||||||
// fprintf(stderr,"setting ptr to %p\n",gb->ptr);
|
gb->endptr = buffer+len;
|
||||||
gb->bits = 0;
|
gb->bits = 0;
|
||||||
gb->dword = 0;
|
|
||||||
#ifdef HAVE_LIBMMX
|
#ifdef HAVE_LIBMMX
|
||||||
// gb->qword = 0;
|
// gb->qword = 0;
|
||||||
#endif /* HAVE_LIBMMX */
|
#endif /* HAVE_LIBMMX */
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#endif /* HAVE_LIBSSE */
|
#endif /* HAVE_LIBSSE */
|
||||||
|
|
||||||
typedef struct _gst_getbits_t gst_getbits_t;
|
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 */
|
/* breaks in structure show alignment on quadword boundaries */
|
||||||
/* FIXME: need to find out how to force GCC to align this to octwords */
|
/* 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 dword;
|
||||||
unsigned long temp;
|
unsigned long temp;
|
||||||
|
|
||||||
unsigned long (*getbits)(gst_getbits_t *gb,unsigned long bits); /* dword */
|
GstGetbitsCallback callback;
|
||||||
void (*backbits)(gst_getbits_t *gb,unsigned long bits); /* dword */
|
void *data;
|
||||||
void (*backbytes)(gst_getbits_t *gb,unsigned long bytes); /* dword */
|
|
||||||
|
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
|
#ifdef HAVE_LIBMMX
|
||||||
mmx_t qword; /* qword */
|
mmx_t qword; /* qword */
|
||||||
|
@ -42,18 +51,95 @@ struct _gst_getbits_t {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#define GST_GETBITS_INLINE
|
|
||||||
|
|
||||||
#ifdef GST_GETBITS_INLINE
|
#ifdef GST_GETBITS_INLINE
|
||||||
#include "gstgetbits_inl.h"
|
#include "gstgetbits_inl.h"
|
||||||
#else
|
#else
|
||||||
|
|
||||||
void gst_getbits_init(gst_getbits_t *gb);
|
void gst_getbits_init(gst_getbits_t *gb, GstGetbitsCallback callback, void *data);
|
||||||
void gst_getbits_newbuf(gst_getbits_t *gb,unsigned char *buffer);
|
void gst_getbits_newbuf(gst_getbits_t *gb, unsigned char *buffer, unsigned long len);
|
||||||
|
|
||||||
#define getbits(gb,bits) (((gb)->getbits)(gb,bits))
|
#define gst_getbits_bitoffset(gb) \
|
||||||
#define getbits_back(gb,bits) (((gb)->backbits)(gb,bits))
|
( \
|
||||||
#define getbits_back_bytes(gb,bytes) (((gb)->backbytes)(gb,bytes))
|
(-(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
|
||||||
|
|
||||||
#endif /* __GST_GETBITS_H__ */
|
#endif /* __GST_GETBITS_H__ */
|
||||||
|
|
115
libs/getbits/gstgetbits_i386.s
Normal file
115
libs/getbits/gstgetbits_i386.s
Normal file
|
@ -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
|
||||||
|
|
|
@ -93,7 +93,7 @@
|
||||||
/* External declarations for bitstream i/o operations. */
|
/* External declarations for bitstream i/o operations. */
|
||||||
extern unsigned long gst_getbits_nBitMask[];
|
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) \
|
#define gst_getbits_newbuf(gb, buffer, len) \
|
||||||
{ \
|
{ \
|
||||||
|
|
|
@ -25,6 +25,8 @@
|
||||||
#include <sys/soundcard.h>
|
#include <sys/soundcard.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
//#define DEBUG_ENABLED
|
||||||
|
|
||||||
#include <gstaudiosink.h>
|
#include <gstaudiosink.h>
|
||||||
#include <gst/meta/audioraw.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(GST_IS_PAD(pad));
|
||||||
g_return_if_fail(buf != NULL);
|
g_return_if_fail(buf != NULL);
|
||||||
|
|
||||||
|
|
||||||
/* this has to be an audio buffer */
|
/* this has to be an audio buffer */
|
||||||
// g_return_if_fail(((GstMeta *)buf->meta)->type !=
|
// g_return_if_fail(((GstMeta *)buf->meta)->type !=
|
||||||
//gst_audiosink_type_audio);
|
//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],
|
gtk_signal_emit(GTK_OBJECT(audiosink),gst_audiosink_signals[SIGNAL_HANDOFF],
|
||||||
audiosink);
|
audiosink);
|
||||||
|
|
||||||
if (GST_BUFFER_DATA(buf) != NULL) {
|
if (GST_BUFFER_DATA(buf) != NULL) {
|
||||||
gst_trace_add_entry(NULL,0,buf,"audiosink: writing to soundcard");
|
gst_trace_add_entry(NULL,0,buf,"audiosink: writing to soundcard");
|
||||||
//g_print("audiosink: writing to soundcard\n");
|
//g_print("audiosink: writing to soundcard\n");
|
||||||
|
@ -219,8 +223,9 @@ void gst_audiosink_chain(GstPad *pad,GstBuffer *buf) {
|
||||||
if (!audiosink->mute) {
|
if (!audiosink->mute) {
|
||||||
gst_clock_wait(audiosink->clock, GST_BUFFER_TIMESTAMP(buf), GST_OBJECT(audiosink));
|
gst_clock_wait(audiosink->clock, GST_BUFFER_TIMESTAMP(buf), GST_OBJECT(audiosink));
|
||||||
ioctl(audiosink->fd,SNDCTL_DSP_GETOSPACE,&ospace);
|
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(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");
|
g_print("audiosink: attempting to open sound device\n");
|
||||||
|
|
||||||
/* first try to open the sound card */
|
/* 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 we have it, set the default parameters and go have fun */
|
||||||
if (sink->fd > 0) {
|
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_COPROC) g_print("audiosink: Has coprocessor\n");
|
||||||
if (sink->caps & DSP_CAP_TRIGGER) g_print("audiosink: Trigger\n");
|
if (sink->caps & DSP_CAP_TRIGGER) g_print("audiosink: Trigger\n");
|
||||||
if (sink->caps & DSP_CAP_MMAP) g_print("audiosink: Direct access\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);
|
GST_FLAG_SET(sink,GST_AUDIOSINK_OPEN);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
|
#include <pthread.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <linux/linkage.h>
|
#include <linux/linkage.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
#include <pthread.h>
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
|
|
||||||
|
@ -15,8 +15,11 @@ pthread_key_t _cothread_key = -1;
|
||||||
cothread_state *cothread_create(cothread_context *ctx) {
|
cothread_state *cothread_create(cothread_context *ctx) {
|
||||||
cothread_state *s;
|
cothread_state *s;
|
||||||
|
|
||||||
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);
|
s = (cothread_state *)malloc(sizeof(int) * COTHREAD_STACKSIZE);
|
||||||
|
printf("new stack at %p\n",s);
|
||||||
} else {
|
} else {
|
||||||
char *sp = CURRENT_STACK_FRAME;
|
char *sp = CURRENT_STACK_FRAME;
|
||||||
unsigned long *stack_end = (unsigned long *)((unsigned long)sp &
|
unsigned long *stack_end = (unsigned long *)((unsigned long)sp &
|
||||||
|
@ -34,11 +37,11 @@ cothread_state *cothread_create(cothread_context *ctx) {
|
||||||
s->ctx = ctx;
|
s->ctx = ctx;
|
||||||
s->threadnum = ctx->nthreads;
|
s->threadnum = ctx->nthreads;
|
||||||
s->flags = 0;
|
s->flags = 0;
|
||||||
s->sp = (int *)(s + COTHREAD_STACKSIZE);
|
s->sp = ((int *)s + COTHREAD_STACKSIZE);
|
||||||
|
|
||||||
ctx->threads[ctx->nthreads++] = s;
|
ctx->threads[ctx->nthreads++] = s;
|
||||||
|
|
||||||
// printf("created cothread at %p\n",s);
|
printf("created cothread at %p %p\n",s, s->sp);
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
@ -56,7 +59,7 @@ cothread_context *cothread_init() {
|
||||||
if (_cothread_key == -1) {
|
if (_cothread_key == -1) {
|
||||||
if (pthread_key_create(&_cothread_key,NULL) != 0) {
|
if (pthread_key_create(&_cothread_key,NULL) != 0) {
|
||||||
perror("pthread_key_create");
|
perror("pthread_key_create");
|
||||||
return;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pthread_setspecific(_cothread_key,ctx);
|
pthread_setspecific(_cothread_key,ctx);
|
||||||
|
@ -70,10 +73,10 @@ cothread_context *cothread_init() {
|
||||||
ctx->threads[0]->argc = 0;
|
ctx->threads[0]->argc = 0;
|
||||||
ctx->threads[0]->argv = NULL;
|
ctx->threads[0]->argv = NULL;
|
||||||
ctx->threads[0]->flags = COTHREAD_STARTED;
|
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;
|
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
|
// we consider the initiating process to be cothread 0
|
||||||
ctx->nthreads = 1;
|
ctx->nthreads = 1;
|
||||||
|
@ -91,11 +94,13 @@ void cothread_stub() {
|
||||||
cothread_context *ctx = pthread_getspecific(_cothread_key);
|
cothread_context *ctx = pthread_getspecific(_cothread_key);
|
||||||
register cothread_state *thread = ctx->threads[ctx->current];
|
register cothread_state *thread = ctx->threads[ctx->current];
|
||||||
|
|
||||||
|
printf("cothread_stub() entered\n");
|
||||||
thread->flags |= COTHREAD_STARTED;
|
thread->flags |= COTHREAD_STARTED;
|
||||||
thread->func(thread->argc,thread->argv);
|
if (thread->func)
|
||||||
|
thread->func(thread->argc,thread->argv);
|
||||||
thread->flags &= ~COTHREAD_STARTED;
|
thread->flags &= ~COTHREAD_STARTED;
|
||||||
thread->pc = 0;
|
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) {
|
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
|
// find the number of the thread to switch to
|
||||||
ctx->current = thread->threadnum;
|
ctx->current = thread->threadnum;
|
||||||
// fprintf(stderr,"about to switch to thread #%d\n",ctx->current);
|
fprintf(stderr,"about to switch to thread #%d\n",ctx->current);
|
||||||
|
|
||||||
/* save the current stack pointer, frame pointer, and pc */
|
/* save the current stack pointer, frame pointer, and pc */
|
||||||
__asm__("movl %%esp, %0" : "=m"(current->sp) : : "esp", "ebp");
|
__asm__("movl %%esp, %0" : "=m"(current->sp) : : "esp", "ebp");
|
||||||
|
@ -131,12 +136,15 @@ void cothread_switch(cothread_state *thread) {
|
||||||
return;
|
return;
|
||||||
enter = 1;
|
enter = 1;
|
||||||
|
|
||||||
|
fprintf(stderr,"set stack to %p\n", thread->sp);
|
||||||
/* restore stack pointer and other stuff of new cothread */
|
/* restore stack pointer and other stuff of new cothread */
|
||||||
__asm__("movl %0, %%esp\n" : "=m"(thread->sp));
|
|
||||||
if (thread->flags & COTHREAD_STARTED) {
|
if (thread->flags & COTHREAD_STARTED) {
|
||||||
|
fprintf(stderr,"in thread \n");
|
||||||
|
__asm__("movl %0, %%esp\n" : "=m"(thread->sp));
|
||||||
// switch to it
|
// switch to it
|
||||||
longjmp(thread->jmp,1);
|
longjmp(thread->jmp,1);
|
||||||
} else {
|
} else {
|
||||||
|
__asm__("movl %0, %%esp\n" : "=m"(thread->sp));
|
||||||
// start it
|
// start it
|
||||||
__asm__("jmp " SYMBOL_NAME_STR(cothread_stub));
|
__asm__("jmp " SYMBOL_NAME_STR(cothread_stub));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,22 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "glib.h"
|
||||||
#include "cothreads.h"
|
#include "cothreads.h"
|
||||||
#include "object.h"
|
#include "object.h"
|
||||||
#include "looper.h"
|
#include "looper.h"
|
||||||
|
|
||||||
|
cothread_context *ctx;
|
||||||
|
|
||||||
int main(int argc,char *argv[]) {
|
int main(int argc,char *argv[]) {
|
||||||
cothread_context *ctx = cothread_init();
|
|
||||||
looper *l1,*l2;
|
looper *l1,*l2;
|
||||||
|
|
||||||
|
ctx = cothread_init();
|
||||||
|
|
||||||
l1 = looper_create("looperone",1,ctx);
|
l1 = looper_create("looperone",1,ctx);
|
||||||
l2 = looper_create("loopertwo",0,ctx);
|
l2 = looper_create("loopertwo",0,ctx);
|
||||||
object_setpeer(OBJECT(l1),OBJECT(l2));
|
object_setpeer(OBJECT(l1),OBJECT(l2));
|
||||||
|
|
||||||
fprintf(stderr,"about to start l1\n\n");
|
fprintf(stderr,"about to start l1\n\n");
|
||||||
object_start(l1);
|
while (1)
|
||||||
|
object_start(l1);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue