summaryrefslogtreecommitdiffstats
path: root/mpeglib/lib/util/abstract
diff options
context:
space:
mode:
Diffstat (limited to 'mpeglib/lib/util/abstract')
-rw-r--r--mpeglib/lib/util/abstract/Makefile.am14
-rw-r--r--mpeglib/lib/util/abstract/abs_thread.h123
-rw-r--r--mpeglib/lib/util/abstract/abs_thread_sdl.cpp89
-rw-r--r--mpeglib/lib/util/abstract/threadQueue.cpp108
-rw-r--r--mpeglib/lib/util/abstract/threadQueue.h74
5 files changed, 408 insertions, 0 deletions
diff --git a/mpeglib/lib/util/abstract/Makefile.am b/mpeglib/lib/util/abstract/Makefile.am
new file mode 100644
index 00000000..a5c49d6b
--- /dev/null
+++ b/mpeglib/lib/util/abstract/Makefile.am
@@ -0,0 +1,14 @@
+# player - Makefile.am
+
+
+INCLUDES = $(all_includes)
+
+noinst_LTLIBRARIES = libutilabstract.la
+
+kmpgincludedir = $(includedir)/$(THIS_LIB_NAME)/util/abstract
+
+kmpginclude_HEADERS = abs_thread.h threadQueue.h
+
+
+libutilabstract_la_SOURCES = abs_thread_sdl.cpp threadQueue.cpp
+
diff --git a/mpeglib/lib/util/abstract/abs_thread.h b/mpeglib/lib/util/abstract/abs_thread.h
new file mode 100644
index 00000000..f65445d8
--- /dev/null
+++ b/mpeglib/lib/util/abstract/abs_thread.h
@@ -0,0 +1,123 @@
+/*
+ abstraction for threads
+ Copyright (C) 2000 Martin Vogt
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Library General Public License as published by
+ the Free Software Foundation.
+
+ For more information look at the file COPYRIGHT in this package
+
+ */
+
+
+#ifndef __ABS_THREAD_H
+#define __ABS_THREAD_H
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+/**
+ This passed alle pthread_xxx calls to this interface, thus
+ it can be easier replaced with other thread "layers"
+
+ All posix pthread calls are conveterd to abs_thread.
+*/
+
+extern "C" {
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+}
+
+#define _ABS_BUSY EBUSY
+
+#ifndef SDL_WRAPPER
+// definitions for direct pthread support
+#include <pthread.h>
+
+typedef pthread_mutex_t abs_thread_mutex_t;
+typedef pthread_cond_t abs_thread_cond_t;
+typedef pthread_t abs_thread_t;
+
+
+
+#define abs_thread_cond_init(cond) pthread_cond_init(cond,NULL)
+#define abs_thread_cond_destroy(cond) pthread_cond_destroy(cond)
+#define abs_thread_cond_signal(cond) pthread_cond_signal(cond)
+#define abs_thread_cond_wait(cond,mutex) pthread_cond_wait(cond,mutex)
+
+// CREATE / JOIN THREAD
+
+#define abs_thread_create(thread,func,arg) pthread_create(thread,NULL,func,arg)
+#define abs_thread_join(th,thread_return) pthread_join(th,thread_return)
+
+// MUTEX FUNCTIONS
+
+#define abs_thread_mutex_lock(mutex) pthread_mutex_lock(mutex)
+#define abs_thread_mutex_unlock(mutex) pthread_mutex_unlock(mutex)
+#define abs_thread_mutex_init(mutex) pthread_mutex_init(mutex,NULL)
+#define abs_thread_mutex_destroy(mutex) pthread_mutex_destroy(mutex)
+
+#endif
+// not SDL_WRAPPER
+
+#ifdef SDL_WRAPPER
+
+
+// SDL SUPPORT DISABLED
+
+#if defined WIN32
+ #include <SDL_thread.h>
+ #include <SDL_mutex.h>
+#else
+ #include <SDL/SDL_thread.h>
+ #include <SDL/SDL_mutex.h>
+#endif
+
+
+typedef SDL_mutex* abs_thread_mutex_t;
+typedef SDL_cond* abs_thread_cond_t;
+typedef SDL_Thread* abs_thread_t;
+
+// SIGNAL FUNCTIONS
+// note we have _no_ cond attribut (not needed)
+int abs_thread_cond_init(abs_thread_cond_t* cond);
+int abs_thread_cond_destroy(abs_thread_cond_t *cond);
+
+int abs_thread_cond_signal(abs_thread_cond_t* cond);
+
+int abs_thread_cond_wait(abs_thread_cond_t* cond,
+ abs_thread_mutex_t *mutex);
+// CREATE / JOIN THREAD
+// Note: we have thread attribute
+int abs_thread_create(abs_thread_t* thread,
+ void * (*start_routine)(void *), void * arg);
+
+int abs_thread_join(abs_thread_t th,
+ void **thread_return);
+
+
+// MUTEX FUNCTIONS
+
+int abs_thread_mutex_lock(abs_thread_mutex_t *mutex);
+int abs_thread_mutex_trylock(abs_thread_mutex_t *mutex);
+int abs_thread_mutex_unlock(abs_thread_mutex_t *mutex);
+// not attribute!
+int abs_thread_mutex_init(abs_thread_mutex_t *mutex);
+
+int abs_thread_mutex_destroy(abs_thread_mutex_t *mutex);
+
+
+
+#endif
+//SDL_WRAPPER
+
+
+
+#endif
+
+
diff --git a/mpeglib/lib/util/abstract/abs_thread_sdl.cpp b/mpeglib/lib/util/abstract/abs_thread_sdl.cpp
new file mode 100644
index 00000000..13c9ce6c
--- /dev/null
+++ b/mpeglib/lib/util/abstract/abs_thread_sdl.cpp
@@ -0,0 +1,89 @@
+/*
+ abstraction for threads
+ Copyright (C) 2000 Martin Vogt
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Library General Public License as published by
+ the Free Software Foundation.
+
+ For more information look at the file COPYRIGHT in this package
+
+ */
+
+
+#include "abs_thread.h"
+
+
+// START SDL
+
+
+#ifdef SDL_WRAPPER
+
+
+
+int abs_thread_cond_init(abs_thread_cond_t* cond) {
+ *cond=SDL_CreateCond();
+ return (*cond != NULL);
+}
+
+int abs_thread_cond_destroy(abs_thread_cond_t *cond) {
+ SDL_DestroyCond(*cond);
+ return true;
+}
+
+
+int abs_thread_cond_signal(abs_thread_cond_t* cond) {
+
+ return SDL_CondSignal(*cond);
+}
+
+
+int abs_thread_cond_wait(abs_thread_cond_t* cond,
+ abs_thread_mutex_t* mutex) {
+ SDL_CondWait(*cond,*mutex);
+ return true;
+}
+
+
+// CREATE / JOIN THREAD
+int abs_thread_create(abs_thread_t* thread,
+ void * (*start_routine)(void *), void * arg) {
+ int (*func)(void *);
+ func=(int (*)(void *))start_routine;
+ *thread=SDL_CreateThread(func,arg);
+ return (*thread != NULL);
+}
+
+int abs_thread_join(abs_thread_t th,
+ void **thread_return) {
+ SDL_WaitThread(th,(int*)*thread_return);
+ return true;
+}
+
+
+// MUTEX FUNCTIONS
+
+int abs_thread_mutex_lock(abs_thread_mutex_t *mutex) {
+ return SDL_LockMutex(*mutex);
+}
+
+
+int abs_thread_mutex_unlock(abs_thread_mutex_t *mutex) {
+ return SDL_UnlockMutex(*mutex);
+}
+
+
+int abs_thread_mutex_init(abs_thread_mutex_t *mutex) {
+ *mutex=SDL_CreateMutex();
+ return true;
+}
+
+
+int abs_thread_mutex_destroy(abs_thread_mutex_t *mutex) {
+ SDL_DestroyMutex(*mutex);
+ return true;
+}
+
+
+
+#endif
diff --git a/mpeglib/lib/util/abstract/threadQueue.cpp b/mpeglib/lib/util/abstract/threadQueue.cpp
new file mode 100644
index 00000000..1b130ba9
--- /dev/null
+++ b/mpeglib/lib/util/abstract/threadQueue.cpp
@@ -0,0 +1,108 @@
+/*
+ fifo waitqueue for threads.(Multi-in, single out)
+ Copyright (C) 2000 Martin Vogt
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Library General Public License as published by
+ the Free Software Foundation.
+
+ For more information look at the file COPYRIGHT in this package
+
+ */
+
+#include "threadQueue.h"
+
+#define _MAX_THREAD_IN_QUEUE 5
+
+#include <iostream>
+
+using namespace std;
+
+//
+// WaitThreadEntry class [START]
+//
+
+WaitThreadEntry::WaitThreadEntry() {
+ abs_thread_cond_init(&waitCond);
+}
+
+
+WaitThreadEntry::~WaitThreadEntry() {
+ abs_thread_cond_destroy(&waitCond);
+}
+
+//
+// WaitThreadEntry class [END]
+//
+
+
+ThreadQueue::ThreadQueue() {
+ waitThreadEntries=new WaitThreadEntry* [_MAX_THREAD_IN_QUEUE];
+ int i;
+ for(i=0;i<_MAX_THREAD_IN_QUEUE;i++) {
+ waitThreadEntries[i]=new WaitThreadEntry();
+ }
+ abs_thread_mutex_init(&queueMut);
+ insertPos=0;
+ removePos=0;
+ size=0;
+}
+
+
+ThreadQueue::~ThreadQueue() {
+ abs_thread_mutex_lock(&queueMut);
+ if (size != 0) {
+ cout << "Aieee! Make sure that all threads are out of ThreadQueue"<<endl;
+ exit(0);
+ }
+ int i;
+ for(i=0;i<_MAX_THREAD_IN_QUEUE;i++) {
+ delete waitThreadEntries[i];
+ }
+ delete [] waitThreadEntries;
+ abs_thread_mutex_unlock(&queueMut);
+ abs_thread_mutex_destroy(&queueMut);
+}
+
+
+void ThreadQueue::waitForExclusiveAccess() {
+ abs_thread_mutex_lock(&queueMut);
+ if (size == 0) {
+ abs_thread_mutex_unlock(&queueMut);
+ return;
+ }
+ // wait
+ size++;
+ if (size == _MAX_THREAD_IN_QUEUE) {
+ cout << "Aieee! ThreadQueue can only buffer:"<<_MAX_THREAD_IN_QUEUE<<endl;
+ exit(0);
+ }
+ abs_thread_cond_t* waitCond=&(waitThreadEntries[insertPos]->waitCond);
+ insertPos++;
+ // wrap counter
+ if (insertPos == _MAX_THREAD_IN_QUEUE) {
+ insertPos=0;
+ }
+ abs_thread_cond_wait(waitCond,&queueMut);
+ abs_thread_mutex_unlock(&queueMut);
+}
+
+
+void ThreadQueue::releaseExclusiveAccess() {
+ abs_thread_mutex_lock(&queueMut);
+ if (size == 0) {
+ abs_thread_mutex_unlock(&queueMut);
+ return;
+ }
+ // wake up next thread
+ abs_thread_cond_t* waitCond=&(waitThreadEntries[removePos]->waitCond);
+ removePos++;
+ // wrap counter
+ if (removePos == _MAX_THREAD_IN_QUEUE) {
+ removePos=0;
+ }
+ size--;
+ abs_thread_cond_signal(waitCond);
+ abs_thread_mutex_unlock(&queueMut);
+}
+
diff --git a/mpeglib/lib/util/abstract/threadQueue.h b/mpeglib/lib/util/abstract/threadQueue.h
new file mode 100644
index 00000000..4c650e21
--- /dev/null
+++ b/mpeglib/lib/util/abstract/threadQueue.h
@@ -0,0 +1,74 @@
+/*
+ fifo waitqueue for threads.(Multi-in, single out)
+ Copyright (C) 2000 Martin Vogt
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Library General Public License as published by
+ the Free Software Foundation.
+
+ For more information look at the file COPYRIGHT in this package
+
+ */
+
+
+#ifndef __THREADQUEUE_H
+#define __THREADQUEUE_H
+
+
+#include "abs_thread.h"
+
+class WaitThreadEntry {
+ public:
+ WaitThreadEntry();
+ ~WaitThreadEntry();
+
+ abs_thread_cond_t waitCond;
+};
+
+/**
+ This class can be used as a general purpuse wrapper to
+ make C++ classes thread safe.
+ Mpeglib uses for every decoder a single thread which
+ reads from the input and write to one output type (video/audio)
+ To make the input and output classes thread safe you have
+ two solutions. First you can try to do it in every class
+ itsself, this is much work and needs understanding of
+ threads or you can use this wrapper class.
+ Normally you don't need two threads in one class, only
+ for the audio/video sync this is necessary, but for
+ the inputstream (file,http,..) this not necessary.
+ For the output this is the same.
+ This class offers two methods. waitForExclusiceAcess()
+ and releaseExlusiveAcess. Internally the thread who
+ calls waitFor.. in enqueued (if it does not get the exclusive
+ access) the thread who have the exclusive access calls
+ sometimes release.. with then pass the exclusive access
+ to the next thread.
+ Why it is needed?
+ Because we access the input/output streams from different
+ threads. A user of mpeglib may want to set mpeg video
+ in fullscreen mode, this means two threads call
+ methods in the output classes including: closing windows,
+ resizing windows ... now this is safley possible when
+ the threadSafeInputStream / threadSafeoutputStream wrappers
+ are used, which forward the calls to the real classes.
+*/
+
+class ThreadQueue {
+
+ abs_thread_mutex_t queueMut;
+ int insertPos;
+ int removePos;
+ int size;
+ WaitThreadEntry** waitThreadEntries;
+
+ public:
+ ThreadQueue();
+ ~ThreadQueue();
+
+ void waitForExclusiveAccess();
+ void releaseExclusiveAccess();
+
+};
+
+#endif