From e2de64d6f1beb9e492daf5b886e19933c1fa41dd Mon Sep 17 00:00:00 2001 From: toma Date: Wed, 25 Nov 2009 17:56:58 +0000 Subject: Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features. BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdemultimedia@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da --- mpeglib/lib/util/abstract/Makefile.am | 14 +++ mpeglib/lib/util/abstract/abs_thread.h | 123 +++++++++++++++++++++++++++ mpeglib/lib/util/abstract/abs_thread_sdl.cpp | 89 +++++++++++++++++++ mpeglib/lib/util/abstract/threadQueue.cpp | 108 +++++++++++++++++++++++ mpeglib/lib/util/abstract/threadQueue.h | 74 ++++++++++++++++ 5 files changed, 408 insertions(+) create mode 100644 mpeglib/lib/util/abstract/Makefile.am create mode 100644 mpeglib/lib/util/abstract/abs_thread.h create mode 100644 mpeglib/lib/util/abstract/abs_thread_sdl.cpp create mode 100644 mpeglib/lib/util/abstract/threadQueue.cpp create mode 100644 mpeglib/lib/util/abstract/threadQueue.h (limited to 'mpeglib/lib/util/abstract') 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 +#include +#include +#include +} + +#define _ABS_BUSY EBUSY + +#ifndef SDL_WRAPPER +// definitions for direct pthread support +#include + +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 + #include +#else + #include + #include +#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 + +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"<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 -- cgit v1.2.1