summaryrefslogtreecommitdiffstats
path: root/mpeglib/lib/util
diff options
context:
space:
mode:
Diffstat (limited to 'mpeglib/lib/util')
-rw-r--r--mpeglib/lib/util/Makefile.am61
-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
-rw-r--r--mpeglib/lib/util/audio/Makefile.am18
-rw-r--r--mpeglib/lib/util/audio/audioIO.cpp49
-rw-r--r--mpeglib/lib/util/audio/audioIO.h80
-rw-r--r--mpeglib/lib/util/audio/audioIO_AIX.cpp533
-rw-r--r--mpeglib/lib/util/audio/audioIO_BeOS.cpp227
-rw-r--r--mpeglib/lib/util/audio/audioIO_HPUX.cpp190
-rw-r--r--mpeglib/lib/util/audio/audioIO_IRIX.cpp157
-rw-r--r--mpeglib/lib/util/audio/audioIO_Linux.cpp220
-rw-r--r--mpeglib/lib/util/audio/audioIO_SDL.cpp164
-rw-r--r--mpeglib/lib/util/audio/audioIO_SunOS.cpp167
-rw-r--r--mpeglib/lib/util/audio/dspWrapper.cpp193
-rw-r--r--mpeglib/lib/util/audio/dspWrapper.h75
-rw-r--r--mpeglib/lib/util/dynBuffer.cpp166
-rw-r--r--mpeglib/lib/util/dynBuffer.h63
-rw-r--r--mpeglib/lib/util/file/Makefile.am25
-rw-r--r--mpeglib/lib/util/file/fileAccess.cpp95
-rw-r--r--mpeglib/lib/util/file/fileAccess.h46
-rw-r--r--mpeglib/lib/util/mmx/Makefile.am46
-rw-r--r--mpeglib/lib/util/mmx/attribute.h33
-rw-r--r--mpeglib/lib/util/mmx/cpu_accel.c162
-rw-r--r--mpeglib/lib/util/mmx/mm_accel.h58
-rw-r--r--mpeglib/lib/util/mmx/mmx.c73
-rw-r--r--mpeglib/lib/util/mmx/mmx.h26
-rw-r--r--mpeglib/lib/util/mmx/mmx_asm.h258
-rw-r--r--mpeglib/lib/util/render/Makefile.am59
-rw-r--r--mpeglib/lib/util/render/dither/Makefile.am40
-rw-r--r--mpeglib/lib/util/render/dither/colorTable8Bit.cpp147
-rw-r--r--mpeglib/lib/util/render/dither/colorTable8Bit.h57
-rw-r--r--mpeglib/lib/util/render/dither/colorTableHighBit.cpp248
-rw-r--r--mpeglib/lib/util/render/dither/colorTableHighBit.h73
-rw-r--r--mpeglib/lib/util/render/dither/dither16Bit.cpp300
-rw-r--r--mpeglib/lib/util/render/dither/dither16Bit.h55
-rw-r--r--mpeglib/lib/util/render/dither/dither32Bit.cpp253
-rw-r--r--mpeglib/lib/util/render/dither/dither32Bit.h55
-rw-r--r--mpeglib/lib/util/render/dither/dither32mmx.cpp272
-rw-r--r--mpeglib/lib/util/render/dither/dither8Bit.cpp306
-rw-r--r--mpeglib/lib/util/render/dither/dither8Bit.h63
-rw-r--r--mpeglib/lib/util/render/dither/ditherDef.h100
-rw-r--r--mpeglib/lib/util/render/dither/ditherMMX.h38
-rw-r--r--mpeglib/lib/util/render/dither/ditherRGB.cpp230
-rw-r--r--mpeglib/lib/util/render/dither/ditherRGB.h45
-rw-r--r--mpeglib/lib/util/render/dither/ditherRGB_flipped.cpp82
-rw-r--r--mpeglib/lib/util/render/dither/ditherRGB_flipped.h34
-rw-r--r--mpeglib/lib/util/render/dither/ditherWrapper.cpp246
-rw-r--r--mpeglib/lib/util/render/dither/ditherWrapper.h80
-rw-r--r--mpeglib/lib/util/render/dither/ditherer_mmx16.cpp256
-rw-r--r--mpeglib/lib/util/render/dither2YUV/Makefile.am22
-rw-r--r--mpeglib/lib/util/render/dither2YUV/README13
-rw-r--r--mpeglib/lib/util/render/dither2YUV/dither2YUV.cpp124
-rw-r--r--mpeglib/lib/util/render/dither2YUV/dither2YUV.h64
-rw-r--r--mpeglib/lib/util/render/dither2YUV/rgb2yuv16.cpp916
-rw-r--r--mpeglib/lib/util/render/dither2YUV/rgb2yuv16.h74
-rw-r--r--mpeglib/lib/util/render/dither2YUV/rgb2yuv32.cpp1143
-rw-r--r--mpeglib/lib/util/render/dither2YUV/rgb2yuv32.h93
-rw-r--r--mpeglib/lib/util/render/dither2YUV/rgb2yuvdefs.h74
-rw-r--r--mpeglib/lib/util/render/imageBase.cpp76
-rw-r--r--mpeglib/lib/util/render/imageBase.h140
-rw-r--r--mpeglib/lib/util/render/pictureArray.cpp101
-rw-r--r--mpeglib/lib/util/render/pictureArray.h76
-rw-r--r--mpeglib/lib/util/render/renderMachine.cpp205
-rw-r--r--mpeglib/lib/util/render/renderMachine.h90
-rw-r--r--mpeglib/lib/util/render/sdl/Makefile.am43
-rw-r--r--mpeglib/lib/util/render/sdl/imageDeskSDL.cpp110
-rw-r--r--mpeglib/lib/util/render/sdl/imageDeskSDL.h65
-rw-r--r--mpeglib/lib/util/render/sdl/sdlSurface.cpp219
-rw-r--r--mpeglib/lib/util/render/sdl/sdlSurface.h78
-rw-r--r--mpeglib/lib/util/render/surface.cpp117
-rw-r--r--mpeglib/lib/util/render/surface.h55
-rw-r--r--mpeglib/lib/util/render/x11/Makefile.am48
-rw-r--r--mpeglib/lib/util/render/x11/imageDGAFull.cpp289
-rw-r--r--mpeglib/lib/util/render/x11/imageDGAFull.h131
-rw-r--r--mpeglib/lib/util/render/x11/imageDeskX11.cpp439
-rw-r--r--mpeglib/lib/util/render/x11/imageDeskX11.h85
-rw-r--r--mpeglib/lib/util/render/x11/imageXVDesk.cpp405
-rw-r--r--mpeglib/lib/util/render/x11/imageXVDesk.h88
-rw-r--r--mpeglib/lib/util/render/x11/initDisplay.cpp255
-rw-r--r--mpeglib/lib/util/render/x11/initDisplay.h34
-rw-r--r--mpeglib/lib/util/render/x11/x11Surface.cpp389
-rw-r--r--mpeglib/lib/util/render/x11/x11Surface.h79
-rw-r--r--mpeglib/lib/util/render/x11/xinit.h99
-rw-r--r--mpeglib/lib/util/render/yuvPicture.cpp253
-rw-r--r--mpeglib/lib/util/render/yuvPicture.h110
-rw-r--r--mpeglib/lib/util/syncClock.cpp59
-rw-r--r--mpeglib/lib/util/syncClock.h61
-rw-r--r--mpeglib/lib/util/syncClockMPEG.cpp221
-rw-r--r--mpeglib/lib/util/syncClockMPEG.h77
-rw-r--r--mpeglib/lib/util/timeStamp.cpp273
-rw-r--r--mpeglib/lib/util/timeStamp.h92
-rw-r--r--mpeglib/lib/util/timeStampArray.cpp178
-rw-r--r--mpeglib/lib/util/timeStampArray.h85
-rw-r--r--mpeglib/lib/util/timeWrapper.cpp77
-rw-r--r--mpeglib/lib/util/timeWrapper.h44
98 files changed, 14401 insertions, 0 deletions
diff --git a/mpeglib/lib/util/Makefile.am b/mpeglib/lib/util/Makefile.am
new file mode 100644
index 00000000..c73de2cc
--- /dev/null
+++ b/mpeglib/lib/util/Makefile.am
@@ -0,0 +1,61 @@
+# player - Makefile.am
+
+SUBDIRS = mmx abstract audio file render
+
+
+INCLUDES = $(all_includes)
+
+
+
+THIS_EXTRALIBS = abstract/libutilabstract.la \
+ audio/libaudio.la \
+ file/libsimplefile.la \
+ render/libutilrender.la \
+ mmx/libmmx.la
+
+
+noinst_LTLIBRARIES = libutil.la
+
+noinst_HEADERS = syncClockMPEG.h
+
+kmpgincludedir = $(includedir)/$(THIS_LIB_NAME)/util
+
+kmpginclude_HEADERS = timeStamp.h dynBuffer.h \
+ timeStampArray.h syncClock.h timeWrapper.h
+
+
+
+libutil_la_SOURCES = timeStamp.cpp \
+ timeStampArray.cpp \
+ dynBuffer.cpp syncClock.cpp \
+ syncClockMPEG.cpp timeWrapper.cpp
+
+libutil_la_LIBADD = $(THIS_EXTRALIBS)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
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
diff --git a/mpeglib/lib/util/audio/Makefile.am b/mpeglib/lib/util/audio/Makefile.am
new file mode 100644
index 00000000..968d1d46
--- /dev/null
+++ b/mpeglib/lib/util/audio/Makefile.am
@@ -0,0 +1,18 @@
+
+# ---- @OS_TYPE@/@ARCH_TYPE@ ----
+
+INCLUDES = $(all_includes)
+
+EXTRA_DIST = audioIO_AIX.cpp audioIO_BeOS.cpp \
+ audioIO_HPUX.cpp \
+ audioIO_IRIX.cpp audioIO_Linux.cpp \
+ audioIO_SunOS.cpp audioIO_SDL.cpp
+
+noinst_HEADERS = audioIO.h dspWrapper.h
+
+noinst_LTLIBRARIES = libaudio.la
+
+libaudio_la_SOURCES = audioIO.cpp dspWrapper.cpp
+
+
+
diff --git a/mpeglib/lib/util/audio/audioIO.cpp b/mpeglib/lib/util/audio/audioIO.cpp
new file mode 100644
index 00000000..d066210f
--- /dev/null
+++ b/mpeglib/lib/util/audio/audioIO.cpp
@@ -0,0 +1,49 @@
+
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+
+#ifdef SDL_WRAPPER
+
+ #include "audioIO_SDL.cpp"
+
+//
+// If native sound is defined compiled for that
+//
+
+#else
+
+
+#ifdef OS_AIX
+ #include "audioIO_AIX.cpp"
+#endif
+
+#ifdef OS_Linux
+ #include "audioIO_Linux.cpp"
+#endif
+
+#ifdef OS_BSD
+ #include "audioIO_Linux.cpp"
+#endif
+
+#if defined(OS_IRIX) || defined(OS_IRIX64)
+ #include "audioIO_IRIX.cpp"
+#endif
+
+#ifdef OS_HPUX
+ #include "audioIO_HPUX.cpp"
+#endif
+
+#ifdef OS_SunOS
+ #include "audioIO_SunOS.cpp"
+#endif
+
+#ifdef __BEOS__
+ #include "audioIO_BeOS.cpp"
+#endif
+
+
+#endif
diff --git a/mpeglib/lib/util/audio/audioIO.h b/mpeglib/lib/util/audio/audioIO.h
new file mode 100644
index 00000000..41e1ceb2
--- /dev/null
+++ b/mpeglib/lib/util/audio/audioIO.h
@@ -0,0 +1,80 @@
+
+
+#ifndef __AUDIOIO_H
+#define __AUDIOIO_H
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+
+
+extern "C" {
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <stdlib.h>
+}
+
+/* AUSUZ should be the amount of data your audio device will accept after it
+ * has said it is ready to receive data. ie when the device is ready
+ * for data it
+ * will accept it without blocking. It must also be a multiple of 128
+ */
+
+#ifdef OS_AIX
+ #define AUSIZ 32768
+#endif
+
+#ifdef OS_Linux
+ extern int AUSIZ;
+#endif
+
+#ifdef OS_BSD
+ #define AUSIZ 32768
+#endif
+
+#if defined(OS_IRIX) || defined(OS_IRIX64)
+ #define AUSIZ 32768
+#endif
+
+#ifdef OS_HPUX
+ #define AUSIZ 4096
+#endif
+
+#ifdef OS_SunOS
+ #define AUSIZ 4096
+#endif
+
+
+#ifdef DEBUG
+ #define DB(type,cmd) if (debugFlags.type) { cmd ; }
+#else
+ #define DB(type,cmd)
+#endif
+
+
+
+
+//Prototypes:
+
+int audioConstruct();
+void audioDestruct();
+
+
+
+int audioOpen();
+void audioClose();
+void audioInit(int sampleSize,int frequency, int stereo,int sign, int bigendian);
+
+
+int mixerOpen();
+void mixerClose();
+void mixerSetVolume(int volumeLeft,int volumeRight);
+
+int audioWrite(char *buffer, int count);
+int getAudioFd();
+int getAudioBufferSize();
+
+#endif
diff --git a/mpeglib/lib/util/audio/audioIO_AIX.cpp b/mpeglib/lib/util/audio/audioIO_AIX.cpp
new file mode 100644
index 00000000..15316852
--- /dev/null
+++ b/mpeglib/lib/util/audio/audioIO_AIX.cpp
@@ -0,0 +1,533 @@
+/*
+ * AIX audio - griff@acm.org 02aug2000
+ * tested on 43P 260 with builtin audio
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/time.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+/* A conflict within AIX 4.3.3 <sys/> headers and probably others as well.
+ * I guess nobody ever uses audio... Shame over AIX header files. */
+#include <sys/machine.h>
+#undef BIG_ENDIAN
+#include <sys/audio.h>
+
+static int audio_fd;
+
+static void debugUpdate( unsigned long& flags, long& bsize );
+
+#ifndef AUDIO_BIG_ENDIAN
+#define AUDIO_BIG_ENDIAN BIG_ENDIAN
+#endif
+
+
+
+int audioConstruct() {
+ printf("audioConstruct AIX ********\n");
+ audio_fd=-1;
+ return true;
+}
+
+
+void audioDestruct() {
+
+}
+
+int audioOpen()
+{
+ char devname[14];
+ for ( int dev=0; dev<4; dev++ )
+ {
+ for ( int chan=1; chan<8; chan++ )
+ {
+ sprintf(devname,"/dev/paud%d/%d",dev,chan);
+ audio_fd = open (devname, O_WRONLY, 0);
+ if ( audio_fd >= 0 )
+ {
+ return 1;
+ }
+ sprintf(devname,"/dev/baud%d/%d",dev,chan);
+ audio_fd = open (devname, O_WRONLY, 0);
+ if ( audio_fd >= 0 )
+ {
+ return 1;
+ }
+ }
+ }
+
+ fprintf(stderr, "Could not open AIX audio device, faking\n" );
+ return 1;
+}
+
+int getAudioBufferSize()
+{
+ audio_buffer paud_bufinfo;
+
+ if( audio_fd < 0 ) return 1024*65;
+
+ if ( ioctl(audio_fd, AUDIO_BUFFER, &paud_bufinfo) < 0 )
+ {
+ perror("ioctl getAudioBufferSize using default");
+ return 1024*65;
+ }
+
+ /*
+ * Do you need the total capacity or the current capacity?
+ * This is the total capacity:
+ */
+ return paud_bufinfo.write_buf_cap;
+ /*
+ * This is the current capacity:
+ * return (paud_bufinfo.write_buf_cap - paud_bufinfo.write_buf_size);
+ */
+}
+
+void audioInit(int sampleSize,int frequency, int stereo, int sign, int bigendian )
+{
+ // int format;
+ int bytes_per_sample;
+ audio_init paud_init;
+ audio_buffer paud_bufinfo;
+ // audio_status paud_status;
+ audio_control paud_control;
+ audio_change paud_change;
+
+ if( audio_fd < 0 ) return;
+
+ /*
+ * We can't set the buffer size - just ask the device for the maximum
+ * that we can have.
+ */
+ if ( ioctl(audio_fd, AUDIO_BUFFER, &paud_bufinfo) < 0 )
+ {
+ perror("Couldn't get audio buffer information");
+ return;
+ }
+
+ /*
+ * Fields in the audio_init structure:
+ *
+ * Ignored by us:
+ *
+ * paud.loadpath[LOAD_PATH]; * DSP code to load, MWave chip only?
+ * paud.slot_number; * slot number of the adapter
+ * paud.device_id; * adapter identification number
+ *
+ * Input:
+ *
+ * paud.srate; * the sampling rate in Hz
+ * paud.bits_per_sample; * 8, 16, 32, ...
+ * paud.bsize; * block size for this rate
+ * paud.mode; * ADPCM, PCM, MU_LAW, A_LAW, SOURCE_MIX
+ * paud.channels; * 1=mono, 2=stereo
+ * paud.flags; * FIXED - fixed length data
+ * * LEFT_ALIGNED, RIGHT_ALIGNED (var len only)
+ * * TWOS_COMPLEMENT - 2's complement data
+ * * SIGNED - signed? comment seems wrong in sys/audio.h
+ * * BIG_ENDIAN
+ * paud.operation; * PLAY, RECORD
+ *
+ * Output:
+ *
+ * paud.flags; * PITCH - pitch is supported
+ * * INPUT - input is supported
+ * * OUTPUT - output is supported
+ * * MONITOR - monitor is supported
+ * * VOLUME - volume is supported
+ * * VOLUME_DELAY - volume delay is supported
+ * * BALANCE - balance is supported
+ * * BALANCE_DELAY - balance delay is supported
+ * * TREBLE - treble control is supported
+ * * BASS - bass control is supported
+ * * BESTFIT_PROVIDED - best fit returned
+ * * LOAD_CODE - DSP load needed
+ * paud.rc; * NO_PLAY - DSP code can't do play requests
+ * * NO_RECORD - DSP code can't do record requests
+ * * INVALID_REQUEST - request was invalid
+ * * CONFLICT - conflict with open's flags
+ * * OVERLOADED - out of DSP MIPS or memory
+ * paud.position_resolution; * smallest increment for position
+ */
+
+ paud_init.srate = frequency;
+ paud_init.mode = PCM;
+ paud_init.operation = PLAY;
+ paud_init.channels = (stereo?2:1);
+
+ /*
+ * options in AIX:
+ * paud_init.bits_per_sample: 8 | 16
+ * paud_init.flags: AUDIO_BIG_ENDIAN (not used here)
+ * SIGNED (always used here)
+ * TWOS_COMPLEMENT (always on for Linux dsp porting?)
+ * FIXED <- that's right for SDL
+ * or LEFT_ALIGNED <- that's right for mpeglib
+ * or RIGHT_ALIGNED
+ * paud_init.bsize: sample byte size,
+ * bits_per_sample * (stereo?2:1) - for SDL
+ * bits_per_sample * (stereo?2:1) * 2 - for mpeglib
+ */
+ if ( sampleSize == 8 )
+ {
+ /* AFMT_S8 in linux dsp */
+ bytes_per_sample = 2; // why not 1 ?
+ paud_init.bits_per_sample = 8;
+ paud_init.flags = TWOS_COMPLEMENT | LEFT_ALIGNED;
+ }
+ else
+ {
+ /* AFMT_S16_LE in linux dsp */
+ bytes_per_sample = 4; // why not 2 ?
+ paud_init.bits_per_sample = 16;
+ paud_init.flags = TWOS_COMPLEMENT | LEFT_ALIGNED;
+ }
+ if( sign ) paud_init.flags |= SIGNED;
+ if( bigendian ) paud_init.flags |= AUDIO_BIG_ENDIAN;
+
+ paud_init.bsize = bytes_per_sample * (stereo?2:1);
+
+#if 0
+ debugUpdate(paud_init.flags, paud_init.bsize);
+
+ printf("CG: sampleSize = %d\n", sampleSize);
+ printf("CG: frequency = %d\n", frequency);
+ printf("CG: stereo = %s\n", (stereo)?"y":"n");
+ printf("CG: mode = %s\n", "PCM");
+ printf("CG: channels = %d\n", paud_init.channels);
+ printf("CG: bsize = %d\n", paud_init.bsize);
+ printf("CG: bits_per_sample = %d\n", paud_init.bits_per_sample);
+ printf("CG: flags & BIG_ENDIAN = %s\n", ((paud_init.flags&AUDIO_BIG_ENDIAN)?"y":"n"));
+ printf("CG: flags & SIGNED = %s\n", ((paud_init.flags&SIGNED)?"y":"n"));
+ printf("CG: flags & TWOS_COMPLEMENT = %s\n", ((paud_init.flags&TWOS_COMPLEMENT)?"y":"n"));
+ printf("CG: flags & FIXED = %s\n", ((paud_init.flags&FIXED)?"y":"n"));
+ printf("CG: flags & LEFT_ALIGNED = %s\n", ((paud_init.flags&LEFT_ALIGNED)?"y":"n"));
+ printf("CG: flags & RIGHT_ALIGNED = %s\n", ((paud_init.flags&RIGHT_ALIGNED)?"y":"n"));
+#endif
+
+ /*
+ * We know the buffer size and the max number of subsequent writes
+ * that can be pending. If more than one can pend, allow the application
+ * to do something like double buffering between our write buffer and
+ * the device's own buffer that we are filling with write() anyway.
+ *
+ * We can calculate the number of samples that fit into the audio
+ * device buffer if that is necessary:
+ *
+ * samples_capacity = paud_bufinfo.write_buf_cap
+ * / bytes_per_sample
+ * / (stereo?2:1);
+ * if ( paud_bufinfo.request_buf_cap != 1 ) samples_capacity /= 2;
+ */
+
+ /*
+ * The AIX paud device init can't modify the values of the audio_init
+ * structure that we pass to it. So we don't need any recalculation
+ * of this stuff and no reinit call as in linux SDL dsp and dma code.
+ *
+ * /dev/paud supports all of the encoding formats, so we don't need
+ * to do anything like reopening the device, either.
+ */
+ if ( ioctl(audio_fd, AUDIO_INIT, &paud_init) < 0 )
+ {
+ switch ( paud_init.rc )
+ {
+ case 1 :
+ perror("Couldn't set audio format: DSP can't do play requests");
+ return;
+ break;
+ case 2 :
+ perror("Couldn't set audio format: DSP can't do record requests");
+ return;
+ break;
+ case 4 :
+ perror("Couldn't set audio format: request was invalid");
+ return;
+ break;
+ case 5 :
+ perror("Couldn't set audio format: conflict with open's flags");
+ return;
+ break;
+ case 6 :
+ perror("Couldn't set audio format: out of DSP MIPS or memory");
+ return;
+ break;
+ default :
+ perror("Couldn't set audio format: not documented in sys/audio.h");
+ return;
+ break;
+ }
+ }
+
+ /*
+ * Set some parameters: full volume, first speaker that we can find.
+ * Ignore the other settings for now.
+ */
+ paud_change.input = AUDIO_IGNORE; /* the new input source */
+ paud_change.output = OUTPUT_1;
+ /* EXTERNAL_SPEAKER,
+ * INTERNAL_SPEAKER,
+ * OUTPUT_1 */
+ paud_change.monitor = AUDIO_IGNORE; /* the new monitor state */
+ paud_change.volume = 0x7fffffff; /* volume level [0-0x7fffffff] */
+ paud_change.volume_delay = AUDIO_IGNORE; /* the new volume delay */
+ paud_change.balance = 0x3fffffff; /* the new balance */
+ paud_change.balance_delay = AUDIO_IGNORE; /* the new balance delay */
+ paud_change.treble = AUDIO_IGNORE; /* the new treble state */
+ paud_change.bass = AUDIO_IGNORE; /* the new bass state */
+ paud_change.pitch = AUDIO_IGNORE; /* the new pitch state */
+
+ paud_control.ioctl_request = AUDIO_CHANGE;
+ paud_control.request_info = (char*)&paud_change;
+ if ( ioctl(audio_fd, AUDIO_CONTROL, &paud_control) < 0 )
+ {
+ perror("Can't change audio display settings (ignoring)" );
+ }
+
+ /*
+ * Tell the device to expect data. Actual start will wait for
+ * the first write() call.
+ */
+ paud_control.ioctl_request = AUDIO_START;
+ paud_control.position = 0;
+ if ( ioctl(audio_fd, AUDIO_CONTROL, &paud_control) < 0 )
+ {
+ perror("Can't start audio play");
+ return;
+ }
+}
+
+
+void audioSetVolume(int volume)
+{
+ long vol = (long)(volume/100.0) * 0x7fffffff;
+ if( audio_fd < 0 ) return;
+
+ audio_control paud_control;
+ audio_change paud_change;
+
+ paud_change.input = AUDIO_IGNORE; /* the new input source */
+ paud_change.output = OUTPUT_1; /* EXTERNAL_SPEAKER,INTERNAL_SPEAKER,
+ OUTPUT_1 */
+ paud_change.monitor = AUDIO_IGNORE; /* the new monitor state */
+ paud_change.volume = vol; /* volume level [0-0x7fffffff] */
+ paud_change.volume_delay = AUDIO_IGNORE; /* the new volume delay */
+ paud_change.balance = AUDIO_IGNORE; /* the new balance */
+ paud_change.balance_delay = AUDIO_IGNORE; /* the new balance delay */
+ paud_change.treble = AUDIO_IGNORE; /* the new treble state */
+ paud_change.bass = AUDIO_IGNORE; /* the new bass state */
+ paud_change.pitch = AUDIO_IGNORE; /* the new pitch state */
+
+ paud_control.ioctl_request = AUDIO_CHANGE;
+ paud_control.request_info = (char*)&paud_change;
+
+ if ( ioctl(audio_fd, AUDIO_CONTROL, &paud_control) < 0 )
+ {
+ perror("Change audio volume failed");
+ }
+}
+
+void audioFlush()
+{
+ if( audio_fd < 0 ) return;
+
+ if ( ioctl(audio_fd, AUDIO_WAIT, NULL) < 0 )
+ {
+ perror("Flush audio buffers failed");
+ }
+}
+
+void audioClose()
+{
+ if( audio_fd < 0 ) return;
+
+ if ( ioctl(audio_fd, AUDIO_WAIT, NULL) < 0 )
+ {
+ perror("Flush audio buffers failed");
+ }
+ close(audio_fd);
+}
+
+int audioWrite(char *buffer, int count)
+{
+ int written = write(audio_fd, buffer, count);
+ if( written < count )
+ {
+ return count;
+ }
+
+ return written;
+}
+
+int
+getAudioFd()
+{
+ return audio_fd;
+}
+
+int mixerOpen()
+{
+ return true;
+}
+
+void mixerClose()
+{
+}
+
+void mixerSetVolume(int leftVolume,int rightVolume)
+{
+ long balance;
+
+ if( audio_fd < 0 ) return;
+
+ balance = 2 * (leftVolume-rightVolume) / (leftVolume+rightVolume);
+ balance = 0x3fffffff + balance*0x3fffffff;
+
+ audio_control paud_control;
+ audio_change paud_change;
+
+ paud_change.input = AUDIO_IGNORE; /* the new input source */
+ paud_change.output = OUTPUT_1; /* EXTERNAL_SPEAKER,INTERNAL_SPEAKER,
+ OUTPUT_1 */
+ paud_change.monitor = AUDIO_IGNORE; /* the new monitor state */
+ paud_change.volume = AUDIO_IGNORE; /* volume level [0-0x7fffffff] */
+ paud_change.volume_delay = AUDIO_IGNORE; /* the new volume delay */
+ paud_change.balance = balance; /* the new balance */
+ paud_change.balance_delay = AUDIO_IGNORE; /* the new balance delay */
+ paud_change.treble = AUDIO_IGNORE; /* the new treble state */
+ paud_change.bass = AUDIO_IGNORE; /* the new bass state */
+ paud_change.pitch = AUDIO_IGNORE; /* the new pitch state */
+
+ paud_control.ioctl_request = AUDIO_CHANGE;
+ paud_control.request_info = (char*)&paud_change;
+
+ if ( ioctl(audio_fd, AUDIO_CONTROL, &paud_control) < 0 )
+ {
+ perror("Change audio volume failed");
+ }
+}
+
+static void debugUpdate( unsigned long& flags, long& bsize )
+{
+ const char* g;
+
+ g = getenv("AUDIO_BIG_ENDIAN");
+ if ( g )
+ {
+ int i = atoi(g);
+ if ( i == 1 )
+ {
+ flags |= AUDIO_BIG_ENDIAN;
+ }
+ else if ( i == 0 )
+ {
+ flags &= ~AUDIO_BIG_ENDIAN;
+ }
+ else
+ {
+ printf("CG: bad AUDIO_BIG_ENDIAN env variable %s\n", g);
+ }
+ }
+
+ g = getenv("SIGNED");
+ if ( g )
+ {
+ int i = atoi(g);
+ if ( i == 1 )
+ {
+ flags |= SIGNED;
+ }
+ else if ( i == 0 )
+ {
+ flags &= ~SIGNED;
+ }
+ else
+ {
+ printf("CG: bad SIGNED env variable %s\n", g);
+ }
+ }
+
+ g = getenv("TWOS_COMPLEMENT");
+ if ( g )
+ {
+ int i = atoi(g);
+ if ( i == 1 )
+ {
+ flags |= TWOS_COMPLEMENT;
+ }
+ else if ( i == 0 )
+ {
+ flags &= ~TWOS_COMPLEMENT;
+ }
+ else
+ {
+ printf("CG: bad TWOS_COMPLEMENT env variable %s\n", g);
+ }
+ }
+
+ g = getenv("FIXED");
+ if ( g )
+ {
+ int i = atoi(g);
+ if ( i == 1 )
+ {
+ flags |= FIXED;
+ }
+ else if ( i == 0 )
+ {
+ flags &= ~FIXED;
+ }
+ else
+ {
+ printf("CG: bad FIXED env variable %s\n", g);
+ }
+ }
+
+ g = getenv("LEFT_ALIGNED");
+ if ( g )
+ {
+ int i = atoi(g);
+ if ( i == 1 )
+ {
+ flags |= LEFT_ALIGNED;
+ }
+ else if ( i == 0 )
+ {
+ flags &= ~LEFT_ALIGNED;
+ }
+ else
+ {
+ printf("CG: bad LEFT_ALIGNED env variable %s\n", g);
+ }
+ }
+
+ g = getenv("RIGHT_ALIGNED");
+ if ( g )
+ {
+ int i = atoi(g);
+ if ( i == 1 )
+ {
+ flags |= RIGHT_ALIGNED;
+ }
+ else if ( i == 0 )
+ {
+ flags &= ~RIGHT_ALIGNED;
+ }
+ else
+ {
+ printf("CG: bad RIGHT_ALIGNED env variable %s\n", g);
+ }
+ }
+
+ g = getenv("BSIZE");
+ if ( g )
+ {
+ bsize = atoi(g);
+ }
+}
+
diff --git a/mpeglib/lib/util/audio/audioIO_BeOS.cpp b/mpeglib/lib/util/audio/audioIO_BeOS.cpp
new file mode 100644
index 00000000..ae4cf5a1
--- /dev/null
+++ b/mpeglib/lib/util/audio/audioIO_BeOS.cpp
@@ -0,0 +1,227 @@
+//
+// BeOS code for amp-0.7.4, (C) 1997 Andy Lo A Foe
+//
+
+
+#include <MediaKit.h>
+#include <KernelKit.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "transform.h"
+#include "audioIO.h"
+#include "audio.h"
+
+// Define the streambuf size here. streambuf is used
+// as a simple fit buffer.
+
+#define STREAMBUF_SIZE (32*1152)
+
+long bytes_in_streambuf;
+
+// streambuf definition and base indicator
+
+BSubscriber *the_sub;
+BDACStream *the_stream;
+
+sem_id ok_to_read;
+sem_id ok_to_write;
+
+
+char streambuf[STREAMBUF_SIZE];
+char *readbase;
+
+static int au_vol = 100;
+
+// Define our own printout function since we are
+// first writing in the streambuf (not needed, I think,
+// but I don't know if the DACStream accepts a buffer
+// size of 1152. Try it...
+
+void printout(void)
+{
+if (A_WRITE_TO_FILE) {
+#ifndef NO_BYTE_SWAPPING
+int i,j;
+short *ptr;
+
+ if (nch==2) {
+ ptr=(short*)stereo_samples;
+ i=j=32 * 18 * 2;
+ } else {
+ ptr=(short*)mono_samples;
+ i=j=32 * 18;
+ }
+
+ for (;i>=0;--i)
+ ptr[i] = ptr[i] << 8 | ptr[i] >> 8;
+#endif
+
+ if (nch==2)
+ fwrite(stereo_samples,1,sizeof stereo_samples,out_file);
+ else
+ fwrite(mono_samples,1,sizeof mono_samples,out_file);
+}
+
+
+ if (A_AUDIO_PLAY) {
+ static char au_buf[STREAMBUF_SIZE];
+ static int au_ptr =0, avail = 0;
+ static int num_smp;
+ static char *readbase = &au_buf[0];
+
+ // Write amount of samples to copy somewhere
+ num_smp = (nch == 2 ? sizeof stereo_samples : sizeof mono_samples);
+
+ // Copy samples in the fit buffer
+ memcpy(au_buf+au_ptr,(nch == 2 ? (char *)stereo_samples : (char *)mono_samples),
+ num_smp);
+
+ // Increase fit buffer pointer and available sample count
+ au_ptr+=num_smp;
+ avail+=num_smp;
+
+ if (avail >= 4096) { // Are there enough smps to feed the stream?
+ audioWrite((char*)readbase,4096); // Feed it!
+ readbase+=4096; // Increase readbase
+ avail-=4096; // Decrease avail smps count
+ if (au_ptr == STREAMBUF_SIZE) { // At end of fit buffer?
+ au_ptr=0; // Reset all pointers
+ readbase=&au_buf[0];
+ }
+ }
+ }
+
+}
+
+
+// Fake Buffer functions, just to keep the sources clean,
+// buffer.c should not be included in the link process...
+
+int AUDIO_BUFFER_SIZE;
+
+int
+audioBufferOpen(int frequency, int stereo, int volume)
+{
+ audioOpen(frequency, stereo, volume);
+}
+
+
+inline void
+audioBufferWrite(char *buf,int bytes)
+{
+ audioWrite(buf, bytes);
+}
+
+
+void
+audioBufferClose()
+{
+ audioClose();
+}
+
+
+int audioRead(char *buffer, int count)
+{
+ //printf("acquiring ok_to_read (%d bytes)\n", count);
+ if (acquire_sem(ok_to_read)==B_NO_ERROR) {
+ for (register int i=0; i < count;i++) {
+ *(buffer++)+=*(readbase++);
+ }
+ bytes_in_streambuf-=count;
+
+ if (bytes_in_streambuf <= 0) {
+ release_sem(ok_to_write);
+ bytes_in_streambuf = 0;
+ } else {
+ release_sem(ok_to_read);
+ }
+ }
+ return (0);
+}
+
+
+bool stream_func(void *arg, char *buf, size_t count, void *header)
+{
+ audioRead(buf, count);
+ return TRUE;
+}
+
+void audioOpen() {
+ readbase = &streambuf[0];
+
+ bytes_in_streambuf = 0;
+
+ the_sub = new BSubscriber("amp DAC writer");
+ the_stream = new BDACStream();
+
+ the_sub->Subscribe(the_stream);
+
+ the_stream->SetSamplingRate(frequency);
+
+ // Create semaphores
+ ok_to_read = create_sem(0, "read sem");
+ ok_to_write = create_sem(1, "write sem");
+
+}
+
+void audioInit(int sampleSize,int frequency, int stereo)
+{
+
+ // Initialize the streambuf
+ bytes_in_streambuf = 0;
+ memset(&streambuf, 0, STREAMBUF_SIZE);
+
+
+ // Enter the stream
+ the_sub->EnterStream(NULL, TRUE, NULL, stream_func, NULL, TRUE);
+}
+
+
+void audioSetVolume(int volume)
+{
+ if (volume > 128) // This allows for a modest volume boost
+ volume = 128;
+ au_vol = volume;
+}
+
+
+void audioClose()
+{
+ the_sub->ExitStream(TRUE);
+ the_sub->Unsubscribe();
+
+ delete_sem(ok_to_read);
+ delete_sem(ok_to_write);
+
+ delete the_sub;
+ delete the_stream;
+}
+
+
+// audioWrite is called from the player thread
+
+int audioWrite(char *buffer, int count)
+{
+ //printf("acquiring ok_to_write (%d bytes)\n", count);
+ if(acquire_sem(ok_to_write)==B_NO_ERROR)
+ {
+ memcpy(&streambuf, buffer, count);
+
+ if (au_vol != 100) { // Handle volume scaling here
+ short *b=(short *)&streambuf;
+ for (int i=0; i < count/2; i++) {
+ int v=((int)b[i]*au_vol)/100;
+ b[i]=(v>32767) ? 32767 : ((v<-32768) ? -32768 : v);
+ }
+ }
+
+ bytes_in_streambuf = count;
+ readbase = &streambuf[0];
+
+ release_sem(ok_to_read);
+ }
+ return 0;
+}
+
diff --git a/mpeglib/lib/util/audio/audioIO_HPUX.cpp b/mpeglib/lib/util/audio/audioIO_HPUX.cpp
new file mode 100644
index 00000000..ae07a148
--- /dev/null
+++ b/mpeglib/lib/util/audio/audioIO_HPUX.cpp
@@ -0,0 +1,190 @@
+/* this file is a part of amp software, (C) tomislav uzelac 1996,1997
+
+ Origional code by: Lutz Vieweg
+ Modified by:
+ * Andrew Richards - moved code from audio.c
+
+ */
+
+
+#include <sys/audio.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/lock.h>
+#include <unistd.h>
+#include <stdio.h>
+#include "audioIO.h"
+
+/* declare these static to effectively isolate the audio device */
+
+static int audio_fd;
+
+
+/* audioOpen() */
+/* should open the audio device, perform any special initialization */
+/* Set the frequency, no of channels and volume. Volume is only set if */
+/* it is not -1 */
+
+void audioOpen() {
+ if ((audio_fd = open("/dev/audio",O_RDWR))==-1)
+ die(" unable to open the audio device\n");
+
+ DB(audio, msg("Audio device opened on %d\n",audio_fd); )
+ }
+
+
+void
+audioInit(int sampleSize,int frequency, int stereo)
+{
+ int flags;
+ int failed = 0;
+ int volume=100;
+
+ if ((flags = fcntl (audio_fd, F_GETFL, 0)) < 0) {
+ die("unable to set non-blocking mode for /dev/audio\n");
+ }
+ flags |= O_NDELAY;
+ if (fcntl (audio_fd, F_SETFL, flags) < 0) {
+ die("unable to set non-blocking mode for /dev/audio\n");
+ }
+
+ if ( ioctl(audio_fd, AUDIO_SET_DATA_FORMAT, AUDIO_FORMAT_LINEAR16BIT) < 0 ||
+ ioctl(audio_fd, AUDIO_SET_CHANNELS, stereo ? 2 : 1) < 0 ||
+ ioctl(audio_fd, AUDIO_SET_OUTPUT, AUDIO_OUT_SPEAKER | AUDIO_OUT_HEADPHONE
+ | AUDIO_OUT_LINE) < 0 ||
+ ioctl(audio_fd, AUDIO_SET_SAMPLE_RATE, frequency) < 0) {
+ failed = -1;
+ }
+ if (volume != -1) {
+ struct audio_describe description;
+ struct audio_gains gains;
+ float fvolume = (float)volume / 100.0f;
+ if (ioctl(audio_fd, AUDIO_DESCRIBE, &description)) {
+ failed = -1;
+ }
+ if (ioctl (audio_fd, AUDIO_GET_GAINS, &gains)) {
+ failed = -1;
+ }
+
+ gains.transmit_gain = (int)((float)description.min_transmit_gain +
+ (float)(description.max_transmit_gain
+ - description.min_transmit_gain)
+ * fvolume);
+
+ /* gains.monitor_gain = description.min_monitor_gain; */ /* don't monitor ! */
+
+ if (ioctl (audio_fd, AUDIO_SET_GAINS, &gains)) {
+ failed = -1;
+ }
+ }
+
+ if (ioctl(audio_fd, AUDIO_SET_TXBUFSIZE, 4096 * 8)) {
+ failed = -1;
+ }
+ if (failed)
+ die(" unable to setup /dev/audio\n");
+}
+
+
+/* audioSetVolume - only code this if your system can change the volume while */
+/* playing. sets the output volume 0-100 */
+
+void
+audioSetVolume(int volume)
+{
+ struct audio_describe description;
+ struct audio_gains gains;
+ int failed = 0;
+ float fvolume = ((float)volume) / 100.0f;
+ if (ioctl(audio_fd, AUDIO_DESCRIBE, &description)) {
+ failed = -1;
+ }
+ if (ioctl (audio_fd, AUDIO_GET_GAINS, &gains)) {
+ failed = -1;
+}
+
+ gains.transmit_gain = (int)((float)description.min_transmit_gain +
+ (float)(description.max_transmit_gain
+ - description.min_transmit_gain)
+ * fvolume);
+ if (ioctl (audio_fd, AUDIO_SET_GAINS, &gains)) {
+ failed = -1;
+ }
+
+ /* could evaluate "failed" here - but who cares? */
+
+ DB(audio, msg("volume set to %d%%\n",volume); )
+
+}
+
+/* audioFlush() */
+/* should flush the audio device */
+
+inline void
+audioFlush()
+{
+ DB(audio, msg("audio: flush %d\n",audio_fd) );
+}
+
+
+/* audioClose() */
+/* should close the audio device and perform any special shutdown */
+
+void
+audioClose()
+{
+ close(audio_fd);
+ DB(audio, msg("audio: closed %d\n",audio_fd) );
+}
+
+
+/* audioWrite */
+/* writes count bytes from buffer to the audio device */
+/* returns the number of bytes actually written */
+
+int audioWrite(char *buffer, int count)
+{
+ DB(audio, msg("audio: Writing %d bytes to audio descriptor %d\n",count,getAudioFd()) );
+ return(write(audio_fd,buffer,count));
+}
+
+
+/* Let buffer.c have the audio descriptor so it can select on it. This means */
+/* that the program is dependent on an file descriptor to work. Should really */
+/* move the select's etc (with inlines of course) in here so that this is the */
+/* ONLY file which has hardware dependent audio stuff in it */
+
+int
+getAudioFd()
+{
+ return(audio_fd);
+}
+
+/*
+ Try to set the priority of this process to a value which
+ allows us to play without buffering, thus saving memory
+ and avoiding cache-misses.
+ If we cannot get any priority high enough to allow for
+ undisturbed replay (because we don't have sufficient
+ privilege), return a zero, otherwise, return a one.
+*/
+int audioSetPriority(void) {
+
+ /* try to lock process in physical memory, just ignore if this fails */
+ plock(PROCSHLIBLOCK);
+
+ /* try to set a realtime-priority of 64 */
+ if (-1 != rtprio(0, 64)) {
+ DB(audio, msg("using real-time priority\n"); )
+ return 1;
+ }
+
+ /* try to set a nice-level of -20 */
+ if (-1 != nice(-20)) {
+ DB(audio, msg("using nice-level -20\n"); )
+ return 1;
+ }
+
+ DB(audio, msg("using buffered output\n"); )
+ return 0; /* need to use a buffer */
+}
diff --git a/mpeglib/lib/util/audio/audioIO_IRIX.cpp b/mpeglib/lib/util/audio/audioIO_IRIX.cpp
new file mode 100644
index 00000000..8498a487
--- /dev/null
+++ b/mpeglib/lib/util/audio/audioIO_IRIX.cpp
@@ -0,0 +1,157 @@
+/* this file is a part of amp software, (C) tomislav uzelac 1996,1997
+
+ Origional code by: Karl Anders Oygard
+ Modified by:
+ * Andrew Richards - moved code from audio.c
+
+ */
+#include <assert.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <dmedia/audio.h>
+#include "audioIO.h"
+
+/* declare these static to effectively isolate the audio device */
+
+static ALport audioport;
+static ALconfig audioconfig;
+
+
+/* audioOpen() */
+/* should open the audio device, perform any special initialization */
+/* Set the frequency, no of channels and volume. Volume is only set if */
+/* it is not -1 */
+
+
+void audioOpen() {
+ printf("sorry. The audio part for irix must be fixed. \n");
+}
+
+void
+audioInit(int sampleSize,int frequency, int stereo)
+{
+ ALconfig audioconfig;
+ audioconfig = ALnewconfig();
+
+ if (!audioconfig)
+ die("out of memory\n");
+ else {
+ long pvbuf[] = { AL_OUTPUT_COUNT, 0, AL_MONITOR_CTL, 0, AL_OUTPUT_RATE, 0};
+
+ if (ALgetparams(AL_DEFAULT_DEVICE, pvbuf, 6) < 0)
+ if (oserror() == AL_BAD_DEVICE_ACCESS)
+ die("couldn't access audio device\n");
+
+ if (pvbuf[1] == 0 && pvbuf[3] == AL_MONITOR_OFF) {
+ long al_params[] = { AL_OUTPUT_RATE, 0};
+
+ al_params[1] = frequency;
+ ALsetparams(AL_DEFAULT_DEVICE, al_params, 2);
+ } else
+ if (pvbuf[5] != frequency)
+ die("audio device is already in use with wrong sample output rate\n");
+
+ /* ALsetsampfmt(audioconfig, AL_SAMPFMT_TWOSCOMP); this is the default */
+ /* ALsetwidth(audioconfig, AL_SAMPLE_16); this is the default */
+
+ if (!stereo) ALsetchannels(audioconfig, AL_MONO);
+ /* else ALsetchannels(audioconfig, AL_STEREO); this is the default */
+
+ ALsetqueuesize(audioconfig, AUSIZ * 2);
+
+ audioport = ALopenport("amp", "w", audioconfig);
+ if (audioport == (ALport) 0) {
+ switch (oserror()) {
+ case AL_BAD_NO_PORTS:
+ die("system is out of ports\n");
+
+ case AL_BAD_DEVICE_ACCESS:
+ die("couldn't access audio device\n");
+
+ case AL_BAD_OUT_OF_MEM:
+ die("out of memory\n");
+ }
+ exit(-1);
+ }
+ ALsetfillpoint(audioport, AUSIZ);
+ }
+}
+
+
+/* audioSetVolume - only code this if your system can change the volume while */
+/* playing. sets the output volume 0-100 */
+
+void
+audioSetVolume(int volume)
+{
+ long al_params[] = { AL_LEFT_SPEAKER_GAIN, 0, AL_RIGHT_SPEAKER_GAIN, 0};
+
+ al_params[1] = al_params[3] = volume * 100 / 255;
+
+ ALsetparams(AL_DEFAULT_DEVICE, al_params, 4);
+}
+
+
+/* audioFlush() */
+/* should flush the audio device */
+
+void
+audioFlush()
+{
+ DB(audio, msg("audio: flush %d\n",audio_fd) );
+}
+
+
+/* audioClose() */
+/* should close the audio device and perform any special shutdown */
+
+void
+audioClose()
+{
+int write_fd;
+
+ /* wait for all samples to be played */
+
+ write_fd = ALgetfd(audioport);
+ if (write_fd >= 0) {
+ fd_set write_fds;
+
+ FD_ZERO(&write_fds);
+ FD_SET(write_fd, &write_fds);
+
+ ALsetfillpoint(audioport, AUSIZ * 2);
+ select(write_fd + 1, NULL, &write_fds, NULL, NULL);
+ }
+
+ /* now close it */
+
+ ALcloseport(audioport);
+ DB(audio, msg("audio: closed %d\n",audio_fd) );
+}
+
+
+/* audioWrite */
+/* writes count bytes from buffer to the audio device */
+/* returns the number of bytes actually written */
+
+int audioWrite(char *buffer, int count)
+{
+ if (ALwritesamps(audioport, buffer, count / 2) == 0) {
+ ALsetfillpoint(audioport, AUSIZ);
+ return(count);
+ } else
+ return 0;
+}
+
+/* Let buffer.c have the audio descriptor so it can select on it. This
+ means that the program is dependent on an file descriptor to
+ work. Should really move the select's etc (with inlines of course) in
+ here so that this is the ONLY file which has hardware dependent audio
+ stuff in it. */
+
+int
+getAudioFd()
+{
+ return ALgetfd(audioport);
+}
+
diff --git a/mpeglib/lib/util/audio/audioIO_Linux.cpp b/mpeglib/lib/util/audio/audioIO_Linux.cpp
new file mode 100644
index 00000000..5ca9231c
--- /dev/null
+++ b/mpeglib/lib/util/audio/audioIO_Linux.cpp
@@ -0,0 +1,220 @@
+/* this file is a part of amp software, (C) tomislav uzelac 1996,1997
+
+ Origional code by: tomislav uzelac
+ Modified by:
+ * Dan Nelson - BSD mods.
+ * Andrew Richards - moved code from audio.c and added mixer support etc
+ * Martin Vogt
+ */
+
+/* Support for Linux and BSD sound devices */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdio.h>
+#include "audioIO.h"
+#include <stdlib.h>
+#include <stdio.h>
+
+//
+// Why all these different system cannot make a standard where this
+// soundcard.h file is ?
+//
+#if defined(HAVE_SYS_SOUNDCARD_H)
+ #undef AUSIZ
+ #undef HAVE_SYS_SOUNDCARD_H
+ #include <sys/soundcard.h>
+#elif defined(HAVE_MACHINE_SOUNDCARD_H)
+ #undef AUSIZ
+ #include <machine/soundcard.h>
+#elif defined(__NetBSD__)
+ #undef AUSIZ
+ #include <soundcard.h>
+#else
+ // fallback:
+ #include <linux/soundcard.h>
+#endif
+
+
+/* optimal fragment size */
+
+int AUSIZ = 0;
+
+// declare these static to effectively isolate the audio device
+
+static int audio_fd;
+static int mixer_fd;
+static int volumeIoctl;
+
+
+
+int audioConstruct() {
+ audio_fd=-1;
+ mixer_fd=-1;
+ return true;
+}
+
+
+void audioDestruct() {
+
+}
+
+
+
+/*
+ should open the audio device, perform any special initialization
+*/
+int audioOpen() {
+ audio_fd = open ("/dev/dsp", O_WRONLY, 0);
+ if (audio_fd < 0) {
+ perror("Unable to open the audio");
+ }
+
+ // Ok here something important if your programm forks:
+ if (audio_fd > 0) {
+ if (fcntl(audio_fd,F_SETFD,true) < 0) {
+ perror("fcntl socket");exit(1);
+ }
+ }
+
+ return (audio_fd > 0);
+}
+
+inline void audioFlush() {
+ if (ioctl(audio_fd, SNDCTL_DSP_RESET, 0) == -1)
+ perror("Unable to reset audio device\n");
+}
+
+/*
+ should close the audio device and perform any special shutdown
+*/
+void audioClose() {
+ audioFlush();
+ if (close(audio_fd) < 0) {
+ perror("error close audiodevice:");
+ }
+}
+
+
+void audioInit(int sampleSize,int frequency, int stereo, int sign, int big) {
+ if( sign == 0 )
+ {
+ fprintf(stderr,
+ "%s, %d: expecting signed audio data, "
+ "initialized unsigned (ignored)\n",
+ __FILE__, __LINE__ );
+ }
+ if( big != 0 )
+ {
+ fprintf(stderr,
+ "%s, %d: expecting little endian audio data, "
+ "initialized big endian (ignored)\n",
+ __FILE__, __LINE__ );
+ }
+
+ int play_format=AFMT_S16_LE;
+
+ if (sampleSize == 8) {
+ play_format=AFMT_S8;
+ }
+ ioctl(audio_fd,SNDCTL_DSP_RESET,NULL);
+
+ if (ioctl(audio_fd, SNDCTL_DSP_SETFMT,&play_format) < 0) {
+ perror("Unable to set required audio format\n");
+ }
+
+ /* Set 1 or 2 channels */
+ stereo=(stereo ? 1 : 0);
+
+ if (ioctl(audio_fd, SNDCTL_DSP_STEREO, &stereo) < 0) {
+ perror("Unable to set stereo/mono\n");
+ exit(0);
+ }
+
+ /* Set the output frequency */
+ if (ioctl(audio_fd, SNDCTL_DSP_SPEED, &frequency) < 0) {
+ perror("Unable to set frequency");
+ exit(0);
+ }
+
+ if (ioctl(audio_fd, SNDCTL_DSP_GETBLKSIZE, &AUSIZ) == -1) {
+ perror("Unable to get fragment size\n");
+ exit(0);
+ }
+}
+
+
+int getAudioBufferSize() {
+ struct audio_buf_info buf_info;
+ int buf=1024*65;
+ if (ioctl(audio_fd,SNDCTL_DSP_GETOSPACE,&buf_info) == -1) {
+ perror("ioctl getAudioBufferSize using default");
+ } else {
+ buf=buf_info.bytes;
+ }
+ return buf;
+}
+
+
+int mixerOpen() {
+ int supportedMixers;
+
+ if ((mixer_fd=open("/dev/mixer",O_RDWR)) == -1) {
+ perror("Unable to open mixer device");
+ }
+
+ // Ok here something important if your programm forks:
+ if (mixer_fd > 0) {
+ if (fcntl(mixer_fd,F_SETFD,true) < 0) {
+ perror("fcntl socket");exit(1);
+ }
+ }
+
+ if (ioctl(mixer_fd, SOUND_MIXER_READ_DEVMASK, &supportedMixers) == -1){
+ perror("Unable to get mixer info assuming master volume");
+ volumeIoctl=SOUND_MIXER_WRITE_VOLUME;
+ } else {
+ if ((supportedMixers & SOUND_MASK_PCM) != 0)
+ volumeIoctl=SOUND_MIXER_WRITE_PCM;
+ else
+ volumeIoctl=0;
+ }
+
+ return (mixer_fd > 0);
+}
+
+
+void mixerClose() {
+ if (mixer_fd != -1) {
+ close(mixer_fd);
+ }
+}
+
+/*
+ only code this if your system can change the volume while
+ playing
+*/
+void mixerSetVolume(int leftVolume,int rightVolume) {
+ int volume;
+
+ volume=leftVolume+(rightVolume<<8);
+ if ((mixer_fd != -1) && (volumeIoctl!=0)) {
+ if (ioctl(mixer_fd, volumeIoctl, &volume) < 0) {
+ perror("Unable to set sound volume");
+ }
+ }
+}
+
+
+
+int audioWrite(char *buffer, int count) {
+ return(write(audio_fd,buffer,count));
+}
+
+
+int getAudioFd() {
+ return(audio_fd);
+}
diff --git a/mpeglib/lib/util/audio/audioIO_SDL.cpp b/mpeglib/lib/util/audio/audioIO_SDL.cpp
new file mode 100644
index 00000000..782fa388
--- /dev/null
+++ b/mpeglib/lib/util/audio/audioIO_SDL.cpp
@@ -0,0 +1,164 @@
+/*
+ audio wrapper for SDL
+ 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 "../../input/bufferInputStream.h"
+#include <assert.h>
+#include <iostream.h>
+#if defined WIN32
+#include <SDL.h>
+#include <SDL_audio.h>
+#else
+#include <SDL/SDL.h>
+#include <SDL/SDL_audio.h>
+#endif
+
+//static SDL_AudioSpec actual;
+static BufferInputStream* audioRing;
+static TimeStamp* dummy;
+static int lOpen=false;
+
+
+
+int audioConstruct() {
+ cout << "audioConstruct ********* SDL"<<endl;
+ if ( SDL_Init(SDL_INIT_AUDIO) < 0 ) {
+ fprintf(stderr, "Warning: Couldn't init SDL audio: %s\n",
+ SDL_GetError());
+ exit(0);
+ }
+ atexit(SDL_Quit);
+ audioRing=new BufferInputStream(1024*65,1024*8,"audioSDL");
+ audioRing->open("audioSDL");
+ dummy=new TimeStamp();
+ lOpen=false;
+ return true;
+}
+
+
+void audioDestruct() {
+ delete audioRing;
+ delete dummy;
+}
+
+
+
+
+int audioOpen() {
+ return true;
+}
+
+
+void audioClose() {
+ lOpen=false;
+ SDL_CloseAudio();
+}
+
+
+void audioCallback(void *, Uint8 *stream, int len) {
+ char* startPtr;
+ TimeStamp* start;
+ int bytePos;
+
+ int read=audioRing->readRemote(&startPtr,len);
+ SDL_MixAudio(stream, (Uint8*) startPtr, read, SDL_MIX_MAXVOLUME);
+
+ audioRing->forwardReadPtr(read);
+ // dequeue time stamps
+ bytePos=audioRing->getBytePosition();
+ start=audioRing->getTimeStamp(bytePos);
+
+}
+
+
+
+void audioInit(int sampleSize,int frequency, int stereo, int sign, int big) {
+ if( sign == 0 )
+ {
+ fprintf(stderr,
+ "%s, %d: expecting signed audio data, "
+ "initialized unsigned (ignored)\n",
+ __FILE__, __LINE__ );
+ }
+ if( big != 0 )
+ {
+ fprintf(stderr,
+ "%s, %d: expecting little endian audio data, "
+ "initialized big endian (ignored)\n",
+ __FILE__, __LINE__ );
+ }
+
+ cout << "SDL audioInit: "
+ << " sampleSize:"<<sampleSize
+ << " frequency:"<<frequency
+ << " stereo:"<<stereo<<endl;
+ if (lOpen==true) {
+ cout << "SDL is buggy, because open != init -> return"<<endl;
+ return;
+ }
+ lOpen=true;
+ SDL_AudioSpec wanted;
+ //SDL_AudioSpec actual;
+ if (sampleSize == 16) {
+ wanted.format= AUDIO_S16LSB;
+ } else {
+ wanted.format= AUDIO_S8;
+ }
+
+ wanted.freq=frequency;
+ wanted.channels=stereo+1;
+ wanted.samples = 1024;
+ wanted.callback = audioCallback;
+ wanted.userdata = NULL;
+
+ int err=SDL_OpenAudio(&wanted, NULL);
+ if (err != 0) {
+ cout << "SDL_OpenAudio not ok"<<endl;
+ cout << "error is:"<<SDL_GetError()<<endl;
+ exit(0);
+ }
+ SDL_PauseAudio(0);
+
+}
+
+
+int mixerOpen() {
+ return true;
+}
+
+
+void mixerClose() {
+}
+
+
+void mixerSetVolume(int volumeLeft,int volumeRight) {
+ cout << "volumeLeft:"<<volumeLeft
+ << " volumeRight:"<<volumeRight<<endl;
+}
+
+
+int audioWrite(char *buffer, int count) {
+
+ audioRing->write(buffer,count,dummy);
+
+
+ return count;
+}
+
+
+int getAudioFd() {
+ return false;
+}
+
+
+int getAudioBufferSize() {
+ int buf=1024*65;
+ return buf;
+}
diff --git a/mpeglib/lib/util/audio/audioIO_SunOS.cpp b/mpeglib/lib/util/audio/audioIO_SunOS.cpp
new file mode 100644
index 00000000..4e9958a1
--- /dev/null
+++ b/mpeglib/lib/util/audio/audioIO_SunOS.cpp
@@ -0,0 +1,167 @@
+/* this file is a part of amp software, (C) tomislav uzelac 1996,1997
+
+ Origional code by: tomislav uzelac
+ Modified by:
+ * Andrew Richards - moved code from audio.c
+ * Jim Crumley - ported some code from other audioIO_'s
+
+ */
+
+#include <sys/types.h>
+#include <sys/stropts.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <sys/audioio.h>
+#include "audioIO.h"
+#include <iostream.h>
+
+/* declare these static to effectively isolate the audio device */
+
+static int audio_fd;
+static audio_info_t auinfo;
+
+
+int audioConstruct(){
+ audio_fd=-1;
+ return true;
+}
+
+void audioDestruct() {
+
+}
+
+
+/* audioOpen() */
+/* should open the audio device and perform any special initialization */
+/* returns the file descriptior of the audio device */
+
+int audioOpen() {
+ AUDIO_INITINFO(&auinfo);
+
+ if ((audio_fd = open("/dev/audio",O_RDWR))==-1) {
+ perror("unable to open the audio device");
+ }
+ // Ok here something important if your programm forks:
+ if (audio_fd > 0) {
+ if (fcntl(audio_fd,F_SETFD,true) < 0) {
+ perror("fcntl socket");exit(1);
+ }
+ }
+
+ DB(audio, msg("Audio device opened on %d\n",audio_fd) );
+ return (audio_fd > 0);
+}
+
+/* audioFlush() */
+/* should flush the audio device */
+
+inline void audioFlush() {
+ DB(audio, msg("audio: flush %d\n",audio_fd) );
+}
+
+
+/* audioClose() */
+/* should close the audio device and perform any special shutdown */
+
+void audioClose() {
+ close(audio_fd);
+}
+
+
+/**
+ Audio init assumes that the audiodevice is open. It initializes
+ it to the given values
+*/
+
+void audioInit(int sampleSize ,int frequency, int stereo,int sign, int big){
+
+ if (ioctl(audio_fd,AUDIO_GETINFO,&auinfo)<0)
+ perror("Unable to get audio info");
+
+ auinfo.play.precision=sampleSize;
+ auinfo.play.encoding=AUDIO_ENCODING_LINEAR;
+ auinfo.play.channels=(stereo ? 2 : 1);
+ DB(audio, msg("setting sample rate to %d Hz",frequency) );
+ auinfo.play.sample_rate=frequency;
+ if (ioctl(audio_fd,AUDIO_SETINFO,&auinfo)<0)
+ perror("Unable to set audio info");
+
+}
+
+/*
+ only code this if your system can change the volume while
+ playing
+*/
+
+
+int getAudioBufferSize() {
+ int buf;
+ if (ioctl(audio_fd,AUDIO_GETINFO,&auinfo) == -1) {
+ perror("ioctl getAudioBufferSize using default");
+ buf=1024*65;
+ } else {
+ buf=auinfo.play.buffer_size;
+ }
+ return buf;
+}
+
+
+void mixerSetVolume(int leftVolume,int rightVolume) {
+ int volume;
+
+ volume=(leftVolume+rightVolume)/2;
+ auinfo.play.gain=(volume*255)/100;
+
+ // now normalize to values 0...32
+ leftVolume=(32*leftVolume)/100;
+ rightVolume=(32*rightVolume)/100;
+
+ // eg : leftVolume=32, rightVolume=32 => balance=32
+ // eg : leftVolume=0, rightVolume=32 => balance=64
+ // eg : leftVolume=32, rightVolume=0 => balance=0
+
+ //cout << "leftVolume:"<<leftVolume<<endl;
+ //cout << "rightVolume:"<<rightVolume<<endl;
+ int balance=leftVolume-rightVolume+32;
+ //cout << "balance:"<<balance<<endl;
+ //someone should fix the volume on solaris
+ balance=0;
+
+ auinfo.play.balance=(uchar_t)balance;
+ if (ioctl(audio_fd,AUDIO_SETINFO,&auinfo)<0)
+ perror("Unable to set sound volume");
+}
+
+
+
+
+int mixerOpen() {
+ return true;
+}
+
+void mixerClose() {
+}
+
+
+
+
+/* audioWrite */
+/* writes count bytes from buffer to the audio device */
+/* returns the number of bytes actually written */
+
+int audioWrite(char *buffer, int count)
+{
+ return(write(audio_fd,buffer,count));
+}
+
+/* Let buffer.c have the audio descriptor so it can select on it. This means */
+/* that the program is dependent on an file descriptor to work. Should really */
+/* move the select's etc (with inlines of course) in here so that this is the */
+/* ONLY file which has hardware dependent audio stuff in it */
+
+int
+getAudioFd()
+{
+ return(audio_fd);
+}
diff --git a/mpeglib/lib/util/audio/dspWrapper.cpp b/mpeglib/lib/util/audio/dspWrapper.cpp
new file mode 100644
index 00000000..cd9afa57
--- /dev/null
+++ b/mpeglib/lib/util/audio/dspWrapper.cpp
@@ -0,0 +1,193 @@
+/*
+ a wrapper for the audioDevice.
+ Copyright (C) 1998 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 "dspWrapper.h"
+#include "audioIO.h"
+
+
+#include "../../frame/pcmFrame.h"
+#include "../../frame/floatFrame.h"
+
+#include <iostream>
+
+using namespace std;
+
+DSPWrapper::DSPWrapper() {
+ currentFormat=new PCMFrame(0);
+ lopenDevice=false;
+ lopenMixer=false;
+
+ audioConstruct();
+}
+
+DSPWrapper::~DSPWrapper() {
+ if (lopenDevice) {
+ audioClose();
+ }
+ if (lopenMixer) {
+ mixerClose();
+ }
+ audioDestruct();
+ delete currentFormat;
+}
+
+
+int DSPWrapper::isOpenDevice() {
+ return lopenDevice;
+}
+
+int DSPWrapper::openDevice() {
+ if (lopenDevice==true) {
+ return true;
+ }
+ lopenDevice=audioOpen();
+ return lopenDevice;
+}
+
+int DSPWrapper::closeDevice() {
+ if (isOpenDevice() == true) {
+ audioClose();
+ currentFormat->setFrameFormat(-1,-1);
+ lopenDevice=false;
+ }
+ return true;
+}
+
+
+int DSPWrapper::isOpenMixer() {
+ return lopenMixer;
+}
+
+
+int DSPWrapper::getAudioBufferSize() {
+ return ::getAudioBufferSize();
+}
+
+
+int DSPWrapper::openMixer() {
+ lopenMixer=mixerOpen();
+ return lopenMixer;
+}
+
+int DSPWrapper::closeMixer() {
+ if (isOpenMixer() == true) {
+ mixerClose();
+ lopenMixer=false;
+ }
+ return true;
+}
+
+
+int DSPWrapper::audioPlay(char *buf, int len) {
+ return audioWrite(buf,len);
+}
+
+int DSPWrapper::audioSetup(int stereo,int sampleSize,int lSigned,
+ int lBigEndian,int freq) {
+
+
+ if (isOpenDevice()==false) {
+ cout << "device not open"<<endl;
+ exit(-1);
+ }
+ /*
+ cout << "sampleSize:"<<sampleSize<<endl;
+ cout << "freq:"<<freq<<endl;
+ cout << "stereo:"<<stereo<<endl;
+ cout << "lSigned:"<<lSigned<<endl;
+ cout << "lBigEndian:"<<lBigEndian<<endl;
+ */
+ audioInit(sampleSize,freq,stereo,lSigned,lBigEndian);
+ if (currentFormat->getSampleSize() != sampleSize) {
+ cout << "FIXME: pcmFrame with sampleSize:"<<sampleSize<<endl;
+ }
+ currentFormat->setFrameFormat(stereo,freq);
+ return true;
+}
+
+int DSPWrapper::audioSetup(AudioFrame* audioFrame) {
+ if (audioFrame == NULL) {
+ cout << "audioFrame NULL: DSPWrapper:audioSetup"<<endl;
+ exit(0);
+ }
+ if(audioFrame->isFormatEqual(currentFormat)==false) {
+ audioSetup(audioFrame->getStereo(),audioFrame->getSampleSize(),
+ audioFrame->getSigned(),audioFrame->getBigEndian(),
+ audioFrame->getFrequenceHZ());
+ }
+ return true;
+}
+
+
+int DSPWrapper::audioPlay(PCMFrame* pcmFrame) {
+ if (pcmFrame == NULL) {
+ cout << "pcmFrame NULL: DSPWrapper:audioPlay"<<endl;
+ exit(0);
+ }
+ if(pcmFrame->isFormatEqual(currentFormat)==false) {
+ audioSetup(pcmFrame->getStereo(),pcmFrame->getSampleSize(),
+ pcmFrame->getSigned(),pcmFrame->getBigEndian(),
+ pcmFrame->getFrequenceHZ());
+ }
+ int len=pcmFrame->getLen()*2;
+ int played=audioPlay((char*)pcmFrame->getData(),len);
+ return (len == played);
+}
+
+
+//
+// Misuse our internal currentFormat for the float->int conversion.
+//
+
+int DSPWrapper::audioPlay(FloatFrame* floatFrame) {
+ if (floatFrame == NULL) {
+ cout << "floatFrame NULL: DSPWrapper:audioPlay"<<endl;
+ exit(0);
+ }
+ if(floatFrame->isFormatEqual(currentFormat)==false) {
+ audioSetup(floatFrame->getStereo(),floatFrame->getSampleSize(),
+ floatFrame->getSigned(),floatFrame->getBigEndian(),
+ floatFrame->getFrequenceHZ());
+ }
+
+ int tmpLen=currentFormat->getLen();
+ if (tmpLen < floatFrame->getLen()) {
+ delete currentFormat;
+ currentFormat=new PCMFrame(floatFrame->getLen());
+ floatFrame->copyFormat(currentFormat);
+ }
+ currentFormat->clearrawdata();
+ currentFormat->putFloatData(floatFrame->getData(),floatFrame->getLen());
+ return audioPlay(currentFormat);
+}
+
+void DSPWrapper::audioFlush() {
+ closeDevice();
+}
+
+
+void DSPWrapper::setVolume(float leftPercent,float rightPercent) {
+ if (isOpenMixer()) {
+ mixerSetVolume((int)leftPercent,(int)rightPercent);
+ } else {
+ cout << "cannot set Mixer settings:not open!"<<endl;
+ }
+}
+
+
+void DSPWrapper::print() {
+ cout<<"lopenDevice:"<<lopenDevice<<endl;
+ cout<<"lopenMixer:"<<lopenMixer<<endl;
+ currentFormat->print("currentFormat");
+
+}
diff --git a/mpeglib/lib/util/audio/dspWrapper.h b/mpeglib/lib/util/audio/dspWrapper.h
new file mode 100644
index 00000000..f323096d
--- /dev/null
+++ b/mpeglib/lib/util/audio/dspWrapper.h
@@ -0,0 +1,75 @@
+/*
+ a wrapper for the audioDevice.
+ Copyright (C) 1998 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 _DSPWRAPPER_H
+#define _DSPWRAPPER_H
+
+class AudioFrame;
+class PCMFrame;
+class FloatFrame;
+#include <kdemacros.h>
+
+/**
+ This class wraps the platform specific /dev/dsp implementation.
+ The only unusal thing is, that it supports each order of
+ init/open.
+ i) you can first init the device and the open
+ ii) you can first open the device and the init it
+ The implementation takes care that the calls are forwarded
+ in the right order to the /dev/dsp implementation.
+ (means: before the init it, we need to open it)
+ But a caller can do it in both orders.
+*/
+
+class KDE_EXPORT DSPWrapper {
+
+ int lopenDevice;
+ int lopenMixer;
+ PCMFrame* currentFormat;
+
+
+ public:
+ DSPWrapper();
+ ~DSPWrapper();
+
+ int openDevice();
+ int closeDevice();
+ int isOpenDevice();
+
+ int openMixer();
+ int closeMixer();
+ int isOpenMixer();
+
+ int getAudioBufferSize();
+ void setVolume(float leftPercent,float rightPercent);
+
+ int audioSetup(int stereo,int sampleSize,int lSigned,
+ int lBigEndian,int freq);
+ int audioSetup(AudioFrame* audioFrame);
+
+ int audioPlay(char *buffer, int size);
+ int audioPlay(PCMFrame* pcmFrame);
+ int audioPlay(FloatFrame* floatFrame);
+ void audioFlush();
+
+ int isEqual(int samplesize,int speed,int stereo,int lSigned,int lBigEndian);
+ int write(char* buf,int len);
+ void print();
+};
+
+#endif
+
+
+
+
diff --git a/mpeglib/lib/util/dynBuffer.cpp b/mpeglib/lib/util/dynBuffer.cpp
new file mode 100644
index 00000000..c93d5381
--- /dev/null
+++ b/mpeglib/lib/util/dynBuffer.cpp
@@ -0,0 +1,166 @@
+/*
+ This class implements a dynamic string buffer
+ Copyright (C) 1998 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 "dynBuffer.h"
+
+#include <iostream>
+
+using namespace std;
+
+
+DynBuffer::DynBuffer(int size) {
+ nSize=size;
+ msg=(char*) malloc(sizeof(char)*(nSize+1));
+ msg[nSize]='\0';
+ clear();
+
+}
+
+
+DynBuffer::~DynBuffer() {
+ free (msg);
+}
+
+
+void DynBuffer::clear() {
+ msg[0]='\0';
+}
+
+void DynBuffer::append(int value) {
+ DynBuffer buf(30);
+ sprintf(buf.getData(),"%d",value);
+ append(buf.getData());
+}
+
+
+
+
+void DynBuffer::append(char* appendMsg) {
+ if (appendMsg == msg) {
+ cout << "cannot append to self"<<endl;
+ exit(0);
+ }
+ char* appendPos=getAppendPos();
+ int nlen=strlen(appendMsg);
+ if (appendPos == NULL) return;
+
+ append(appendMsg,nlen);
+}
+
+
+void DynBuffer::append(const char* appendMsg) {
+ append((char*)appendMsg);
+}
+
+
+void DynBuffer::append(char* buffer,int buflen) {
+ int nlen=len();
+ int nBedarf;
+ if (buffer == msg) {
+ cout << "cannot append to self"<<endl;
+ exit(0);
+ }
+ if (buflen+nlen <= nSize) {
+ char* appendPos=getAppendPos();
+ strncpy(appendPos,buffer,buflen);
+ appendPos[buflen]='\0';
+ return;
+ }
+ nBedarf=(nlen+buflen)-nSize;
+ grow(nBedarf);
+ append(buffer,buflen);
+}
+
+char* DynBuffer::getAppendPos() {
+ int i;
+ // this Array has nSize+1 entries!
+ // and it *is* granted that msg[nSize]=0; (think so)
+ for (i=0;i<=nSize;i++) {
+ if (msg[i] == '\0') return &(msg[i]);
+ }
+ // should never reach this point
+ return NULL;
+}
+
+
+void DynBuffer::setData(char* msg) {
+ if (strlen(msg) == 0) {
+ clear();
+ return;
+ }
+ clear();
+ append(msg);
+}
+
+char* DynBuffer::getData() {
+ return msg;
+}
+
+
+int DynBuffer::len() {
+ return strlen(msg);
+}
+
+int DynBuffer::getSize() {
+ return nSize;
+}
+
+void DynBuffer::grow(int size) {
+ int i;
+ int newSize=nSize+size;
+ char* tmp=(char*) malloc(sizeof(char)*(newSize+1));
+ tmp[newSize]='\0';
+ for(i=0;i<=nSize;i++) {
+ tmp[i]=msg[i];
+ }
+
+ nSize=newSize;
+ free(msg);
+ msg=tmp;
+
+}
+
+
+int DynBuffer::find(char zeichen) {
+ int i;
+ int nlen=len();
+ for(i=0;i<nlen;i++) {
+ if (msg[i] == zeichen) return i;
+ }
+ return -1;
+}
+
+
+
+void DynBuffer::forward(int bytes) {
+ int i;
+ int aktPos;
+ int nlen=len();
+ if (bytes > nlen) {
+ bytes=nlen;
+ }
+ i=0;
+ aktPos=bytes;
+ while(aktPos <= nlen) {
+ msg[i]=msg[aktPos];
+ i++;
+ aktPos++;
+ }
+}
+
+
+
+void DynBuffer::print() {
+ printf("DynBuffer:%s\n",msg);
+}
diff --git a/mpeglib/lib/util/dynBuffer.h b/mpeglib/lib/util/dynBuffer.h
new file mode 100644
index 00000000..7ba99d42
--- /dev/null
+++ b/mpeglib/lib/util/dynBuffer.h
@@ -0,0 +1,63 @@
+/*
+ This class implements a static string buffer
+ Copyright (C) 1998 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 __DYNBUFFER_H
+#define __DYNBUFFER_H
+
+
+extern "C" {
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+ }
+
+class DynBuffer {
+
+ char* msg;
+ int nSize;
+
+ public:
+ DynBuffer(int size);
+ ~DynBuffer();
+
+ void clear();
+ void append(int value); // appends values as string
+ void append(char* msg);
+ void append(const char* msg);
+
+ void append(char* buffer,int buflen);
+
+ int find(char zeichen);
+ int len();
+
+ void setData(char* msg);
+ char* getData();
+
+ int getSize();
+ void grow(int size);
+
+ void forward(int bytes);
+ void print();
+ private:
+ char* getAppendPos();
+ void read(FILE stream);
+
+};
+
+
+#endif
+
+
+
diff --git a/mpeglib/lib/util/file/Makefile.am b/mpeglib/lib/util/file/Makefile.am
new file mode 100644
index 00000000..96b16fff
--- /dev/null
+++ b/mpeglib/lib/util/file/Makefile.am
@@ -0,0 +1,25 @@
+# libsplay - Makefile.am
+
+
+INCLUDES = $(all_includes)
+
+noinst_LTLIBRARIES = libsimplefile.la
+
+noinst_HEADERS = fileAccess.h
+
+kmpgincludedir = $(includedir)/$(THIS_LIB_NAME)/util/file
+
+kmpginclude_HEADERS = fileAccess.h
+
+
+libsimplefile_la_SOURCES = fileAccess.cpp
+
+
+
+
+
+
+
+
+
+
diff --git a/mpeglib/lib/util/file/fileAccess.cpp b/mpeglib/lib/util/file/fileAccess.cpp
new file mode 100644
index 00000000..8eab864f
--- /dev/null
+++ b/mpeglib/lib/util/file/fileAccess.cpp
@@ -0,0 +1,95 @@
+/*
+ simple file access interface.
+ Copyright (C) 2001 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 "fileAccess.h"
+
+
+FileAccess::FileAccess() {
+ file=NULL;
+ length=0;
+}
+
+
+FileAccess::~FileAccess() {
+ close();
+}
+
+
+int FileAccess::open(const char* path) {
+ close();
+ file=fopen(path,"rb");
+ length=calcByteLength();
+ return (file != NULL);
+}
+
+
+void FileAccess::close() {
+ if (file != NULL) {
+ fclose(file);
+ file=NULL;
+ length=0;
+ }
+}
+
+
+int FileAccess::read(char* dest,int len) {
+ int back=0;
+ if (file != NULL) {
+ back=fread(dest,1,len,file);
+ } else {
+ printf("FileAccess::read not open\n");
+ }
+ return back;
+}
+
+int FileAccess::eof() {
+ int back=true;
+ if (file != NULL) {
+ back=feof(file);
+ }
+ return back;
+}
+
+
+int FileAccess::seek(long pos) {
+ if (file == NULL) {
+ return -1;
+ }
+ return fseek(file,pos,SEEK_SET);
+}
+
+
+long FileAccess::getBytePosition() {
+ if (file == NULL) {
+ return 0;
+ }
+ return ftell(file);
+}
+
+
+long FileAccess::getByteLength() {
+ return length;
+}
+
+long FileAccess::calcByteLength() {
+ if (file == NULL) {
+ return 0;
+ }
+ long pos=getBytePosition();
+ fseek(file,0,SEEK_END);
+ long back=getBytePosition();
+ fseek(file,pos,SEEK_SET);
+ return back;
+}
+
diff --git a/mpeglib/lib/util/file/fileAccess.h b/mpeglib/lib/util/file/fileAccess.h
new file mode 100644
index 00000000..d9bf9e2e
--- /dev/null
+++ b/mpeglib/lib/util/file/fileAccess.h
@@ -0,0 +1,46 @@
+/*
+ simple file access interface.
+ Copyright (C) 2001 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 __FILEACCESS_H
+#define __FILEACCESS_H
+
+
+#include "stdio.h"
+
+/**
+ Extension to the normal "read" function.
+ This interface is useful for the AudioInfo.
+*/
+
+class FileAccess {
+
+ FILE* file;
+ long length;
+
+ public:
+ FileAccess();
+ virtual ~FileAccess();
+
+ virtual int open(const char* file);
+ virtual void close();
+ virtual int read(char* dest,int len);
+ virtual int eof();
+ virtual int seek(long pos);
+ virtual long getBytePosition();
+ virtual long getByteLength();
+
+ private:
+ long calcByteLength();
+
+};
+#endif
+
diff --git a/mpeglib/lib/util/mmx/Makefile.am b/mpeglib/lib/util/mmx/Makefile.am
new file mode 100644
index 00000000..ce8875e0
--- /dev/null
+++ b/mpeglib/lib/util/mmx/Makefile.am
@@ -0,0 +1,46 @@
+# ---- @OS_TYPE@/@ARCH_TYPE@ ----
+
+# For cpu_accel compile we cannot have ansi
+# (I dont have debugged why)
+
+INCLUDES = $(all_includes)
+
+noinst_LTLIBRARIES = libmmx.la
+noinst_HEADERS =
+
+kmpgincludedir = $(includedir)/$(THIS_LIB_NAME)/util/mmx
+
+kmpginclude_HEADERS = mmx.h mmx_asm.h mm_accel.h
+
+libmmx_la_SOURCES = cpu_accel.c mmx.c
+
+AM_ASFLAGS = $(DEFS) $(DEFAULT_INCLUDES) $(all_includes)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/mpeglib/lib/util/mmx/attribute.h b/mpeglib/lib/util/mmx/attribute.h
new file mode 100644
index 00000000..4dfd3e1e
--- /dev/null
+++ b/mpeglib/lib/util/mmx/attribute.h
@@ -0,0 +1,33 @@
+/*
+ align attribut definition (g++)
+ Copyright (C) 2001 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 __ATTRIBUTE_H
+#define __ATTRIBUTE_H
+
+
+
+#include "vidi/vidi_config.h"
+
+
+/* use gcc attribs to align critical data structures */
+
+#ifdef ATTRIBUTE_ALIGNED_MAX
+#define ATTR_ALIGN(align) __attribute__ \
+ ((__aligned__ ((ATTRIBUTE_ALIGNED_MAX <align) ? \
+ ATTRIBUTE_ALIGNED_MAX : align)))
+#else
+#define ATTR_ALIGN(align)
+#endif
+
+
+#endif
diff --git a/mpeglib/lib/util/mmx/cpu_accel.c b/mpeglib/lib/util/mmx/cpu_accel.c
new file mode 100644
index 00000000..8f138308
--- /dev/null
+++ b/mpeglib/lib/util/mmx/cpu_accel.c
@@ -0,0 +1,162 @@
+/*
+ * cpu_accel.c
+ * Copyright (C) 2000-2001 Michel Lespinasse <walken@zoy.org>
+ * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
+ *
+ * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
+ * See http://libmpeg2.sourceforge.net/ for updates.
+ *
+ * mpeg2dec is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * mpeg2dec is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "config.h"
+
+#if defined(MMX_SUPPORT) || defined(INTEL)
+#define ARCH_X86 1
+#endif
+
+#include <inttypes.h>
+
+#include "mm_accel.h"
+
+#ifdef ARCH_X86
+static uint32_t arch_accel (void)
+{
+ uint32_t eax, ebx, ecx, edx;
+ int AMD;
+ uint32_t caps;
+
+#ifndef PIC
+#define cpuid(op,eax,ebx,ecx,edx) \
+ __asm__ ("cpuid" \
+ : "=a" (eax), \
+ "=b" (ebx), \
+ "=c" (ecx), \
+ "=d" (edx) \
+ : "a" (op) \
+ : "cc")
+#else /* PIC version : save ebx */
+#define cpuid(op,eax,ebx,ecx,edx) \
+ __asm__ ("pushl %%ebx\n\t" \
+ "cpuid\n\t" \
+ "movl %%ebx,%1\n\t" \
+ "popl %%ebx" \
+ : "=a" (eax), \
+ "=r" (ebx), \
+ "=c" (ecx), \
+ "=d" (edx) \
+ : "a" (op) \
+ : "cc")
+#endif
+
+ __asm__ ("pushfl\n\t"
+ "pushfl\n\t"
+ "popl %0\n\t"
+ "movl %0,%1\n\t"
+ "xorl $0x200000,%0\n\t"
+ "pushl %0\n\t"
+ "popfl\n\t"
+ "pushfl\n\t"
+ "popl %0\n\t"
+ "popfl"
+ : "=r" (eax),
+ "=r" (ebx)
+ :
+ : "cc");
+
+ if (eax == ebx) /* no cpuid */
+ return 0;
+
+ cpuid (0x00000000, eax, ebx, ecx, edx);
+ if (!eax) /* vendor string only */
+ return 0;
+
+ AMD = (ebx == 0x68747541) && (ecx == 0x444d4163) && (edx == 0x69746e65);
+
+ cpuid (0x00000001, eax, ebx, ecx, edx);
+ if (! (edx & 0x00800000)) /* no MMX */
+ return 0;
+
+ caps = MM_ACCEL_X86_MMX;
+ if (edx & 0x02000000) /* SSE - identical to AMD MMX extensions */
+ caps = MM_ACCEL_X86_MMX | MM_ACCEL_X86_MMXEXT;
+
+ cpuid (0x80000000, eax, ebx, ecx, edx);
+ if (eax < 0x80000001) /* no extended capabilities */
+ return caps;
+
+ cpuid (0x80000001, eax, ebx, ecx, edx);
+
+ if (edx & 0x80000000)
+ caps |= MM_ACCEL_X86_3DNOW;
+
+ if (AMD && (edx & 0x00400000)) /* AMD MMX extensions */
+ caps |= MM_ACCEL_X86_MMXEXT;
+
+ return caps;
+}
+#endif /* ARCH_X86 */
+
+#ifdef ARCH_PPC
+#include <signal.h>
+#include <setjmp.h>
+
+static sigjmp_buf jmpbuf;
+static volatile sig_atomic_t canjump = 0;
+
+static RETSIGTYPE sigill_handler (int sig)
+{
+ if (!canjump) {
+ signal (sig, SIG_DFL);
+ raise (sig);
+ }
+
+ canjump = 0;
+ siglongjmp (jmpbuf, 1);
+}
+
+static uint32_t arch_accel (void)
+{
+ signal (SIGILL, sigill_handler);
+ if (sigsetjmp (jmpbuf, 1)) {
+ signal (SIGILL, SIG_DFL);
+ return 0;
+ }
+
+ canjump = 1;
+
+ __asm__ volatile ("mtspr 256,%0" :: "r" (-1));
+
+ signal (SIGILL, SIG_DFL);
+ return MM_ACCEL_PPC_ALTIVEC;
+}
+#endif /* ARCH_PPC */
+
+uint32_t mm_accel (void)
+{
+#if defined (ARCH_X86) || defined (ARCH_PPC)
+ static int got_accel = 0;
+ static uint32_t accel;
+
+ if (!got_accel) {
+ got_accel = 1;
+ accel = arch_accel ();
+ }
+
+ return accel;
+#else
+ return 0;
+#endif
+}
diff --git a/mpeglib/lib/util/mmx/mm_accel.h b/mpeglib/lib/util/mmx/mm_accel.h
new file mode 100644
index 00000000..e0690804
--- /dev/null
+++ b/mpeglib/lib/util/mmx/mm_accel.h
@@ -0,0 +1,58 @@
+/*
+ * mm_accel.h
+ * Copyright (C) 2000-2001 Michel Lespinasse <walken@zoy.org>
+ * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
+ *
+ * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
+ * See http://libmpeg2.sourceforge.net/ for updates.
+ *
+ * mpeg2dec is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * mpeg2dec is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef MM_ACCEL_H
+#define MM_ACCEL_H
+
+#include <inttypes.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+
+/* generic accelerations */
+#define MM_ACCEL_MLIB 0x00000001
+
+/* x86 accelerations */
+#define MM_ACCEL_X86_MMX 0x80000000
+#define MM_ACCEL_X86_3DNOW 0x40000000
+#define MM_ACCEL_X86_MMXEXT 0x20000000
+
+/* powerpc accelerations */
+#define MM_ACCEL_PPC_ALTIVEC 0x80000000
+
+/* detailed SIMD info */
+uint32_t mm_accel (void);
+
+/* true if MMX support */
+int mm_support();
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif
+/* MM_ACCEL_H */
diff --git a/mpeglib/lib/util/mmx/mmx.c b/mpeglib/lib/util/mmx/mmx.c
new file mode 100644
index 00000000..4ac3d6b8
--- /dev/null
+++ b/mpeglib/lib/util/mmx/mmx.c
@@ -0,0 +1,73 @@
+/*
+ wrapper for MMX calls
+ 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 "mmx.h"
+
+static int mmSupport=-1;
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#if defined(MMX_SUPPORT) || defined(INTEL)
+#define HAVE_ACCEL
+#endif
+
+
+#ifndef HAVE_ACCEL
+int emms() {
+ printf("urgs! emms() never should happen\n");
+ exit(0);
+}
+
+int mm_support() {
+ return 0;
+}
+
+#endif
+
+
+#ifdef HAVE_ACCEL
+#include <inttypes.h>
+#include "mm_accel.h"
+
+
+
+
+int emms() {
+ __asm__ ("emms");
+ return 1;
+}
+
+
+int mm_support() {
+
+ int val;
+
+ if (mmSupport == -1) {
+
+ val=mm_accel();
+ if (val & MM_ACCEL_X86_MMX) {
+ mmSupport=1;
+ } else {
+ mmSupport=0;
+ }
+
+ }
+ /* Return */
+ return(mmSupport);
+}
+
+
+#endif
diff --git a/mpeglib/lib/util/mmx/mmx.h b/mpeglib/lib/util/mmx/mmx.h
new file mode 100644
index 00000000..c4b8340d
--- /dev/null
+++ b/mpeglib/lib/util/mmx/mmx.h
@@ -0,0 +1,26 @@
+
+
+
+#ifndef __MMX_H
+#define __MMX_H
+
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+
+extern int emms();
+extern int mm_support();
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif
diff --git a/mpeglib/lib/util/mmx/mmx_asm.h b/mpeglib/lib/util/mmx/mmx_asm.h
new file mode 100644
index 00000000..8717eff5
--- /dev/null
+++ b/mpeglib/lib/util/mmx/mmx_asm.h
@@ -0,0 +1,258 @@
+/*
+ * mmx.h
+ * Copyright (C) 1997-2001 H. Dietz and R. Fisher
+ *
+ * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
+ *
+ * mpeg2dec is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+/*
+ * The type of an value that fits in an MMX register (note that long
+ * long constant values MUST be suffixed by LL and unsigned long long
+ * values by ULL, lest they be truncated by the compiler)
+ */
+
+#ifndef __MMX_ASM_H
+#define __MMX_ASM_H
+
+#include "attribute.h"
+
+
+typedef union {
+ long long q; /* Quadword (64-bit) value */
+ unsigned long long uq; /* Unsigned Quadword */
+ int d[2]; /* 2 Doubleword (32-bit) values */
+ unsigned int ud[2]; /* 2 Unsigned Doubleword */
+ short w[4]; /* 4 Word (16-bit) values */
+ unsigned short uw[4]; /* 4 Unsigned Word */
+ char b[8]; /* 8 Byte (8-bit) values */
+ unsigned char ub[8]; /* 8 Unsigned Byte */
+ float s[2]; /* Single-precision (32-bit) value */
+} ATTR_ALIGN(8) mmx_t; /* On an 8-byte (64-bit) boundary */
+
+
+#define mmx_i2r(op,imm,reg) \
+ __asm__ __volatile__ (#op " %0, %%" #reg \
+ : /* nothing */ \
+ : "X" (imm) )
+
+#define mmx_m2r(op,mem,reg) \
+ __asm__ __volatile__ (#op " %0, %%" #reg \
+ : /* nothing */ \
+ : "X" (mem))
+
+#define mmx_r2m(op,reg,mem) \
+ __asm__ __volatile__ (#op " %%" #reg ", %0" \
+ : "=X" (mem) \
+ : /* nothing */ )
+
+#define mmx_r2r(op,regs,regd) \
+ __asm__ __volatile__ (#op " %" #regs ", %" #regd)
+
+
+#define emms() __asm__ __volatile__ ("emms")
+
+#define movd_m2r(var,reg) mmx_m2r (movd, var, reg)
+#define movd_r2m(reg,var) mmx_r2m (movd, reg, var)
+#define movd_r2r(regs,regd) mmx_r2r (movd, regs, regd)
+
+#define movq_m2r(var,reg) mmx_m2r (movq, var, reg)
+#define movq_r2m(reg,var) mmx_r2m (movq, reg, var)
+#define movq_r2r(regs,regd) mmx_r2r (movq, regs, regd)
+
+#define packssdw_m2r(var,reg) mmx_m2r (packssdw, var, reg)
+#define packssdw_r2r(regs,regd) mmx_r2r (packssdw, regs, regd)
+#define packsswb_m2r(var,reg) mmx_m2r (packsswb, var, reg)
+#define packsswb_r2r(regs,regd) mmx_r2r (packsswb, regs, regd)
+
+#define packuswb_m2r(var,reg) mmx_m2r (packuswb, var, reg)
+#define packuswb_r2r(regs,regd) mmx_r2r (packuswb, regs, regd)
+
+#define paddb_m2r(var,reg) mmx_m2r (paddb, var, reg)
+#define paddb_r2r(regs,regd) mmx_r2r (paddb, regs, regd)
+#define paddd_m2r(var,reg) mmx_m2r (paddd, var, reg)
+#define paddd_r2r(regs,regd) mmx_r2r (paddd, regs, regd)
+#define paddw_m2r(var,reg) mmx_m2r (paddw, var, reg)
+#define paddw_r2r(regs,regd) mmx_r2r (paddw, regs, regd)
+
+#define paddsb_m2r(var,reg) mmx_m2r (paddsb, var, reg)
+#define paddsb_r2r(regs,regd) mmx_r2r (paddsb, regs, regd)
+#define paddsw_m2r(var,reg) mmx_m2r (paddsw, var, reg)
+#define paddsw_r2r(regs,regd) mmx_r2r (paddsw, regs, regd)
+
+#define paddusb_m2r(var,reg) mmx_m2r (paddusb, var, reg)
+#define paddusb_r2r(regs,regd) mmx_r2r (paddusb, regs, regd)
+#define paddusw_m2r(var,reg) mmx_m2r (paddusw, var, reg)
+#define paddusw_r2r(regs,regd) mmx_r2r (paddusw, regs, regd)
+
+#define pand_m2r(var,reg) mmx_m2r (pand, var, reg)
+#define pand_r2r(regs,regd) mmx_r2r (pand, regs, regd)
+
+#define pandn_m2r(var,reg) mmx_m2r (pandn, var, reg)
+#define pandn_r2r(regs,regd) mmx_r2r (pandn, regs, regd)
+
+#define pcmpeqb_m2r(var,reg) mmx_m2r (pcmpeqb, var, reg)
+#define pcmpeqb_r2r(regs,regd) mmx_r2r (pcmpeqb, regs, regd)
+#define pcmpeqd_m2r(var,reg) mmx_m2r (pcmpeqd, var, reg)
+#define pcmpeqd_r2r(regs,regd) mmx_r2r (pcmpeqd, regs, regd)
+#define pcmpeqw_m2r(var,reg) mmx_m2r (pcmpeqw, var, reg)
+#define pcmpeqw_r2r(regs,regd) mmx_r2r (pcmpeqw, regs, regd)
+
+#define pcmpgtb_m2r(var,reg) mmx_m2r (pcmpgtb, var, reg)
+#define pcmpgtb_r2r(regs,regd) mmx_r2r (pcmpgtb, regs, regd)
+#define pcmpgtd_m2r(var,reg) mmx_m2r (pcmpgtd, var, reg)
+#define pcmpgtd_r2r(regs,regd) mmx_r2r (pcmpgtd, regs, regd)
+#define pcmpgtw_m2r(var,reg) mmx_m2r (pcmpgtw, var, reg)
+#define pcmpgtw_r2r(regs,regd) mmx_r2r (pcmpgtw, regs, regd)
+
+#define pmaddwd_m2r(var,reg) mmx_m2r (pmaddwd, var, reg)
+#define pmaddwd_r2r(regs,regd) mmx_r2r (pmaddwd, regs, regd)
+
+#define pmulhw_m2r(var,reg) mmx_m2r (pmulhw, var, reg)
+#define pmulhw_r2r(regs,regd) mmx_r2r (pmulhw, regs, regd)
+
+#define pmullw_m2r(var,reg) mmx_m2r (pmullw, var, reg)
+#define pmullw_r2r(regs,regd) mmx_r2r (pmullw, regs, regd)
+
+#define por_m2r(var,reg) mmx_m2r (por, var, reg)
+#define por_r2r(regs,regd) mmx_r2r (por, regs, regd)
+
+#define pslld_i2r(imm,reg) mmx_i2r (pslld, imm, reg)
+#define pslld_m2r(var,reg) mmx_m2r (pslld, var, reg)
+#define pslld_r2r(regs,regd) mmx_r2r (pslld, regs, regd)
+#define psllq_i2r(imm,reg) mmx_i2r (psllq, imm, reg)
+#define psllq_m2r(var,reg) mmx_m2r (psllq, var, reg)
+#define psllq_r2r(regs,regd) mmx_r2r (psllq, regs, regd)
+#define psllw_i2r(imm,reg) mmx_i2r (psllw, imm, reg)
+#define psllw_m2r(var,reg) mmx_m2r (psllw, var, reg)
+#define psllw_r2r(regs,regd) mmx_r2r (psllw, regs, regd)
+
+#define psrad_i2r(imm,reg) mmx_i2r (psrad, imm, reg)
+#define psrad_m2r(var,reg) mmx_m2r (psrad, var, reg)
+#define psrad_r2r(regs,regd) mmx_r2r (psrad, regs, regd)
+#define psraw_i2r(imm,reg) mmx_i2r (psraw, imm, reg)
+#define psraw_m2r(var,reg) mmx_m2r (psraw, var, reg)
+#define psraw_r2r(regs,regd) mmx_r2r (psraw, regs, regd)
+
+#define psrld_i2r(imm,reg) mmx_i2r (psrld, imm, reg)
+#define psrld_m2r(var,reg) mmx_m2r (psrld, var, reg)
+#define psrld_r2r(regs,regd) mmx_r2r (psrld, regs, regd)
+#define psrlq_i2r(imm,reg) mmx_i2r (psrlq, imm, reg)
+#define psrlq_m2r(var,reg) mmx_m2r (psrlq, var, reg)
+#define psrlq_r2r(regs,regd) mmx_r2r (psrlq, regs, regd)
+#define psrlw_i2r(imm,reg) mmx_i2r (psrlw, imm, reg)
+#define psrlw_m2r(var,reg) mmx_m2r (psrlw, var, reg)
+#define psrlw_r2r(regs,regd) mmx_r2r (psrlw, regs, regd)
+
+#define psubb_m2r(var,reg) mmx_m2r (psubb, var, reg)
+#define psubb_r2r(regs,regd) mmx_r2r (psubb, regs, regd)
+#define psubd_m2r(var,reg) mmx_m2r (psubd, var, reg)
+#define psubd_r2r(regs,regd) mmx_r2r (psubd, regs, regd)
+#define psubw_m2r(var,reg) mmx_m2r (psubw, var, reg)
+#define psubw_r2r(regs,regd) mmx_r2r (psubw, regs, regd)
+
+#define psubsb_m2r(var,reg) mmx_m2r (psubsb, var, reg)
+#define psubsb_r2r(regs,regd) mmx_r2r (psubsb, regs, regd)
+#define psubsw_m2r(var,reg) mmx_m2r (psubsw, var, reg)
+#define psubsw_r2r(regs,regd) mmx_r2r (psubsw, regs, regd)
+
+#define psubusb_m2r(var,reg) mmx_m2r (psubusb, var, reg)
+#define psubusb_r2r(regs,regd) mmx_r2r (psubusb, regs, regd)
+#define psubusw_m2r(var,reg) mmx_m2r (psubusw, var, reg)
+#define psubusw_r2r(regs,regd) mmx_r2r (psubusw, regs, regd)
+
+#define punpckhbw_m2r(var,reg) mmx_m2r (punpckhbw, var, reg)
+#define punpckhbw_r2r(regs,regd) mmx_r2r (punpckhbw, regs, regd)
+#define punpckhdq_m2r(var,reg) mmx_m2r (punpckhdq, var, reg)
+#define punpckhdq_r2r(regs,regd) mmx_r2r (punpckhdq, regs, regd)
+#define punpckhwd_m2r(var,reg) mmx_m2r (punpckhwd, var, reg)
+#define punpckhwd_r2r(regs,regd) mmx_r2r (punpckhwd, regs, regd)
+
+#define punpcklbw_m2r(var,reg) mmx_m2r (punpcklbw, var, reg)
+#define punpcklbw_r2r(regs,regd) mmx_r2r (punpcklbw, regs, regd)
+#define punpckldq_m2r(var,reg) mmx_m2r (punpckldq, var, reg)
+#define punpckldq_r2r(regs,regd) mmx_r2r (punpckldq, regs, regd)
+#define punpcklwd_m2r(var,reg) mmx_m2r (punpcklwd, var, reg)
+#define punpcklwd_r2r(regs,regd) mmx_r2r (punpcklwd, regs, regd)
+
+#define pxor_m2r(var,reg) mmx_m2r (pxor, var, reg)
+#define pxor_r2r(regs,regd) mmx_r2r (pxor, regs, regd)
+
+
+/* 3DNOW extensions */
+
+#define pavgusb_m2r(var,reg) mmx_m2r (pavgusb, var, reg)
+#define pavgusb_r2r(regs,regd) mmx_r2r (pavgusb, regs, regd)
+
+
+/* AMD MMX extensions - also available in intel SSE */
+
+
+#define mmx_m2ri(op,mem,reg,imm) \
+ __asm__ __volatile__ (#op " %1, %0, %%" #reg \
+ : /* nothing */ \
+ : "X" (mem), "X" (imm))
+#define mmx_r2ri(op,regs,regd,imm) \
+ __asm__ __volatile__ (#op " %0, %%" #regs ", %%" #regd \
+ : /* nothing */ \
+ : "X" (imm) )
+
+#define mmx_fetch(mem,hint) \
+ __asm__ __volatile__ ("prefetch" #hint " %0" \
+ : /* nothing */ \
+ : "X" (mem))
+
+
+#define maskmovq(regs,maskreg) mmx_r2ri (maskmovq, regs, maskreg)
+
+#define movntq_r2m(mmreg,var) mmx_r2m (movntq, mmreg, var)
+
+#define pavgb_m2r(var,reg) mmx_m2r (pavgb, var, reg)
+#define pavgb_r2r(regs,regd) mmx_r2r (pavgb, regs, regd)
+#define pavgw_m2r(var,reg) mmx_m2r (pavgw, var, reg)
+#define pavgw_r2r(regs,regd) mmx_r2r (pavgw, regs, regd)
+
+#define pextrw_r2r(mmreg,reg,imm) mmx_r2ri (pextrw, mmreg, reg, imm)
+
+#define pinsrw_r2r(reg,mmreg,imm) mmx_r2ri (pinsrw, reg, mmreg, imm)
+
+#define pmaxsw_m2r(var,reg) mmx_m2r (pmaxsw, var, reg)
+#define pmaxsw_r2r(regs,regd) mmx_r2r (pmaxsw, regs, regd)
+
+#define pmaxub_m2r(var,reg) mmx_m2r (pmaxub, var, reg)
+#define pmaxub_r2r(regs,regd) mmx_r2r (pmaxub, regs, regd)
+
+#define pminsw_m2r(var,reg) mmx_m2r (pminsw, var, reg)
+#define pminsw_r2r(regs,regd) mmx_r2r (pminsw, regs, regd)
+
+#define pminub_m2r(var,reg) mmx_m2r (pminub, var, reg)
+#define pminub_r2r(regs,regd) mmx_r2r (pminub, regs, regd)
+
+#define pmovmskb(mmreg,reg) \
+ __asm__ __volatile__ ("movmskps %" #mmreg ", %" #reg)
+
+#define pmulhuw_m2r(var,reg) mmx_m2r (pmulhuw, var, reg)
+#define pmulhuw_r2r(regs,regd) mmx_r2r (pmulhuw, regs, regd)
+
+#define prefetcht0(mem) mmx_fetch (mem, t0)
+#define prefetcht1(mem) mmx_fetch (mem, t1)
+#define prefetcht2(mem) mmx_fetch (mem, t2)
+#define prefetchnta(mem) mmx_fetch (mem, nta)
+
+#define psadbw_m2r(var,reg) mmx_m2r (psadbw, var, reg)
+#define psadbw_r2r(regs,regd) mmx_r2r (psadbw, regs, regd)
+
+#define pshufw_m2r(var,reg,imm) mmx_m2ri(pshufw, var, reg, imm)
+#define pshufw_r2r(regs,regd,imm) mmx_r2ri(pshufw, regs, regd, imm)
+
+#define sfence() __asm__ __volatile__ ("sfence\n\t")
+
+
+#endif
+
+
diff --git a/mpeglib/lib/util/render/Makefile.am b/mpeglib/lib/util/render/Makefile.am
new file mode 100644
index 00000000..24bc691f
--- /dev/null
+++ b/mpeglib/lib/util/render/Makefile.am
@@ -0,0 +1,59 @@
+# player - Makefile.am
+
+SUBDIRS = dither dither2YUV x11 sdl
+
+INCLUDES = $(all_includes)
+
+THIS_EXTRALIBS = dither/libdither.la \
+ dither2YUV/libdivxutil_dither.la \
+ x11/libutilx11.la
+
+
+noinst_LTLIBRARIES = libutilrender.la
+
+noinst_HEADERS = imageBase.h \
+ renderMachine.h surface.h
+
+
+kmpgincludedir = $(includedir)/$(THIS_LIB_NAME)/util/render
+
+kmpginclude_HEADERS = yuvPicture.h pictureArray.h
+
+
+libutilrender_la_SOURCES = yuvPicture.cpp imageBase.cpp \
+ renderMachine.cpp surface.cpp \
+ pictureArray.cpp
+
+libutilrender_la_LIBADD = $(THIS_EXTRALIBS)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/mpeglib/lib/util/render/dither/Makefile.am b/mpeglib/lib/util/render/dither/Makefile.am
new file mode 100644
index 00000000..166d5ca3
--- /dev/null
+++ b/mpeglib/lib/util/render/dither/Makefile.am
@@ -0,0 +1,40 @@
+# liboutplugin - Makefile.am
+
+INCLUDES = $(all_includes)
+
+EXTRA_DIST = ditherDef.h ditherMMX.h \
+ ditherer_mmx16.cpp dither32mmx.cpp
+
+noinst_LTLIBRARIES = libdither.la
+
+noinst_HEADERS = ditherWrapper.h \
+ dither8Bit.h colorTable8Bit.h \
+ colorTableHighBit.h dither16Bit.h \
+ dither32Bit.h ditherRGB_flipped.h \
+ ditherRGB.h
+
+libdither_la_SOURCES = ditherWrapper.cpp \
+ dither8Bit.cpp \
+ colorTable8Bit.cpp colorTableHighBit.cpp \
+ dither16Bit.cpp dither32Bit.cpp \
+ ditherRGB_flipped.cpp ditherRGB.cpp \
+ ditherer_mmx16.cpp dither32mmx.cpp
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/mpeglib/lib/util/render/dither/colorTable8Bit.cpp b/mpeglib/lib/util/render/dither/colorTable8Bit.cpp
new file mode 100644
index 00000000..57c533de
--- /dev/null
+++ b/mpeglib/lib/util/render/dither/colorTable8Bit.cpp
@@ -0,0 +1,147 @@
+/*
+ colorTables for 8 Bit depth
+ 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 "colorTable8Bit.h"
+
+
+ColorTable8Bit::ColorTable8Bit() {
+
+ lum_values = new int[LUM_RANGE];
+ cr_values = new int[CR_RANGE];
+ cb_values = new int[CB_RANGE];
+
+
+ /* We can exploit cache by allocating contiguous blocks */
+
+ colortab = new TABTYPE[5*256];
+
+ Cr_r_tab = &colortab[0*256];
+ Cr_g_tab = &colortab[1*256];
+ Cb_g_tab = &colortab[2*256];
+ Cb_b_tab = &colortab[3*256];
+ L_tab = &colortab[4*256];
+
+ init8BitColor();
+}
+
+
+ColorTable8Bit::~ColorTable8Bit() {
+ delete lum_values;
+ delete cr_values;
+ delete cb_values;
+ delete colortab;
+}
+
+
+void ColorTable8Bit::init8BitColor() {
+ int i;
+
+
+
+ for (i=0; i<LUM_RANGE; i++) {
+ lum_values[i] = ((i * 256) / (LUM_RANGE)) + (256/(LUM_RANGE*2));
+ L_tab[i] = lum_values[i];
+ if (gammaCorrectFlag) {
+ L_tab[i] = GAMMA_CORRECTION(L_tab[i]);
+ }
+
+ }
+
+
+ for (i=0; i<CR_RANGE; i++) {
+ register double tmp;
+ if (chromaCorrectFlag) {
+ tmp = ((i * 256) / (CR_RANGE)) + (256/(CR_RANGE*2));
+ Cr_r_tab[i]=(TABTYPE) ((0.419/0.299)*CHROMA_CORRECTION128D(tmp-128.0));
+ Cr_g_tab[i]=(TABTYPE) (-(0.299/0.419)*CHROMA_CORRECTION128D(tmp-128.0));
+ cr_values[i] = CHROMA_CORRECTION256(tmp);
+ } else {
+ tmp = ((i * 256) / (CR_RANGE)) + (256/(CR_RANGE*2));
+ Cr_r_tab[i] = (TABTYPE) ((0.419/0.299) * (tmp - 128.0));
+ Cr_g_tab[i] = (TABTYPE) (-(0.299/0.419) * (tmp - 128.0));
+ cr_values[i] = (int) tmp;
+ }
+ }
+
+
+ for (i=0; i<CB_RANGE; i++) {
+ register double tmp;
+ if (chromaCorrectFlag) {
+ tmp = ((i * 256) / (CB_RANGE)) + (256/(CB_RANGE*2));
+ Cb_g_tab[i]=(TABTYPE) (-(0.114/0.331)*CHROMA_CORRECTION128D(tmp-128.0));
+ Cb_b_tab[i]=(TABTYPE) ((0.587/0.331)*CHROMA_CORRECTION128D(tmp-128.0));
+ cb_values[i] = CHROMA_CORRECTION256(tmp);
+ } else {
+ tmp = ((i * 256) / (CB_RANGE)) + (256/(CB_RANGE*2));
+ Cb_g_tab[i] = (TABTYPE) (-(0.114/0.331) * (tmp - 128.0));
+ Cb_b_tab[i] = (TABTYPE) ((0.587/0.331) * (tmp - 128.0));
+ cb_values[i] = (int) tmp;
+ }
+ }
+}
+
+
+
+/*
+ *--------------------------------------------------------------
+ *
+ * ConvertColor --
+ *
+ * Given a l, cr, cb tuple, converts it to r,g,b.
+ *
+ * Results:
+ * r,g,b values returned in pointers passed as parameters.
+ *
+ * Side effects:
+ * None.
+ *
+ *--------------------------------------------------------------
+ */
+void ColorTable8Bit::ConvertColor(unsigned int l, unsigned int cr,
+ unsigned int cb, unsigned char* r,
+ unsigned char* g, unsigned char* b) {
+
+ double fl, fr, fg, fb;
+
+ /*
+ * Old method w/o lookup table
+ *
+ * fl = 1.164*(((double) l)-16.0);
+ * fcr = ((double) cr) - 128.0;
+ * fcb = ((double) cb) - 128.0;
+ *
+ * fr = fl + (1.366 * fcr);
+ * fg = fl - (0.700 * fcr) - (0.334 * fcb);
+ * fb = fl + (1.732 * fcb);
+ */
+
+ fl = L_tab[l];
+
+ fr = fl + Cr_r_tab[cr];
+ fg = fl + Cr_g_tab[cr] + Cb_g_tab[cb];
+ fb = fl + Cb_b_tab[cb];
+
+ if (fr < 0.0) fr = 0.0;
+ else if (fr > 255.0) fr = 255.0;
+
+ if (fg < 0.0) fg = 0.0;
+ else if (fg > 255.0) fg = 255.0;
+
+ if (fb < 0.0) fb = 0.0;
+ else if (fb > 255.0) fb = 255.0;
+
+ *r = (unsigned char) fr;
+ *g = (unsigned char) fg;
+ *b = (unsigned char) fb;
+
+}
diff --git a/mpeglib/lib/util/render/dither/colorTable8Bit.h b/mpeglib/lib/util/render/dither/colorTable8Bit.h
new file mode 100644
index 00000000..6d873d1d
--- /dev/null
+++ b/mpeglib/lib/util/render/dither/colorTable8Bit.h
@@ -0,0 +1,57 @@
+/*
+ colorTables for 8 Bit depth
+ 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 __COLORTABLE8BIT_H
+#define __COLORTABLE8BIT_H
+
+#include "ditherDef.h"
+
+
+class ColorTable8Bit {
+
+ // Arrays holding quantized value ranged for lum, cr, and cb.
+ // (used for 8 Bit)
+
+ int* lum_values;
+ int* cr_values;
+ int* cb_values;
+
+
+
+
+ TABTYPE *L_tab;
+ TABTYPE *Cr_r_tab;
+ TABTYPE *Cr_g_tab;
+ TABTYPE *Cb_g_tab;
+ TABTYPE *Cb_b_tab;
+ TABTYPE *colortab;
+
+
+ public:
+ ColorTable8Bit();
+ ~ColorTable8Bit();
+
+ inline int* getLumValues() { return lum_values; }
+ inline int* getCrValues() { return cr_values; }
+ inline int* getCbValues() { return cb_values; }
+
+ void ConvertColor(unsigned int l, unsigned int cr, unsigned int cb,
+ unsigned char* r, unsigned char* g, unsigned char* b);
+
+
+ private:
+ void init8BitColor();
+
+
+};
+#endif
diff --git a/mpeglib/lib/util/render/dither/colorTableHighBit.cpp b/mpeglib/lib/util/render/dither/colorTableHighBit.cpp
new file mode 100644
index 00000000..171f4e97
--- /dev/null
+++ b/mpeglib/lib/util/render/dither/colorTableHighBit.cpp
@@ -0,0 +1,248 @@
+/*
+ colorTables for 16,32 Bit depth
+ 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 "colorTableHighBit.h"
+
+//#define INTERPOLATE
+
+
+/*
+ * Erik Corry's multi-byte dither routines.
+ *
+ * The basic idea is that the Init generates all the necessary tables.
+ * The tables incorporate the information about the layout of pixels
+ * in the XImage, so that it should be able to cope with 15-bit, 16-bit
+ * 24-bit (non-packed) and 32-bit (10-11 bits per color!) screens.
+ * At present it cannot cope with 24-bit packed mode, since this involves
+ * getting down to byte level again. It is assumed that the bits for each
+ * color are contiguous in the longword.
+ *
+ * Writing to memory is done in shorts or ints. (Unfortunately, short is not
+ * very fast on Alpha, so there is room for improvement here). There is no
+ * dither time check for overflow - instead the tables have slack at
+ * each end. This is likely to be faster than an 'if' test as many modern
+ * architectures are really bad at ifs. Potentially, each '&&' causes a
+ * pipeline flush!
+ *
+ * There is no shifting and fixed point arithmetic, as I really doubt you
+ * can see the difference, and it costs. This may be just my bias, since I
+ * heard that Intel is really bad at shifting.
+ */
+
+
+/*
+ * How many 1 bits are there in the PIXVALword.
+ * Low performance, do not call often.
+ */
+static int number_of_bits_set(unsigned PIXVAL a) {
+ if(!a) return 0;
+ if(a & 1) return 1 + number_of_bits_set(a >> 1);
+ return(number_of_bits_set(a >> 1));
+}
+
+
+
+/*
+ * How many 0 bits are there at most significant end of PIXVALword.
+ * Low performance, do not call often.
+ */
+static int free_bits_at_top(unsigned PIXVAL a) {
+ /* assume char is 8 bits */
+ if(!a) return sizeof(unsigned PIXVAL) * 8;
+ /* assume twos complement */
+ if(((PIXVAL)a) < 0l) return 0;
+ return 1 + free_bits_at_top ( a << 1);
+}
+
+/*
+ * How many 0 bits are there at least significant end of PIXVALword.
+ * Low performance, do not call often.
+ */
+static int free_bits_at_bottom(unsigned PIXVAL a) {
+ /* assume char is 8 bits */
+ if(!a) return sizeof(unsigned PIXVAL) * 8;
+ if(((PIXVAL)a) & 1l) return 0;
+ return 1 + free_bits_at_bottom ( a >> 1);
+}
+
+
+
+ColorTableHighBit::ColorTableHighBit(int bpp,unsigned int redMask,
+ unsigned int greenMask,
+ unsigned int blueMask) {
+ this->bpp=bpp;
+ this->redMask=redMask;
+ this->greenMask=greenMask;
+ this->blueMask=blueMask;
+
+ colortab = new TABTYPE[5*256];
+
+ Cr_r_tab = &colortab[0*256];
+ Cr_g_tab = &colortab[1*256];
+ Cb_g_tab = &colortab[2*256];
+ Cb_b_tab = &colortab[3*256];
+ L_tab = &colortab[4*256];
+
+ rgb_2_pix = new PIXVAL [3*768];
+
+ r_2_pix_alloc = &rgb_2_pix[0*768];
+ g_2_pix_alloc = &rgb_2_pix[1*768];
+ b_2_pix_alloc = &rgb_2_pix[2*768];
+
+ initHighColor(bpp>=24,redMask,greenMask,blueMask);
+
+}
+
+
+ColorTableHighBit::~ColorTableHighBit() {
+ delete colortab;
+ delete rgb_2_pix;
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * InitColor16Dither --
+ *
+ * To get rid of the multiply and other conversions in color
+ * dither, we use a lookup table.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * The lookup tables are initialized.
+ *
+ *--------------------------------------------------------------
+ */
+
+void ColorTableHighBit::initHighColor(int thirty2,unsigned int redMask,
+ unsigned int greenMask,
+ unsigned int blueMask) {
+
+ unsigned PIXVAL red_mask = redMask;
+ unsigned PIXVAL green_mask =greenMask;
+ unsigned PIXVAL blue_mask = blueMask;
+
+ int CR, CB, i;
+
+
+ for (i=0; i<256; i++) {
+ L_tab[i] = i;
+ if (gammaCorrectFlag) {
+ L_tab[i] = (TABTYPE)GAMMA_CORRECTION(i);
+ }
+
+ CB = CR = i;
+
+ if (chromaCorrectFlag) {
+ CB -= 128;
+ CB = CHROMA_CORRECTION128(CB);
+ CR -= 128;
+ CR = CHROMA_CORRECTION128(CR);
+ } else {
+ CB -= 128; CR -= 128;
+ }
+/* was
+ Cr_r_tab[i] = 1.596 * CR;
+ Cr_g_tab[i] = -0.813 * CR;
+ Cb_g_tab[i] = -0.391 * CB;
+ Cb_b_tab[i] = 2.018 * CB;
+ but they were just messed up.
+ Then was (_Video Deymstified_):
+ Cr_r_tab[i] = 1.366 * CR;
+ Cr_g_tab[i] = -0.700 * CR;
+ Cb_g_tab[i] = -0.334 * CB;
+ Cb_b_tab[i] = 1.732 * CB;
+ but really should be:
+ (from ITU-R BT.470-2 System B, G and SMPTE 170M )
+*/
+ Cr_r_tab[i] = (TABTYPE) ( (0.419/0.299) * CR );
+ Cr_g_tab[i] = (TABTYPE) ( -(0.299/0.419) * CR );
+ Cb_g_tab[i] = (TABTYPE) ( -(0.114/0.331) * CB );
+ Cb_b_tab[i] = (TABTYPE) ( (0.587/0.331) * CB );
+
+/*
+ though you could argue for:
+ SMPTE 240M
+ Cr_r_tab[i] = (0.445/0.212) * CR;
+ Cr_g_tab[i] = -(0.212/0.445) * CR;
+ Cb_g_tab[i] = -(0.087/0.384) * CB;
+ Cb_b_tab[i] = (0.701/0.384) * CB;
+ FCC
+ Cr_r_tab[i] = (0.421/0.30) * CR;
+ Cr_g_tab[i] = -(0.30/0.421) * CR;
+ Cb_g_tab[i] = -(0.11/0.331) * CB;
+ Cb_b_tab[i] = (0.59/0.331) * CB;
+ ITU-R BT.709
+ Cr_r_tab[i] = (0.454/0.2125) * CR;
+ Cr_g_tab[i] = -(0.2125/0.454) * CR;
+ Cb_g_tab[i] = -(0.0721/0.386) * CB;
+ Cb_b_tab[i] = (0.7154/0.386) * CB;
+*/
+ }
+
+ /*
+ * Set up entries 0-255 in rgb-to-pixel value tables.
+ */
+ for (i = 0; i < 256; i++) {
+ r_2_pix_alloc[i + 256] = i >> (8 - number_of_bits_set(red_mask));
+ r_2_pix_alloc[i + 256] <<= free_bits_at_bottom(red_mask);
+ g_2_pix_alloc[i + 256] = i >> (8 - number_of_bits_set(green_mask));
+ g_2_pix_alloc[i + 256] <<= free_bits_at_bottom(green_mask);
+ b_2_pix_alloc[i + 256] = i >> (8 - number_of_bits_set(blue_mask));
+ b_2_pix_alloc[i + 256] <<= free_bits_at_bottom(blue_mask);
+ /*
+ * If we have 16-bit output depth, then we double the value
+ * in the top word. This means that we can write out both
+ * pixels in the pixel doubling mode with one op. It is
+ * harmless in the normal case as storing a 32-bit value
+ * through a short pointer will lose the top bits anyway.
+ * A similar optimisation for Alpha for 64 bit has been
+ * prepared for, but is not yet implemented.
+ */
+ if(!thirty2) {
+ r_2_pix_alloc[i + 256] |= (r_2_pix_alloc[i + 256]) << 16;
+ g_2_pix_alloc[i + 256] |= (g_2_pix_alloc[i + 256]) << 16;
+ b_2_pix_alloc[i + 256] |= (b_2_pix_alloc[i + 256]) << 16;
+
+ }
+#ifdef SIXTYFOUR_BIT
+ if(thirty2) {
+
+ r_2_pix_alloc[i + 256] |= (r_2_pix_alloc[i + 256]) << 32;
+ g_2_pix_alloc[i + 256] |= (g_2_pix_alloc[i + 256]) << 32;
+ b_2_pix_alloc[i + 256] |= (b_2_pix_alloc[i + 256]) << 32;
+
+ }
+#endif
+ }
+
+ /*
+ * Spread out the values we have to the rest of the array so that
+ * we do not need to check for overflow.
+ */
+ for (i = 0; i < 256; i++) {
+ r_2_pix_alloc[i] = r_2_pix_alloc[256];
+ r_2_pix_alloc[i+ 512] = r_2_pix_alloc[511];
+ g_2_pix_alloc[i] = g_2_pix_alloc[256];
+ g_2_pix_alloc[i+ 512] = g_2_pix_alloc[511];
+ b_2_pix_alloc[i] = b_2_pix_alloc[256];
+ b_2_pix_alloc[i+ 512] = b_2_pix_alloc[511];
+ }
+
+ r_2_pix = r_2_pix_alloc + 256;
+ g_2_pix = g_2_pix_alloc + 256;
+ b_2_pix = b_2_pix_alloc + 256;
+}
diff --git a/mpeglib/lib/util/render/dither/colorTableHighBit.h b/mpeglib/lib/util/render/dither/colorTableHighBit.h
new file mode 100644
index 00000000..9945414d
--- /dev/null
+++ b/mpeglib/lib/util/render/dither/colorTableHighBit.h
@@ -0,0 +1,73 @@
+/*
+ colorTables for 16,32 Bit depth
+ 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 __COLORTABLEHIGHBIT_H
+#define __COLORTABLEHIGHBIT_H
+
+#include "ditherDef.h"
+
+
+
+
+class ColorTableHighBit {
+
+ TABTYPE *L_tab;
+ TABTYPE *Cr_r_tab;
+ TABTYPE *Cr_g_tab;
+ TABTYPE *Cb_g_tab;
+ TABTYPE *Cb_b_tab;
+ TABTYPE *colortab;
+
+
+ PIXVAL *r_2_pix;
+ PIXVAL *g_2_pix;
+ PIXVAL *b_2_pix;
+ PIXVAL *rgb_2_pix;
+
+ PIXVAL *r_2_pix_alloc;
+ PIXVAL *g_2_pix_alloc;
+ PIXVAL *b_2_pix_alloc;
+
+
+
+ // init stuff
+ int bpp;
+ // colorMask
+ unsigned int redMask;
+ unsigned int greenMask;
+ unsigned int blueMask;
+
+ public:
+ ColorTableHighBit(int bpp,unsigned int redMask,
+ unsigned int greenMask,unsigned int blueMask);
+ ~ColorTableHighBit();
+
+ inline TABTYPE* getL_tab() { return L_tab ; }
+ inline TABTYPE* getCr_r_tab() { return Cr_r_tab ; }
+ inline TABTYPE* getCr_g_tab() { return Cr_g_tab ; }
+ inline TABTYPE* getCb_g_tab() { return Cb_g_tab ; }
+ inline TABTYPE* getCb_b_tab() { return Cb_b_tab ; }
+
+
+ inline PIXVAL* getr_2_pix() { return r_2_pix ; }
+ inline PIXVAL* getg_2_pix() { return g_2_pix ; }
+ inline PIXVAL* getb_2_pix() { return b_2_pix ; }
+
+
+
+ private:
+ void initHighColor(int thirty2,unsigned int redMask,
+ unsigned int greenMask,unsigned int blueMask);
+
+};
+#endif
diff --git a/mpeglib/lib/util/render/dither/dither16Bit.cpp b/mpeglib/lib/util/render/dither/dither16Bit.cpp
new file mode 100644
index 00000000..0a843ee9
--- /dev/null
+++ b/mpeglib/lib/util/render/dither/dither16Bit.cpp
@@ -0,0 +1,300 @@
+/*
+ dither 16 bit depth yuv images
+ 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 "dither16Bit.h"
+
+
+Dither16Bit::Dither16Bit(unsigned int redMask,
+ unsigned int greenMask,unsigned int blueMask) {
+
+
+ colorTableHighBit=new ColorTableHighBit(16,redMask,greenMask,blueMask);
+ L_tab=colorTableHighBit->getL_tab();
+ Cr_r_tab=colorTableHighBit->getCr_r_tab();
+ Cr_g_tab=colorTableHighBit->getCr_g_tab();
+ Cb_g_tab=colorTableHighBit->getCb_g_tab();
+ Cb_b_tab=colorTableHighBit->getCb_b_tab();
+
+ r_2_pix=colorTableHighBit->getr_2_pix();
+ g_2_pix=colorTableHighBit->getg_2_pix();
+ b_2_pix=colorTableHighBit->getb_2_pix();
+
+}
+
+
+Dither16Bit::~Dither16Bit() {
+ delete colorTableHighBit;
+}
+
+
+/*
+ *--------------------------------------------------------------
+ *
+ * Color16DitherImage --
+ *
+ * Converts image into 16 bit color.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *--------------------------------------------------------------
+ */
+
+void Dither16Bit::ditherImageColor16(unsigned char* lum,
+ unsigned char* cr,
+ unsigned char* cb,
+ unsigned char* out,
+ int rows,
+ int cols,
+ int offset) {
+
+ int L, CR, CB;
+ unsigned short *row1, *row2;
+ unsigned char *lum2;
+ int x, y;
+ int cr_r;
+ int cr_g;
+ int cb_g;
+ int cb_b;
+ int cols_2 = cols/2;
+
+ row1 = (unsigned short *)out;
+ row2=row1+cols_2+cols_2+offset; // start of second row
+
+ offset=2*offset+cols_2+cols_2;
+
+ lum2 = lum + cols_2 + cols_2;
+
+
+ for (y=0; y<rows; y+=2) {
+ for (x=0; x<cols_2; x++) {
+ int R, G, B;
+
+ CR = *cr++;
+ CB = *cb++;
+ cr_r = Cr_r_tab[CR];
+ cr_g = Cr_g_tab[CR];
+ cb_g = Cb_g_tab[CB];
+ cb_b = Cb_b_tab[CB];
+
+ L = L_tab[(int) *lum++];
+
+ R = L + cr_r;
+ G = L + cr_g + cb_g;
+ B = L + cb_b;
+
+ *row1++ = (r_2_pix[R] | g_2_pix[G] | b_2_pix[B]);
+
+
+#ifdef INTERPOLATE
+ if(x != cols_2 - 1) {
+ CR = (CR + *cr) >> 1;
+ CB = (CB + *cb) >> 1;
+ cr_r = Cr_r_tab[CR];
+ cr_g = Cr_g_tab[CR];
+ cb_g = Cb_g_tab[CB];
+ cb_b = Cb_b_tab[CB];
+ }
+#endif
+
+ L = L_tab[(int) *lum++];
+
+ R = L + cr_r;
+ G = L + cr_g + cb_g;
+ B = L + cb_b;
+
+ *row1++ = (r_2_pix[R] | g_2_pix[G] | b_2_pix[B]);
+
+ /*
+ * Now, do second row.
+ */
+#ifdef INTERPOLATE
+ if(y != rows - 2) {
+ CR = (CR + *(cr + cols_2 - 1)) >> 1;
+ CB = (CB + *(cb + cols_2 - 1)) >> 1;
+ cr_r = Cr_r_tab[CR];
+ cr_g = Cr_g_tab[CR];
+ cb_g = Cb_g_tab[CB];
+ cb_b = Cb_b_tab[CB];
+ }
+#endif
+
+ L = L_tab[(int) *lum2++];
+ R = L + cr_r;
+ G = L + cr_g + cb_g;
+ B = L + cb_b;
+
+ *row2++ = (r_2_pix[R] | g_2_pix[G] | b_2_pix[B]);
+
+ L = L_tab[(int) *lum2++];
+ R = L + cr_r;
+ G = L + cr_g + cb_g;
+ B = L + cb_b;
+
+ *row2++ = (r_2_pix[R] | g_2_pix[G] | b_2_pix[B]);
+ }
+ /*
+ * These values are at the start of the next line, (due
+ * to the ++'s above),but they need to be at the start
+ * of the line after that.
+ */
+ lum += cols_2 + cols_2;
+ lum2 += cols_2 + cols_2;
+ row1 += offset;
+ row2 += offset;
+ }
+}
+
+
+/*
+ * Erik Corry's pixel doubling routines for 15/16/24/32 bit screens.
+ */
+
+
+/*
+ *--------------------------------------------------------------
+ *
+ * Twox2Color16DitherImage --
+ *
+ * Converts image into 16 bit color at double size.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *--------------------------------------------------------------
+ */
+
+/*
+ * In this function I make use of a nasty trick. The tables have the lower
+ * 16 bits replicated in the upper 16. This means I can write ints and get
+ * the horisontal doubling for free (almost).
+ */
+
+void Dither16Bit::ditherImageTwox2Color16(unsigned char* lum,
+ unsigned char* cr,
+ unsigned char* cb,
+ unsigned char* out,
+ int rows,
+ int cols,
+ int mod) {
+ int L, CR, CB;
+ unsigned int *row1 = (unsigned int *)out;
+ unsigned int *row2 = row1 + cols + mod/2;
+ unsigned int *row3 = row2 + cols + mod/2;
+ unsigned int *row4 = row3 + cols + mod/2;
+ unsigned char *lum2;
+ int x, y;
+ int cr_r;
+ int cr_g;
+ int cb_g;
+ int cb_b;
+ int cols_2 = cols/2;
+
+ lum2 = lum + cols_2 + cols_2;
+ for (y=0; y<rows; y+=2) {
+ for (x=0; x<cols_2; x++) {
+ int R, G, B;
+ int t;
+
+ CR = *cr++;
+ CB = *cb++;
+ cr_r = Cr_r_tab[CR];
+ cr_g = Cr_g_tab[CR];
+ cb_g = Cb_g_tab[CB];
+ cb_b = Cb_b_tab[CB];
+
+ L = L_tab[(int) *lum++];
+
+ R = L + cr_r;
+ G = L + cr_g + cb_g;
+ B = L + cb_b;
+
+ t = (r_2_pix[R] | g_2_pix[G] | b_2_pix[B]);
+ row1[0] = t;
+ row1++;
+ row2[0] = t;
+ row2++;
+
+ // INTERPOLATE
+ if(x != cols_2 - 1) {
+ CR = (CR + *cr) >> 1;
+ CB = (CB + *cb) >> 1;
+ cr_r = Cr_r_tab[CR];
+ cr_g = Cr_g_tab[CR];
+ cb_g = Cb_g_tab[CB];
+ cb_b = Cb_b_tab[CB];
+ }
+ // end
+
+ L = L_tab[(int) *lum++];
+
+ R = L + cr_r;
+ G = L + cr_g + cb_g;
+ B = L + cb_b;
+
+ t = (r_2_pix[R] | g_2_pix[G] | b_2_pix[B]);
+ row1[0] = t;
+ row1++;
+ row2[0] = t;
+ row2++;
+
+ /*
+ * Now, do second row.
+ */
+ // INTERPOLATE
+ if(y != rows - 2) {
+ CR = (CR + *(cr + cols_2 - 1)) >> 1;
+ CB = (CB + *(cb + cols_2 - 1)) >> 1;
+ cr_r = Cr_r_tab[CR];
+ cr_g = Cr_g_tab[CR];
+ cb_g = Cb_g_tab[CB];
+ cb_b = Cb_b_tab[CB];
+ }
+ // end
+
+ L = L_tab[(int) *lum2++];
+ R = L + cr_r;
+ G = L + cr_g + cb_g;
+ B = L + cb_b;
+
+ t = (r_2_pix[R] | g_2_pix[G] | b_2_pix[B]);
+ row3[0] = t;
+ row3++;
+ row4[0] = t;
+ row4++;
+
+ L = L_tab[(int) *lum2++];
+ R = L + cr_r;
+ G = L + cr_g + cb_g;
+ B = L + cb_b;
+
+ t = (r_2_pix[R] | g_2_pix[G] | b_2_pix[B]);
+ row3[0] = t;
+ row3++;
+ row4[0] = t;
+ row4++;
+ }
+ lum += cols_2 + cols_2;
+ lum2 += cols_2 + cols_2;
+ row1 += 6 * cols_2 + 2*mod;
+ row3 += 6 * cols_2 + 2*mod;
+ row2 += 6 * cols_2 + 2*mod;
+ row4 += 6 * cols_2 + 2*mod;
+ }
+}
diff --git a/mpeglib/lib/util/render/dither/dither16Bit.h b/mpeglib/lib/util/render/dither/dither16Bit.h
new file mode 100644
index 00000000..2e47c01c
--- /dev/null
+++ b/mpeglib/lib/util/render/dither/dither16Bit.h
@@ -0,0 +1,55 @@
+/*
+ dither 16 bit depth yuv images
+ 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 __DITHER16Bit_H
+#define __DITHER16Bit_H
+
+#include "colorTableHighBit.h"
+
+class Dither16Bit {
+
+ ColorTableHighBit* colorTableHighBit;
+
+ TABTYPE *L_tab;
+ TABTYPE *Cr_r_tab;
+ TABTYPE *Cr_g_tab;
+ TABTYPE *Cb_g_tab;
+ TABTYPE *Cb_b_tab;
+
+ PIXVAL *r_2_pix;
+ PIXVAL *g_2_pix;
+ PIXVAL *b_2_pix;
+
+ public:
+ Dither16Bit(unsigned int redMask,
+ unsigned int greenMask,unsigned int blueMask);
+ ~Dither16Bit();
+
+ void ditherImageColor16(unsigned char* lum,
+ unsigned char* cr,
+ unsigned char* cb,
+ unsigned char* out,
+ int rows,
+ int cols,
+ int offset);
+
+ void ditherImageTwox2Color16(unsigned char* lum,
+ unsigned char* cr,
+ unsigned char* cb,
+ unsigned char* out,
+ int rows,
+ int cols,
+ int mod);
+
+};
+
+#endif
diff --git a/mpeglib/lib/util/render/dither/dither32Bit.cpp b/mpeglib/lib/util/render/dither/dither32Bit.cpp
new file mode 100644
index 00000000..61a1d2dc
--- /dev/null
+++ b/mpeglib/lib/util/render/dither/dither32Bit.cpp
@@ -0,0 +1,253 @@
+/*
+ dither 32 bit depth yuv images
+ 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 "dither32Bit.h"
+
+
+#define doRow(row,Lum) *row++=(local_r_2_pix[Lum] | \
+ local_g_2_pix[Lum] | local_b_2_pix[Lum])
+
+
+Dither32Bit::Dither32Bit(unsigned int redMask,
+ unsigned int greenMask,unsigned int blueMask) {
+
+
+ colorTableHighBit=new ColorTableHighBit(32,redMask,greenMask,blueMask);
+ L_tab=colorTableHighBit->getL_tab();
+ Cr_r_tab=colorTableHighBit->getCr_r_tab();
+ Cr_g_tab=colorTableHighBit->getCr_g_tab();
+ Cb_g_tab=colorTableHighBit->getCb_g_tab();
+ Cb_b_tab=colorTableHighBit->getCb_b_tab();
+
+ r_2_pix=colorTableHighBit->getr_2_pix();
+ g_2_pix=colorTableHighBit->getg_2_pix();
+ b_2_pix=colorTableHighBit->getb_2_pix();
+
+}
+
+
+Dither32Bit::~Dither32Bit() {
+ delete colorTableHighBit;
+}
+
+
+void Dither32Bit::ditherImageColor32(unsigned char* lum,
+ unsigned char* cr,
+ unsigned char* cb,
+ unsigned char* out,
+ int rows,
+ int cols,
+ int mod) {
+
+ int L;
+ int n;
+ int rowWork;
+ int colWork;
+
+ unsigned int *row1, *row2;
+ unsigned char *lum2;
+ PIXVAL* local_r_2_pix;
+ PIXVAL* local_g_2_pix;
+ PIXVAL* local_b_2_pix;
+
+ row1 = (unsigned int *)out;
+
+ row2 = row1+cols+mod;
+ lum2 = lum+cols;
+
+ // because the width/height are a multiply of a macroblocksize
+ // cols/rows always are even
+ colWork=cols>>1;
+ rowWork=rows>>1;
+ mod=cols+2*mod;
+
+ while(rowWork--) {
+ n=colWork;
+ while(n--) {
+
+ local_r_2_pix=r_2_pix+Cr_r_tab[*cr];
+ local_g_2_pix=g_2_pix+Cr_g_tab[*cr++] + Cb_g_tab[*cb];
+ local_b_2_pix=b_2_pix+Cb_b_tab[*cb++];
+
+ L = L_tab[*lum++];
+ doRow(row1,L);
+
+ L = L_tab[*lum++];
+ doRow(row1,L);
+
+ L = L_tab [*lum2++];
+ doRow(row2,L);
+
+ L = L_tab [*lum2++];
+ doRow(row2,L);
+
+
+ }
+ row2 += mod;
+ lum += cols;
+ lum2 += cols;
+ row1 += mod;
+
+ }
+
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * Twox2Color32 --
+ *
+ * Converts image into 24/32 bit color.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *--------------------------------------------------------------
+ */
+
+void Dither32Bit::ditherImageTwox2Color32(unsigned char* lum,
+ unsigned char* cr,
+ unsigned char* cb,
+ unsigned char* out,
+ int rows,
+ int cols,
+ int mod) {
+ int L, CR, CB;
+ unsigned PIXVAL *row1 = (unsigned PIXVAL *)out;
+ unsigned PIXVAL *row2 = row1 + cols * ONE_TWO + mod;
+ unsigned PIXVAL *row3 = row2 + cols * ONE_TWO + mod;
+ unsigned PIXVAL *row4 = row3 + cols * ONE_TWO + mod;
+ unsigned char *lum2;
+ int x, y;
+ int cr_r;
+ int cr_g;
+ int cb_g;
+ int cb_b;
+ int cols_2 = cols/2;
+ int loffset = ONE_TWO * 6 *cols_2 + 4*mod ;
+
+ lum2 = lum + cols_2 + cols_2;
+ for (y=0; y<rows; y+=2) {
+ for (x=0; x<cols_2; x++) {
+ int R, G, B;
+ PIXVAL t;
+
+ CR = *cr++;
+ CB = *cb++;
+ cr_r = Cr_r_tab[CR];
+ cr_g = Cr_g_tab[CR];
+ cb_g = Cb_g_tab[CB];
+ cb_b = Cb_b_tab[CB];
+
+ L = L_tab[ (int) *lum++];
+
+ R = L + cr_r;
+ G = L + cr_g + cb_g;
+ B = L + cb_b;
+
+ t = (r_2_pix[R] | g_2_pix[G] | b_2_pix[B]);
+ row1[0] = t;
+ row2[0] = t;
+#ifndef SIXTYFOUR_BIT
+ row1[1] = t;
+ row2[1] = t;
+#endif
+ row1 += ONE_TWO;
+ row2 += ONE_TWO;
+
+ /* INTERPOLATE is now standard */
+ // INTERPOLATE
+ if(x != cols_2 - 1) {
+ CR = (CR + *cr) >> 1;
+ CB = (CB + *cb) >> 1;
+ cr_r = Cr_r_tab[CR];
+ cr_g = Cr_g_tab[CR];
+ cb_g = Cb_g_tab[CB];
+ cb_b = Cb_b_tab[CB];
+ }
+ // end
+ /* end INTERPOLATE */
+
+ L = L_tab[ (int) *lum++];
+
+ R = L + cr_r;
+ G = L + cr_g + cb_g;
+ B = L + cb_b;
+
+ t = (r_2_pix[R] | g_2_pix[G] | b_2_pix[B]);
+ row1[0] = t;
+ row2[0] = t;
+#ifndef SIXTYFOUR_BIT
+ row1[1] = t;
+ row2[1] = t;
+#endif
+ row1 += ONE_TWO;
+ row2 += ONE_TWO;
+
+ /*
+ * Now, do second row.
+ */
+ /* INTERPOLATE is now standard */
+ // INTERPOLATE
+ if(y != rows - 2) {
+ CR = (unsigned int) (CR + *(cr + cols_2 - 1)) >> 1;
+ CB = (unsigned int) (CB + *(cb + cols_2 - 1)) >> 1;
+ cr_r = Cr_r_tab[CR];
+ cr_g = Cr_g_tab[CR];
+ cb_g = Cb_g_tab[CB];
+ cb_b = Cb_b_tab[CB];
+ }
+ // end
+ /* endif */
+ L = L_tab[ (int) *lum2++];
+ R = L + cr_r;
+ G = L + cr_g + cb_g;
+ B = L + cb_b;
+
+ t = (r_2_pix[R] | g_2_pix[G] | b_2_pix[B]);
+ row3[0] = t;
+ row4[0] = t;
+#ifndef SIXTYFOUR_BIT
+ row3[1] = t;
+ row4[1] = t;
+#endif
+ row3 += ONE_TWO;
+ row4 += ONE_TWO;
+
+ L = L_tab[(int) *lum2++];
+ R = L + cr_r;
+ G = L + cr_g + cb_g;
+ B = L + cb_b;
+
+ t = (r_2_pix[R] | g_2_pix[G] | b_2_pix[B]);
+ row3[0] = t;
+ row4[0] = t;
+#ifndef SIXTYFOUR_BIT
+ row3[1] = t;
+ row4[1] = t;
+#endif
+ row3 += ONE_TWO;
+ row4 += ONE_TWO;
+ }
+ lum += cols_2 + cols_2;
+ lum2 += cols_2 + cols_2;
+
+ row1 += loffset;
+ row3 += loffset;
+ row2 += loffset;
+ row4 += loffset;
+ }
+}
diff --git a/mpeglib/lib/util/render/dither/dither32Bit.h b/mpeglib/lib/util/render/dither/dither32Bit.h
new file mode 100644
index 00000000..440d021a
--- /dev/null
+++ b/mpeglib/lib/util/render/dither/dither32Bit.h
@@ -0,0 +1,55 @@
+/*
+ dither 32 bit depth yuv images
+ 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 __DITHER32Bit_H
+#define __DITHER32Bit_H
+
+#include "colorTableHighBit.h"
+
+class Dither32Bit {
+
+ ColorTableHighBit* colorTableHighBit;
+
+ TABTYPE *L_tab;
+ TABTYPE *Cr_r_tab;
+ TABTYPE *Cr_g_tab;
+ TABTYPE *Cb_g_tab;
+ TABTYPE *Cb_b_tab;
+
+ PIXVAL *r_2_pix;
+ PIXVAL *g_2_pix;
+ PIXVAL *b_2_pix;
+
+ public:
+ Dither32Bit(unsigned int redMask,
+ unsigned int greenMask,unsigned int blueMask);
+ ~Dither32Bit();
+
+ void ditherImageColor32(unsigned char* lum,
+ unsigned char* cr,
+ unsigned char* cb,
+ unsigned char* out,
+ int rows,
+ int cols,
+ int offset);
+
+ void ditherImageTwox2Color32(unsigned char* lum,
+ unsigned char* cr,
+ unsigned char* cb,
+ unsigned char* out,
+ int rows,
+ int cols,
+ int mod);
+
+};
+
+#endif
diff --git a/mpeglib/lib/util/render/dither/dither32mmx.cpp b/mpeglib/lib/util/render/dither/dither32mmx.cpp
new file mode 100644
index 00000000..b5fa4807
--- /dev/null
+++ b/mpeglib/lib/util/render/dither/dither32mmx.cpp
@@ -0,0 +1,272 @@
+/*
+ MMX ditherer for 32 bit displays
+ 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 "ditherMMX.h"
+
+#include <iostream>
+
+using namespace std;
+
+
+#ifndef INTEL
+ void dither32_mmx(unsigned char* lum,
+ unsigned char* cr,
+ unsigned char* cb,
+ unsigned char* out,
+ int rows,
+ int cols,
+ int mod) {
+ printf("urgs! dither32_mmx \n");
+ printf("never should happen!\n");
+ exit(0);
+}
+
+#else
+
+
+static unsigned long MMX32_80w[] = {0x00800080, 0x00800080};
+static unsigned long MMX32_10w[] = {0x00100010, 0x00100010};
+static unsigned long MMX32_00FFw[] = {0x00ff00ff, 0x00ff00ff};
+static unsigned long MMX32_FF00w[] = {0xff00ff00, 0xff00ff00};
+static unsigned short MMX32_Ycoeff[] = {0x4a, 0x4a, 0x4a, 0x4a};
+static unsigned short MMX32_Vredcoeff[] = {0x59, 0x59, 0x59, 0x59};
+static unsigned short MMX32_Ubluecoeff[] = {0x72, 0x72, 0x72, 0x72};
+static unsigned short MMX32_Ugrncoeff[] = {0xffea,0xffea,0xffea,0xffea};
+static unsigned short MMX32_Vgrncoeff[] = {0xffd2,0xffd2,0xffd2,0xffd2};
+
+void dummy_dithermmx32() {
+ cout << "MMX32_10w:"<<MMX32_10w<<endl;
+ cout << "MMX32_80w:"<<MMX32_80w<<endl;
+ cout << "MMX32_Ubluecoeff:"<<MMX32_Ubluecoeff<<endl;
+ cout << "MMX32_Vredcoeff:"<<MMX32_Vredcoeff<<endl;
+ cout << "MMX32_Ugrncoeff:"<<MMX32_Ugrncoeff<<endl;
+ cout << "MMX32_Vgrncoeff:"<<MMX32_Vgrncoeff<<endl;
+ cout << "MMX32_Ycoeff:"<<MMX32_Ycoeff<<endl;
+ cout << "MMX32_00FFw:"<<MMX32_00FFw<<endl;
+ cout << "MMX32_FF00w:"<<MMX32_FF00w<<endl;
+}
+
+
+/**
+ This MMX assembler is my first assembler/MMX program ever.
+ Thus it maybe buggy.
+ Send patches to:
+ mvogt@rhrk.uni-kl.de
+
+ After it worked fine I have "obfuscated" the code a bit to have
+ more parallism in the MMX units. This means I moved
+ initilisation around and delayed other instruction.
+ Performance measurement did not show that this brought any advantage
+ but in theory it _should_ be faster this way.
+
+ The overall performanve gain to the C based dither was 30%-40%.
+ The MMX routine calculates 256bit=8RGB values in each cycle
+ (4 for row1 & 4 for row2)
+
+ The red/green/blue.. coefficents are taken from the mpeg_play
+ player. They look nice, but I dont know if you can have
+ better values, to avoid integer rounding errors.
+
+
+ IMPORTANT:
+ ==========
+
+ It is a requirement that the cr/cb/lum are 8 byte aligned and
+ the out are 16byte aligned or you will/may get segfaults
+
+*/
+
+void dither32_mmx(unsigned char* lum,
+ unsigned char* cr,
+ unsigned char* cb,
+ unsigned char* out,
+ int rows,
+ int cols,
+ int mod) {
+
+
+
+ unsigned int *row1;
+ unsigned int *row2;
+ row1 = (unsigned int *)out; // 32 bit target
+
+ unsigned char* end = lum +cols*rows; // Pointer to the end
+ int x=cols;
+ row2=row1+cols+mod; // start of second row
+ mod=4*cols+8*mod; // increment for row1 in byte
+
+ // buffer for asm function
+ int buf[6];
+ buf[0]=(int)(lum+cols); // lum2 pointer
+ buf[1]=(int)end;
+ buf[2]=x;
+ buf[3]=mod;
+ buf[4]=0; //tmp0;
+ buf[5]=cols;
+
+
+ __asm__ __volatile__ (
+ ".align 32\n"
+ "1:\n"
+
+ // create Cr (result in mm1)
+ "movd (%0), %%mm1\n" // 0 0 0 0 v3 v2 v1 v0
+ "pxor %%mm7,%%mm7\n" // 00 00 00 00 00 00 00 00
+ "movd (%2), %%mm2\n" // 0 0 0 0 l3 l2 l1 l0
+ "punpcklbw %%mm7,%%mm1\n" // 0 v3 0 v2 00 v1 00 v0
+ "punpckldq %%mm1,%%mm1\n" // 00 v1 00 v0 00 v1 00 v0
+ "psubw MMX32_80w,%%mm1\n" // mm1-128:r1 r1 r0 r0 r1 r1 r0 r0
+
+ // create Cr_g (result in mm0)
+ "movq %%mm1,%%mm0\n" // r1 r1 r0 r0 r1 r1 r0 r0
+ "pmullw MMX32_Vgrncoeff,%%mm0\n" // red*-46dec=0.7136*64
+ "pmullw MMX32_Vredcoeff,%%mm1\n" // red*89dec=1.4013*64
+ "psraw $6, %%mm0\n" // red=red/64
+ "psraw $6, %%mm1\n" // red=red/64
+
+
+ // create L1 L2 (result in mm2,mm4)
+ // L2=lum2
+ "movl %2,16%5\n" // store register in tmp0
+ "movl %5,%2\n" // lum2->register
+ "movd (%2),%%mm3\n" // 0 0 0 0 L3 L2 L1 L0
+ "movl 16%5,%2\n" // tmp0->register
+ "punpckldq %%mm3,%%mm2\n" // L3 L2 L1 L0 l3 l2 l1 l0
+ "movq %%mm2,%%mm4\n" // L3 L2 L1 L0 l3 l2 l1 l0
+ "pand MMX32_FF00w, %%mm2\n" // L3 0 L1 0 l3 0 l1 0
+ "pand MMX32_00FFw, %%mm4\n" // 0 L2 0 L0 0 l2 0 l0
+ "psrlw $8,%%mm2\n" // 0 L3 0 L1 0 l3 0 l1
+
+
+
+ // create R (result in mm6)
+ "movq %%mm2,%%mm5\n" // 0 L3 0 L1 0 l3 0 l1
+ "movq %%mm4,%%mm6\n" // 0 L2 0 L0 0 l2 0 l0
+ "paddsw %%mm1, %%mm5\n" // lum1+red:x R3 x R1 x r3 x r1
+ "paddsw %%mm1, %%mm6\n" // lum1+red:x R2 x R0 x r2 x r0
+ "packuswb %%mm5,%%mm5\n" // R3 R1 r3 r1 R3 R1 r3 r1
+ "packuswb %%mm6,%%mm6\n" // R2 R0 r2 r0 R2 R0 r2 r0
+ "pxor %%mm7,%%mm7\n" // 00 00 00 00 00 00 00 00
+ "punpcklbw %%mm5,%%mm6\n" // R3 R2 R1 R0 r3 r2 r1 r0
+
+
+ // create Cb (result in mm1)
+ "movd (%1), %%mm1\n" // 0 0 0 0 u3 u2 u1 u0
+ "punpcklbw %%mm7,%%mm1\n" // 0 u3 0 u2 00 u1 00 u0
+ "punpckldq %%mm1,%%mm1\n" // 00 u1 00 u0 00 u1 00 u0
+ "psubw MMX32_80w,%%mm1\n" // mm1-128:u1 u1 u0 u0 u1 u1 u0 u0
+ // create Cb_g (result in mm5)
+ "movq %%mm1,%%mm5\n" // u1 u1 u0 u0 u1 u1 u0 u0
+ "pmullw MMX32_Ugrncoeff,%%mm5\n" // blue*-109dec=1.7129*64
+ "pmullw MMX32_Ubluecoeff,%%mm1\n" // blue*114dec=1.78125*64
+ "psraw $6, %%mm5\n" // blue=red/64
+ "psraw $6, %%mm1\n" // blue=blue/64
+
+
+ // create G (result in mm7)
+ "movq %%mm2,%%mm3\n" // 0 L3 0 L1 0 l3 0 l1
+ "movq %%mm4,%%mm7\n" // 0 L2 0 L0 0 l2 0 l1
+ "paddsw %%mm5, %%mm3\n" // lum1+Cb_g:x G3t x G1t x g3t x g1t
+ "paddsw %%mm5, %%mm7\n" // lum1+Cb_g:x G2t x G0t x g2t x g0t
+ "paddsw %%mm0, %%mm3\n" // lum1+Cr_g:x G3 x G1 x g3 x g1
+ "paddsw %%mm0, %%mm7\n" // lum1+blue:x G2 x G0 x g2 x g0
+ "packuswb %%mm3,%%mm3\n" // G3 G1 g3 g1 G3 G1 g3 g1
+ "packuswb %%mm7,%%mm7\n" // G2 G0 g2 g0 G2 G0 g2 g0
+ "punpcklbw %%mm3,%%mm7\n" // G3 G2 G1 G0 g3 g2 g1 g0
+
+
+ // create B (result in mm5)
+ "movq %%mm2,%%mm3\n" // 0 L3 0 L1 0 l3 0 l1
+ "movq %%mm4,%%mm5\n" // 0 L2 0 L0 0 l2 0 l1
+ "paddsw %%mm1, %%mm3\n" // lum1+blue:x B3 x B1 x b3 x b1
+ "paddsw %%mm1, %%mm5\n" // lum1+blue:x B2 x B0 x b2 x b0
+ "packuswb %%mm3,%%mm3\n" // B3 B1 b3 b1 B3 B1 b3 b1
+ "packuswb %%mm5,%%mm5\n" // B2 B0 b2 b0 B2 B0 b2 b0
+ "punpcklbw %%mm3,%%mm5\n" // B3 B2 B1 B0 b3 b2 b1 b0
+
+
+ // fill destination row1 (needed are mm6=Rr,mm7=Gg,mm5=Bb)
+
+ "pxor %%mm2,%%mm2\n" // 0 0 0 0 0 0 0 0
+ "pxor %%mm4,%%mm4\n" // 0 0 0 0 0 0 0 0
+ "movq %%mm6,%%mm1\n" // R3 R2 R1 R0 r3 r2 r1 r0
+ "movq %%mm5,%%mm3\n" // B3 B2 B1 B0 b3 b2 b1 b0
+ // process lower lum
+ "punpcklbw %%mm4,%%mm1\n" // 0 r3 0 r2 0 r1 0 r0
+ "punpcklbw %%mm4,%%mm3\n" // 0 b3 0 b2 0 b1 0 b0
+ "movq %%mm1,%%mm2\n" // 0 r3 0 r2 0 r1 0 r0
+ "movq %%mm3,%%mm0\n" // 0 b3 0 b2 0 b1 0 b0
+ "punpcklwd %%mm1,%%mm3\n" // 0 r1 0 b1 0 r0 0 b0
+ "punpckhwd %%mm2,%%mm0\n" // 0 r3 0 b3 0 r2 0 b2
+
+ "pxor %%mm2,%%mm2\n" // 0 0 0 0 0 0 0 0
+ "movq %%mm7,%%mm1\n" // G3 G2 G1 G0 g3 g2 g1 g0
+ "punpcklbw %%mm1,%%mm2\n" // g3 0 g2 0 g1 0 g0 0
+ "punpcklwd %%mm4,%%mm2\n" // 0 0 g1 0 0 0 g0 0
+ "por %%mm3, %%mm2\n" // 0 r1 g1 b1 0 r0 g0 b0
+ "movq %%mm2,(%3)\n" // wrote out ! row1
+
+ "pxor %%mm2,%%mm2\n" // 0 0 0 0 0 0 0 0
+ "punpcklbw %%mm1,%%mm4\n" // g3 0 g2 0 g1 0 g0 0
+ "punpckhwd %%mm2,%%mm4\n" // 0 0 g3 0 0 0 g2 0
+ "por %%mm0, %%mm4\n" // 0 r3 g3 b3 0 r2 g2 b2
+ "movq %%mm4,8(%3)\n" // wrote out ! row1
+
+ // fill destination row2 (needed are mm6=Rr,mm7=Gg,mm5=Bb)
+ // this can be done "destructive"
+ "pxor %%mm2,%%mm2\n" // 0 0 0 0 0 0 0 0
+ "punpckhbw %%mm2,%%mm6\n" // 0 R3 0 R2 0 R1 0 R0
+ "punpckhbw %%mm1,%%mm5\n" // G3 B3 G2 B2 G1 B1 G0 B0
+ "movq %%mm5,%%mm1\n" // G3 B3 G2 B2 G1 B1 G0 B0
+ "punpcklwd %%mm6,%%mm1\n" // 0 R1 G1 B1 0 R0 G0 B0
+ "movq %%mm1,(%4)\n" // wrote out ! row2
+ "punpckhwd %%mm6,%%mm5\n" // 0 R3 G3 B3 0 R2 G2 B2
+ "movq %%mm5,8(%4)\n" // wrote out ! row2
+
+ "addl $4,%2\n" // lum+4
+ "addl $4,%5\n" // lum2+4
+ "leal 16(%3),%3\n" // row1+16
+ "leal 16(%4),%4\n" // row2+16
+ "addl $2, %0\n" // cr+2
+ "addl $2, %1\n" // cb+2
+
+ "subl $4,8%5\n" // x+4 x is buf[2]
+ "cmpl $0,8%5\n"
+
+ "jne 1b\n"
+ "addl 20%5, %2\n" // lum += cols
+ "movl %2,16%5\n" // store register in tmp0
+ "movl 20%5,%2\n" // cols->register
+
+ "addl %2, %5\n" // lum2 += cols
+ "addl 12%5, %3\n" // row1+= mod is buf[0]
+ "addl 12%5, %4\n" // row2+= mod is buf[0]
+
+ "movl %2, 8%5\n" // x=cols
+ "movl 16%5,%2\n" // store tmp0 in register
+
+ "cmpl 4%5, %2\n" // buf[1] is end
+ "jl 1b\n"
+ "emms\n"
+ :
+ : "r" (cr), "r"(cb),"r"(lum),
+ "r"(row1),"r"(row2),"m"(buf[0])
+ );
+
+
+
+}
+
+
+#endif
diff --git a/mpeglib/lib/util/render/dither/dither8Bit.cpp b/mpeglib/lib/util/render/dither/dither8Bit.cpp
new file mode 100644
index 00000000..4f85d3fb
--- /dev/null
+++ b/mpeglib/lib/util/render/dither/dither8Bit.cpp
@@ -0,0 +1,306 @@
+/*
+ dither 8 bit depth yuv images
+ 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 "dither8Bit.h"
+
+
+Dither8Bit::Dither8Bit(unsigned char pixel[256]) {
+
+ int i;
+ for(i=0;i<256;i++) {
+ this->pixel[i]=pixel[i];
+ }
+ colorTable8Bit=new ColorTable8Bit();
+
+ lum_values = colorTable8Bit->getLumValues();
+ cr_values = colorTable8Bit->getCrValues();
+ cb_values = colorTable8Bit->getCbValues();
+
+
+
+ initOrderedDither();
+
+}
+
+
+Dither8Bit::~Dither8Bit() {
+ int i;
+ for (i=0; i<DITH_SIZE; i++) {
+ delete cb_darrays[i];
+ delete l_darrays[i];
+ delete cr_darrays[i];
+ }
+}
+
+
+
+
+
+/*
+ *--------------------------------------------------------------
+ *
+ * InitOrderedDither--
+ *
+ * Structures initialized for ordered dithering.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *--------------------------------------------------------------
+ */
+void Dither8Bit::initOrderedDither() {
+ int i, j, k, err_range, threshval;
+ unsigned char *lmark, *cmark;
+
+ for (i=0; i<DITH_SIZE; i++) {
+ lmark = l_darrays[i] = new unsigned char[256];
+ for (j=0; j<lum_values[0]; j++) {
+ *lmark++ = 0;
+ }
+ for (j=0; j<(LUM_RANGE-1); j++) {
+ err_range = lum_values[j+1] - lum_values[j];
+ threshval = ((i * err_range) / DITH_SIZE)+lum_values[j];
+
+ for (k=lum_values[j]; k<lum_values[j+1]; k++) {
+ if (k > threshval) {
+ *lmark++ = ((j+1) * (CR_RANGE * CB_RANGE));
+ }
+ else {
+ *lmark++ = (j * (CR_RANGE * CB_RANGE));
+ }
+ }
+ }
+ for (j=lum_values[LUM_RANGE-1]; j<256; j++) {
+ *lmark++ = (LUM_RANGE-1)*(CR_RANGE * CB_RANGE);
+ }
+ }
+ for (i=0; i<DITH_SIZE; i++) {
+ cmark = cr_darrays[i] = new unsigned char[256];
+
+ for (j=0; j<cr_values[0]; j++) {
+ *cmark++ = 0;
+ }
+
+ for (j=0; j<(CR_RANGE-1); j++) {
+ err_range = cr_values[j+1] - cr_values[j];
+ threshval = ((i * err_range) / DITH_SIZE)+cr_values[j];
+
+ for (k=cr_values[j]; k<cr_values[j+1]; k++) {
+ if (k > threshval) {
+ *cmark++ = ((j+1) * CB_RANGE);
+ }
+ else {
+ *cmark++ = (j * CB_RANGE);
+ }
+ }
+ }
+
+ for (j=cr_values[CR_RANGE-1]; j<256; j++) {
+ *cmark++ = (CR_RANGE-1)*(CB_RANGE);
+ }
+ }
+
+ for (i=0; i<DITH_SIZE; i++) {
+ cmark = cb_darrays[i] = new unsigned char[256];
+
+ for (j=0; j<cb_values[0]; j++) {
+ *cmark++ = 0;
+ }
+
+ for (j=0; j<(CB_RANGE-1); j++) {
+ err_range = cb_values[j+1] - cb_values[j];
+ threshval = ((i * err_range) / DITH_SIZE)+cb_values[j];
+
+ for (k=cb_values[j]; k<cb_values[j+1]; k++) {
+ if (k > threshval) {
+ *cmark++ = j+1;
+ }
+ else {
+ *cmark++ = j;
+ }
+ }
+ }
+
+ for (j=cb_values[CB_RANGE-1]; j<256; j++) {
+ *cmark++ = CB_RANGE-1;
+ }
+ }
+}
+
+
+
+/*
+ *--------------------------------------------------------------
+ *
+ * OrderedDitherImage --
+ *
+ * Dithers an image using an ordered dither.
+ * Assumptions made:
+ * 1) The color space is allocated y:cr:cb = 8:4:4
+ * 2) The spatial resolution of y:cr:cb is 4:1:1
+ * The channels are dithered based on the standard
+ * ordered dither pattern for a 4x4 area.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *--------------------------------------------------------------
+ */
+
+void Dither8Bit::ditherImageOrdered (unsigned char* lum,
+ unsigned char* cr,
+ unsigned char* cb,
+ unsigned char* out,
+ int h,
+ int w) {
+ unsigned char *l, *r, *b, *o1, *o2;
+ unsigned char *l2;
+ unsigned char L, R, B;
+ int i, j;
+
+ l = lum;
+ l2 = lum+w;
+ r = cr;
+ b = cb;
+ o1 = out;
+ o2 = out+w;
+
+
+ for (i=0; i<h; i+=4) {
+
+ for (j=0; j<w; j+=8) {
+
+ R = r[0]; B = b[0];
+
+ L = l[0];
+ o1[0] = pixel[(l_darrays[0][L] + cr_darrays[0][R] + cb_darrays[0][B])];
+ L = l[1];
+ o1[1] = pixel[(l_darrays[8][L] + cr_darrays[8][R] + cb_darrays[8][B])];
+ L = l2[0];
+ o2[0] = pixel[(l_darrays[12][L] + cr_darrays[12][R] + cb_darrays[12][B])];
+ L = l2[1];
+ o2[1] = pixel[(l_darrays[4][L] + cr_darrays[4][R] + cb_darrays[4][B])];
+
+ R = r[1]; B = b[1];
+
+ L = l[2];
+ o1[2] = pixel[(l_darrays[2][L] + cr_darrays[2][R] + cb_darrays[2][B])];
+ L = l[3];
+ o1[3] = pixel[(l_darrays[10][L] + cr_darrays[10][R] + cb_darrays[10][B])];
+ L = l2[2];
+ o2[2] = pixel[(l_darrays[14][L] + cr_darrays[14][R] + cb_darrays[14][B])];
+ L = l2[3];
+ o2[3] = pixel[(l_darrays[6][L] + cr_darrays[6][R] + cb_darrays[6][B])];
+
+ R = r[2]; B = b[2];
+
+ L = l[4];
+ o1[4] = pixel[(l_darrays[0][L] + cr_darrays[0][R] + cb_darrays[0][B])];
+ L = l[5];
+ o1[5] = pixel[(l_darrays[8][L] + cr_darrays[8][R] + cb_darrays[8][B])];
+ L = l2[4];
+ o2[4] = pixel[(l_darrays[12][L] + cr_darrays[12][R] + cb_darrays[12][B])];
+ L = l2[5];
+ o2[5] = pixel[(l_darrays[4][L] + cr_darrays[4][R] + cb_darrays[4][B])];
+
+ R = r[3]; B = b[3];
+
+ L = l[6];
+ o1[6] = pixel[(l_darrays[2][L] + cr_darrays[2][R] + cb_darrays[2][B])];
+ L = l[7];
+ o1[7] = pixel[(l_darrays[10][L] + cr_darrays[10][R] + cb_darrays[10][B])];
+ L = l2[6];
+ o2[6] = pixel[(l_darrays[14][L] + cr_darrays[14][R] + cb_darrays[14][B])];
+ L = l2[7];
+ o2[7] = pixel[(l_darrays[6][L] + cr_darrays[6][R] + cb_darrays[6][B])];
+
+ l += 8;
+ l2 += 8;
+ r += 4;
+ b += 4;
+ o1 += 8;
+ o2 += 8;
+ }
+
+ l += w;
+ l2 += w;
+ o1 += w;
+ o2 += w;
+
+ for (j=0; j<w; j+=8) {
+
+ R = r[0]; B = b[0];
+
+ L = l[0];
+ o1[0] = pixel[(l_darrays[3][L] + cr_darrays[3][R] + cb_darrays[3][B])];
+ L = l[1];
+ o1[1] = pixel[(l_darrays[11][L] + cr_darrays[11][R] + cb_darrays[11][B])];
+ L = l2[0];
+ o2[0] = pixel[(l_darrays[15][L] + cr_darrays[15][R] + cb_darrays[15][B])];
+ L = l2[1];
+ o2[1] = pixel[(l_darrays[7][L] + cr_darrays[7][R] + cb_darrays[7][B])];
+
+ R = r[1]; B = b[1];
+
+ L = l[2];
+ o1[2] = pixel[(l_darrays[1][L] + cr_darrays[1][R] + cb_darrays[1][B])];
+ L = l[3];
+ o1[3] = pixel[(l_darrays[9][L] + cr_darrays[9][R] + cb_darrays[9][B])];
+ L = l2[2];
+ o2[2] = pixel[(l_darrays[13][L] + cr_darrays[13][R] + cb_darrays[13][B])];
+ L = l2[3];
+ o2[3] = pixel[(l_darrays[5][L] + cr_darrays[5][R] + cb_darrays[5][B])];
+
+ R = r[2]; B = b[2];
+
+ L = l[4];
+ o1[4] = pixel[(l_darrays[3][L] + cr_darrays[3][R] + cb_darrays[3][B])];
+ L = l[5];
+ o1[5] = pixel[(l_darrays[11][L] + cr_darrays[11][R] + cb_darrays[11][B])];
+ L = l2[4];
+ o2[4] = pixel[(l_darrays[15][L] + cr_darrays[15][R] + cb_darrays[15][B])];
+ L = l2[5];
+ o2[5] = pixel[(l_darrays[7][L] + cr_darrays[7][R] + cb_darrays[7][B])];
+
+ R = r[3]; B = b[3];
+
+ L = l[6];
+ o1[6] = pixel[(l_darrays[1][L] + cr_darrays[1][R] + cb_darrays[1][B])];
+ L = l[7];
+ o1[7] = pixel[(l_darrays[9][L] + cr_darrays[9][R] + cb_darrays[9][B])];
+ L = l2[6];
+ o2[6] = pixel[(l_darrays[13][L] + cr_darrays[13][R] + cb_darrays[13][B])];
+ L = l2[7];
+ o2[7] = pixel[(l_darrays[5][L] + cr_darrays[5][R] + cb_darrays[5][B])];
+
+ l += 8;
+ l2 += 8;
+ r += 4;
+ b += 4;
+ o1 += 8;
+ o2 += 8;
+ }
+
+ l += w;
+ l2 += w;
+ o1 += w;
+ o2 += w;
+ }
+}
+
diff --git a/mpeglib/lib/util/render/dither/dither8Bit.h b/mpeglib/lib/util/render/dither/dither8Bit.h
new file mode 100644
index 00000000..7bdd4d8f
--- /dev/null
+++ b/mpeglib/lib/util/render/dither/dither8Bit.h
@@ -0,0 +1,63 @@
+/*
+ dither 8 bit depth yuv images
+ 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 __DITHER_8BIT_H
+#define __DITHER_8BIT_H
+
+
+#include "colorTable8Bit.h"
+
+#define DITH_SIZE 16
+
+
+class Dither8Bit {
+
+ /* Structures used to implement hybrid ordered dither/floyd-steinberg
+ dither algorithm.
+ */
+
+ unsigned char *l_darrays[DITH_SIZE];
+ unsigned char *cr_darrays[DITH_SIZE];
+ unsigned char *cb_darrays[DITH_SIZE];
+
+ // private colormap
+ unsigned char pixel[256];
+
+ ColorTable8Bit* colorTable8Bit;
+
+ // Arrays holding quantized value ranged for lum, cr, and cb.
+ // (used for 8 Bit)
+
+ int* lum_values;
+ int* cr_values;
+ int* cb_values;
+
+
+ public:
+ Dither8Bit(unsigned char pixel[256]);
+ ~Dither8Bit();
+
+ void ditherImageOrdered (unsigned char* lum,
+ unsigned char* cr,
+ unsigned char* cb,
+ unsigned char* out,
+ int h,
+ int w);
+
+ private:
+ void initOrderedDither();
+};
+
+#endif
+
diff --git a/mpeglib/lib/util/render/dither/ditherDef.h b/mpeglib/lib/util/render/dither/ditherDef.h
new file mode 100644
index 00000000..2e8d7d0e
--- /dev/null
+++ b/mpeglib/lib/util/render/dither/ditherDef.h
@@ -0,0 +1,100 @@
+/*
+ global definitions for dithering
+ 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 __DITHERDEF_H
+#define __DITHERDEF_H
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+extern "C" {
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+}
+
+
+#ifdef __GNUC__
+#if (__GNUC__ < 2 || ( __GNUC__ == 2 && __GNUC_MINOR__ < 91 ) )
+#ifndef _AIX
+#warning "inline code disabled! (buggy egcs version)"
+#undef __NO_MATH_INLINES
+#define __NO_MATH_INLINES 1
+#endif
+#endif
+#endif
+#include <math.h>
+
+
+
+/* Gamma correction stuff */
+extern int gammaCorrectFlag;
+extern double gammaCorrect;
+
+/* Chroma correction stuff */
+extern int chromaCorrectFlag;
+extern double chromaCorrect;
+
+
+#define CB_BASE 1
+#define CR_BASE (CB_BASE*CB_RANGE)
+#define LUM_BASE (CR_BASE*CR_RANGE)
+
+#define TABTYPE short
+
+#ifdef SIXTYFOUR_BIT
+#define PIXVAL long
+#else
+#define PIXVAL int
+#endif
+
+#ifdef SIXTYFOUR_BIT
+#define ONE_TWO 1
+#else
+#define ONE_TWO 2
+#endif
+
+
+
+#define Min(x,y) (((x) < (y)) ? (x) : (y))
+#define Max(x,y) (((x) > (y)) ? (x) : (y))
+
+#define CHROMA_CORRECTION128(x) ((x) >= 0 \
+ ? Min(127, (int)(((x) * chromaCorrect))) \
+ : Max(-128, (int)(((x) * chromaCorrect))))
+#define CHROMA_CORRECTION256D(x) ((x) >= 128 \
+ ? 128.0 + Min(127.0, (((x)-128.0) * chromaCorrect)) \
+ : 128.0 - Min(128.0, (((128.0-(x))* chromaCorrect))))
+
+
+
+#define GAMMA_CORRECTION(x) ((int)(pow((x) / 255.0, 1.0/gammaCorrect)* 255.0))
+
+#define CHROMA_CORRECTION128D(x) ((x) >= 0 \
+ ? Min(127.0, ((x) * chromaCorrect)) \
+ : Max(-128.0, ((x) * chromaCorrect)))
+
+#define CHROMA_CORRECTION256(x) ((x) >= 128 \
+ ? 128 + Min(127, (int)(((x)-128.0) * chromaCorrect)) \
+ : 128 - Min(128, (int)((128.0-(x)) * chromaCorrect)))
+
+// Range values for lum, cr, cb.
+#define LUM_RANGE 8
+#define CR_RANGE 4
+#define CB_RANGE 4
+
+
+#endif
diff --git a/mpeglib/lib/util/render/dither/ditherMMX.h b/mpeglib/lib/util/render/dither/ditherMMX.h
new file mode 100644
index 00000000..2f08b689
--- /dev/null
+++ b/mpeglib/lib/util/render/dither/ditherMMX.h
@@ -0,0 +1,38 @@
+/*
+ mmx ditherer
+ 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 __DITHERMMX_H
+#define __DITHERMMX_H
+
+#include "ditherDef.h"
+
+
+// The mmx dither routine come from NIST
+// NIST is an mpeg2/dvd player
+// more: http://home.germany.net/100-5083/
+extern void ditherBlock(unsigned char *lum,
+ unsigned char *cr,
+ unsigned char *cb,
+ unsigned char *out,
+ int rows, int cols, int mod);
+
+extern void dither32_mmx(unsigned char* lum,
+ unsigned char* cr,
+ unsigned char* cb,
+ unsigned char* out,
+ int rows,
+ int cols,
+ int mod);
+
+
+#endif
diff --git a/mpeglib/lib/util/render/dither/ditherRGB.cpp b/mpeglib/lib/util/render/dither/ditherRGB.cpp
new file mode 100644
index 00000000..1bcdb2ff
--- /dev/null
+++ b/mpeglib/lib/util/render/dither/ditherRGB.cpp
@@ -0,0 +1,230 @@
+/*
+ copys RGB images to a destination
+ 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 "ditherRGB.h"
+
+#include <iostream>
+
+using namespace std;
+
+DitherRGB::DitherRGB() {
+}
+
+
+DitherRGB::~DitherRGB() {
+}
+
+
+int DitherRGB::getDepth(int pixel) {
+ int byteDepth=0;
+
+ switch(pixel) {
+ case 8:
+ byteDepth=1;
+ break;
+ case 15:
+ case 16:
+ byteDepth=2;
+ break;
+ case 24:
+ case 32:
+ byteDepth=4;
+ break;
+ default:
+ cout << "unknown byteDepth:"<<pixel
+ << " in DitherRGB_flipped::flipRGBImage"<<endl;
+ }
+ return byteDepth;
+
+}
+
+void DitherRGB::ditherRGBImage(unsigned char* dest,unsigned char* src,
+ int depth,int width,int height,int offset) {
+ int byteDepth=getDepth(depth);
+ if (byteDepth == 0) {
+ return;
+ }
+
+
+ if (offset==0) {
+ int bytes=height*width*byteDepth;
+ memcpy(dest,src,bytes);
+ return;
+ }
+
+ int i;
+ int lineSize=width*byteDepth;
+
+ offset=offset*byteDepth+lineSize;
+
+ for (i=0;i<height;i++) {
+ memcpy(dest,src,lineSize);
+ src+=lineSize;
+ dest+=offset;
+ }
+
+
+}
+
+void DitherRGB::ditherRGBImage_x2(unsigned char* dest,unsigned char* src,
+ int depth,int width,int height,int offset) {
+
+ int byteDepth=getDepth(depth);
+ if (byteDepth == 0) {
+ return;
+ }
+
+ switch(byteDepth) {
+ case 1:
+ ditherRGB1Byte_x2(dest,src,1,width, height,offset);
+ break;
+ case 2:
+ ditherRGB2Byte_x2(dest,src,2,width, height,offset);
+ break;
+ case 4:
+ ditherRGB4Byte_x2(dest,src,4,width, height,offset);
+ break;
+ default:
+ cout <<"ditherRGBImage_x2 byteDepth:"<<byteDepth
+ <<" not supported"<<endl;
+ }
+}
+
+
+void DitherRGB::ditherRGB1Byte_x2(unsigned char* dest,unsigned char* src,
+ int depth,int width,int height,int offset) {
+
+ //
+ // dest destr
+ // destd destrd
+
+ int lineInc=2*width+offset;
+ unsigned char* destr=dest+1;
+ unsigned char* destd=dest+lineInc;
+ unsigned char* destrd=destd+1;
+
+ int row;
+ int col;
+ //
+ // We copy byte by byte this is slow, but works for
+ // all byteDepth
+ // this memcpy can be optimized with MMX very i) good ii) easily
+
+ for(row=0;row<height;row++) {
+ for(col=0;col<width;col++) {
+ *dest++=*src;
+ *destr++=*src;
+ *destd++=*src;
+ *destrd++=*src;
+ dest++;
+ destr++;
+ destd++;
+ destrd++;
+
+ src++;
+ }
+ dest+=lineInc;
+ destr+=lineInc;
+ destd+=lineInc;
+ destrd+=lineInc;
+ }
+}
+
+
+void DitherRGB::ditherRGB2Byte_x2(unsigned char* destination,
+ unsigned char* source,
+ int depth,int width,int height,int offset) {
+ //
+ // dest destr
+ // destd destrd
+
+ unsigned short int* src=(unsigned short int*) source;
+ unsigned short int* dest=(unsigned short int*) destination;
+
+ int lineInc=2*width+offset;
+ unsigned short int* destr=dest+1;
+ unsigned short int* destd=dest+lineInc;
+ unsigned short int* destrd=destd+1;
+
+ int row;
+ int col;
+ //
+ // We copy byte by byte this is slow, but works for
+ // all byteDepth
+ // this memcpy can be optimized with MMX very i) good ii) easily
+
+ for(row=0;row<height;row++) {
+ for(col=0;col<width;col++) {
+ *dest++=*src;
+ *destr++=*src;
+ *destd++=*src;
+ *destrd++=*src;
+ dest++;
+ destr++;
+ destd++;
+ destrd++;
+
+ src++;
+ }
+ dest+=lineInc;
+ destr+=lineInc;
+ destd+=lineInc;
+ destrd+=lineInc;
+ }
+}
+
+
+void DitherRGB::ditherRGB4Byte_x2(unsigned char* destination,
+ unsigned char* source,
+ int depth,int width,int height,int offset) {
+
+ //
+ // dest destr
+ // destd destrd
+
+ unsigned int* src=(unsigned int*) source;
+ unsigned int* dest=(unsigned int*) destination;
+
+ int lineInc=2*width+offset;
+ unsigned int* destr=dest+1;
+ unsigned int* destd=dest+lineInc;
+ unsigned int* destrd=destd+1;
+
+ int row;
+ int col;
+ //
+ // We copy byte by byte this is slow, but works for
+ // all byteDepth
+ // this memcpy can be optimized with MMX very i) good ii) easily
+
+ for(row=0;row<height;row++) {
+ for(col=0;col<width;col++) {
+ *dest++=*src;
+ *destr++=*src;
+ *destd++=*src;
+ *destrd++=*src;
+ dest++;
+ destr++;
+ destd++;
+ destrd++;
+
+ src++;
+ }
+ dest+=lineInc;
+ destr+=lineInc;
+ destd+=lineInc;
+ destrd+=lineInc;
+ }
+
+}
+
diff --git a/mpeglib/lib/util/render/dither/ditherRGB.h b/mpeglib/lib/util/render/dither/ditherRGB.h
new file mode 100644
index 00000000..6f24cd8c
--- /dev/null
+++ b/mpeglib/lib/util/render/dither/ditherRGB.h
@@ -0,0 +1,45 @@
+/*
+ copys RGB images to a destination
+ 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 __DITHERRGB_H
+#define __DITHERRGB_H
+
+#include "colorTableHighBit.h"
+
+class DitherRGB {
+
+ int flipSize;
+ unsigned char* flipSpace;
+
+ public:
+ DitherRGB();
+ ~DitherRGB();
+
+ // Note: this methods swaps the image
+ // itsself
+ void ditherRGBImage(unsigned char* dest,unsigned char* src,
+ int depth,int width,int height,int offset);
+ void ditherRGBImage_x2(unsigned char* dest,unsigned char* src,
+ int depth,int width,int height,int offset);
+ private:
+ int getDepth(int pixel);
+ // depth is here in byte!
+ void ditherRGB1Byte_x2(unsigned char* dest,unsigned char* src,
+ int depth,int width,int height,int offset);
+ void ditherRGB2Byte_x2(unsigned char* dest,unsigned char* src,
+ int depth,int width,int height,int offset);
+ void ditherRGB4Byte_x2(unsigned char* dest,unsigned char* src,
+ int depth,int width,int height,int offset);
+
+};
+
+#endif
diff --git a/mpeglib/lib/util/render/dither/ditherRGB_flipped.cpp b/mpeglib/lib/util/render/dither/ditherRGB_flipped.cpp
new file mode 100644
index 00000000..ba177675
--- /dev/null
+++ b/mpeglib/lib/util/render/dither/ditherRGB_flipped.cpp
@@ -0,0 +1,82 @@
+/*
+ flips RGB images
+ 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 "ditherRGB_flipped.h"
+
+#include <iostream>
+
+using namespace std;
+
+
+DitherRGB_flipped::DitherRGB_flipped() {
+ flipSpace=NULL;
+ flipSize=0;
+}
+
+DitherRGB_flipped::~DitherRGB_flipped() {
+ if (flipSpace != NULL) {
+ delete flipSpace;
+ }
+}
+
+
+
+
+void DitherRGB_flipped::flipRGBImage(unsigned char* dest,unsigned char* src,
+ int depth,int width,int height,int ) {
+
+ int byteDepth;
+
+ switch(depth) {
+ case 8:
+ byteDepth=1;
+ break;
+ case 15:
+ case 16:
+ byteDepth=2;
+ break;
+ case 24:
+ case 32:
+ byteDepth=4;
+ break;
+ default:
+ cout << "unknown byteDepth:"<<depth
+ << " in DitherRGB_flipped::flipRGBImage"<<endl;
+ return;
+ }
+
+
+ int spaceNeeded=width*height*byteDepth;
+
+ if (spaceNeeded > flipSize) {
+ if (flipSpace != NULL) {
+ delete flipSpace;
+ }
+ cout << "flipSpace:"<<spaceNeeded<<endl;
+ flipSpace=new unsigned char[spaceNeeded+64];
+ flipSize=spaceNeeded;
+ }
+
+ int i;
+ int lineSize=width*byteDepth;
+ unsigned char* end=dest+lineSize*(height-1);
+
+ for (i=0;i<height;i++) {
+ memcpy(end,src,lineSize);
+ src+=lineSize;
+ end-=lineSize;
+ }
+
+}
+
+
diff --git a/mpeglib/lib/util/render/dither/ditherRGB_flipped.h b/mpeglib/lib/util/render/dither/ditherRGB_flipped.h
new file mode 100644
index 00000000..1d99f7f6
--- /dev/null
+++ b/mpeglib/lib/util/render/dither/ditherRGB_flipped.h
@@ -0,0 +1,34 @@
+/*
+ flips RGB images
+ 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 __DITHERRGB_FLIPPED_H
+#define __DITHERRGB_FLIPPED_H
+
+#include "colorTableHighBit.h"
+
+class DitherRGB_flipped {
+
+ int flipSize;
+ unsigned char* flipSpace;
+
+ public:
+ DitherRGB_flipped();
+ ~DitherRGB_flipped();
+
+ // Note: this methods swaps the image
+ // itsself
+ void flipRGBImage(unsigned char* dest,unsigned char* src,
+ int depth,int width,int height,int offset);
+
+};
+
+#endif
diff --git a/mpeglib/lib/util/render/dither/ditherWrapper.cpp b/mpeglib/lib/util/render/dither/ditherWrapper.cpp
new file mode 100644
index 00000000..c6c37a79
--- /dev/null
+++ b/mpeglib/lib/util/render/dither/ditherWrapper.cpp
@@ -0,0 +1,246 @@
+/*
+ wrapper for X11 Window
+ Copyright (C) 1999 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 "ditherWrapper.h"
+
+#include <iostream>
+
+using namespace std;
+
+
+/*
+ Flag for gamma correction
+ Makes images brighter/darker.
+ It's in the source but not activated (for now)
+*/
+int gammaCorrectFlag = 0;
+double gammaCorrect = 1.0;
+
+/*
+ Flag for chroma correction.
+ reduce the color intensity..
+ It's in the source but not activated (for now)
+*/
+int chromaCorrectFlag = 0;
+double chromaCorrect = 1.0;
+
+
+
+DitherWrapper::DitherWrapper(int bpp,unsigned int redMask,
+ unsigned int greenMask,unsigned int blueMask,
+ unsigned char pixel[256]) {
+
+ this->bpp=bpp;
+ this->redMask=redMask;
+ this->greenMask=greenMask;
+ this->blueMask=blueMask;
+
+
+ dither8Bit=new Dither8Bit(pixel);
+ dither16Bit=new Dither16Bit(redMask,greenMask,blueMask);
+ dither32Bit=new Dither32Bit(redMask,greenMask,blueMask);
+ ditherRGB_flipped=new DitherRGB_flipped();
+ ditherRGB=new DitherRGB();
+
+
+#ifdef INTEL
+ lmmx=mm_support();
+#else
+ lmmx=false;
+#endif
+
+
+}
+
+
+DitherWrapper::~DitherWrapper(){
+ delete dither16Bit;
+ delete dither8Bit;
+ delete dither32Bit;
+ delete ditherRGB_flipped;
+ delete ditherRGB;
+}
+
+
+
+
+
+void DitherWrapper::doDither(YUVPicture* pic,int depth,int imageMode,
+ unsigned char* dest,int offset) {
+
+
+ //
+ // according to the input imageType and the output area
+ // handle different dither methods
+ //
+
+ int inputType=pic->getImageType();
+
+ if ( (inputType == PICTURE_YUVMODE_CR_CB) ||
+ (inputType == PICTURE_YUVMODE_CB_CR) ) {
+ doDitherYUV(pic,depth,imageMode,dest,offset);
+ return;
+ }
+
+ if ( (inputType == PICTURE_RGB) ||
+ (inputType == PICTURE_RGB_FLIPPED) ){
+ doDitherRGB(pic,depth,imageMode,dest,offset);
+ return;
+ }
+
+ cout << "unknown inputType:"<<inputType
+ << " in DitherWrapper::doDither"<<endl;
+}
+
+
+void DitherWrapper::doDitherRGB(YUVPicture* pic,int depth,int imageMode,
+ unsigned char* dest,int offset) {
+
+ int inputType=pic->getImageType();
+
+ switch(inputType) {
+ case PICTURE_RGB:
+ doDitherRGB_NORMAL(pic,depth,imageMode,dest,offset);
+ break;
+ case PICTURE_RGB_FLIPPED:
+ doDitherRGB_FLIPPED(pic,depth,imageMode,dest,offset);
+ break;
+ default:
+ cout << "unknown RGB type:"<<inputType<<" in DitherWrapper"<<endl;
+ exit(0);
+ }
+}
+
+
+void DitherWrapper::doDitherRGB_NORMAL(YUVPicture* pic,
+ int depth,int imageMode,
+ unsigned char* dest,int offset) {
+
+ int w=pic->getWidth();
+ int h=pic->getHeight();
+
+ unsigned char* src=pic->getImagePtr();
+
+ if (imageMode & _IMAGE_DOUBLE) {
+ ditherRGB->ditherRGBImage_x2(dest,src,depth,w,h,offset);
+ } else {
+ ditherRGB->ditherRGBImage(dest,src,depth,w,h,offset);
+ }
+}
+
+void DitherWrapper::doDitherRGB_FLIPPED(YUVPicture* pic,
+ int depth,int imageMode,
+ unsigned char* dest,int offset) {
+
+ int w=pic->getWidth();
+ int h=pic->getHeight();
+
+ unsigned char* src=pic->getImagePtr();
+
+ ditherRGB_flipped->flipRGBImage(dest,src,depth,w,h,offset);
+}
+
+
+
+void DitherWrapper::doDitherYUV(YUVPicture* pic,int depth,int imageMode,
+ unsigned char* dest,int offset) {
+
+ if (imageMode & _IMAGE_DOUBLE) {
+ doDither_x2(pic,depth,dest,offset);
+ } else {
+ doDither_std(pic,depth,dest,offset);
+ }
+}
+
+
+void DitherWrapper::doDither_std(YUVPicture* pic,int depth,
+ unsigned char* dest,int offset){
+
+ int h=pic->getHeight();
+ int w=pic->getWidth();
+ unsigned char* lum=pic->getLuminancePtr();
+ unsigned char* cr=pic->getCrPtr();
+ unsigned char* cb=pic->getCbPtr();
+
+
+ switch (depth) {
+ case 8:
+ dither8Bit->ditherImageOrdered(lum, cr, cb,dest , h, w);
+ break;
+ case 16:
+ if (lmmx) {
+ ditherBlock(lum,cr,cb,dest,h,w,offset);
+ } else {
+ dither16Bit->ditherImageColor16(lum,cr,cb,dest,h,w,offset);
+ }
+
+ break;
+ case 24:
+ case 32:
+ if (lmmx) {
+ dither32_mmx(lum, cr, cb,dest ,h,w,offset);
+ } else {
+ dither32Bit->ditherImageColor32(lum, cr, cb,dest ,h,w,offset);
+ }
+
+
+ break;
+ default:
+ cout << "cannot dither depth:"<<depth<<endl;
+ }
+
+}
+
+
+void DitherWrapper::doDither_x2(YUVPicture* pic,int depth,
+ unsigned char* dest,int offset){
+
+ int h=pic->getHeight();
+ int w=pic->getWidth();
+ unsigned char* lum=pic->getLuminancePtr();
+ unsigned char* cr=pic->getCrPtr();
+ unsigned char* cb=pic->getCbPtr();
+
+
+ switch (depth) {
+ case 8: {
+ // we do dither with the 8Bit std YUV ditherer to RGB
+ // and then we do the double part with the
+ // RGB ditherer. Its obviously much slower but at
+ // least it works. To not allocate memory twice
+ // we are a bit tricky. We know that the image
+ // has space for doubls size. We but the not double size
+ // image at the bottom of the dest. Maybe that
+ // the last line gets overwritten
+ int memPos=3*h*w;
+ dither8Bit->ditherImageOrdered(lum, cr, cb,dest+memPos, h, w);
+ unsigned char* src=dest+memPos;
+ ditherRGB->ditherRGBImage_x2(dest,src,depth,w,h,0);
+ break;
+ }
+ case 16:
+ dither16Bit->ditherImageTwox2Color16(lum,cr,cb,dest,h,w,offset);
+ break;
+ case 24:
+ case 32:
+ if (lmmx) {
+ //dither32x2_mmx(lum, cr, cb,dest ,h,w,offset);
+ dither32Bit->ditherImageTwox2Color32(lum,cr,cb,dest,h,w,offset);
+ } else {
+ dither32Bit->ditherImageTwox2Color32(lum,cr,cb,dest,h,w,offset);
+ }
+ break;
+ default:
+ cout << "cannot dither depth:" << depth << endl;
+ }
+}
diff --git a/mpeglib/lib/util/render/dither/ditherWrapper.h b/mpeglib/lib/util/render/dither/ditherWrapper.h
new file mode 100644
index 00000000..b01abff8
--- /dev/null
+++ b/mpeglib/lib/util/render/dither/ditherWrapper.h
@@ -0,0 +1,80 @@
+/*
+ wrapper for X11 Window
+ Copyright (C) 1999 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 __DITHERWRAPPER_H
+#define __DITHERWRAPPER_H
+
+
+#include "../../mmx/mmx.h"
+
+#include "../yuvPicture.h"
+#include "../imageBase.h"
+#include <stdlib.h>
+#include "ditherMMX.h"
+#include "dither8Bit.h"
+#include "dither16Bit.h"
+#include "dither32Bit.h"
+#include "ditherRGB_flipped.h"
+#include "ditherRGB.h"
+
+
+/**
+ Wraps all calls to software ditherer and the different
+ resolutions,mmx enhancements, and doublesize ditherers.
+*/
+
+
+class DitherWrapper {
+
+ int lmmx;
+
+ int bpp;
+ // colorMask
+ unsigned int redMask;
+ unsigned int greenMask;
+ unsigned int blueMask;
+
+ Dither8Bit* dither8Bit;
+ Dither16Bit* dither16Bit;
+ Dither32Bit* dither32Bit;
+ DitherRGB_flipped* ditherRGB_flipped;
+ DitherRGB* ditherRGB;
+
+ public:
+ DitherWrapper(int bpp,unsigned int redMask,
+ unsigned int greenMask,unsigned int blueMask,
+ unsigned char pixel[256]);
+ ~DitherWrapper();
+
+/* int getDitherSize(); */
+/* void setDitherSize(int ditherMode); */
+
+ void doDither(YUVPicture* pic,int depth,int imageMode,
+ unsigned char* dest,int offset);
+
+
+ private:
+ void doDitherYUV(YUVPicture* pic,int depth,int imageMode,
+ unsigned char* dest,int offset);
+ void doDitherRGB(YUVPicture* pic,int depth,int imageMode,
+ unsigned char* dest,int offset);
+ void doDitherRGB_NORMAL(YUVPicture* pic,int depth,int imageMode,
+ unsigned char* dest,int offset);
+ void doDitherRGB_FLIPPED(YUVPicture* pic,int depth,int imageMode,
+ unsigned char* dest,int offset);
+
+ void doDither_std(YUVPicture* pic,int depth,unsigned char* dest,int offset);
+ void doDither_x2(YUVPicture* pic,int depth,unsigned char* dest,int offset);
+};
+
+#endif
diff --git a/mpeglib/lib/util/render/dither/ditherer_mmx16.cpp b/mpeglib/lib/util/render/dither/ditherer_mmx16.cpp
new file mode 100644
index 00000000..757f0676
--- /dev/null
+++ b/mpeglib/lib/util/render/dither/ditherer_mmx16.cpp
@@ -0,0 +1,256 @@
+
+#include "ditherMMX.h"
+
+#include <iostream>
+
+using namespace std;
+
+#ifndef INTEL
+// nothing
+void ditherBlock(unsigned char *lum, unsigned char *cr, unsigned char *cb,
+ unsigned char *out,
+ int cols, int rows, int screen_width) {
+ printf("call to ditherBlock. this should never happen\n");
+ printf("check mmx detection routine.\n");
+ exit(0);
+}
+#else
+
+
+static long long MMX16_0 = 0L;
+static unsigned long MMX16_10w[] = {0x00100010, 0x00100010};
+static unsigned long MMX16_80w[] = {0x00800080, 0x00800080};
+static unsigned long MMX16_00FFw[] = {0x00ff00ff, 0x00ff00ff};
+static unsigned short MMX16_Ublucoeff[] = {0x81, 0x81, 0x81, 0x81};
+static unsigned short MMX16_Vredcoeff[] = {0x66, 0x66, 0x66, 0x66};
+static unsigned short MMX16_Ugrncoeff[] = {0xffe8, 0xffe8, 0xffe8, 0xffe8};
+static unsigned short MMX16_Vgrncoeff[] = {0xffcd, 0xffcd, 0xffcd, 0xffcd};
+static unsigned short MMX16_Ycoeff[] = {0x4a, 0x4a, 0x4a, 0x4a};
+static unsigned short MMX16_redmask[] = {0xf800, 0xf800, 0xf800, 0xf800};
+static unsigned short MMX16_grnmask[] = {0x7e0, 0x7e0, 0x7e0, 0x7e0};
+
+void dummy_dithermmx16() {
+ cout << "MMX16_0"<<MMX16_0<<endl;
+ cout << "MMX16_10w:"<<MMX16_10w<<endl;
+ cout << "MMX16_80w:"<<MMX16_80w<<endl;
+ cout << "MMX16_Ublucoeff:"<<MMX16_Ublucoeff<<endl;
+ cout << "MMX16_Vredcoeff:"<<MMX16_Vredcoeff<<endl;
+ cout << "MMX16_Ugrncoeff:"<<MMX16_Ugrncoeff<<endl;
+ cout << "MMX16_Vgrncoeff:"<<MMX16_Vgrncoeff<<endl;
+ cout << "MMX16_Ycoeff:"<<MMX16_Ycoeff<<endl;
+ cout << "MMX16_redmask:"<<MMX16_redmask<<endl;
+ cout << "MMX16_grnmask:"<<MMX16_grnmask<<endl;
+ cout << "MMX16_00FFw:"<<MMX16_00FFw<<endl;
+}
+
+
+void ditherBlock(unsigned char *lum,
+ unsigned char *cr,
+ unsigned char *cb,
+ unsigned char *out,
+ int rows,
+ int cols,
+ int mod) {
+
+ unsigned short *row1;
+ unsigned short *row2;
+ row1 = (unsigned short* )out; // 16 bit target
+
+ unsigned char* end = lum +cols*rows; // Pointer to the end
+ int x=cols;
+ row2=row1+mod+cols; // start of second row
+ mod=2*cols+4*mod; // increment for row1 in byte
+
+ // buffer for asm function
+ int buf[6];
+ buf[0]=(int)(lum+cols); // lum2 pointer
+ buf[1]=(int)end;
+ buf[2]=x;
+ buf[3]=mod;
+ buf[4]=0; //tmp0;
+ buf[5]=cols;
+
+
+
+ __asm__ __volatile__(
+ ".align 32\n"
+ "1:\n"
+ "movd (%1), %%mm0\n" // 4 Cb 0 0 0 0 u3 u2 u1 u0
+ "pxor %%mm7, %%mm7\n"
+ "movd (%0), %%mm1\n" // 4 Cr 0 0 0 0 v3 v2 v1 v0
+ "punpcklbw %%mm7, %%mm0\n" // 4 W cb 0 u3 0 u2 0 u1 0 u0
+ "punpcklbw %%mm7, %%mm1\n" // 4 W cr 0 v3 0 v2 0 v1 0 v0
+ "psubw MMX16_80w, %%mm0\n"
+ "psubw MMX16_80w, %%mm1\n"
+ "movq %%mm0, %%mm2\n" // Cb 0 u3 0 u2 0 u1 0 u0
+ "movq %%mm1, %%mm3\n" // Cr
+ "pmullw MMX16_Ugrncoeff, %%mm2\n" // Cb2green 0 R3 0 R2 0 R1 0 R0
+ "movq (%2), %%mm6\n" // L1 l7 L6 L5 L4 L3 L2 L1 L0
+ "pmullw MMX16_Ublucoeff, %%mm0\n" // Cb2blue
+ "pand MMX16_00FFw, %%mm6\n" // L1 00 L6 00 L4 00 L2 00 L0
+ "pmullw MMX16_Vgrncoeff, %%mm3\n" // Cr2green
+ "movq (%2), %%mm7\n" // L2
+ "pmullw MMX16_Vredcoeff, %%mm1\n" // Cr2red
+ // "psubw MMX16_10w, %%mm6\n"
+ "psrlw $8, %%mm7\n" // L2 00 L7 00 L5 00 L3 00 L1
+ "pmullw MMX16_Ycoeff, %%mm6\n" // lum1
+ // "psubw MMX16_10w, %%mm7\n" // L2
+ "paddw %%mm3, %%mm2\n" // Cb2green + Cr2green == green
+ "pmullw MMX16_Ycoeff, %%mm7\n" // lum2
+
+ "movq %%mm6, %%mm4\n" // lum1
+ "paddw %%mm0, %%mm6\n" // lum1 +blue 00 B6 00 B4 00 B2 00 B0
+ "movq %%mm4, %%mm5\n" // lum1
+ "paddw %%mm1, %%mm4\n" // lum1 +red 00 R6 00 R4 00 R2 00 R0
+ "paddw %%mm2, %%mm5\n" // lum1 +green 00 G6 00 G4 00 G2 00 G0
+ "psraw $6, %%mm4\n" // R1 0 .. 64
+ "movq %%mm7, %%mm3\n" // lum2 00 L7 00 L5 00 L3 00 L1
+ "psraw $6, %%mm5\n" // G1 - .. +
+ "paddw %%mm0, %%mm7\n" // Lum2 +blue 00 B7 00 B5 00 B3 00 B1
+ "psraw $6, %%mm6\n" // B1 0 .. 64
+ "packuswb %%mm4, %%mm4\n" // R1 R1
+ "packuswb %%mm5, %%mm5\n" // G1 G1
+ "packuswb %%mm6, %%mm6\n" // B1 B1
+ "punpcklbw %%mm4, %%mm4\n"
+ "punpcklbw %%mm5, %%mm5\n"
+
+ "pand MMX16_redmask, %%mm4\n"
+ "psllw $3, %%mm5\n" // GREEN 1
+ "punpcklbw %%mm6, %%mm6\n"
+ "pand MMX16_grnmask, %%mm5\n"
+ "pand MMX16_redmask, %%mm6\n"
+ "por %%mm5, %%mm4\n" //
+ "psrlw $11, %%mm6\n" // BLUE 1
+ "movq %%mm3, %%mm5\n" // lum2
+ "paddw %%mm1, %%mm3\n" // lum2 +red 00 R7 00 R5 00 R3 00 R1
+ "paddw %%mm2, %%mm5\n" // lum2 +green 00 G7 00 G5 00 G3 00 G1
+ "psraw $6, %%mm3\n" // R2
+ "por %%mm6, %%mm4\n" // MM4
+ "psraw $6, %%mm5\n" // G2
+
+ "movl %2,16%5\n" // store register in tmp0
+ "movl %5,%2\n" // lum2->register
+ "movq (%2),%%mm6\n" // 0 0 0 0 L3 L2 L1 L0 (load lum2)
+
+
+ //"movq (%2, %5), %%mm6\n" // L3 load lum2
+ "psraw $6, %%mm7\n"
+ "packuswb %%mm3, %%mm3\n"
+ "packuswb %%mm5, %%mm5\n"
+ "packuswb %%mm7, %%mm7\n"
+ "pand MMX16_00FFw, %%mm6\n" // L3
+ "punpcklbw %%mm3, %%mm3\n"
+ // "psubw MMX16_10w, %%mm6\n" // L3
+ "punpcklbw %%mm5, %%mm5\n"
+ "pmullw MMX16_Ycoeff, %%mm6\n" // lum3
+ "punpcklbw %%mm7, %%mm7\n"
+ "psllw $3, %%mm5\n" // GREEN 2
+ "pand MMX16_redmask, %%mm7\n"
+ "pand MMX16_redmask, %%mm3\n"
+ "psrlw $11, %%mm7\n" // BLUE 2
+ "pand MMX16_grnmask, %%mm5\n"
+ "por %%mm7, %%mm3\n"
+
+ "movq (%2), %%mm7\n" // L4 load lum2
+ "movl 16%5,%2\n" // tmp0->register
+
+ "por %%mm5, %%mm3\n" //
+ "psrlw $8, %%mm7\n" // L4
+ "movq %%mm4, %%mm5\n"
+ // "psubw MMX16_10w, %%mm7\n" // L4
+ "punpcklwd %%mm3, %%mm4\n"
+ "pmullw MMX16_Ycoeff, %%mm7\n" // lum4
+ "punpckhwd %%mm3, %%mm5\n"
+
+ "movq %%mm4, (%3)\n" // write row1
+ "movq %%mm5, 8(%3)\n" // write row1
+
+ "movq %%mm6, %%mm4\n" // Lum3
+ "paddw %%mm0, %%mm6\n" // Lum3 +blue
+
+ "movq %%mm4, %%mm5\n" // Lum3
+ "paddw %%mm1, %%mm4\n" // Lum3 +red
+ "paddw %%mm2, %%mm5\n" // Lum3 +green
+ "psraw $6, %%mm4\n"
+ "movq %%mm7, %%mm3\n" // Lum4
+ "psraw $6, %%mm5\n"
+ "paddw %%mm0, %%mm7\n" // Lum4 +blue
+ "psraw $6, %%mm6\n" // Lum3 +blue
+ "movq %%mm3, %%mm0\n" // Lum4
+ "packuswb %%mm4, %%mm4\n"
+ "paddw %%mm1, %%mm3\n" // Lum4 +red
+ "packuswb %%mm5, %%mm5\n"
+ "paddw %%mm2, %%mm0\n" // Lum4 +green
+ "packuswb %%mm6, %%mm6\n"
+ "punpcklbw %%mm4, %%mm4\n"
+ "punpcklbw %%mm5, %%mm5\n"
+ "punpcklbw %%mm6, %%mm6\n"
+ "psllw $3, %%mm5\n" // GREEN 3
+ "pand MMX16_redmask, %%mm4\n"
+ "psraw $6, %%mm3\n" // psr 6
+ "psraw $6, %%mm0\n"
+ "pand MMX16_redmask, %%mm6\n" // BLUE
+ "pand MMX16_grnmask, %%mm5\n"
+ "psrlw $11, %%mm6\n" // BLUE 3
+ "por %%mm5, %%mm4\n"
+ "psraw $6, %%mm7\n"
+ "por %%mm6, %%mm4\n"
+ "packuswb %%mm3, %%mm3\n"
+ "packuswb %%mm0, %%mm0\n"
+ "packuswb %%mm7, %%mm7\n"
+ "punpcklbw %%mm3, %%mm3\n"
+ "punpcklbw %%mm0, %%mm0\n"
+ "punpcklbw %%mm7, %%mm7\n"
+ "pand MMX16_redmask, %%mm3\n"
+ "pand MMX16_redmask, %%mm7\n" // BLUE
+ "psllw $3, %%mm0\n" // GREEN 4
+ "psrlw $11, %%mm7\n"
+ "pand MMX16_grnmask, %%mm0\n"
+ "por %%mm7, %%mm3\n"
+ "por %%mm0, %%mm3\n"
+
+ "movq %%mm4, %%mm5\n"
+
+ "punpcklwd %%mm3, %%mm4\n"
+ "punpckhwd %%mm3, %%mm5\n"
+
+ "movq %%mm4, (%4)\n"
+ "movq %%mm5, 8(%4)\n"
+
+ "subl $8, 8%5\n" // x-=8
+ "addl $8, %5\n" // lum2+8
+ "addl $8, %2\n"
+ "addl $4, %0\n"
+ "addl $4, %1\n"
+ "cmpl $0, 8%5\n"
+ "leal 16(%3), %3\n"
+ "leal 16(%4), %4\n" // row2+16
+
+
+ "jne 1b\n"
+ "addl 20%5, %2\n" // lum += cols
+
+ "movl %2,16%5\n" // store register in tmp0
+ "movl 20%5,%2\n" // cols->register
+
+ "addl %2, %5\n" // lum2 += cols
+ "addl 12%5, %3\n" // row1+= mod
+ "addl 12%5, %4\n" // row2+= mod
+ "movl %2, 8%5\n" // x=cols
+ "movl 16%5,%2\n" // store tmp0 in register
+
+ "cmpl 4%5, %2\n"
+ "jl 1b\n"
+
+ :
+ :"r" (cr), "r"(cb),"r"(lum),
+ "r"(row1),"r"(row2),"m"(buf[0])
+
+ );
+ __asm__ (
+ "emms\n"
+ );
+
+ }
+
+#endif
diff --git a/mpeglib/lib/util/render/dither2YUV/Makefile.am b/mpeglib/lib/util/render/dither2YUV/Makefile.am
new file mode 100644
index 00000000..374658a3
--- /dev/null
+++ b/mpeglib/lib/util/render/dither2YUV/Makefile.am
@@ -0,0 +1,22 @@
+# libdivxplugin - Makefile.am
+
+EXTRA_DIST = README
+
+INCLUDES = -I.. $(all_includes)
+
+
+noinst_LTLIBRARIES = libdivxutil_dither.la
+
+noinst_HEADERS = dither2YUV.h rgb2yuvdefs.h rgb2yuv16.h \
+ rgb2yuv32.h
+
+libdivxutil_dither_la_SOURCES = dither2YUV.cpp rgb2yuv16.cpp \
+ rgb2yuv32.cpp
+
+
+
+
+
+
+
+
diff --git a/mpeglib/lib/util/render/dither2YUV/README b/mpeglib/lib/util/render/dither2YUV/README
new file mode 100644
index 00000000..66246c13
--- /dev/null
+++ b/mpeglib/lib/util/render/dither2YUV/README
@@ -0,0 +1,13 @@
+
+
+* we have a Dither2Yuv base class. Currently this is not derived
+ from a basic ditherWrapper class because we don not have this
+ in mpeglib yet.
+ TODO: change in mpeglib DitherWrapper->Dither2RGB and
+ make DitherWrapper pure virtual and derive Dither2YUV
+ Dither2RGB from this class.
+
+* Note we do not support 8 Bit here, thus the constructor looks
+ dofferent.
+
+
diff --git a/mpeglib/lib/util/render/dither2YUV/dither2YUV.cpp b/mpeglib/lib/util/render/dither2YUV/dither2YUV.cpp
new file mode 100644
index 00000000..db4a3288
--- /dev/null
+++ b/mpeglib/lib/util/render/dither2YUV/dither2YUV.cpp
@@ -0,0 +1,124 @@
+/*
+ this class dithery RGB picture to yuv12
+ 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 "dither2YUV.h"
+
+#include <iostream>
+
+using namespace std;
+
+
+Dither2YUV::Dither2YUV() {
+
+
+ lmmx=mm_support();
+
+}
+
+
+Dither2YUV::~Dither2YUV(){
+}
+
+
+
+
+
+
+void Dither2YUV::doDither(YUVPicture* pic,int depth,int ditherSize,
+ unsigned char* dest,int offset) {
+
+ int inputType=pic->getImageType();
+
+ switch(inputType) {
+ case PICTURE_RGB:
+ doDitherRGB_NORMAL(pic,depth,ditherSize,dest,offset);
+ break;
+ default:
+ std::cout << "unknown RGB type:"<<inputType<<" in Dither2YUV"<<std::endl;
+ exit(0);
+ }
+}
+
+
+void Dither2YUV::doDitherRGB_NORMAL(YUVPicture* rgbPic,
+ int depth,int ditherSize,
+ unsigned char* dest,int offset) {
+
+ switch (ditherSize) {
+ case _SIZE_NORMAL:
+ doDither2YUV_std(rgbPic,depth,dest,offset);
+ break;
+ case _SIZE_DOUBLE:
+ std::cout << "double not supported for RGB"<<std::endl;
+ break;
+ default:
+ std::cout << "unknown size:"<<ditherSize<<" in Dither2YUV"<<std::endl;
+ exit(0);
+ }
+}
+
+
+void Dither2YUV::doDither2YUV_std(YUVPicture* rgbPic,int depth,
+ unsigned char* dest,int offset){
+
+ int h=rgbPic->getHeight();
+ int w=rgbPic->getWidth();
+ int lumLength=w * h;
+ int colorLength=(w * h) / 4;
+
+ unsigned char* lum=dest;
+ unsigned char* cr=lum+lumLength;
+ unsigned char* cb=cr+colorLength;
+ unsigned char* rgbSource=rgbPic->getImagePtr();
+
+
+ switch (depth) {
+ case 8:
+ std::cout << "8 bit dither to yuv not supported"<<std::endl;
+ exit(0);
+ break;
+ case 16:
+ if (lmmx) {
+#ifdef INTEL
+ rgb2yuv16bit_mmx(rgbSource,lum,cr,cb,h,w);
+#endif
+ } else {
+ rgb2yuv16bit(rgbSource,lum,cr,cb,h,w);
+ }
+
+ break;
+ case 24:
+ if (lmmx) {
+#ifdef INTEL
+ rgb2yuv24bit_mmx(rgbSource,lum,cr,cb,h,w);
+#endif
+ } else {
+ rgb2yuv24bit(rgbSource,lum,cr,cb,h,w);
+ }
+ break;
+ case 32:
+ if (lmmx) {
+#ifdef INTEL
+ rgb2yuv32bit_mmx(rgbSource,lum,cr,cb,h,w);
+#endif
+ } else {
+ rgb2yuv32bit(rgbSource,lum,cr,cb,h,w);
+ }
+ break;
+ default:
+ std::cout << "cannot dither depth:"<<depth<<std::endl;
+ }
+
+}
+
+
diff --git a/mpeglib/lib/util/render/dither2YUV/dither2YUV.h b/mpeglib/lib/util/render/dither2YUV/dither2YUV.h
new file mode 100644
index 00000000..5ef26b2b
--- /dev/null
+++ b/mpeglib/lib/util/render/dither2YUV/dither2YUV.h
@@ -0,0 +1,64 @@
+/*
+ this class dithery RGB picture to yuv12
+ 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 __DITHER2YUV_H
+#define __DITHER2YUV_H
+
+
+#include "../../mmx/mmx.h"
+#include "../yuvPicture.h"
+
+
+#include <stdlib.h>
+#include "rgb2yuv16.h"
+#include "rgb2yuv32.h"
+
+#define _SIZE_NONE 0
+#define _SIZE_NORMAL 1
+#define _SIZE_DOUBLE 2
+
+
+/**
+ Wraps all calls to software ditherer and the different
+ resolutions,mmx enhancements, and doublesize ditherers.
+*/
+
+
+class Dither2YUV {
+
+ int lmmx;
+
+ int bpp;
+
+
+ public:
+ Dither2YUV();
+ ~Dither2YUV();
+
+ int getDitherSize();
+ void setDitherSize(int ditherSize);
+
+ void doDither(YUVPicture* pic,int depth,int ditherSize,
+ unsigned char* dest,int offset);
+
+
+ private:
+ void doDitherRGB_NORMAL(YUVPicture* pic,int depth,int ditherSize,
+ unsigned char* dest,int offset);
+
+ void doDither2YUV_std(YUVPicture* pic,int depth,
+ unsigned char* dest,int offset);
+
+};
+
+#endif
diff --git a/mpeglib/lib/util/render/dither2YUV/rgb2yuv16.cpp b/mpeglib/lib/util/render/dither2YUV/rgb2yuv16.cpp
new file mode 100644
index 00000000..e0d7fc86
--- /dev/null
+++ b/mpeglib/lib/util/render/dither2YUV/rgb2yuv16.cpp
@@ -0,0 +1,916 @@
+/***************************************************************************
+ rgb2yuv16.c - description
+ -------------------
+ begin : Tue Nov 2 2000
+ copyright : (C) 2000 by Christian Gerlach
+ email : cgerlach@rhrk.uni-kl.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "rgb2yuv16.h"
+#include <iostream>
+
+static unsigned short KEEPR[4] = { 63488, 63488, 63488, 63488 };
+unsigned short KEEPG[4] = { 2016, 2016, 2016, 2016 };
+unsigned short KEEPB[4] = { 31, 31, 31, 31 };
+
+short Y_RED[4] = { 307, 307, 307, 307 };
+short Y_GREEN[4] = { 302, 302, 302, 302 };
+short Y_BLUE[4] = { 117, 117, 117, 117 };
+
+short U_RED[4] = { -150, -150, -150, -150 };
+short U_GREEN[4] = { -147, -147, -147, -147 };
+short U_BLUE[4] = { 444, 444, 444, 444 };
+
+short V_RED[4] = { 632, 632, 632, 632 };
+short V_GREEN[4] = { -265, -265, -265, -265 };
+short V_BLUE[4] = { -102, -102, -102, -102 };
+
+
+// how to avoid these nasty compiler warinings?
+// heres one (maybe bad) method
+void dummyRGB2YUV16Bit() {
+
+ printf("%p\n",KEEPR);
+ printf("%p\n",KEEPG);
+ printf("%p\n",KEEPB);
+ printf("%p\n",Y_RED);
+ printf("%p\n",Y_GREEN);
+ printf("%p\n",Y_BLUE);
+ printf("%p\n",U_RED);
+ printf("%p\n",U_GREEN);
+ printf("%p\n",U_BLUE);
+ printf("%p\n",V_RED);
+ printf("%p\n",V_GREEN);
+ printf("%p\n",V_BLUE);
+}
+
+
+#ifndef INTEL
+void rgb2yuv16bit_mmx(unsigned char* ,unsigned char* ,unsigned char* ,
+ unsigned char* ,int , int ) {
+ std::cout << "RGB->YUV not compiled with INTEL" << std::endl;
+ exit(0);
+}
+
+void rgb2yuv16bit_mmx_fast(unsigned char* ,unsigned char* ,unsigned char* ,
+ unsigned char* ,int , int ) {
+ std::cout << "RGB->YUV not compiled with INTEL" << std::endl;
+ exit(0);
+}
+#endif
+
+
+void rgb2yuv16(unsigned char* rgbSource, unsigned char* dest)
+{
+ int rgb = *((unsigned short*) rgbSource++ );
+ int r = RED(rgb);
+ int g = GREEN(rgb);
+ int b = BLUE(rgb);
+
+ dest[0] = Y_RGB(r, g, b);
+ dest[1] = U_RGB(r, g, b);
+ dest[2] = V_RGB(r, g, b);
+}
+
+void rgb2yuv16bit(unsigned char* rgbSource,
+ unsigned char* lum,
+ unsigned char* cr,
+ unsigned char* cb,int height, int width) {
+
+ int height2 = height / 2;
+ int width2 = width / 2;
+ int r, g, b, row, col, rgb;
+
+ for (row=0 ; row<height2 ; row++) {
+ for (col=0 ; col<width2 ; col++) {
+ rgb = *((unsigned short*) rgbSource++ );
+ r = RED(rgb);
+ g = GREEN(rgb);
+ b = BLUE(rgb);
+
+ *lum++ = Y_RGB(r, g, b);
+ *cr++ = U_RGB(r, g, b);
+ *cb++ = V_RGB(r, g, b);
+
+ rgb = *((unsigned short*) rgbSource++ );
+ r = RED(rgb);
+ g = GREEN(rgb);
+ b = BLUE(rgb);
+
+ *lum++ = Y_RGB(r, g, b);
+ }
+ for (col=0 ; col<width ; col++) {
+ rgb = *((unsigned short*) rgbSource++ );
+ r = RED(rgb);
+ g = GREEN(rgb);
+ b = BLUE(rgb);
+
+ *lum++ = Y_RGB(r, g, b);
+ }
+ }
+}
+
+
+#ifdef INTEL
+
+void rgb2yuv16bit_mmx(unsigned char* rgbSource,
+ unsigned char* lum,
+ unsigned char* cr,
+ unsigned char* cb,int height, int width) {
+ int height2 = height / 2;
+ int width2 = width / 2;
+ int bytesPerLine = width * 2;
+
+ for (int row=0 ; row<height2 ; row++) {
+ rgb2yuv16bit_mmx422_row(rgbSource, lum, cr, cb, width);
+ rgbSource += bytesPerLine;
+ lum += width;
+ cr += width2;
+ cb += width2;
+
+ rgb2y16bit_mmx_row(rgbSource, lum, width);
+ rgbSource += bytesPerLine;
+ lum += width;
+ }
+}
+
+void rgb2yuv16bit_mmx_fast(unsigned char* rgbSource,
+ unsigned char* lum,
+ unsigned char* cr,
+ unsigned char* cb,int height, int width) {
+
+ int height2 = height / 2;
+ int width2 = width / 2;
+ int bytesPerLine = width * 2;
+
+ for (int row=0 ; row<height2 ; row++) {
+ rgb2yuv16bit_mmx422_row_fast(rgbSource, lum, cr, cb, width);
+ rgbSource += bytesPerLine;
+ lum += width;
+ cr += width2;
+ cb += width2;
+
+ rgb2y16bit_mmx_row_fast(rgbSource, lum, width);
+ rgbSource += bytesPerLine;
+ lum += width;
+ }
+}
+
+void rgb2yuv16bit_mmx422_row(unsigned char* rgb,
+ unsigned char* lum, unsigned char* cr,
+ unsigned char* cb, int pixel) {
+ unsigned int buf[17];
+
+ // 36%5 = TEMP0
+ // 44%5 = TEMPY
+ // 52%5 = TEMPU
+ // 60%5 = TEMPV
+
+ __asm__ __volatile__ (
+ "1:\n"
+
+ // unpack hicolor ( pixel 1 - 4)
+ "movq (%0), %%mm0\n"
+
+ "movq %%mm0, %%mm1\n"
+ "pand KEEPR, %%mm1\n"
+ "psrlq $8, %%mm1\n" // B3B2B1B0 -> mm1
+ "movq %%mm0, %%mm2\n"
+ "pand KEEPG, %%mm2\n"
+ "psrlq $3, %%mm2\n" // G3G2G1G0 -> mm2
+ "movq %%mm0, %%mm3\n"
+ "pand KEEPB, %%mm3\n"
+ "psllq $3, %%mm3\n" // G3G2G1G0 -> mm3
+
+ "movq %%mm2, %%mm0\n"
+ "punpcklbw %%mm1, %%mm2\n"
+ "punpckhbw %%mm1, %%mm0\n"
+
+ "pxor %%mm5, %%mm5\n"
+ "movq %%mm3, %%mm4\n"
+ "punpcklbw %%mm5, %%mm3\n"
+ "punpckhbw %%mm5, %%mm4\n"
+
+ "psllq $8, %%mm2\n"
+ "por %%mm2, %%mm3\n" // 0B1G1R10B0G0G0 -> mm3
+ "psllq $8, %%mm0\n"
+ "por %%mm0, %%mm4\n" // 0B3G3R30B2G2G2 -> mm4
+
+ "movq %%mm3, %5\n"
+ "movq %%mm4, 8%5\n"
+
+ // next 4 pixels ------------------------------
+
+ "movq 8(%0), %%mm0\n"
+
+ "movq %%mm0, %%mm1\n"
+ "pand KEEPR, %%mm1\n"
+ "psrlq $8, %%mm1\n" // B3B2B1B0 -> mm1
+ "movq %%mm0, %%mm2\n"
+ "pand KEEPG, %%mm2\n"
+ "psrlq $3, %%mm2\n" // G3G2G1G0 -> mm2
+ "movq %%mm0, %%mm3\n"
+ "pand KEEPB, %%mm3\n"
+ "psllq $3, %%mm3\n" // G3G2G1G0 -> mm3
+
+ "movq %%mm2, %%mm0\n"
+ "punpcklbw %%mm1, %%mm2\n"
+ "punpckhbw %%mm1, %%mm0\n"
+
+ "pxor %%mm5, %%mm5\n"
+ "movq %%mm3, %%mm4\n"
+ "punpcklbw %%mm5, %%mm3\n"
+ "punpckhbw %%mm5, %%mm4\n"
+
+ "psllq $8, %%mm2\n"
+ "por %%mm2, %%mm3\n" // 0B1G1R10B0G0G0 -> mm3
+ "psllq $8, %%mm0\n"
+ "por %%mm0, %%mm4\n" // 0B3G3R30B2G2G2 -> mm4
+
+ "movq %%mm3, 16%5\n"
+ "movq %%mm4, 24%5\n"
+
+ "add $16, %0\n"
+
+ // standard algorithm --------------------------------------------------
+
+ // pack rgb
+ // was: "movq (%0), %%mm1\n" // load G2R2B1G1R1B0G0R0
+ // ------------------------------
+ // (uses: mm0, mm1)
+ "movd 8%5, %%mm0\n"
+ "psllq $24, %%mm0\n"
+ "movd 4%5, %%mm1\n"
+ "por %%mm1, %%mm0\n"
+ "psllq $24, %%mm0\n"
+ "movd %5, %%mm1\n"
+ "por %%mm0, %%mm1\n"
+ // ------------------------------
+
+ "pxor %%mm6, %%mm6\n" // 0 -> mm6
+ "movq %%mm1, %%mm0\n" // G2R2B1G1R1B0G0R0 -> mm0
+ "psrlq $16, %%mm1\n" // 00G2R2B1G1R1B0 -> mm1
+ "punpcklbw ZEROSX, %%mm0\n" // R1B0G0R0 -> mm0
+ "movq %%mm1, %%mm7\n" // 00G2R2B1G1R1B0 -> mm7
+ "punpcklbw ZEROSX, %%mm1\n" // B1G1R1B0 -> mm1
+ "movq %%mm0, %%mm2\n" // R1B0G0R0 -> mm2
+ "pmaddwd YR0GRX, %%mm0\n" // yrR1,ygG0+yrR0 -> mm0
+
+ "movq %%mm1, %%mm3\n" // B1G1R1B0 -> mm3
+ "pmaddwd YBG0BX, %%mm1\n" // ybB1+ygG1,ybB0 -> mm1
+ "movq %%mm2, %%mm4\n" // R1B0G0R0 -> mm4
+ "pmaddwd UR0GRX, %%mm2\n" // urR1,ugG0+urR0 -> mm2
+ "movq %%mm3, %%mm5\n" // B1G1R1B0 -> mm5
+ "pmaddwd UBG0BX, %%mm3\n" // ubB1+ugG1,ubB0 -> mm3
+ "punpckhbw %%mm6, %%mm7\n" // 00G2R2 -> mm7
+ "pmaddwd VR0GRX, %%mm4\n" // vrR1,vgG0+vrR0 -> mm4
+ "paddd %%mm1, %%mm0\n" // Y1Y0 -> mm0
+
+ "pmaddwd VBG0BX, %%mm5\n" // vbB1+vgG1,vbB0 -> mm5
+
+ // pack rgb
+ // was: "movq 8(%0),%%mm1\n" // R5B4G4R4B3G3R3B2 -> mm1
+ // ------------------------------
+ // (uses: mm1, mm6)
+ "movd 20%5, %%mm1\n"
+ "psllq $24, %%mm1\n"
+ "movd 16%5, %%mm6\n"
+ "por %%mm6, %%mm1\n"
+ "psllq $24, %%mm1\n"
+ "movd 12%5, %%mm6\n"
+ "por %%mm6, %%mm1\n"
+ "psllq $8, %%mm1\n"
+ "movd 8%5, %%mm6\n"
+ "psrlq $16, %%mm6\n"
+ "por %%mm6, %%mm1\n"
+ // ------------------------------
+
+ "paddd %%mm3, %%mm2\n" // U1U0 -> mm2
+
+ "movq %%mm1, %%mm6\n" // R5B4G4R4B3G3R3B2 -> mm6
+ "punpcklbw ZEROSX, %%mm1\n" // B3G3R3B2 -> mm1
+ "paddd %%mm5, %%mm4\n" // V1V0 -> mm4
+
+ //----------------------------------------------------------------------
+
+ "movq %%mm1, %%mm5\n" // B3G3R3B2 -> mm5
+ "psllq $32, %%mm1\n" // R3B200 -> mm1
+
+ "paddd %%mm7, %%mm1\n" // R3B200+00G2R2=R3B2G2R2->mm1
+
+ "punpckhbw ZEROSX, %%mm6\n" // R5B4G4R3 -> mm6
+ "movq %%mm1, %%mm3\n" // R3B2G2R2 -> mm3
+
+ "pmaddwd YR0GRX, %%mm1\n" // yrR3,ygG2+yrR2 -> mm1
+ "movq %%mm5, %%mm7\n" // B3G3R3B2 -> mm7
+
+ "pmaddwd YBG0BX, %%mm5\n" // ybB3+ygG3,ybB2 -> mm5
+ "psrad $15, %%mm0\n" // 32-bit scaled Y1Y0 -> mm0
+
+ "movq %%mm6, 36%5\n" // R5B4G4R4 -> TEMP0
+ "movq %%mm3, %%mm6\n" // R3B2G2R2 -> mm6
+ "pmaddwd UR0GRX, %%mm6\n" // urR3,ugG2+urR2 -> mm6
+ "psrad $15, %%mm2\n" // 32-bit scaled U1U0 -> mm2
+
+ "paddd %%mm5, %%mm1\n" // Y3Y2 -> mm1
+ "movq %%mm7, %%mm5\n" // B3G3R3B2 -> mm5
+ "pmaddwd UBG0BX, %%mm7\n" // ubB3+ugG3,ubB2
+ "psrad $15, %%mm1\n" // 32-bit scaled Y3Y2 -> mm1
+
+ "pmaddwd VR0GRX, %%mm3\n" // vrR3,vgG2+vgR2
+ "packssdw %%mm1, %%mm0\n" // Y3Y2Y1Y0 -> mm0
+
+ "pmaddwd VBG0BX, %%mm5\n" // vbB3+vgG3,vbB2 -> mm5
+ "psrad $15, %%mm4\n" // 32-bit scaled V1V0 -> mm4
+
+ //----------------------------------------------------------------------
+
+ "paddd %%mm7, %%mm6\n" // U3U2 -> mm6
+
+ // pack rgb
+ // was: "movq 16(%0), %%mm1\n" // B7G7R7B6G6R6B5G5 -> mm1
+ // ------------------------------
+ // (uses: mm1, mm7)
+ "movd 28%5, %%mm1\n"
+ "psllq $24, %%mm1\n"
+ "movd 24%5, %%mm7\n"
+ "por %%mm7, %%mm1\n"
+ "psllq $16, %%mm1\n"
+ "movd 20%5, %%mm7\n"
+ "psrlq $8, %%mm7\n"
+ "por %%mm7, %%mm1\n"
+ // ------------------------------
+
+ "movq %%mm1, %%mm7\n" // B7G7R7B6G6R6B5G5 -> mm1
+ "psrad $15, %%mm6\n" // 32-bit scaled U3U2 -> mm6
+
+ "paddd %%mm5, %%mm3\n" // V3V2 -> mm3
+ "psllq $16, %%mm7\n" // R7B6G6R6B5G500 -> mm7
+
+ "movq %%mm7, %%mm5\n" // R7B6G6R6B5G500 -> mm5
+ "psrad $15, %%mm3\n" // 32-bit scaled V3V2 -> mm3
+
+ "movq %%mm0, 44%5\n" // 32-bit scaled Y3Y2Y1Y0 -> TEMPY
+
+ "packssdw %%mm6, %%mm2\n" // 32-bit scaled U3U2U1U0 -> mm2
+
+ "movq 36%5, %%mm0\n" // R5B4G4R4 -> mm0
+
+ "punpcklbw ZEROSX, %%mm7\n" // B5G500 -> mm7
+ "movq %%mm0, %%mm6\n" // R5B4G4R4 -> mm6
+
+ "movq %%mm2, 52%5\n" // 32-bit scaled U3U2U1U0 -> TEMPU
+ "psrlq $32, %%mm0\n" // 00R5B4 -> mm0
+
+ "paddw %%mm0, %%mm7\n" // B5G5R5B4 -> mm7
+ "movq %%mm6, %%mm2\n" // B5B4G4R4 -> mm2
+
+ "pmaddwd YR0GRX, %%mm2\n" // yrR5,ygG4+yrR4 -> mm2
+ "movq %%mm7, %%mm0\n" // B5G5R5B4 -> mm0
+
+ "pmaddwd YBG0BX, %%mm7\n" // ybB5+ygG5,ybB4 -> mm7
+ "packssdw %%mm3, %%mm4\n" // 32-bit scaled V3V2V1V0 -> mm4
+
+ //----------------------------------------------------------------------
+
+ "movq %%mm4, 60%5\n" // (V3V2V1V0)/256 -> mm4
+
+ "movq %%mm6, %%mm4\n" // B5B4G4R4 -> mm4
+
+ "pmaddwd UR0GRX, %%mm6\n" // urR5,ugG4+urR4
+ "movq %%mm0, %%mm3\n" // B5G5R5B4 -> mm0
+
+ "pmaddwd UBG0BX, %%mm0\n" // ubB5+ugG5,ubB4
+ "paddd %%mm7, %%mm2\n" // Y5Y4 -> mm2
+
+ //----------------------------------------------------------------------
+
+ "pmaddwd VR0GRX, %%mm4\n" // vrR5,vgG4+vrR4 -> mm4
+ "pxor %%mm7, %%mm7\n" // 0 -> mm7
+
+ "pmaddwd VBG0BX, %%mm3\n" // vbB5+vgG5,vbB4 -> mm3
+ "punpckhbw %%mm7, %%mm1\n" // B7G7R7B6 -> mm1
+
+ "paddd %%mm6, %%mm0\n" // U5U4 -> mm0
+ "movq %%mm1, %%mm6\n" // B7G7R7B6 -> mm6
+
+ "pmaddwd YBG0BX, %%mm6\n" // ybB7+ygG7,ybB6 -> mm6
+ "punpckhbw %%mm7, %%mm5\n" // R7B6G6R6 -> mm5
+
+ "movq %%mm5, %%mm7\n" // R7B6G6R6 -> mm7
+ "paddd %%mm4, %%mm3\n" // V5V4 -> mm3
+
+ "pmaddwd YR0GRX, %%mm5\n" // yrR7,ygG6+yrR6 -> mm5
+ "movq %%mm1, %%mm4\n" // B7G7R7B6 -> mm4
+
+ "pmaddwd UBG0BX, %%mm4\n" // ubB7+ugG7,ubB6 -> mm4
+ "psrad $15, %%mm0\n" // 32-bit scaled U5U4 -> %%mm0
+
+ //----------------------------------------------------------------------
+
+ "paddd OFFSETWX, %%mm0\n" // add offset to U5U4 -> mm0
+ "psrad $15, %%mm2\n" // 32-bit scaled Y5Y4 -> mm2
+
+ "paddd %%mm5, %%mm6\n" // Y7Y6 -> mm6
+ "movq %%mm7, %%mm5\n" // R7B6G6R6 -> mm5
+
+ "pmaddwd UR0GRX, %%mm7\n" // urR7,ugG6+ugR6 -> mm7
+ "psrad $15, %%mm3\n" // 32-bit scaled V5V4 -> mm3
+
+ "pmaddwd VBG0BX, %%mm1\n" // vbB7+vgG7,vbB6 -> mm1
+ "psrad $15, %%mm6\n" // 32-bit scaled Y7Y6 -> mm6
+
+ "paddd OFFSETDX, %%mm4\n" // add offset to U7U6
+ "packssdw %%mm6, %%mm2\n" // Y7Y6Y5Y4 -> mm2
+
+ "pmaddwd VR0GRX, %%mm5\n" // vrR7,vgG6+vrR6 -> mm5
+ "paddd %%mm4, %%mm7\n" // U7U6 -> mm7
+
+ "psrad $15, %%mm7\n" // 32-bit scaled U7U6 -> mm7
+
+ //----------------------------------------------------------------------
+
+ "movq 44%5, %%mm6\n" // 32-bit scaled Y3Y2Y1Y0 -> mm6
+ "packssdw %%mm7, %%mm0\n" // 32-bit scaled U7U6U5U4 -> mm0
+
+ "movq 52%5, %%mm4\n" // 32-bit scaled U3U2U1U0 -> mm4
+ "packuswb %%mm2, %%mm6\n" // all 8 Y values -> mm6
+
+ "movq OFFSETBX, %%mm7\n" // 128,128,128,128 -> mm7
+ "paddd %%mm5, %%mm1\n" // V7V6 -> mm1
+
+ "paddw %%mm7, %%mm4\n" // add offset to U3U2U1U0/256
+ "psrad $15, %%mm1\n" // 32-bit scaled V7V6 -> mm1
+
+ //----------------------------------------------------------------------
+
+ "movq %%mm6, (%1)\n" // store Y
+
+ "packuswb %%mm0, %%mm4\n" // all 8 U values -> mm4
+ "movq 60%5, %%mm5\n" // 32-bit scaled V3V2V1V0 -> mm5
+
+ "packssdw %%mm1, %%mm3\n" // V7V6V5V4 -> mm3
+ "paddw %%mm7, %%mm5\n" // add offset to V3V2V1V0
+ "paddw %%mm7, %%mm3\n" // add offset to V7V6V5V4
+
+ "packuswb %%mm3, %%mm5\n" // ALL 8 V values -> mm5
+
+ "movq CLEARX, %%mm2\n"
+ "pand %%mm2, %%mm4\n"
+ "pand %%mm2, %%mm5\n"
+
+ "packuswb %%mm5, %%mm4\n"
+
+ "movd %%mm4, (%2)\n"
+ "psrlq $32, %%mm4\n"
+ "movd %%mm4, (%3)\n"
+
+ "add $8, %1\n"
+ "add $4, %2\n"
+ "add $4, %3\n"
+
+ "sub $8, %4\n"
+ "jnz 1b\n"
+
+ "emms\n"
+
+ :
+ : "r" (rgb), "r" (lum), "r" (cr), "r" (cb),
+ "m" (pixel), "m" (buf[0])
+
+ );
+}
+
+void rgb2yuv16bit_mmx422_row_fast(unsigned char* rgb,
+ unsigned char* lum, unsigned char* cr,
+ unsigned char* cb, int pixel)
+{
+ __asm__ __volatile__ (
+ "1:\n"
+
+ // unpack hicolor ( pixel 0 - 3)
+ "movq (%0), %%mm0\n"
+
+ "movq %%mm0, %%mm1\n"
+ "pand KEEPR, %%mm1\n"
+ "psrlq $11, %%mm1\n" // B3B2B1B0 -> mm1
+
+ "movq %%mm0, %%mm2\n"
+ "pand KEEPG, %%mm2\n"
+ "psrlq $5, %%mm2\n" // G3G2G1G0 -> mm2
+
+ "movq %%mm0, %%mm3\n"
+ "pand KEEPB, %%mm3\n" // R3R2R1R0 -> mm3
+
+ // unpack hicolor ( pixel 4 - 7)
+ "movq 8(%0), %%mm0\n"
+
+ "movq %%mm0, %%mm4\n"
+ "pand KEEPR, %%mm4\n"
+ "psrlq $11, %%mm4\n" // B7B6B5B4 -> mm4
+
+ "movq %%mm0, %%mm5\n"
+ "pand KEEPG, %%mm5\n"
+ "psrlq $5, %%mm5\n" // G7G6G5G4 -> mm5
+
+ "movq %%mm0, %%mm6\n"
+ "pand KEEPB, %%mm6\n" // R7R6R5R4 -> mm6
+
+ // calculate Y
+ "movq %%mm6, %%mm7\n"
+ "pmullw Y_RED, %%mm7\n"
+
+ "movq %%mm5, %%mm0\n"
+ "pmullw Y_GREEN, %%mm0\n"
+ "paddw %%mm0, %%mm7\n"
+
+ "movq %%mm4, %%mm0\n"
+ "pmullw Y_BLUE, %%mm0\n"
+ "paddw %%mm0, %%mm7\n"
+
+ "psrlw $7, %%mm7\n" // Y3Y2Y1Y0 -> mm7
+
+ "pxor %%mm0, %%mm0\n"
+ "packuswb %%mm0, %%mm7\n"
+ "movd %%mm7, 4(%1)\n" // Y3Y2Y1Y0 -> lum
+
+ // --------
+
+ "movq %%mm3, %%mm7\n"
+ "pmullw Y_RED, %%mm7\n"
+
+ "movq %%mm2, %%mm0\n"
+ "pmullw Y_GREEN, %%mm0\n"
+ "paddw %%mm0, %%mm7\n"
+
+ "movq %%mm1, %%mm0\n"
+ "pmullw Y_BLUE, %%mm0\n"
+ "paddw %%mm0, %%mm7\n"
+
+ "psrlw $7, %%mm7\n" // Y7Y6Y5Y4 -> mm7
+
+ "pxor %%mm0, %%mm0\n"
+ "packuswb %%mm0, %%mm7\n"
+ "movd %%mm7, (%1)\n" // Y7Y6Y5Y4 -> lum
+ "add $8, %1\n"
+
+ // pack RGB
+ "packuswb %%mm4, %%mm1\n"
+ "pand CLEARX, %%mm1\n" // B6B4B2B0 -> mm1
+ "packuswb %%mm5, %%mm2\n"
+ "pand CLEARX, %%mm2\n" // GRG4G2G0 -> mm2
+ "packuswb %%mm6, %%mm3\n"
+ "pand CLEARX, %%mm3\n" // R6R4R2R0 -> mm3
+
+ // calculate U
+ "movq %%mm3, %%mm7\n"
+ "pmullw U_RED, %%mm7\n"
+
+ "movq %%mm2, %%mm0\n"
+ "pmullw U_GREEN, %%mm0\n"
+ "paddw %%mm0, %%mm7\n"
+
+ "movq %%mm1, %%mm0\n"
+ "pmullw U_BLUE, %%mm0\n"
+ "paddw %%mm0, %%mm7\n"
+
+ "psrlw $7, %%mm7\n" // U3U2U1U0 -> mm7
+ "paddw OFFSETBX,%%mm7\n"
+ "pand CLEARX, %%mm7\n"
+
+ "pxor %%mm0, %%mm0\n"
+ "packuswb %%mm0, %%mm7\n"
+ "movd %%mm7, (%2)\n" // U3U2U1U0 -> lum
+ "add $4, %2\n"
+
+ // calculate V
+ "movq %%mm3, %%mm7\n"
+ "pmullw V_RED, %%mm7\n"
+
+ "movq %%mm2, %%mm0\n"
+ "pmullw V_GREEN, %%mm0\n"
+ "paddw %%mm0, %%mm7\n"
+
+ "movq %%mm1, %%mm0\n"
+ "pmullw V_BLUE, %%mm0\n"
+ "paddw %%mm0, %%mm7\n"
+
+ "psrlw $7, %%mm7\n" // V3V2V1V0 -> mm7
+ "paddw OFFSETBX,%%mm7\n"
+ "pand CLEARX, %%mm7\n"
+
+ "pxor %%mm0, %%mm0\n"
+ "packuswb %%mm0, %%mm7\n"
+ "movd %%mm7, (%3)\n" // V3V2V1V0 -> lum
+ "add $4, %3\n"
+
+ "add $16, %0\n"
+
+ "sub $8, %4\n"
+ "jnz 1b\n"
+
+ "emms\n"
+
+ :
+ : "r" (rgb), "r" (lum), "r" (cr), "r" (cb), "m" (pixel)
+
+ );
+}
+
+void rgb2y16bit_mmx_row(unsigned char* rgbSource,
+ unsigned char* lum, int pixel)
+{
+ unsigned int buf[16];
+
+ // 36%3 = TEMP0
+ // 44%3 = TEMPY
+
+ __asm__ __volatile__ (
+ "1:\n"
+
+ // unpack hicolor ( pixel 1 - 4)
+ "movq (%0), %%mm0\n"
+
+ "movq %%mm0, %%mm1\n"
+ "pand KEEPR, %%mm1\n"
+ "psrlq $8, %%mm1\n" // B3B2B1B0 -> mm1
+ "movq %%mm0, %%mm2\n"
+ "pand KEEPG, %%mm2\n"
+ "psrlq $3, %%mm2\n" // G3G2G1G0 -> mm2
+ "movq %%mm0, %%mm3\n"
+ "pand KEEPB, %%mm3\n"
+ "psllq $3, %%mm3\n" // G3G2G1G0 -> mm3
+
+ "movq %%mm2, %%mm0\n"
+ "punpcklbw %%mm1, %%mm2\n"
+ "punpckhbw %%mm1, %%mm0\n"
+
+ "pxor %%mm5, %%mm5\n"
+ "movq %%mm3, %%mm4\n"
+ "punpcklbw %%mm5, %%mm3\n"
+ "punpckhbw %%mm5, %%mm4\n"
+
+ "psllq $8, %%mm2\n"
+ "por %%mm2, %%mm3\n" // 0B1G1R10B0G0G0 -> mm3
+ "psllq $8, %%mm0\n"
+ "por %%mm0, %%mm4\n" // 0B3G3R30B2G2G2 -> mm4
+
+ "movq %%mm3, %3\n"
+ "movq %%mm4, 8%3\n"
+
+ // next 4 pixels ------------------------------
+
+ "movq 8(%0), %%mm0\n"
+
+ "movq %%mm0, %%mm1\n"
+ "pand KEEPR, %%mm1\n"
+ "psrlq $8, %%mm1\n" // B3B2B1B0 -> mm1
+ "movq %%mm0, %%mm2\n"
+ "pand KEEPG, %%mm2\n"
+ "psrlq $3, %%mm2\n" // G3G2G1G0 -> mm2
+ "movq %%mm0, %%mm3\n"
+ "pand KEEPB, %%mm3\n"
+ "psllq $3, %%mm3\n" // G3G2G1G0 -> mm3
+
+ "movq %%mm2, %%mm0\n"
+ "punpcklbw %%mm1, %%mm2\n"
+ "punpckhbw %%mm1, %%mm0\n"
+
+ "pxor %%mm5, %%mm5\n"
+ "movq %%mm3, %%mm4\n"
+ "punpcklbw %%mm5, %%mm3\n"
+ "punpckhbw %%mm5, %%mm4\n"
+
+ "psllq $8, %%mm2\n"
+ "por %%mm2, %%mm3\n" // 0B1G1R10B0G0G0 -> mm3
+ "psllq $8, %%mm0\n"
+ "por %%mm0, %%mm4\n" // 0B3G3R30B2G2G2 -> mm4
+
+ "movq %%mm3, 16%3\n"
+ "movq %%mm4, 24%3\n"
+
+ "add $16, %0\n"
+
+ // standard algorithm --------------------------------------------------
+
+ // pack rgb
+ // was: "movq (%0), %%mm1\n" // load G2R2B1G1R1B0G0R0
+ // ------------------------------
+ // (uses: mm0, mm1)
+ "movd 8%3, %%mm0\n"
+ "psllq $24, %%mm0\n"
+ "movd 4%3, %%mm1\n"
+ "por %%mm1, %%mm0\n"
+ "psllq $24, %%mm0\n"
+ "movd %3, %%mm1\n"
+ "por %%mm0, %%mm1\n"
+ // ------------------------------
+
+ "pxor %%mm6, %%mm6\n" // 0 -> mm6
+ "movq %%mm1, %%mm0\n" // G2R2B1G1R1B0G0R0 -> mm0
+ "psrlq $16, %%mm1\n" // 00G2R2B1G1R1B0 -> mm1
+ "punpcklbw ZEROSX, %%mm0\n" // R1B0G0R0 -> mm0
+ "movq %%mm1, %%mm7\n" // 00G2R2B1G1R1B0 -> mm7
+ "punpcklbw ZEROSX, %%mm1\n" // B1G1R1B0 -> mm1
+ "movq %%mm0, %%mm2\n" // R1B0G0R0 -> mm2
+ "pmaddwd YR0GRX, %%mm0\n" // yrR1,ygG0+yrR0 -> mm0
+ "movq %%mm1, %%mm3\n" // B1G1R1B0 -> mm3
+ "pmaddwd YBG0BX, %%mm1\n" // ybB1+ygG1,ybB0 -> mm1
+ "movq %%mm2, %%mm4\n" // R1B0G0R0 -> mm4
+ "movq %%mm3, %%mm5\n" // B1G1R1B0 -> mm5
+ "punpckhbw %%mm6, %%mm7\n" // 00G2R2 -> mm7
+ "paddd %%mm1, %%mm0\n" // Y1Y0 -> mm0
+
+ // pack rgb
+ // was: "movq 8(%0),%%mm1\n" // R5B4G4R4B3G3R3B2 -> mm1
+ // ------------------------------
+ // (uses: mm1, mm6)
+ "movd 20%3, %%mm1\n"
+ "psllq $24, %%mm1\n"
+ "movd 16%3, %%mm6\n"
+ "por %%mm6, %%mm1\n"
+ "psllq $24, %%mm1\n"
+ "movd 12%3, %%mm6\n"
+ "por %%mm6, %%mm1\n"
+ "psllq $8, %%mm1\n"
+ "movd 8%3, %%mm6\n"
+ "psrlq $16, %%mm6\n"
+ "por %%mm6, %%mm1\n"
+ // ------------------------------
+
+ "movq %%mm1, %%mm6\n" // R5B4G4R4B3G3R3B2 -> mm6
+ "punpcklbw ZEROSX, %%mm1\n" // B3G3R3B2 -> mm1
+
+ //----------------------------------------------------------------------
+
+ "movq %%mm1, %%mm5\n" // B3G3R3B2 -> mm5
+ "psllq $32, %%mm1\n" // R3B200 -> mm1
+
+ "paddd %%mm7, %%mm1\n" // R3B200+00G2R2=R3B2G2R2->mm1
+
+ "punpckhbw ZEROSX, %%mm6\n" // R5B4G4R3 -> mm6
+ "movq %%mm1, %%mm3\n" // R3B2G2R2 -> mm3
+
+ "pmaddwd YR0GRX, %%mm1\n" // yrR3,ygG2+yrR2 -> mm1
+ "movq %%mm5, %%mm7\n" // B3G3R3B2 -> mm7
+
+ "pmaddwd YBG0BX, %%mm5\n" // ybB3+ygG3,ybB2 -> mm5
+ "psrad $15, %%mm0\n" // 32-bit scaled Y1Y0 -> mm0
+
+ "movq %%mm6, 36%3\n" // R5B4G4R4 -> TEMP0
+ "movq %%mm3, %%mm6\n" // R3B2G2R2 -> mm6
+
+ "paddd %%mm5, %%mm1\n" // Y3Y2 -> mm1
+ "movq %%mm7, %%mm5\n" // B3G3R3B2 -> mm5
+ "psrad $15, %%mm1\n" // 32-bit scaled Y3Y2 -> mm1
+
+ "packssdw %%mm1, %%mm0\n" // Y3Y2Y1Y0 -> mm0
+
+ //----------------------------------------------------------------------
+
+ // pack rgb
+ // was: "movq 16(%0), %%mm1\n" // B7G7R7B6G6R6B5G5 -> mm1
+ // ------------------------------
+ // (uses: mm1, mm7)
+ "movd 28%3, %%mm1\n"
+ "psllq $24, %%mm1\n"
+ "movd 24%3, %%mm7\n"
+ "por %%mm7, %%mm1\n"
+ "psllq $16, %%mm1\n"
+ "movd 20%3, %%mm7\n"
+ "psrlq $8, %%mm7\n"
+ "por %%mm7, %%mm1\n"
+ // ------------------------------
+
+ "movq %%mm1, %%mm7\n" // B7G7R7B6G6R6B5G5 -> mm1
+
+ "psllq $16, %%mm7\n" // R7B6G6R6B5G500 -> mm7
+
+ "movq %%mm7, %%mm5\n" // R7B6G6R6B5G500 -> mm5
+
+ "movq %%mm0, 44%3\n" // 32-bit scaled Y3Y2Y1Y0 -> TEMPY
+
+ "movq 36%3, %%mm0\n" // R5B4G4R4 -> mm0
+
+ "punpcklbw ZEROSX, %%mm7\n" // B5G500 -> mm7
+ "movq %%mm0, %%mm6\n" // R5B4G4R4 -> mm6
+
+ "psrlq $32, %%mm0\n" // 00R5B4 -> mm0
+
+ "paddw %%mm0, %%mm7\n" // B5G5R5B4 -> mm7
+ "movq %%mm6, %%mm2\n" // B5B4G4R4 -> mm2
+
+ "pmaddwd YR0GRX, %%mm2\n" // yrR5,ygG4+yrR4 -> mm2
+
+ "pmaddwd YBG0BX, %%mm7\n" // ybB5+ygG5,ybB4 -> mm7
+
+ //----------------------------------------------------------------------
+ "paddd %%mm7, %%mm2\n" // Y5Y4 -> mm2
+
+ //----------------------------------------------------------------------
+
+ "pxor %%mm7, %%mm7\n" // 0 -> mm7
+
+ "punpckhbw %%mm7, %%mm1\n" // B7G7R7B6 -> mm1
+
+ "movq %%mm1, %%mm6\n" // B7G7R7B6 -> mm6
+
+ "pmaddwd YBG0BX, %%mm6\n" // ybB7+ygG7,ybB6 -> mm6
+ "punpckhbw %%mm7, %%mm5\n" // R7B6G6R6 -> mm5
+
+ "pmaddwd YR0GRX, %%mm5\n" // yrR7,ygG6+yrR6 -> mm5
+
+ //----------------------------------------------------------------------
+
+ "psrad $15, %%mm2\n" // 32-bit scaled Y5Y4 -> mm2
+
+ "paddd %%mm5, %%mm6\n" // Y7Y6 -> mm6
+ "psrad $15, %%mm6\n" // 32-bit scaled Y7Y6 -> mm6
+
+ "packssdw %%mm6, %%mm2\n" // Y7Y6Y5Y4 -> mm2
+
+ //----------------------------------------------------------------------
+
+ "movq 44%3, %%mm6\n" // 32-bit scaled Y3Y2Y1Y0 -> mm6
+ "packuswb %%mm2, %%mm6\n" // all 8 Y values -> mm6
+
+ //----------------------------------------------------------------------
+
+ "movq %%mm6, (%1)\n" // store Y
+
+ "add $8, %1\n"
+
+ "sub $8, %2\n"
+ "jnz 1b\n"
+ "emms\n"
+
+ :
+ : "r" (rgbSource), "r" (lum), "m" (pixel), "m" (buf[0])
+
+ );
+}
+
+void rgb2y16bit_mmx_row_fast(unsigned char* rgb, unsigned char* lum, int pixel)
+{
+ __asm__ __volatile__ (
+ "1:\n"
+
+ // unpack hicolor ( pixel 1 - 4)
+ "movq (%0), %%mm0\n"
+
+ "movq %%mm0, %%mm1\n"
+ "pand KEEPR, %%mm1\n"
+ "psrlq $11, %%mm1\n" // B3B2B1B0 -> mm1
+
+ "movq %%mm0, %%mm2\n"
+ "pand KEEPG, %%mm2\n"
+ "psrlq $5, %%mm2\n" // G3G2G1G0 -> mm2
+ "movq %%mm0, %%mm3\n"
+ "pand KEEPB, %%mm3\n" // R3R2R1R0 -> mm3
+
+ // calculate Y
+ "movq %%mm3, %%mm4\n"
+ "pmullw Y_RED, %%mm4\n"
+
+ "movq %%mm2, %%mm5\n"
+ "pmullw Y_GREEN, %%mm5\n"
+ "paddw %%mm5, %%mm4\n"
+
+ "movq %%mm1, %%mm6\n"
+ "pmullw Y_BLUE, %%mm6\n"
+ "paddw %%mm6, %%mm4\n"
+
+ "psrlw $7, %%mm4\n" // Y3Y2Y1Y0 -> mm4
+
+ "pxor %%mm5, %%mm5\n"
+ "packuswb %%mm5, %%mm4\n"
+
+ "movd %%mm4, (%1)\n"
+ "add $4, %1\n"
+
+ "add $8, %0\n"
+
+ "sub $4, %2\n"
+ "jnz 1b\n"
+
+ "emms\n"
+
+ :
+ : "r" (rgb), "r" (lum), "m" (pixel)
+ );
+}
+
+
+#endif
+// INTEL
+
+
diff --git a/mpeglib/lib/util/render/dither2YUV/rgb2yuv16.h b/mpeglib/lib/util/render/dither2YUV/rgb2yuv16.h
new file mode 100644
index 00000000..7e4d6508
--- /dev/null
+++ b/mpeglib/lib/util/render/dither2YUV/rgb2yuv16.h
@@ -0,0 +1,74 @@
+/***************************************************************************
+ rgb2yuv16.h - description
+ -------------------
+ begin : Tue Nov 2 2000
+ copyright : (C) 2000 by Christian Gerlach
+ email : cgerlach@rhrk.uni-kl.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef __RGB2YUV16_H
+#define __RGB2YUV16_H
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "../yuvPicture.h"
+#include "rgb2yuvdefs.h"
+
+// slow C implementation
+void rgb2yuv16bit(unsigned char* rgbSource,
+ unsigned char* destLum,
+ unsigned char* destCr,
+ unsigned char* destCb,int height, int width);
+
+
+
+//
+// We compile with MMX if we are on INTEL arch
+// (this does not mean that we really support MMX,
+// this is a seperate/runtime check)
+//
+
+#ifdef INTEL
+
+void rgb2yuv16bit_mmx(unsigned char* rgbSource,
+ unsigned char* lum,
+ unsigned char* cr,
+ unsigned char* cb,int height, int width);
+
+void rgb2yuv16bit_mmx_fast(unsigned char* rgbSource,
+ unsigned char* lum,
+ unsigned char* cr,
+ unsigned char* cb,int height, int width);
+
+void rgb2yuv16bit_mmx422_row(unsigned char* rgb,
+ unsigned char* lum, unsigned char* cr,
+ unsigned char* cb, int pixel);
+
+void rgb2y16bit_mmx_row(unsigned char* rgbSource,
+ unsigned char* lum, int pixel);
+
+void rgb2yuv16bit_mmx422_row_fast(unsigned char* rgb,
+ unsigned char* lum, unsigned char* cr,
+ unsigned char* cb, int pixel);
+
+void rgb2y16bit_mmx_row_fast(unsigned char* rgb,
+ unsigned char* lum, int pixel);
+
+
+#endif
+// INTEL
+
+
+
+#endif
diff --git a/mpeglib/lib/util/render/dither2YUV/rgb2yuv32.cpp b/mpeglib/lib/util/render/dither2YUV/rgb2yuv32.cpp
new file mode 100644
index 00000000..3e246e25
--- /dev/null
+++ b/mpeglib/lib/util/render/dither2YUV/rgb2yuv32.cpp
@@ -0,0 +1,1143 @@
+/***************************************************************************
+ rgb2yuv32.cpp - description
+ -------------------
+ begin : Tue Nov 2 2000
+ copyright : (C) 2000 by Christian Gerlach
+ email : cgerlach@rhrk.uni-kl.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "rgb2yuv32.h"
+#include <iostream>
+
+void rgb2yuv32(unsigned char* rgb, unsigned char* dest)
+{
+ dest[0] = Y_RGB(rgb[0], rgb[1], rgb[2]);
+ dest[1] = U_RGB(rgb[0], rgb[1], rgb[2]);
+ dest[2] = V_RGB(rgb[0], rgb[1], rgb[2]);
+}
+
+void rgb2yuv24bit(unsigned char* rgbSource,
+ unsigned char* lum,
+ unsigned char* cr,
+ unsigned char* cb,int height, int width) {
+ int width2 = width / 2;
+ int height2 = height / 2;
+ int r, g, b, row, col;
+
+ for (row=0 ; row<height2 ; row++) {
+ for (col=0 ; col<width2 ; col++) {
+ r = *rgbSource++;
+ g = *rgbSource++;
+ b = *rgbSource++;
+
+ *lum++ = Y_RGB(r, g, b);
+ *cr++ = U_RGB(r, g, b);
+ *cb++ = V_RGB(r, g, b);
+
+ r = *rgbSource++;
+ g = *rgbSource++;
+ b = *rgbSource++;
+
+ *lum++ = Y_RGB(r, g, b);
+ }
+ for (col=0 ; col<width ; col++) {
+ r = *rgbSource++;
+ g = *rgbSource++;
+ b = *rgbSource++;
+
+ *lum++ = Y_RGB(r, g, b);
+ }
+ }
+}
+
+void rgb2yuv32bit(unsigned char* rgbSource,
+ unsigned char* lum,
+ unsigned char* cr,
+ unsigned char* cb,int height, int width) {
+
+ int width2 = width / 2;
+ int height2 = height / 2;
+ int r, g, b, row, col;
+
+ for (row=0 ; row<height2 ; row++) {
+ for (col=0 ; col<width2 ; col++) {
+ r = *rgbSource++;
+ g = *rgbSource++;
+ b = *rgbSource++;
+ rgbSource ++;
+
+ *lum++ = Y_RGB(r, g, b);
+ *cr++ = U_RGB(r, g, b);
+ *cb++ = V_RGB(r, g, b);
+
+ r = *rgbSource++;
+ g = *rgbSource++;
+ b = *rgbSource++;
+ rgbSource++;
+
+ *lum++ = Y_RGB(r, g, b);
+ }
+ for (col=0 ; col<width ; col++) {
+ r = *rgbSource++;
+ g = *rgbSource++;
+ b = *rgbSource++;
+ rgbSource ++;
+
+ *lum++ = Y_RGB(r, g, b);
+ }
+ }
+}
+
+#ifndef INTEL
+void rgb2yuv24bit_mmx(unsigned char* rgbSource,
+ unsigned char* lum,
+ unsigned char* cr,
+ unsigned char* cb,int height, int width) {
+ std::cout << "RGB->YUV render not compiled for INTEL"<<std::endl;
+ exit(0);
+}
+
+void rgb2yuv32bit_mmx(unsigned char* rgbSource,
+ unsigned char* lum,
+ unsigned char* cr,
+ unsigned char* cb,int height, int width) {
+ std::cout << "RGB->YUV render not compiled for INTEL"<<std::endl;
+ exit(0);
+}
+
+#endif
+
+#ifdef INTEL
+
+void rgb2yuv24bit_mmx(unsigned char* rgbSource,
+ unsigned char* lum,
+ unsigned char* cr,
+ unsigned char* cb,int height, int width) {
+ int width2 = width / 2;
+ int height2 = height / 2;
+ int row;
+ int bytesPerLine = width * 3;
+
+ for (row=0 ; row<height2 ; row++) {
+ rgb2yuv24bit_mmx422_row(rgbSource, lum, cr, cb, width);
+ rgbSource += bytesPerLine;
+ lum += width;
+ cr += width2;
+ cb += width2;
+
+ rgb2y24bit_mmx_row(rgbSource, lum, width);
+ rgbSource += bytesPerLine;
+ lum += width;
+ }
+}
+
+void rgb2yuv32bit_mmx(unsigned char* rgbSource,
+ unsigned char* lum,
+ unsigned char* cr,
+ unsigned char* cb,int height, int width) {
+
+
+ int width2 = width / 2;
+ int height2 = height / 2;
+ int bytesPerLine = width * 4;
+
+ for (int row=0 ; row<height2 ; row++) {
+ rgb2yuv32bit_mmx422_row(rgbSource, lum,cr, cb, width);
+ rgbSource += bytesPerLine;
+ lum += width;
+ cr += width2;
+ cb += width2;
+
+ rgb2y32bit_mmx_row(rgbSource, lum, width);
+ rgbSource += bytesPerLine;
+ lum += width;
+ }
+}
+
+void rgb2yuv24bit_mmx444_row(unsigned char* rgb, unsigned char* lum, unsigned char* cr,
+ unsigned char* cb, int pixel)
+{
+ unsigned int buf[8];
+
+ // %5 = TEMP0
+ // 8%5 = TEMPY
+ // 16%5 = TEMPU
+ // 24%5 = TEMPV
+
+ __asm__ __volatile__ (
+ "1:\n"
+
+ "movq (%0), %%mm1\n" // load G2R2B1G1R1B0G0R0
+ "pxor %%mm6, %%mm6\n" // 0 -> mm6
+ "movq %%mm1, %%mm0\n" // G2R2B1G1R1B0G0R0 -> mm0
+ "psrlq $16, %%mm1\n" // 00G2R2B1G1R1B0 -> mm1
+ "punpcklbw ZEROSX, %%mm0\n" // R1B0G0R0 -> mm0
+ "movq %%mm1, %%mm7\n" // 00G2R2B1G1R1B0 -> mm7
+ "punpcklbw ZEROSX, %%mm1\n" // B1G1R1B0 -> mm1
+ "movq %%mm0, %%mm2\n" // R1B0G0R0 -> mm2
+ "pmaddwd YR0GRX, %%mm0\n" // yrR1,ygG0+yrR0 -> mm0
+ "movq %%mm1, %%mm3\n" // B1G1R1B0 -> mm3
+ "pmaddwd YBG0BX, %%mm1\n" // ybB1+ygG1,ybB0 -> mm1
+ "movq %%mm2, %%mm4\n" // R1B0G0R0 -> mm4
+ "pmaddwd UR0GRX, %%mm2\n" // urR1,ugG0+urR0 -> mm2
+ "movq %%mm3, %%mm5\n" // B1G1R1B0 -> mm5
+ "pmaddwd UBG0BX, %%mm3\n" // ubB1+ugG1,ubB0 -> mm3
+ "punpckhbw %%mm6, %%mm7\n" // 00G2R2 -> mm7
+ "pmaddwd VR0GRX, %%mm4\n" // vrR1,vgG0+vrR0 -> mm4
+ "paddd %%mm1, %%mm0\n" // Y1Y0 -> mm0
+
+ "pmaddwd VBG0BX, %%mm5\n" // vbB1+vgG1,vbB0 -> mm5
+
+ "movq 8(%0),%%mm1\n" // load G2R2B1G1R1B0G0R0
+ "paddd %%mm3, %%mm2\n" // U1U0 -> mm2
+
+ "movq %%mm1, %%mm6\n" // R5B4G4R4B3G3R3B2 -> mm6
+ "punpcklbw ZEROSX, %%mm1\n" // B3G3R3B2 -> mm1
+ "paddd %%mm5, %%mm4\n" // V1V0 -> mm4
+
+ //----------------------------------------------------------------------
+
+ "movq %%mm1, %%mm5\n" // B3G3R3B2 -> mm5
+ "psllq $32, %%mm1\n" // R3B200 -> mm1
+
+ "paddd %%mm7, %%mm1\n" // R3B200+00G2R2=R3B2G2R2->mm1
+
+ "punpckhbw ZEROSX, %%mm6\n" // R5B4G4R3 -> mm6
+ "movq %%mm1, %%mm3\n" // R3B2G2R2 -> mm3
+
+ "pmaddwd YR0GRX, %%mm1\n" // yrR3,ygG2+yrR2 -> mm1
+ "movq %%mm5, %%mm7\n" // B3G3R3B2 -> mm7
+
+ "pmaddwd YBG0BX, %%mm5\n" // ybB3+ygG3,ybB2 -> mm5
+ "psrad $15, %%mm0\n" // 32-bit scaled Y1Y0 -> mm0
+
+ "movq %%mm6, %5\n" // R5B4G4R4 -> TEMP0
+ "movq %%mm3, %%mm6\n" // R3B2G2R2 -> mm6
+ "pmaddwd UR0GRX, %%mm6\n" // urR3,ugG2+urR2 -> mm6
+ "psrad $15, %%mm2\n" // 32-bit scaled U1U0 -> mm2
+
+ "paddd %%mm5, %%mm1\n" // Y3Y2 -> mm1
+ "movq %%mm7, %%mm5\n" // B3G3R3B2 -> mm5
+ "pmaddwd UBG0BX, %%mm7\n" // ubB3+ugG3,ubB2
+ "psrad $15, %%mm1\n" // 32-bit scaled Y3Y2 -> mm1
+
+ "pmaddwd VR0GRX, %%mm3\n" // vrR3,vgG2+vgR2
+ "packssdw %%mm1, %%mm0\n" // Y3Y2Y1Y0 -> mm0
+
+ "pmaddwd VBG0BX, %%mm5\n" // vbB3+vgG3,vbB2 -> mm5
+ "psrad $15, %%mm4\n" // 32-bit scaled V1V0 -> mm4
+
+ //----------------------------------------------------------------------
+
+ "movq 16(%0), %%mm1\n" // B7G7R7B6G6R6B5G5 -> mm7
+ "paddd %%mm7, %%mm6\n" // U3U2 -> mm6
+
+ "movq %%mm1, %%mm7\n" // B7G7R7B6G6R6B5G5 -> mm1
+ "psrad $15, %%mm6\n" // 32-bit scaled U3U2 -> mm6
+
+ "paddd %%mm5, %%mm3\n" // V3V2 -> mm3
+ "psllq $16, %%mm7\n" // R7B6G6R6B5G500 -> mm7
+
+ "movq %%mm7, %%mm5\n" // R7B6G6R6B5G500 -> mm5
+ "psrad $15, %%mm3\n" // 32-bit scaled V3V2 -> mm3
+
+ "movq %%mm0, 8%5\n" // 32-bit scaled Y3Y2Y1Y0 -> TEMPY
+ "packssdw %%mm6, %%mm2\n" // 32-bit scaled U3U2U1U0 -> mm2
+
+ "movq %5, %%mm0\n" // R5B4G4R4 -> mm0
+
+ "punpcklbw ZEROSX, %%mm7\n" // B5G500 -> mm7
+ "movq %%mm0, %%mm6\n" // R5B4G4R4 -> mm6
+
+ "movq %%mm2, 16%5\n" // 32-bit scaled U3U2U1U0 -> TEMPU
+ "psrlq $32, %%mm0\n" // 00R5B4 -> mm0
+
+ "paddw %%mm0, %%mm7\n" // B5G5R5B4 -> mm7
+ "movq %%mm6, %%mm2\n" // B5B4G4R4 -> mm2
+
+ "pmaddwd YR0GRX, %%mm2\n" // yrR5,ygG4+yrR4 -> mm2
+ "movq %%mm7, %%mm0\n" // B5G5R5B4 -> mm0
+
+ "pmaddwd YBG0BX, %%mm7\n" // ybB5+ygG5,ybB4 -> mm7
+ "packssdw %%mm3, %%mm4\n" // 32-bit scaled V3V2V1V0 -> mm4
+
+ //----------------------------------------------------------------------
+
+ "movq %%mm4, 24%5\n" // (V3V2V1V0)/256 -> mm4
+
+ "movq %%mm6, %%mm4\n" // B5B4G4R4 -> mm4
+
+ "pmaddwd UR0GRX, %%mm6\n" // urR5,ugG4+urR4
+ "movq %%mm0, %%mm3\n" // B5G5R5B4 -> mm0
+
+ "pmaddwd UBG0BX, %%mm0\n" // ubB5+ugG5,ubB4
+ "paddd %%mm7, %%mm2\n" // Y5Y4 -> mm2
+
+ //----------------------------------------------------------------------
+
+ "pmaddwd VR0GRX, %%mm4\n" // vrR5,vgG4+vrR4 -> mm4
+ "pxor %%mm7, %%mm7\n" // 0 -> mm7
+
+ "pmaddwd VBG0BX, %%mm3\n" // vbB5+vgG5,vbB4 -> mm3
+ "punpckhbw %%mm7, %%mm1\n" // B7G7R7B6 -> mm1
+
+ "paddd %%mm6, %%mm0\n" // U5U4 -> mm0
+ "movq %%mm1, %%mm6\n" // B7G7R7B6 -> mm6
+
+ "pmaddwd YBG0BX, %%mm6\n" // ybB7+ygG7,ybB6 -> mm6
+ "punpckhbw %%mm7, %%mm5\n" // R7B6G6R6 -> mm5
+
+ "movq %%mm5, %%mm7\n" // R7B6G6R6 -> mm7
+ "paddd %%mm4, %%mm3\n" // V5V4 -> mm3
+
+ "pmaddwd YR0GRX, %%mm5\n" // yrR7,ygG6+yrR6 -> mm5
+ "movq %%mm1, %%mm4\n" // B7G7R7B6 -> mm4
+
+ "pmaddwd UBG0BX, %%mm4\n" // ubB7+ugG7,ubB6 -> mm4
+ "psrad $15, %%mm0\n" // 32-bit scaled U5U4 -> %%mm0
+
+ //----------------------------------------------------------------------
+
+ "paddd OFFSETWX, %%mm0\n" // add offset to U5U4 -> mm0
+ "psrad $15, %%mm2\n" // 32-bit scaled Y5Y4 -> mm2
+
+ "paddd %%mm5, %%mm6\n" // Y7Y6 -> mm6
+ "movq %%mm7, %%mm5\n" // R7B6G6R6 -> mm5
+
+ "pmaddwd UR0GRX, %%mm7\n" // urR7,ugG6+ugR6 -> mm7
+ "psrad $15, %%mm3\n" // 32-bit scaled V5V4 -> mm3
+
+ "pmaddwd VBG0BX, %%mm1\n" // vbB7+vgG7,vbB6 -> mm1
+ "psrad $15, %%mm6\n" // 32-bit scaled Y7Y6 -> mm6
+
+ "paddd OFFSETDX, %%mm4\n" // add offset to U7U6
+ "packssdw %%mm6, %%mm2\n" // Y7Y6Y5Y4 -> mm2
+
+ "pmaddwd VR0GRX, %%mm5\n" // vrR7,vgG6+vrR6 -> mm5
+ "paddd %%mm4, %%mm7\n" // U7U6 -> mm7
+
+ "psrad $15, %%mm7\n" // 32-bit scaled U7U6 -> mm7
+
+ //----------------------------------------------------------------------
+
+ "movq 8%5, %%mm6\n" // 32-bit scaled Y3Y2Y1Y0 -> mm6
+ "packssdw %%mm7, %%mm0\n" // 32-bit scaled U7U6U5U4 -> mm0
+
+ "movq 16%5, %%mm4\n" // 32-bit scaled U3U2U1U0 -> mm4
+ "packuswb %%mm2, %%mm6\n" // all 8 Y values -> mm6
+
+ "movq OFFSETBX, %%mm7\n" // 128,128,128,128 -> mm7
+ "paddd %%mm5, %%mm1\n" // V7V6 -> mm1
+
+ "paddw %%mm7, %%mm4\n" // add offset to U3U2U1U0/256
+ "psrad $15, %%mm1\n" // 32-bit scaled V7V6 -> mm1
+
+ //----------------------------------------------------------------------
+
+ "movq %%mm6, (%1)\n" // store Y
+ "packuswb %%mm0, %%mm4\n" // all 8 U values -> mm4
+
+ "movq 24%5, %%mm5\n" // 32-bit scaled V3V2V1V0 -> mm5
+ "packssdw %%mm1, %%mm3\n" // V7V6V5V4 -> mm3
+ "paddw %%mm7, %%mm5\n" // add offset to V3V2V1V0
+ "paddw %%mm7, %%mm3\n" // add offset to V7V6V5V4
+
+ "movq %%mm4, (%2)\n" // store U
+ "packuswb %%mm3, %%mm5\n" // ALL 8 V values -> mm5
+
+ "movq %%mm5, (%3)\n" // store V
+
+ "sub $8, %4\n"
+ "jnz 1b\n"
+ "emms\n"
+
+ :
+ : "r" (rgb), "r" (lum), "r" (cr), "r" (cb), "m" (pixel), "m" (buf[0])
+ );
+}
+
+void rgb2yuv24bit_mmx422_row(unsigned char* rgb, unsigned char* lum, unsigned char* cr,
+ unsigned char* cb, int pixel)
+{
+ unsigned int buf[8];
+
+ // %5 = TEMP0
+ // 8%5 = TEMPY
+ // 16%5 = TEMPU
+ // 24%5 = TEMPV
+
+ __asm__ __volatile__ (
+ "1:\n"
+
+ "movq (%0), %%mm1\n" // load G2R2B1G1R1B0G0R0
+ "pxor %%mm6, %%mm6\n" // 0 -> mm6
+ "movq %%mm1, %%mm0\n" // G2R2B1G1R1B0G0R0 -> mm0
+ "psrlq $16, %%mm1\n" // 00G2R2B1G1R1B0 -> mm1
+ "punpcklbw ZEROSX, %%mm0\n" // R1B0G0R0 -> mm0
+ "movq %%mm1, %%mm7\n" // 00G2R2B1G1R1B0 -> mm7
+ "punpcklbw ZEROSX, %%mm1\n" // B1G1R1B0 -> mm1
+ "movq %%mm0, %%mm2\n" // R1B0G0R0 -> mm2
+ "pmaddwd YR0GRX, %%mm0\n" // yrR1,ygG0+yrR0 -> mm0
+
+ "movq %%mm1, %%mm3\n" // B1G1R1B0 -> mm3
+ "pmaddwd YBG0BX, %%mm1\n" // ybB1+ygG1,ybB0 -> mm1
+ "movq %%mm2, %%mm4\n" // R1B0G0R0 -> mm4
+ "pmaddwd UR0GRX, %%mm2\n" // urR1,ugG0+urR0 -> mm2
+ "movq %%mm3, %%mm5\n" // B1G1R1B0 -> mm5
+ "pmaddwd UBG0BX, %%mm3\n" // ubB1+ugG1,ubB0 -> mm3
+ "punpckhbw %%mm6, %%mm7\n" // 00G2R2 -> mm7
+ "pmaddwd VR0GRX, %%mm4\n" // vrR1,vgG0+vrR0 -> mm4
+ "paddd %%mm1, %%mm0\n" // Y1Y0 -> mm0
+
+ "pmaddwd VBG0BX, %%mm5\n" // vbB1+vgG1,vbB0 -> mm5
+
+ "movq 8(%0),%%mm1\n" // load G2R2B1G1R1B0G0R0
+ "paddd %%mm3, %%mm2\n" // U1U0 -> mm2
+
+ "movq %%mm1, %%mm6\n" // R5B4G4R4B3G3R3B2 -> mm6
+ "punpcklbw ZEROSX, %%mm1\n" // B3G3R3B2 -> mm1
+ "paddd %%mm5, %%mm4\n" // V1V0 -> mm4
+
+ //----------------------------------------------------------------------
+
+ "movq %%mm1, %%mm5\n" // B3G3R3B2 -> mm5
+ "psllq $32, %%mm1\n" // R3B200 -> mm1
+
+ "paddd %%mm7, %%mm1\n" // R3B200+00G2R2=R3B2G2R2->mm1
+
+ "punpckhbw ZEROSX, %%mm6\n" // R5B4G4R3 -> mm6
+ "movq %%mm1, %%mm3\n" // R3B2G2R2 -> mm3
+
+ "pmaddwd YR0GRX, %%mm1\n" // yrR3,ygG2+yrR2 -> mm1
+ "movq %%mm5, %%mm7\n" // B3G3R3B2 -> mm7
+
+ "pmaddwd YBG0BX, %%mm5\n" // ybB3+ygG3,ybB2 -> mm5
+ "psrad $15, %%mm0\n" // 32-bit scaled Y1Y0 -> mm0
+
+ "movq %%mm6, %5\n" // R5B4G4R4 -> TEMP0
+ "movq %%mm3, %%mm6\n" // R3B2G2R2 -> mm6
+ "pmaddwd UR0GRX, %%mm6\n" // urR3,ugG2+urR2 -> mm6
+ "psrad $15, %%mm2\n" // 32-bit scaled U1U0 -> mm2
+
+ "paddd %%mm5, %%mm1\n" // Y3Y2 -> mm1
+ "movq %%mm7, %%mm5\n" // B3G3R3B2 -> mm5
+ "pmaddwd UBG0BX, %%mm7\n" // ubB3+ugG3,ubB2
+ "psrad $15, %%mm1\n" // 32-bit scaled Y3Y2 -> mm1
+
+ "pmaddwd VR0GRX, %%mm3\n" // vrR3,vgG2+vgR2
+ "packssdw %%mm1, %%mm0\n" // Y3Y2Y1Y0 -> mm0
+
+ "pmaddwd VBG0BX, %%mm5\n" // vbB3+vgG3,vbB2 -> mm5
+ "psrad $15, %%mm4\n" // 32-bit scaled V1V0 -> mm4
+
+ //----------------------------------------------------------------------
+
+ "movq 16(%0), %%mm1\n" // B7G7R7B6G6R6B5G5 -> mm7
+ "paddd %%mm7, %%mm6\n" // U3U2 -> mm6
+
+ "movq %%mm1, %%mm7\n" // B7G7R7B6G6R6B5G5 -> mm1
+ "psrad $15, %%mm6\n" // 32-bit scaled U3U2 -> mm6
+
+ "paddd %%mm5, %%mm3\n" // V3V2 -> mm3
+ "psllq $16, %%mm7\n" // R7B6G6R6B5G500 -> mm7
+
+ "movq %%mm7, %%mm5\n" // R7B6G6R6B5G500 -> mm5
+ "psrad $15, %%mm3\n" // 32-bit scaled V3V2 -> mm3
+
+ "movq %%mm0, 8%5\n" // 32-bit scaled Y3Y2Y1Y0 -> TEMPY
+ "packssdw %%mm6, %%mm2\n" // 32-bit scaled U3U2U1U0 -> mm2
+
+ "movq %5, %%mm0\n" // R5B4G4R4 -> mm0
+
+ "punpcklbw ZEROSX, %%mm7\n" // B5G500 -> mm7
+ "movq %%mm0, %%mm6\n" // R5B4G4R4 -> mm6
+
+ "movq %%mm2, 16%5\n" // 32-bit scaled U3U2U1U0 -> TEMPU
+ "psrlq $32, %%mm0\n" // 00R5B4 -> mm0
+
+ "paddw %%mm0, %%mm7\n" // B5G5R5B4 -> mm7
+ "movq %%mm6, %%mm2\n" // B5B4G4R4 -> mm2
+
+ "pmaddwd YR0GRX, %%mm2\n" // yrR5,ygG4+yrR4 -> mm2
+ "movq %%mm7, %%mm0\n" // B5G5R5B4 -> mm0
+
+ "pmaddwd YBG0BX, %%mm7\n" // ybB5+ygG5,ybB4 -> mm7
+ "packssdw %%mm3, %%mm4\n" // 32-bit scaled V3V2V1V0 -> mm4
+
+ //----------------------------------------------------------------------
+
+ "movq %%mm4, 24%5\n" // (V3V2V1V0)/256 -> mm4
+
+ "movq %%mm6, %%mm4\n" // B5B4G4R4 -> mm4
+
+ "pmaddwd UR0GRX, %%mm6\n" // urR5,ugG4+urR4
+ "movq %%mm0, %%mm3\n" // B5G5R5B4 -> mm0
+
+ "pmaddwd UBG0BX, %%mm0\n" // ubB5+ugG5,ubB4
+ "paddd %%mm7, %%mm2\n" // Y5Y4 -> mm2
+
+ //----------------------------------------------------------------------
+
+ "pmaddwd VR0GRX, %%mm4\n" // vrR5,vgG4+vrR4 -> mm4
+ "pxor %%mm7, %%mm7\n" // 0 -> mm7
+
+ "pmaddwd VBG0BX, %%mm3\n" // vbB5+vgG5,vbB4 -> mm3
+ "punpckhbw %%mm7, %%mm1\n" // B7G7R7B6 -> mm1
+
+ "paddd %%mm6, %%mm0\n" // U5U4 -> mm0
+ "movq %%mm1, %%mm6\n" // B7G7R7B6 -> mm6
+
+ "pmaddwd YBG0BX, %%mm6\n" // ybB7+ygG7,ybB6 -> mm6
+ "punpckhbw %%mm7, %%mm5\n" // R7B6G6R6 -> mm5
+
+ "movq %%mm5, %%mm7\n" // R7B6G6R6 -> mm7
+ "paddd %%mm4, %%mm3\n" // V5V4 -> mm3
+
+ "pmaddwd YR0GRX, %%mm5\n" // yrR7,ygG6+yrR6 -> mm5
+ "movq %%mm1, %%mm4\n" // B7G7R7B6 -> mm4
+
+ "pmaddwd UBG0BX, %%mm4\n" // ubB7+ugG7,ubB6 -> mm4
+ "psrad $15, %%mm0\n" // 32-bit scaled U5U4 -> %%mm0
+
+ //----------------------------------------------------------------------
+
+ "paddd OFFSETWX, %%mm0\n" // add offset to U5U4 -> mm0
+ "psrad $15, %%mm2\n" // 32-bit scaled Y5Y4 -> mm2
+
+ "paddd %%mm5, %%mm6\n" // Y7Y6 -> mm6
+ "movq %%mm7, %%mm5\n" // R7B6G6R6 -> mm5
+
+ "pmaddwd UR0GRX, %%mm7\n" // urR7,ugG6+ugR6 -> mm7
+ "psrad $15, %%mm3\n" // 32-bit scaled V5V4 -> mm3
+
+ "pmaddwd VBG0BX, %%mm1\n" // vbB7+vgG7,vbB6 -> mm1
+ "psrad $15, %%mm6\n" // 32-bit scaled Y7Y6 -> mm6
+
+ "paddd OFFSETDX, %%mm4\n" // add offset to U7U6
+ "packssdw %%mm6, %%mm2\n" // Y7Y6Y5Y4 -> mm2
+
+ "pmaddwd VR0GRX, %%mm5\n" // vrR7,vgG6+vrR6 -> mm5
+ "paddd %%mm4, %%mm7\n" // U7U6 -> mm7
+
+ "psrad $15, %%mm7\n" // 32-bit scaled U7U6 -> mm7
+
+ //----------------------------------------------------------------------
+
+ "movq 8%5, %%mm6\n" // 32-bit scaled Y3Y2Y1Y0 -> mm6
+ "packssdw %%mm7, %%mm0\n" // 32-bit scaled U7U6U5U4 -> mm0
+
+ "movq 16%5, %%mm4\n" // 32-bit scaled U3U2U1U0 -> mm4
+ "packuswb %%mm2, %%mm6\n" // all 8 Y values -> mm6
+
+ "movq OFFSETBX, %%mm7\n" // 128,128,128,128 -> mm7
+ "paddd %%mm5, %%mm1\n" // V7V6 -> mm1
+
+ "paddw %%mm7, %%mm4\n" // add offset to U3U2U1U0/256
+ "psrad $15, %%mm1\n" // 32-bit scaled V7V6 -> mm1
+
+ //----------------------------------------------------------------------
+
+ "movq %%mm6, (%1)\n" // store Y
+ "packuswb %%mm0, %%mm4\n" // all 8 U values -> mm4
+
+ "movq 24%5, %%mm5\n" // 32-bit scaled V3V2V1V0 -> mm5
+ "packssdw %%mm1, %%mm3\n" // V7V6V5V4 -> mm3
+ "paddw %%mm7, %%mm5\n" // add offset to V3V2V1V0
+ "paddw %%mm7, %%mm3\n" // add offset to V7V6V5V4
+
+ "packuswb %%mm3, %%mm5\n" // ALL 8 V values -> mm5
+
+ // pack U and V
+ "movq CLEARX, %%mm2\n"
+ "pand %%mm2, %%mm4\n"
+ "pand %%mm2, %%mm5\n"
+
+ "packuswb %%mm5, %%mm4\n"
+
+ "movd %%mm4, (%2)\n"
+ "psrlq $32, %%mm4\n"
+ "movd %%mm4, (%3)\n"
+
+ "add $24, %0\n"
+ "add $8, %1\n"
+ "add $4, %2\n"
+ "add $4, %3\n"
+
+ "sub $8, %4\n"
+ "jnz 1b\n"
+ "emms\n"
+
+ :
+ : "r" (rgb), "r" (lum), "r" (cr), "r" (cb), "m" (pixel), "m" (buf[0])
+ );
+}
+
+void rgb2yuv32bit_mmx422_row(unsigned char* rgb, unsigned char* lum, unsigned char* cr,
+ unsigned char* cb, int pixel)
+{
+ unsigned int buf[8];
+
+ // %5 = TEMP0
+ // 8%5 = TEMPY
+ // 16%5 = TEMPU
+ // 24%5 = TEMPV
+
+ __asm__ __volatile__ (
+ "1:\n"
+
+ // pack rgb
+ // was: "movq (%0), %%mm1\n" // load G2R2B1G1R1B0G0R0
+ // ------------------------------
+ // (uses: mm0, mm1)
+ "movd 8(%0), %%mm0\n"
+ "psllq $24, %%mm0\n"
+ "movd 4(%0), %%mm1\n"
+ "por %%mm1, %%mm0\n"
+ "psllq $24, %%mm0\n"
+ "movd (%0), %%mm1\n"
+ "por %%mm0, %%mm1\n"
+ // ------------------------------
+
+ "pxor %%mm6, %%mm6\n" // 0 -> mm6
+ "movq %%mm1, %%mm0\n" // G2R2B1G1R1B0G0R0 -> mm0
+ "psrlq $16, %%mm1\n" // 00G2R2B1G1R1B0 -> mm1
+ "punpcklbw ZEROSX, %%mm0\n" // R1B0G0R0 -> mm0
+ "movq %%mm1, %%mm7\n" // 00G2R2B1G1R1B0 -> mm7
+ "punpcklbw ZEROSX, %%mm1\n" // B1G1R1B0 -> mm1
+ "movq %%mm0, %%mm2\n" // R1B0G0R0 -> mm2
+ "pmaddwd YR0GRX, %%mm0\n" // yrR1,ygG0+yrR0 -> mm0
+
+ "movq %%mm1, %%mm3\n" // B1G1R1B0 -> mm3
+ "pmaddwd YBG0BX, %%mm1\n" // ybB1+ygG1,ybB0 -> mm1
+ "movq %%mm2, %%mm4\n" // R1B0G0R0 -> mm4
+ "pmaddwd UR0GRX, %%mm2\n" // urR1,ugG0+urR0 -> mm2
+ "movq %%mm3, %%mm5\n" // B1G1R1B0 -> mm5
+ "pmaddwd UBG0BX, %%mm3\n" // ubB1+ugG1,ubB0 -> mm3
+ "punpckhbw %%mm6, %%mm7\n" // 00G2R2 -> mm7
+ "pmaddwd VR0GRX, %%mm4\n" // vrR1,vgG0+vrR0 -> mm4
+ "paddd %%mm1, %%mm0\n" // Y1Y0 -> mm0
+
+ "pmaddwd VBG0BX, %%mm5\n" // vbB1+vgG1,vbB0 -> mm5
+
+ // pack rgb
+ // was: "movq 8(%0),%%mm1\n" // R5B4G4R4B3G3R3B2 -> mm1
+ // ------------------------------
+ // (uses: mm1, mm6)
+ "movd 20(%0), %%mm1\n"
+ "psllq $24, %%mm1\n"
+ "movd 16(%0), %%mm6\n"
+ "por %%mm6, %%mm1\n"
+ "psllq $24, %%mm1\n"
+ "movd 12(%0), %%mm6\n"
+ "por %%mm6, %%mm1\n"
+ "psllq $8, %%mm1\n"
+ "movd 8(%0), %%mm6\n"
+ "psrlq $16, %%mm6\n"
+ "por %%mm6, %%mm1\n"
+ // ------------------------------
+
+ "paddd %%mm3, %%mm2\n" // U1U0 -> mm2
+
+ "movq %%mm1, %%mm6\n" // R5B4G4R4B3G3R3B2 -> mm6
+ "punpcklbw ZEROSX, %%mm1\n" // B3G3R3B2 -> mm1
+ "paddd %%mm5, %%mm4\n" // V1V0 -> mm4
+
+ //----------------------------------------------------------------------
+
+ "movq %%mm1, %%mm5\n" // B3G3R3B2 -> mm5
+ "psllq $32, %%mm1\n" // R3B200 -> mm1
+
+ "paddd %%mm7, %%mm1\n" // R3B200+00G2R2=R3B2G2R2->mm1
+
+ "punpckhbw ZEROSX, %%mm6\n" // R5B4G4R3 -> mm6
+ "movq %%mm1, %%mm3\n" // R3B2G2R2 -> mm3
+
+ "pmaddwd YR0GRX, %%mm1\n" // yrR3,ygG2+yrR2 -> mm1
+ "movq %%mm5, %%mm7\n" // B3G3R3B2 -> mm7
+
+ "pmaddwd YBG0BX, %%mm5\n" // ybB3+ygG3,ybB2 -> mm5
+ "psrad $15, %%mm0\n" // 32-bit scaled Y1Y0 -> mm0
+
+ "movq %%mm6, %5\n" // R5B4G4R4 -> TEMP0
+ "movq %%mm3, %%mm6\n" // R3B2G2R2 -> mm6
+ "pmaddwd UR0GRX, %%mm6\n" // urR3,ugG2+urR2 -> mm6
+ "psrad $15, %%mm2\n" // 32-bit scaled U1U0 -> mm2
+
+ "paddd %%mm5, %%mm1\n" // Y3Y2 -> mm1
+ "movq %%mm7, %%mm5\n" // B3G3R3B2 -> mm5
+ "pmaddwd UBG0BX, %%mm7\n" // ubB3+ugG3,ubB2
+ "psrad $15, %%mm1\n" // 32-bit scaled Y3Y2 -> mm1
+
+ "pmaddwd VR0GRX, %%mm3\n" // vrR3,vgG2+vgR2
+ "packssdw %%mm1, %%mm0\n" // Y3Y2Y1Y0 -> mm0
+
+ "pmaddwd VBG0BX, %%mm5\n" // vbB3+vgG3,vbB2 -> mm5
+ "psrad $15, %%mm4\n" // 32-bit scaled V1V0 -> mm4
+
+ //----------------------------------------------------------------------
+
+ "paddd %%mm7, %%mm6\n" // U3U2 -> mm6
+
+ // pack rgb
+ // was: "movq 16(%0), %%mm1\n" // B7G7R7B6G6R6B5G5 -> mm1
+ // ------------------------------
+ // (uses: mm1, mm7)
+ "movd 28(%0), %%mm1\n"
+ "psllq $24, %%mm1\n"
+ "movd 24(%0), %%mm7\n"
+ "por %%mm7, %%mm1\n"
+ "psllq $16, %%mm1\n"
+ "movd 20(%0), %%mm7\n"
+ "psrlq $8, %%mm7\n"
+ "por %%mm7, %%mm1\n"
+ // ------------------------------
+
+ "movq %%mm1, %%mm7\n" // B7G7R7B6G6R6B5G5 -> mm1
+ "psrad $15, %%mm6\n" // 32-bit scaled U3U2 -> mm6
+
+ "paddd %%mm5, %%mm3\n" // V3V2 -> mm3
+ "psllq $16, %%mm7\n" // R7B6G6R6B5G500 -> mm7
+
+ "movq %%mm7, %%mm5\n" // R7B6G6R6B5G500 -> mm5
+ "psrad $15, %%mm3\n" // 32-bit scaled V3V2 -> mm3
+
+ "movq %%mm0, 8%5\n" // 32-bit scaled Y3Y2Y1Y0 -> TEMPY
+
+ "packssdw %%mm6, %%mm2\n" // 32-bit scaled U3U2U1U0 -> mm2
+
+ "movq %5, %%mm0\n" // R5B4G4R4 -> mm0
+
+ "punpcklbw ZEROSX, %%mm7\n" // B5G500 -> mm7
+ "movq %%mm0, %%mm6\n" // R5B4G4R4 -> mm6
+
+ "movq %%mm2, 16%5\n" // 32-bit scaled U3U2U1U0 -> TEMPU
+ "psrlq $32, %%mm0\n" // 00R5B4 -> mm0
+
+ "paddw %%mm0, %%mm7\n" // B5G5R5B4 -> mm7
+ "movq %%mm6, %%mm2\n" // B5B4G4R4 -> mm2
+
+ "pmaddwd YR0GRX, %%mm2\n" // yrR5,ygG4+yrR4 -> mm2
+ "movq %%mm7, %%mm0\n" // B5G5R5B4 -> mm0
+
+ "pmaddwd YBG0BX, %%mm7\n" // ybB5+ygG5,ybB4 -> mm7
+ "packssdw %%mm3, %%mm4\n" // 32-bit scaled V3V2V1V0 -> mm4
+
+ //----------------------------------------------------------------------
+
+ "movq %%mm4, 24%5\n" // (V3V2V1V0)/256 -> mm4
+
+ "movq %%mm6, %%mm4\n" // B5B4G4R4 -> mm4
+
+ "pmaddwd UR0GRX, %%mm6\n" // urR5,ugG4+urR4
+ "movq %%mm0, %%mm3\n" // B5G5R5B4 -> mm0
+
+ "pmaddwd UBG0BX, %%mm0\n" // ubB5+ugG5,ubB4
+ "paddd %%mm7, %%mm2\n" // Y5Y4 -> mm2
+
+ //----------------------------------------------------------------------
+
+ "pmaddwd VR0GRX, %%mm4\n" // vrR5,vgG4+vrR4 -> mm4
+ "pxor %%mm7, %%mm7\n" // 0 -> mm7
+
+ "pmaddwd VBG0BX, %%mm3\n" // vbB5+vgG5,vbB4 -> mm3
+ "punpckhbw %%mm7, %%mm1\n" // B7G7R7B6 -> mm1
+
+ "paddd %%mm6, %%mm0\n" // U5U4 -> mm0
+ "movq %%mm1, %%mm6\n" // B7G7R7B6 -> mm6
+
+ "pmaddwd YBG0BX, %%mm6\n" // ybB7+ygG7,ybB6 -> mm6
+ "punpckhbw %%mm7, %%mm5\n" // R7B6G6R6 -> mm5
+
+ "movq %%mm5, %%mm7\n" // R7B6G6R6 -> mm7
+ "paddd %%mm4, %%mm3\n" // V5V4 -> mm3
+
+ "pmaddwd YR0GRX, %%mm5\n" // yrR7,ygG6+yrR6 -> mm5
+ "movq %%mm1, %%mm4\n" // B7G7R7B6 -> mm4
+
+ "pmaddwd UBG0BX, %%mm4\n" // ubB7+ugG7,ubB6 -> mm4
+ "psrad $15, %%mm0\n" // 32-bit scaled U5U4 -> %%mm0
+
+ //----------------------------------------------------------------------
+
+ "paddd OFFSETWX, %%mm0\n" // add offset to U5U4 -> mm0
+ "psrad $15, %%mm2\n" // 32-bit scaled Y5Y4 -> mm2
+
+ "paddd %%mm5, %%mm6\n" // Y7Y6 -> mm6
+ "movq %%mm7, %%mm5\n" // R7B6G6R6 -> mm5
+
+ "pmaddwd UR0GRX, %%mm7\n" // urR7,ugG6+ugR6 -> mm7
+ "psrad $15, %%mm3\n" // 32-bit scaled V5V4 -> mm3
+
+ "pmaddwd VBG0BX, %%mm1\n" // vbB7+vgG7,vbB6 -> mm1
+ "psrad $15, %%mm6\n" // 32-bit scaled Y7Y6 -> mm6
+
+ "paddd OFFSETDX, %%mm4\n" // add offset to U7U6
+ "packssdw %%mm6, %%mm2\n" // Y7Y6Y5Y4 -> mm2
+
+ "pmaddwd VR0GRX, %%mm5\n" // vrR7,vgG6+vrR6 -> mm5
+ "paddd %%mm4, %%mm7\n" // U7U6 -> mm7
+
+ "psrad $15, %%mm7\n" // 32-bit scaled U7U6 -> mm7
+
+ //----------------------------------------------------------------------
+
+ "movq 8%5, %%mm6\n" // 32-bit scaled Y3Y2Y1Y0 -> mm6
+ "packssdw %%mm7, %%mm0\n" // 32-bit scaled U7U6U5U4 -> mm0
+
+ "movq 16%5, %%mm4\n" // 32-bit scaled U3U2U1U0 -> mm4
+ "packuswb %%mm2, %%mm6\n" // all 8 Y values -> mm6
+
+ "movq OFFSETBX, %%mm7\n" // 128,128,128,128 -> mm7
+ "paddd %%mm5, %%mm1\n" // V7V6 -> mm1
+
+ "paddw %%mm7, %%mm4\n" // add offset to U3U2U1U0/256
+ "psrad $15, %%mm1\n" // 32-bit scaled V7V6 -> mm1
+
+ //----------------------------------------------------------------------
+
+ "movq %%mm6, (%1)\n" // store Y
+
+ "packuswb %%mm0, %%mm4\n" // all 8 U values -> mm4
+ "movq 24%5, %%mm5\n" // 32-bit scaled V3V2V1V0 -> mm5
+
+ "packssdw %%mm1, %%mm3\n" // V7V6V5V4 -> mm3
+ "paddw %%mm7, %%mm5\n" // add offset to V3V2V1V0
+ "paddw %%mm7, %%mm3\n" // add offset to V7V6V5V4
+
+ "packuswb %%mm3, %%mm5\n" // ALL 8 V values -> mm5
+
+ "movq CLEARX, %%mm2\n"
+ "pand %%mm2, %%mm4\n"
+ "pand %%mm2, %%mm5\n"
+
+ "packuswb %%mm5, %%mm4\n"
+
+ "movd %%mm4, (%2)\n"
+ "psrlq $32, %%mm4\n"
+ "movd %%mm4, (%3)\n"
+
+ "add $32, %0\n"
+ "add $8, %1\n"
+ "add $4, %2\n"
+ "add $4, %3\n"
+
+ "sub $8, %4\n"
+ "jnz 1b\n"
+
+ "emms\n"
+
+ :
+ : "r" (rgb), "r" (lum), "r" (cr), "r" (cb), "m" (pixel), "m" (buf[0])
+
+ );
+}
+
+void rgb2y24bit_mmx_row(unsigned char* rgbSource, unsigned char* lum, int pixel)
+{
+ unsigned int buf[4];
+
+ // %3 = TEMP0
+ // 8%3 = TEMPY
+
+ __asm__ __volatile__ (
+ "1:\n"
+
+ "movq (%0), %%mm1\n" // load G2R2B1G1R1B0G0R0
+ "pxor %%mm6, %%mm6\n" // 0 -> mm6
+ "movq %%mm1, %%mm0\n" // G2R2B1G1R1B0G0R0 -> mm0
+ "psrlq $16, %%mm1\n" // 00G2R2B1G1R1B0 -> mm1
+ "punpcklbw ZEROSX, %%mm0\n" // R1B0G0R0 -> mm0
+ "movq %%mm1, %%mm7\n" // 00G2R2B1G1R1B0 -> mm7
+ "punpcklbw ZEROSX, %%mm1\n" // B1G1R1B0 -> mm1
+ "movq %%mm0, %%mm2\n" // R1B0G0R0 -> mm2
+ "pmaddwd YR0GRX, %%mm0\n" // yrR1,ygG0+yrR0 -> mm0
+ "movq %%mm1, %%mm3\n" // B1G1R1B0 -> mm3
+ "pmaddwd YBG0BX, %%mm1\n" // ybB1+ygG1,ybB0 -> mm1
+ "movq %%mm2, %%mm4\n" // R1B0G0R0 -> mm4
+ "movq %%mm3, %%mm5\n" // B1G1R1B0 -> mm5
+ "punpckhbw %%mm6, %%mm7\n" // 00G2R2 -> mm7
+ "paddd %%mm1, %%mm0\n" // Y1Y0 -> mm0
+
+ "movq 8(%0),%%mm1\n" // load G2R2B1G1R1B0G0R0
+
+ "movq %%mm1, %%mm6\n" // R5B4G4R4B3G3R3B2 -> mm6
+ "punpcklbw ZEROSX, %%mm1\n" // B3G3R3B2 -> mm1
+
+ //----------------------------------------------------------------------
+
+ "movq %%mm1, %%mm5\n" // B3G3R3B2 -> mm5
+ "psllq $32, %%mm1\n" // R3B200 -> mm1
+
+ "paddd %%mm7, %%mm1\n" // R3B200+00G2R2=R3B2G2R2->mm1
+
+ "punpckhbw ZEROSX, %%mm6\n" // R5B4G4R3 -> mm6
+ "movq %%mm1, %%mm3\n" // R3B2G2R2 -> mm3
+
+ "pmaddwd YR0GRX, %%mm1\n" // yrR3,ygG2+yrR2 -> mm1
+ "movq %%mm5, %%mm7\n" // B3G3R3B2 -> mm7
+
+ "pmaddwd YBG0BX, %%mm5\n" // ybB3+ygG3,ybB2 -> mm5
+ "psrad $15, %%mm0\n" // 32-bit scaled Y1Y0 -> mm0
+
+ "movq %%mm6, %3\n" // R5B4G4R4 -> TEMP0
+ "movq %%mm3, %%mm6\n" // R3B2G2R2 -> mm6
+
+ "paddd %%mm5, %%mm1\n" // Y3Y2 -> mm1
+ "movq %%mm7, %%mm5\n" // B3G3R3B2 -> mm5
+ "psrad $15, %%mm1\n" // 32-bit scaled Y3Y2 -> mm1
+
+ "packssdw %%mm1, %%mm0\n" // Y3Y2Y1Y0 -> mm0
+
+ //----------------------------------------------------------------------
+
+ "movq 16(%0), %%mm1\n" // B7G7R7B6G6R6B5G5 -> mm7
+
+ "movq %%mm1, %%mm7\n" // B7G7R7B6G6R6B5G5 -> mm1
+
+ "psllq $16, %%mm7\n" // R7B6G6R6B5G500 -> mm7
+
+ "movq %%mm7, %%mm5\n" // R7B6G6R6B5G500 -> mm5
+
+ "movq %%mm0, 8%3\n" // 32-bit scaled Y3Y2Y1Y0 -> TEMPY
+
+ "movq %3, %%mm0\n" // R5B4G4R4 -> mm0
+
+ "punpcklbw ZEROSX, %%mm7\n" // B5G500 -> mm7
+ "movq %%mm0, %%mm6\n" // R5B4G4R4 -> mm6
+
+ "psrlq $32, %%mm0\n" // 00R5B4 -> mm0
+
+ "paddw %%mm0, %%mm7\n" // B5G5R5B4 -> mm7
+ "movq %%mm6, %%mm2\n" // B5B4G4R4 -> mm2
+
+ "pmaddwd YR0GRX, %%mm2\n" // yrR5,ygG4+yrR4 -> mm2
+
+ "pmaddwd YBG0BX, %%mm7\n" // ybB5+ygG5,ybB4 -> mm7
+
+ //----------------------------------------------------------------------
+ "paddd %%mm7, %%mm2\n" // Y5Y4 -> mm2
+
+ //----------------------------------------------------------------------
+
+ "pxor %%mm7, %%mm7\n" // 0 -> mm7
+
+ "punpckhbw %%mm7, %%mm1\n" // B7G7R7B6 -> mm1
+
+ "movq %%mm1, %%mm6\n" // B7G7R7B6 -> mm6
+
+ "pmaddwd YBG0BX, %%mm6\n" // ybB7+ygG7,ybB6 -> mm6
+ "punpckhbw %%mm7, %%mm5\n" // R7B6G6R6 -> mm5
+
+ "pmaddwd YR0GRX, %%mm5\n" // yrR7,ygG6+yrR6 -> mm5
+
+ //----------------------------------------------------------------------
+
+ "psrad $15, %%mm2\n" // 32-bit scaled Y5Y4 -> mm2
+
+ "paddd %%mm5, %%mm6\n" // Y7Y6 -> mm6
+ "psrad $15, %%mm6\n" // 32-bit scaled Y7Y6 -> mm6
+
+ "packssdw %%mm6, %%mm2\n" // Y7Y6Y5Y4 -> mm2
+
+ //----------------------------------------------------------------------
+
+ "movq 8%3, %%mm6\n" // 32-bit scaled Y3Y2Y1Y0 -> mm6
+ "packuswb %%mm2, %%mm6\n" // all 8 Y values -> mm6
+
+ //----------------------------------------------------------------------
+
+ "movq %%mm6, (%1)\n" // store Y
+
+ "add $24, %0\n"
+ "add $8, %1\n"
+
+ "sub $8, %2\n"
+ "jnz 1b\n"
+ "emms\n"
+
+ :
+ : "r" (rgbSource), "r" (lum), "m" (pixel), "m" (buf[0])
+
+ );
+}
+
+void rgb2y32bit_mmx_row(unsigned char* rgbSource, unsigned char* lum, int pixel)
+{
+ unsigned int buf[4];
+
+ // %3 = TEMP0
+ // 8%3 = TEMPY
+
+ __asm__ __volatile__ (
+ "1:\n"
+
+ // pack rgb
+ // was: "movq (%0), %%mm1\n" // load G2R2B1G1R1B0G0R0
+ // ------------------------------
+ // (uses: mm0, mm1)
+ "movd 8(%0), %%mm0\n"
+ "psllq $24, %%mm0\n"
+ "movd 4(%0), %%mm1\n"
+ "por %%mm1, %%mm0\n"
+ "psllq $24, %%mm0\n"
+ "movd (%0), %%mm1\n"
+ "por %%mm0, %%mm1\n"
+ // ------------------------------
+
+ "pxor %%mm6, %%mm6\n" // 0 -> mm6
+ "movq %%mm1, %%mm0\n" // G2R2B1G1R1B0G0R0 -> mm0
+ "psrlq $16, %%mm1\n" // 00G2R2B1G1R1B0 -> mm1
+ "punpcklbw ZEROSX, %%mm0\n" // R1B0G0R0 -> mm0
+ "movq %%mm1, %%mm7\n" // 00G2R2B1G1R1B0 -> mm7
+ "punpcklbw ZEROSX, %%mm1\n" // B1G1R1B0 -> mm1
+ "movq %%mm0, %%mm2\n" // R1B0G0R0 -> mm2
+ "pmaddwd YR0GRX, %%mm0\n" // yrR1,ygG0+yrR0 -> mm0
+ "movq %%mm1, %%mm3\n" // B1G1R1B0 -> mm3
+ "pmaddwd YBG0BX, %%mm1\n" // ybB1+ygG1,ybB0 -> mm1
+ "movq %%mm2, %%mm4\n" // R1B0G0R0 -> mm4
+ "movq %%mm3, %%mm5\n" // B1G1R1B0 -> mm5
+ "punpckhbw %%mm6, %%mm7\n" // 00G2R2 -> mm7
+ "paddd %%mm1, %%mm0\n" // Y1Y0 -> mm0
+
+ // pack rgb
+ // was: "movq 8(%0),%%mm1\n" // R5B4G4R4B3G3R3B2 -> mm1
+ // ------------------------------
+ // (uses: mm1, mm6)
+ "movd 20(%0), %%mm1\n"
+ "psllq $24, %%mm1\n"
+ "movd 16(%0), %%mm6\n"
+ "por %%mm6, %%mm1\n"
+ "psllq $24, %%mm1\n"
+ "movd 12(%0), %%mm6\n"
+ "por %%mm6, %%mm1\n"
+ "psllq $8, %%mm1\n"
+ "movd 8(%0), %%mm6\n"
+ "psrlq $16, %%mm6\n"
+ "por %%mm6, %%mm1\n"
+ // ------------------------------
+
+ "movq %%mm1, %%mm6\n" // R5B4G4R4B3G3R3B2 -> mm6
+ "punpcklbw ZEROSX, %%mm1\n" // B3G3R3B2 -> mm1
+
+ //----------------------------------------------------------------------
+
+ "movq %%mm1, %%mm5\n" // B3G3R3B2 -> mm5
+ "psllq $32, %%mm1\n" // R3B200 -> mm1
+
+ "paddd %%mm7, %%mm1\n" // R3B200+00G2R2=R3B2G2R2->mm1
+
+ "punpckhbw ZEROSX, %%mm6\n" // R5B4G4R3 -> mm6
+ "movq %%mm1, %%mm3\n" // R3B2G2R2 -> mm3
+
+ "pmaddwd YR0GRX, %%mm1\n" // yrR3,ygG2+yrR2 -> mm1
+ "movq %%mm5, %%mm7\n" // B3G3R3B2 -> mm7
+
+ "pmaddwd YBG0BX, %%mm5\n" // ybB3+ygG3,ybB2 -> mm5
+ "psrad $15, %%mm0\n" // 32-bit scaled Y1Y0 -> mm0
+
+ "movq %%mm6, %3\n" // R5B4G4R4 -> TEMP0
+ "movq %%mm3, %%mm6\n" // R3B2G2R2 -> mm6
+
+ "paddd %%mm5, %%mm1\n" // Y3Y2 -> mm1
+ "movq %%mm7, %%mm5\n" // B3G3R3B2 -> mm5
+ "psrad $15, %%mm1\n" // 32-bit scaled Y3Y2 -> mm1
+
+ "packssdw %%mm1, %%mm0\n" // Y3Y2Y1Y0 -> mm0
+
+ //----------------------------------------------------------------------
+
+ // pack rgb
+ // was: "movq 16(%0), %%mm1\n" // B7G7R7B6G6R6B5G5 -> mm1
+ // ------------------------------
+ // (uses: mm1, mm7)
+ "movd 28(%0), %%mm1\n"
+ "psllq $24, %%mm1\n"
+ "movd 24(%0), %%mm7\n"
+ "por %%mm7, %%mm1\n"
+ "psllq $16, %%mm1\n"
+ "movd 20(%0), %%mm7\n"
+ "psrlq $8, %%mm7\n"
+ "por %%mm7, %%mm1\n"
+ // ------------------------------
+
+ "movq %%mm1, %%mm7\n" // B7G7R7B6G6R6B5G5 -> mm1
+
+ "psllq $16, %%mm7\n" // R7B6G6R6B5G500 -> mm7
+
+ "movq %%mm7, %%mm5\n" // R7B6G6R6B5G500 -> mm5
+
+ "movq %%mm0, 8%3\n" // 32-bit scaled Y3Y2Y1Y0 -> TEMPY
+
+ "movq %3, %%mm0\n" // R5B4G4R4 -> mm0
+
+ "punpcklbw ZEROSX, %%mm7\n" // B5G500 -> mm7
+ "movq %%mm0, %%mm6\n" // R5B4G4R4 -> mm6
+
+ "psrlq $32, %%mm0\n" // 00R5B4 -> mm0
+
+ "paddw %%mm0, %%mm7\n" // B5G5R5B4 -> mm7
+ "movq %%mm6, %%mm2\n" // B5B4G4R4 -> mm2
+
+ "pmaddwd YR0GRX, %%mm2\n" // yrR5,ygG4+yrR4 -> mm2
+
+ "pmaddwd YBG0BX, %%mm7\n" // ybB5+ygG5,ybB4 -> mm7
+
+ //----------------------------------------------------------------------
+ "paddd %%mm7, %%mm2\n" // Y5Y4 -> mm2
+
+ //----------------------------------------------------------------------
+
+ "pxor %%mm7, %%mm7\n" // 0 -> mm7
+
+ "punpckhbw %%mm7, %%mm1\n" // B7G7R7B6 -> mm1
+
+ "movq %%mm1, %%mm6\n" // B7G7R7B6 -> mm6
+
+ "pmaddwd YBG0BX, %%mm6\n" // ybB7+ygG7,ybB6 -> mm6
+ "punpckhbw %%mm7, %%mm5\n" // R7B6G6R6 -> mm5
+
+ "pmaddwd YR0GRX, %%mm5\n" // yrR7,ygG6+yrR6 -> mm5
+
+ //----------------------------------------------------------------------
+
+ "psrad $15, %%mm2\n" // 32-bit scaled Y5Y4 -> mm2
+
+ "paddd %%mm5, %%mm6\n" // Y7Y6 -> mm6
+ "psrad $15, %%mm6\n" // 32-bit scaled Y7Y6 -> mm6
+
+ "packssdw %%mm6, %%mm2\n" // Y7Y6Y5Y4 -> mm2
+
+ //----------------------------------------------------------------------
+
+ "movq 8%3, %%mm6\n" // 32-bit scaled Y3Y2Y1Y0 -> mm6
+ "packuswb %%mm2, %%mm6\n" // all 8 Y values -> mm6
+
+ //----------------------------------------------------------------------
+
+ "movq %%mm6, (%1)\n" // store Y
+
+ "add $32, %0\n"
+ "add $8, %1\n"
+
+ "sub $8, %2\n"
+ "jnz 1b\n"
+ "emms\n"
+
+ :
+ : "r" (rgbSource), "r" (lum), "r" (pixel), "m" (buf[0])
+
+ );
+}
+
+#endif
+// INTEL
+
diff --git a/mpeglib/lib/util/render/dither2YUV/rgb2yuv32.h b/mpeglib/lib/util/render/dither2YUV/rgb2yuv32.h
new file mode 100644
index 00000000..75fea27f
--- /dev/null
+++ b/mpeglib/lib/util/render/dither2YUV/rgb2yuv32.h
@@ -0,0 +1,93 @@
+/***************************************************************************
+ rgb2yuv32.h - description
+ -------------------
+ begin : Tue Nov 2 2000
+ copyright : (C) 2000 by Christian Gerlach
+ email : cgerlach@rhrk.uni-kl.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef _RGB2YUV32_H_
+#define _RGB2YUV32_H_
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "../yuvPicture.h"
+#include "rgb2yuvdefs.h"
+
+void rgb2yuv32(unsigned char* rgb, unsigned char* dest);
+
+// slow C rountines
+void rgb2yuv24bit(unsigned char* rgbSource,
+ unsigned char* lum,
+ unsigned char* cr,
+ unsigned char* cb,int height, int width);
+
+void rgb2yuv32bit(unsigned char* rgbSource,
+ unsigned char* lum,
+ unsigned char* cr,
+ unsigned char* cb,int height, int width);
+
+
+
+
+#ifndef INTEL
+void rgb2yuv24bit_mmx(unsigned char* rgbSource,
+ unsigned char* lum,
+ unsigned char* cr,
+ unsigned char* cb,int height, int width);
+
+void rgb2yuv32bit_mmx(unsigned char* rgbSource,
+ unsigned char* lum,
+ unsigned char* cr,
+ unsigned char* cb,int height, int width);
+#endif
+
+
+#ifdef INTEL
+
+void rgb2yuv24bit_mmx(unsigned char* rgbSource,
+ unsigned char* lum,
+ unsigned char* cr,
+ unsigned char* cb,int height, int width);
+
+void rgb2yuv32bit_mmx(unsigned char* rgbSource,
+ unsigned char* lum,
+ unsigned char* cr,
+ unsigned char* cb,int height, int width);
+
+
+void rgb2yuv24bit_mmx444_row(unsigned char* rgb,
+ unsigned char* lum, unsigned char* cr,
+ unsigned char* cb, int pixel);
+
+
+void rgb2yuv24bit_mmx422_row(unsigned char* rgb,
+ unsigned char* lum, unsigned char* cr,
+ unsigned char* cb, int pixel);
+
+void rgb2yuv32bit_mmx422_row(unsigned char* rgb,
+ unsigned char* lum, unsigned char* cr,
+ unsigned char* cb, int pixel);
+
+void rgb2y24bit_mmx_row(unsigned char* rgbSource,
+ unsigned char* lum, int pixel);
+
+void rgb2y32bit_mmx_row(unsigned char* rgbSource,
+ unsigned char* lum, int pixel);
+
+#endif
+//INTEL
+
+
+#endif
diff --git a/mpeglib/lib/util/render/dither2YUV/rgb2yuvdefs.h b/mpeglib/lib/util/render/dither2YUV/rgb2yuvdefs.h
new file mode 100644
index 00000000..5c7ae574
--- /dev/null
+++ b/mpeglib/lib/util/render/dither2YUV/rgb2yuvdefs.h
@@ -0,0 +1,74 @@
+/***************************************************************************
+ rgb2yuvdefs.h - description
+ -------------------
+ begin : Tue Nov 2 2000
+ copyright : (C) 2000 by Christian Gerlach
+ email : cgerlach@rhrk.uni-kl.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef __RGB2YUVDEFS_H
+#define __RGB2YUVDEFS_H
+
+/* gcc 3.3.1 and later optimise the "not used" (only in asm code)
+ symbols away. So we need to mark them as used. */
+#if defined(__GNUC_PREREQ__) && !defined(__GNUC_PREREQ)
+#define __GNUC_PREREQ __GNUC_PREREQ__
+#endif
+#ifdef __GNUC_PREREQ
+#if __GNUC_PREREQ (3,1)
+# define __attribute_used__ __attribute__ ((__used__))
+#else
+# define __attribute_used__
+#endif
+#else
+# define __attribute_used__
+#endif
+
+// hicolor mode (16 bit) with r(5) g(6) b(5) bits (reverse order b, g, r)
+#define RED(rgb) (unsigned char) ((rgb) << 3)
+#define GREEN(rgb) (((rgb) & 0x7e0) >> 3)
+#define BLUE(rgb) (((rgb) & 0xf800) >> 8)
+
+#define YUV_SHIFT 15
+#define YUV_HALF (1<<(YUV_SHIFT-1))
+#define YUV_ONE (1<<YUV_SHIFT)
+#define Y_R ((int)( 0.299 * YUV_ONE ))
+#define Y_G ((int)( 0.587 * YUV_ONE ))
+#define Y_B ((int)( 0.114 * YUV_ONE ))
+#define U_R ((int)(-0.146 * YUV_ONE ))
+#define U_G ((int)(-0.288 * YUV_ONE ))
+#define U_B ((int)( 0.434 * YUV_ONE ))
+#define V_R ((int)( 0.617 * YUV_ONE ))
+#define V_G ((int)(-0.517 * YUV_ONE ))
+#define V_B ((int)(-0.100 * YUV_ONE ))
+
+#define Y_RGB(R,G,B) (( Y_R * (R) + Y_G * (G) + Y_B * (B)) >> YUV_SHIFT)
+#define U_RGB(R,G,B) ((( U_R * (R) + U_G * (G) + U_B * (B)) >> YUV_SHIFT) + 128)
+#define V_RGB(R,G,B) ((( V_R * (R) + V_G * (G) + V_B * (B)) >> YUV_SHIFT) + 128)
+
+static unsigned char __attribute_used__ CLEARX[8] = { 255, 0, 255, 0, 255, 0, 255, 0 };
+static short __attribute_used__ ZEROSX[4] = { 0, 0, 0, 0 };
+
+static short __attribute_used__ OFFSETDX[4] = { 0, 64, 0, 64 };
+static short __attribute_used__ OFFSETWX[4] = { 128, 0, 128, 0 };
+static short __attribute_used__ OFFSETBX[4] = { 128, 128, 128, 128 };
+
+static short __attribute_used__ YR0GRX[4] = { Y_R, Y_G, 0, Y_R };
+static short __attribute_used__ YBG0BX[4] = { Y_B, 0, Y_G, Y_B };
+
+static short __attribute_used__ UR0GRX[4] = { U_R, U_G, 0, U_R };
+static short __attribute_used__ UBG0BX[4] = { U_B, 0, U_G, U_B };
+
+static short __attribute_used__ VR0GRX[4] = { V_R, V_G, 0, V_R };
+static short __attribute_used__ VBG0BX[4] = { V_B, 0, V_G, V_B };
+
+#endif
diff --git a/mpeglib/lib/util/render/imageBase.cpp b/mpeglib/lib/util/render/imageBase.cpp
new file mode 100644
index 00000000..040486ea
--- /dev/null
+++ b/mpeglib/lib/util/render/imageBase.cpp
@@ -0,0 +1,76 @@
+/*
+ base clase for X11 images (stores important parameters and dither pic)
+ 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 "imageBase.h"
+
+#include <iostream>
+
+using namespace std;
+
+ImageBase::ImageBase() {
+ identifier = NULL;
+}
+
+
+ImageBase::~ImageBase() {
+ if (identifier != NULL)
+ delete [] identifier;
+}
+
+void ImageBase::init(XWindow* xWindow, YUVPicture*)
+{
+ cout << "direct virtual call: ImageBase::init "<<endl;
+}
+
+int ImageBase::support() {
+ cout << "direct virtual call: ImageBase::support "<<endl;
+ return false;
+}
+
+int ImageBase::openImage(int) {
+ cout << "direct virtual call: ImageBase::openImage "<<endl;
+ return false;
+}
+
+
+int ImageBase::closeImage(){
+ cout << "direct virtual call: ImageBase::closeImage "<<endl;
+ return false;
+}
+
+void ImageBase::ditherImage(YUVPicture*) {
+ cout << "direct virtual call: ImageBase::ditherImage "<<endl;
+}
+
+
+void ImageBase::putImage() {
+ cout << "direct virtual call: ImageBase::putImage "<<endl;
+}
+
+void ImageBase::putImage(int ,int ) {
+ cout << "direct virtual call: ImageBase::putImage(w,h) "<<endl;
+}
+
+void ImageBase::setIdentifier(const char *id)
+{
+ if (identifier != NULL)
+ delete [] identifier;
+
+ identifier = new char [strlen(id) + 1];
+ strcpy(identifier, id);
+}
+
+char *ImageBase::getIdentifier()
+{
+ return identifier;
+}
diff --git a/mpeglib/lib/util/render/imageBase.h b/mpeglib/lib/util/render/imageBase.h
new file mode 100644
index 00000000..e1f7ae8c
--- /dev/null
+++ b/mpeglib/lib/util/render/imageBase.h
@@ -0,0 +1,140 @@
+/*
+ base clase for X11 images (stores important parameters and dither pic)
+ 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 __IMAGEBASE_H
+#define __IMAGEBASE_H
+
+
+#include <stdio.h>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+
+#include "yuvPicture.h"
+#include "dither/ditherWrapper.h"
+
+
+
+#define _IMAGE_NONE 0
+#define _IMAGE_DESK 1
+#define _IMAGE_FULL 2
+#define _IMAGE_DOUBLE 4
+#define _IMAGE_RESIZE 8
+#define _IMAGE_DISABLED 16
+
+
+#define HAS_DESK(image) ((((image)->supportedModes) & _IMAGE_DESK) > 0)
+#define HAS_FULL(image) ((((image)->supportedModes) & _IMAGE_FULL) > 0)
+#define HAS_DOUBLE(image) ((((image)->supportedModes) & _IMAGE_DOUBLE) > 0)
+#define HAS_RESIZE(image) ((((image)->supportedModes) & _IMAGE_RESIZE) > 0)
+#define IS_DISABLED(image) ((((image)->supportedModes) & _IMAGE_DISABLED) > 0)
+
+#define IS_DESK(mode) (((mode) & _IMAGE_DESK) > 0)
+#define IS_FULL(mode) (((mode) & _IMAGE_FULL) > 0)
+#define IS_DOUBLE(mode) (((mode) & _IMAGE_DOUBLE) > 0)
+#define IS_RESIZEABLE(mode) (((mode) & _IMAGE_RESIZE) > 0)
+
+
+/**
+ This class creates from a given X11 Window a special image to
+ display.
+ An image has some characteristics, like startadress, width height,
+ if each row has a terminating modifier etc...
+
+ The image is resposible for the conversion from the yuv
+ format to the destination.
+
+ It is initialized with the constructed x11Window.
+ During a mode-switch (which is handled by x11window) the following
+ sequence is called:
+
+ support() ->true/false if this image type is supported
+ (switching to it is allowed)
+
+ openImage() called once when we switch to this
+ image type
+
+ ditherImage(..) for the conversion from yuv->rgb
+ obviously called for every image
+ putImage(..) time for display it
+
+ closeImage() called once, when we leave this image type
+
+
+ This sequence is necessary, because the user likey to switch
+ form desktop display to dga fullscreen.
+
+ The following image classes seems to be useful:
+
+ imageDeskX11 : standard ximage, maybe with shared mem support
+ full software rendering
+ imageDeskXV : image with hardware yuv->rgb rendering
+
+ imageDGAFull : dga 2.0 full software rendering (needs root)
+ imageXVFull : fullscreen hardware yuv->rgb rendering
+
+ The hierarchy is as follows:
+
+ (desk mode)
+ imageStdX11 : fallback, should work everywhere
+ imageStdXV : if supported imageStdX11 is disabled
+
+ (fullscreen mode)
+ imageDGAFull :
+ imageXVFull :
+
+ The supported switches between the modes are
+
+
+ desktop <-> fullscreen mode.
+
+
+*/
+
+
+class XWindow;
+
+class ImageBase {
+ private:
+ char *identifier;
+
+ public:
+ unsigned int supportedModes;
+
+ public:
+ ImageBase();
+ virtual ~ImageBase();
+
+ virtual void init(XWindow* xWindow, YUVPicture* pic = NULL);
+
+ virtual int support();
+
+ virtual int openImage(int imageMode);
+ virtual int closeImage();
+
+ virtual void ditherImage(YUVPicture* pic);
+ virtual void putImage();
+ virtual void putImage(int w,int h);
+
+ virtual int active() { return true; }
+
+ void setIdentifier(const char *id);
+ char *getIdentifier();
+
+};
+
+#endif
+
diff --git a/mpeglib/lib/util/render/pictureArray.cpp b/mpeglib/lib/util/render/pictureArray.cpp
new file mode 100644
index 00000000..71381ea0
--- /dev/null
+++ b/mpeglib/lib/util/render/pictureArray.cpp
@@ -0,0 +1,101 @@
+/*
+ nice try of an X11 output plugin
+ Copyright (C) 1999 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 "pictureArray.h"
+
+
+
+PictureArray::PictureArray(int width, int height) {
+ int i;
+ pictureCallback=NULL;
+ imageType=PICTURE_NO_TYPE;
+
+ for (i=0;i<_PICTURE_ARRAY_SIZE;i++) {
+ pictureArray[i]=new YUVPicture(width,height);
+ imageType=pictureArray[i]->getImageType();
+ }
+
+ /* Find a pict image structure in ring buffer not currently locked. */
+ /* Set current pict image structure to the one just found in ring. */
+
+ current=pictureArray[0];
+ past=pictureArray[1];
+ future=pictureArray[2];
+
+ picPerSec=0.0;
+ this->width=width;
+ this->height=height;
+
+}
+
+
+PictureArray::~PictureArray() {
+ int i;
+ for (i=0;i<_PICTURE_ARRAY_SIZE;i++) {
+ if (pictureArray[i] != NULL) {
+ delete pictureArray[i];
+ pictureArray[i]=NULL;
+ }
+
+ }
+}
+
+
+
+
+
+void PictureArray::setPicturePerSecond(double val) {
+ picPerSec=val;
+}
+
+
+double PictureArray::getPicturePerSecond() {
+ return picPerSec;
+}
+
+
+
+
+void PictureArray::forward() {
+ /* Update past and future references if needed. */
+
+ YUVPicture* tmp=past;
+
+ past = future;
+ future = current;
+ current = tmp;
+
+
+}
+
+
+
+
+YUVPicture* PictureArray::getYUVPictureCallback() {
+ return pictureCallback;
+}
+
+
+void PictureArray::setYUVPictureCallback(YUVPicture* pic) {
+ this->pictureCallback=pic;
+}
+
+
+void PictureArray::setImageType(int imageType) {
+ int i;
+ this->imageType=imageType;
+ for (i=0;i<_PICTURE_ARRAY_SIZE;i++) {
+ pictureArray[i]->setImageType(imageType);
+ }
+}
+
diff --git a/mpeglib/lib/util/render/pictureArray.h b/mpeglib/lib/util/render/pictureArray.h
new file mode 100644
index 00000000..6a7e731c
--- /dev/null
+++ b/mpeglib/lib/util/render/pictureArray.h
@@ -0,0 +1,76 @@
+/*
+ nice try of an X11 output plugin
+ Copyright (C) 1999 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 __VIDEOOUTPUTX11_H
+#define __VIDEOOUTPUTX11_H
+
+
+#include "yuvPicture.h"
+#include <stdlib.h>
+
+#define _PICTURE_ARRAY_SIZE 5
+
+class PictureArray {
+
+ class YUVPicture* pictureArray[_PICTURE_ARRAY_SIZE];
+
+ class YUVPicture* past; /* Past predictive frame. */
+ class YUVPicture* future; /* Future predictive frame. */
+ class YUVPicture* current; /* Current frame. */
+
+ double picPerSec;
+ int width;
+ int height;
+
+ int imageType;
+
+ public:
+ PictureArray(int width, int height);
+ ~PictureArray();
+
+ inline YUVPicture* getPast() {return past;}
+ inline YUVPicture* getFuture() {return future;}
+ inline YUVPicture* getCurrent() {return current;}
+
+
+ inline void setPast(YUVPicture* pic) {past=pic;}
+ inline void setFuture(YUVPicture* pic) {future=pic;}
+ inline void setCurrent(YUVPicture* pic) {current=pic;}
+ inline int getWidth() { return width; }
+ inline int getWidth_Half() { return width/2; }
+
+ // attention with these!
+ // these are shares pointer
+ // only call after mpegVidRsrc and then set them back to NULL
+ YUVPicture* getYUVPictureCallback();
+ void setYUVPictureCallback(YUVPicture* pic);
+
+
+ void forward();
+
+ void setPicturePerSecond(double val);
+ double getPicturePerSecond();
+
+ // use these to swap the yuv Mode
+ inline int getImageType() { return imageType; }
+ void setImageType(int mode);
+
+
+ private:
+ YUVPicture* pictureCallback;
+
+
+};
+#endif
+
diff --git a/mpeglib/lib/util/render/renderMachine.cpp b/mpeglib/lib/util/render/renderMachine.cpp
new file mode 100644
index 00000000..c6327930
--- /dev/null
+++ b/mpeglib/lib/util/render/renderMachine.cpp
@@ -0,0 +1,205 @@
+ /*
+ puts the yuv images onto a surface
+ 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 "renderMachine.h"
+
+#include <iostream>
+
+using namespace std;
+
+
+RenderMachine::RenderMachine() {
+
+#ifndef SDL_WRAPPER
+ surface=new X11Surface();
+#endif
+#ifdef SDL_WRAPPER
+ surface=new SDLSurface();
+#endif
+
+
+ pictureArray=NULL;
+
+ startTime=new TimeStamp();
+ endTime=new TimeStamp();
+
+ initialMode = _IMAGE_DESK;
+}
+
+
+RenderMachine::~RenderMachine() {
+
+
+ closeWindow();
+ delete surface;
+
+ delete startTime;
+ delete endTime;
+
+}
+
+
+
+
+
+
+void RenderMachine::waitRestTime() {
+ endTime->gettimeofday();
+ startTime->minus(endTime,endTime);
+ endTime->waitForIt();
+
+}
+
+int RenderMachine::x11WindowId()
+{
+ return surface->x11WindowId();
+}
+
+
+int RenderMachine::openWindow(int width,
+ int height,const char *title) {
+if (surface->open(width,height,title)) {
+ pictureArray=new PictureArray(width, height);
+
+ return switchToMode(initialMode);
+ }
+ return false;
+}
+
+
+void RenderMachine::closeWindow() {
+
+ if (surface->isOpen()==false) {
+ return;
+ }
+ if (pictureArray != NULL) {
+ delete pictureArray;
+ pictureArray=NULL;
+ }
+ surface->close();
+}
+
+/**
+ important method. This is our only way to switch from
+ fullscreen back to the desktop screen.
+ This method is called if the video end (normal or by user request)
+ We dont have a callback, thus after the image stops, we would
+ never get events.
+*/
+void RenderMachine::flushWindow() {
+
+ // we always switch back to desk mode.
+ if (IS_FULL(surface->getImageMode())) {
+ switchToMode(surface->getImageMode() ^ _IMAGE_DESK ^ _IMAGE_FULL);
+ }
+
+
+}
+
+
+
+
+void RenderMachine::putImage(YUVPicture* pic,
+ TimeStamp* waitTime,
+ TimeStamp* ) {
+ if (pic == NULL) {
+ cout << "pic is null"<<endl;
+ return;
+ }
+ startTime->gettimeofday();
+ startTime->addOffset(waitTime);
+
+ // need dither?
+ surface->dither(pic);
+
+ int nextMode;
+ if (surface->checkEvent(&nextMode) == true) {
+ switchToMode(nextMode);
+ }
+ surface->putImage(pic);
+ waitRestTime();
+}
+
+
+int RenderMachine::switchToMode(int mode) {
+ if (surface->getImageMode() != mode) {
+ surface->closeImage();
+ if (mode != _IMAGE_NONE) {
+ surface->openImage(mode);
+ }
+
+ else {
+ cout << "no imageMode, no open, that's life"<<endl;
+ return false;
+ }
+ }
+ return true;
+}
+
+
+
+PictureArray* RenderMachine::lockPictureArray() {
+ return pictureArray;
+}
+
+
+void RenderMachine::unlockPictureArray(PictureArray* pictureArray) {
+
+ // chance to switch mode
+
+
+ // put picture out
+ if (surface->getImageMode() != _IMAGE_NONE) {
+ YUVPicture* pic=pictureArray->getYUVPictureCallback();
+ if (pic != NULL) {
+ TimeStamp* waitTime=pic->getWaitTime();
+ TimeStamp* earlyTime=pic->getEarlyTime();
+ putImage(pic,waitTime,earlyTime);
+ }
+ } else {
+ cout << "no mode selected"<<endl;
+ }
+}
+
+
+void RenderMachine::config(const char* key,
+ const char* value,void* user_data) {
+ if (strcmp(key,"getDepth")==0) {
+ int* val=(int*)user_data;
+ *val=surface->getDepth();
+ }
+ if (surface != NULL) {
+ int mode = surface->getImageMode();
+ if (strcmp(key,"toggleFullscreen")==0) {
+ if (surface->findImage(mode ^ _IMAGE_FULL) != NULL) {
+ if (surface->isOpen())
+ switchToMode(mode ^ _IMAGE_FULL);
+ else
+ initialMode = _IMAGE_FULL;
+ }
+ }
+ if (strcmp(key,"toggleDouble")==0) {
+ if (surface->findImage(mode ^ _IMAGE_DOUBLE) != NULL) {
+ if (surface->isOpen())
+ switchToMode(mode ^ _IMAGE_DOUBLE);
+ else
+ initialMode = _IMAGE_DOUBLE;
+ }
+ }
+ }
+
+ surface->config(key,value,user_data);
+}
+
+
+
diff --git a/mpeglib/lib/util/render/renderMachine.h b/mpeglib/lib/util/render/renderMachine.h
new file mode 100644
index 00000000..728a6740
--- /dev/null
+++ b/mpeglib/lib/util/render/renderMachine.h
@@ -0,0 +1,90 @@
+/*
+ puts the yuv images onto a surface
+ 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 __RENDERMACHINE_H
+#define __RENDERMACHINE_H
+
+
+
+
+/**
+ RenderMachine. We still have the problem, because of performance,
+ that we cannot have a yuv picture format in the decoder
+ and one in the output to x11. they must be shared.
+ XV support then directly works on them and SDL images
+ can be exported to the decoder as well.
+
+ Another point is : mode switch. User want desktop->fullscreen switch.
+ Due to the threaded nature, we must have a single synchronization
+ point, when we know that the decoder currently does _not_ decode
+ so that we can switch the imaged and free the memory.
+
+ Some points are currently unclear, for example how to handle
+ applications, which want to redirect the image into their own
+ buffers, but hey, there are that many classes and layers
+ I really think it should be doable somehow
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifndef SDL_WRAPPER
+#include "x11/x11Surface.h"
+#endif
+
+#ifdef SDL_WRAPPER
+#include "sdl/sdlSurface.h"
+#endif
+
+#include "pictureArray.h"
+#include "../abstract/abs_thread.h"
+
+class RenderMachine {
+
+
+ Surface* surface;
+ PictureArray* pictureArray;
+
+
+ TimeStamp* startTime;
+ TimeStamp* endTime;
+
+ int initialMode;
+
+ public:
+ RenderMachine();
+ ~RenderMachine();
+
+ int openWindow(int width, int height,const char *title);
+ int x11WindowId();
+ void closeWindow();
+ void flushWindow();
+
+
+ PictureArray* lockPictureArray();
+ void unlockPictureArray(PictureArray* pictureArray);
+
+ void config(const char* key, const char* value,void* user_data);
+
+ private:
+ void waitRestTime();
+ void putImage(YUVPicture* pic,TimeStamp* waitTime,TimeStamp* earlyTime);
+
+ int switchToMode(int mode);
+
+};
+#endif
diff --git a/mpeglib/lib/util/render/sdl/Makefile.am b/mpeglib/lib/util/render/sdl/Makefile.am
new file mode 100644
index 00000000..1a4b85eb
--- /dev/null
+++ b/mpeglib/lib/util/render/sdl/Makefile.am
@@ -0,0 +1,43 @@
+# player - Makefile.am
+
+INCLUDES = $(all_includes)
+
+
+noinst_LTLIBRARIES = libutilsdl.la
+
+noinst_HEADERS = imageDeskSDL.h sdlSurface.h
+
+libutilsdl_la_SOURCES = imageDeskSDL.cpp sdlSurface.cpp
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/mpeglib/lib/util/render/sdl/imageDeskSDL.cpp b/mpeglib/lib/util/render/sdl/imageDeskSDL.cpp
new file mode 100644
index 00000000..b1ff9a7c
--- /dev/null
+++ b/mpeglib/lib/util/render/sdl/imageDeskSDL.cpp
@@ -0,0 +1,110 @@
+/*
+ SDL surface output
+ 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 "imageDeskSDL.h"
+
+#ifdef SDL_WRAPPER
+
+
+ImageDeskSDL::ImageDeskSDL() {
+
+ this->surface=NULL;
+ this->rect=NULL;
+ imageMode=_IMAGE_NONE;
+ lSupport=true;
+ image=NULL;
+}
+
+
+ImageDeskSDL::~ImageDeskSDL() {
+ closeImage();
+ cout << "SDL destry needed"<<endl;
+}
+
+
+
+int ImageDeskSDL::support() {
+ return lSupport;
+}
+
+
+void ImageDeskSDL::init(XWindow* xWindow, YUVPicture* pic) {
+ cout << "ImageDeskSDL::init"<<endl;
+ this->surface=(SDL_Surface*)xWindow;
+ this->rect=(SDL_Rect*)pic;
+}
+
+int ImageDeskSDL::openImage(int imageMode) {
+ int w=rect->w;
+ int h=rect->h;
+ this->imageMode=imageMode;
+ /* Create a YV12 image (Y + V + U) */
+ cout << "CreateYUVOverlay -s"<<imageMode<<" w:"<<w<<" h:"<<h<<endl;
+ image = SDL_CreateYUVOverlay(w,h,
+ SDL_YV12_OVERLAY,
+ surface);
+ if (image == NULL) {
+ cout << "error creating image"<<endl;
+ exit(0);
+ }
+ cout << "CreateYUVOverlay -e"<<endl;
+ return true;
+}
+
+
+int ImageDeskSDL::closeImage() {
+ if (image != NULL) {
+ cout << "FreeYUVOverlay -s"<<endl;
+ SDL_FreeYUVOverlay(image);
+ // otherwise test of NULL will fail
+ image = NULL;
+ cout << "FreeYUVOverlay -e"<<endl;
+ }
+ return true;
+}
+
+
+
+void ImageDeskSDL::ditherImage(YUVPicture* pic) {
+
+ int w=pic->getWidth();
+ int h=pic->getHeight();
+ int size=w*h+(w*h)/2;
+ SDL_LockYUVOverlay(image);
+ memcpy(*((char**)image->pixels),pic->getLuminancePtr(),size);
+ SDL_UnlockYUVOverlay(image);
+
+}
+
+
+void ImageDeskSDL::putImage(int w, int h) {
+ SDL_Rect dest;
+ dest.x=0;
+ dest.y=0;
+ dest.w=rect->w;
+ dest.h=rect->h;
+ if (imageMode & _IMAGE_RESIZE) {
+ dest.w = w;
+ dest.h = h;
+ }
+
+ if (imageMode & _IMAGE_DOUBLE) {
+ dest.w*=2;
+ dest.h*=2;
+ }
+ SDL_DisplayYUVOverlay(image,&dest);
+
+}
+
+#endif
+
diff --git a/mpeglib/lib/util/render/sdl/imageDeskSDL.h b/mpeglib/lib/util/render/sdl/imageDeskSDL.h
new file mode 100644
index 00000000..1bccb94a
--- /dev/null
+++ b/mpeglib/lib/util/render/sdl/imageDeskSDL.h
@@ -0,0 +1,65 @@
+/*
+ SDL surface output
+ 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 __IMAGEDESKSDL_H
+#define __IMAGEDESKSDL_H
+
+#include "../imageBase.h"
+
+
+
+#ifndef SDL_WRAPPER
+ class ImageDeskSDL : public ImageBase {
+ };
+#endif
+
+#ifdef SDL_WRAPPER
+
+#if defined WIN32
+#include <SDL.h>
+#include <SDL_video.h>
+#else
+#include <SDL/SDL.h>
+#include <SDL/SDL_video.h>
+#endif
+
+class ImageDeskSDL : public ImageBase {
+
+ int lSupport;
+ SDL_Overlay *image;
+
+ SDL_Surface* surface;
+ SDL_Rect* rect;
+ int imageMode;
+
+ public:
+ ImageDeskSDL();
+ ~ImageDeskSDL();
+
+ int support();
+ void init(XWindow* xWindow, YUVPicture* pic=NULL);
+
+
+ int openImage(int imageMode);
+ int closeImage();
+
+ void ditherImage(YUVPicture* pic);
+
+ void putImage(int w, int h);
+
+
+
+};
+#endif
+
+#endif
diff --git a/mpeglib/lib/util/render/sdl/sdlSurface.cpp b/mpeglib/lib/util/render/sdl/sdlSurface.cpp
new file mode 100644
index 00000000..86ef41bb
--- /dev/null
+++ b/mpeglib/lib/util/render/sdl/sdlSurface.cpp
@@ -0,0 +1,219 @@
+/*
+ surface wrapper for SDL
+ 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 "sdlSurface.h"
+
+
+#ifdef SDL_WRAPPER
+
+
+SDLSurface::SDLSurface() {
+ surface=NULL;
+ lOpen=false;
+ imageMode=_IMAGE_NONE;
+ lSDLInit=false;
+ imageDeskSDL=new ImageDeskSDL();
+}
+
+
+SDLSurface::~SDLSurface() {
+ close();
+ if (imageCurrent != NULL) {
+ imageCurrent->closeImage();
+ delete imageCurrent;
+ // otherwise test of NULL will fail
+ imageCurrent = NULL;
+ }
+}
+
+
+int SDLSurface::isOpen() {
+ return lOpen;
+}
+
+int SDLSurface::getImageMode() {
+ return imageMode;
+}
+
+int SDLSurface::open(int width, int height,const char *title,bool border) {
+ cout << "SDL openImage:"<<title<<endl;
+
+ sdlinit();
+
+ rect.x = 0;
+ rect.y = 0;
+ rect.w = width;
+ rect.h = height;
+
+ return true;
+}
+
+
+int SDLSurface::close() {
+ if (isOpen()==false) {
+ cout << "WindowOut::closeWindow already closed"<<endl;
+ return true;
+ }
+ if(surface) {
+ SDL_FreeSurface(surface);
+ surface = NULL;
+ }
+
+ lOpen=false;
+ return true;
+}
+
+
+int SDLSurface::getHeight() {
+ return rect.h;
+}
+
+
+int SDLSurface::getWidth() {
+ return rect.w;
+}
+
+
+int SDLSurface::getDepth() {
+ return video_bpp;
+}
+
+int SDLSurface::putImage(YUVPicture* ) {
+ return true;
+}
+
+
+int SDLSurface::openImage(int imageMode, YUVPicture* pic) {
+ if (this->imageMode != _IMAGE_NONE) {
+ cout << "bad open error X11Surface::openImage"<<endl;
+ exit(0);
+ }
+ cout << "************* openImage SDL"<<imageMode<<endl;
+ this->imageMode=imageMode;
+ imageCurrent=NULL;
+ int w=getWidth();
+ int h=getHeight();
+ if(imageMode & _IMAGE_RESIZE) {
+ w=resize_rect.w;
+ h=resize_rect.h;
+ }
+
+ if (imageMode & _IMAGE_DOUBLE) {
+ w=rect.w*2;
+ h=rect.h*2;
+ }
+
+ if (imageMode & _IMAGE_DESK) {
+ if (imageDeskSDL->support()) {
+ imageCurrent=imageDeskSDL;
+ int video_flags = SDL_SWSURFACE;
+ video_flags |= SDL_ASYNCBLIT;
+ video_flags |= SDL_RESIZABLE;
+ if(surface)
+ SDL_FreeSurface(surface);
+ surface = SDL_SetVideoMode(w, h, video_bpp, video_flags);
+
+ }
+ }
+ if (imageMode & _IMAGE_FULL) {
+ if (imageDeskSDL->support()) {
+ imageCurrent=imageDeskSDL;
+ int video_flags = SDL_FULLSCREEN;
+ video_flags |= SDL_ASYNCBLIT;
+ video_flags |= SDL_HWSURFACE;
+ if(surface)
+ SDL_FreeSurface(surface);
+ surface = SDL_SetVideoMode(w, h, video_bpp, video_flags);
+ }
+ }
+ if (imageCurrent != NULL) {
+ cout << "surface:"<<surface<<endl;
+ imageCurrent->init((XWindow*)surface,(YUVPicture*)&rect);
+ imageCurrent->openImage(imageMode);
+ }
+ return (imageCurrent != NULL);
+}
+
+
+int SDLSurface::closeImage() {
+ this->imageMode = _IMAGE_NONE;
+ if (imageCurrent != NULL) {
+ imageCurrent->closeImage();
+ }
+ imageCurrent=NULL;
+ return true;
+}
+
+int SDLSurface::checkEvent(int* newMode) {
+ int back=false;
+ SDL_Event event;
+ SDL_PollEvent(&event);
+ switch (event.type) {
+ case SDL_MOUSEBUTTONDOWN: {
+ int button=event.button.button;
+ if (button == 1) {
+ *newMode = imageMode ^ _IMAGE_DOUBLE;
+ back=true;
+ }
+ if (button == 3) {
+ *newMode = imageMode ^ _IMAGE_DESK ^ _IMAGE_FULL;
+ back=true;
+ }
+ break;
+ }
+ case SDL_VIDEORESIZE : {
+ resize_rect.w = event.resize.w;
+ resize_rect.h = event.resize.h;
+ *newMode = imageMode | _IMAGE_RESIZE;
+ back = true;
+ break;
+ }
+
+ }
+ return back;
+}
+
+int SDLSurface::dither(YUVPicture* pic) {
+ if (imageCurrent != NULL) {
+ imageCurrent->ditherImage(pic);
+ if(imageMode & _IMAGE_RESIZE) {
+ imageCurrent->putImage(resize_rect.w, resize_rect.h);
+ } else {
+ imageCurrent->putImage(rect.w, rect.h);
+ }
+ }
+ return true;
+}
+
+void SDLSurface::sdlinit() {
+ if (lSDLInit == false) {
+ if (SDL_Init(SDL_INIT_VIDEO) < 0 ) {
+ fprintf(stderr, "Warning: Couldn't init SDL video: %s\n",
+ SDL_GetError());
+ fprintf(stderr, "Will ignore video stream\n");
+ exit(0);
+ }
+ atexit(SDL_Quit);
+ cout << "****************** SDL VIDEO System **********"<<endl;
+ /* Get the "native" video mode */
+ video_info=SDL_GetVideoInfo();
+ video_bpp=video_info->vfmt->BitsPerPixel;
+ imageMode=_IMAGE_NONE;
+
+ imageCurrent=NULL;
+ }
+ lSDLInit=true;
+}
+
+#endif
diff --git a/mpeglib/lib/util/render/sdl/sdlSurface.h b/mpeglib/lib/util/render/sdl/sdlSurface.h
new file mode 100644
index 00000000..aca5f293
--- /dev/null
+++ b/mpeglib/lib/util/render/sdl/sdlSurface.h
@@ -0,0 +1,78 @@
+/*
+ surface wrapper for SDL
+ 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 __SDLSURFACE_H
+#define __SDLSURFACE_H
+
+
+#include "../surface.h"
+#include "imageDeskSDL.h"
+
+
+
+#ifndef SDL_WRAPPER
+ class SDLSurface : public Surface {
+ };
+#endif
+
+#ifdef SDL_WRAPPER
+#if defined WIN32
+#include <SDL.h>
+#include <SDL_video.h>
+#else
+#include <SDL/SDL.h>
+#include <SDL/SDL_video.h>
+#endif
+
+
+class SDLSurface : public Surface {
+
+ int lOpen;
+ int imageMode;
+ int lSDLInit;
+ int video_bpp;
+ SDL_Surface* surface;
+ SDL_Rect rect;
+ SDL_Rect resize_rect;
+ const SDL_VideoInfo *video_info;
+
+ ImageBase* imageCurrent;
+
+ ImageDeskSDL* imageDeskSDL;
+
+ public:
+ SDLSurface();
+ ~SDLSurface();
+
+ int isOpen();
+ int open(int width, int height,const char *title, bool border=false);
+ int close();
+ int getHeight();
+ int getWidth();
+ int getDepth();
+ int getImageMode();
+ int checkEvent(int* mode);
+
+ int openImage(int imageMode, YUVPicture* pic = NULL);
+ int closeImage();
+ int dither(YUVPicture* pic);
+ int putImage(YUVPicture* pic);
+
+
+ private:
+ void sdlinit();
+};
+#endif
+
+#endif
diff --git a/mpeglib/lib/util/render/surface.cpp b/mpeglib/lib/util/render/surface.cpp
new file mode 100644
index 00000000..12a15410
--- /dev/null
+++ b/mpeglib/lib/util/render/surface.cpp
@@ -0,0 +1,117 @@
+/*
+ surface base class
+ 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 "surface.h"
+
+#include <iostream>
+
+using namespace std;
+
+Surface::Surface() {
+}
+
+
+Surface::~Surface() {
+}
+
+
+int Surface::isOpen() {
+ cout << "direct virtual call Surface::isOpen "<<endl;
+ return false;
+}
+
+
+int Surface::open(int width, int height,const char *title, bool border) {
+ cout << "direct virtual call Surface::open "<<endl;
+ cout << "width:"<<width<<" height:"<<height
+ << " title:"<<title<<endl;
+ return false;
+}
+
+
+int Surface::close() {
+ cout << "direct virtual call Surface::close "<<endl;
+ return true;
+}
+
+
+int Surface::getHeight() {
+ cout << "direct virtual call Surface::getHeight "<<endl;
+ return 0;
+}
+
+
+int Surface::getWidth() {
+ cout << "direct virtual call Surface::getWidth "<<endl;
+ return 0;
+}
+
+
+int Surface::getDepth() {
+ cout << "direct virtual call Surface::getDepth "<<endl;
+ return 0;
+}
+
+int Surface::getImageMode() {
+ cout << "direct virtual call Surface::getImageMode "<<endl;
+ return 0;
+}
+
+int Surface::x11WindowId() {
+ cout << "direct virtual call Surface::x11WindowId " << endl;
+ return -1;
+}
+
+ImageBase *Surface::findImage(int)
+{
+ cout << "direct virtual call: Surface::findImage "<<endl;
+ return NULL;
+}
+
+int Surface::openImage(int mode, YUVPicture*) {
+ cout << "direct virtual call Surface::openImage "<<endl;
+ cout << "imageMode:"<<mode<<endl;
+ return false;
+}
+
+
+int Surface::closeImage() {
+ cout << "direct virtual call Surface::closeImage "<<endl;
+ return true;
+}
+
+
+int Surface::dither(YUVPicture* pic) {
+ cout << "direct virtual call Surface::dither "<<endl;
+ pic->print("Surface::dither");
+ return false;
+}
+
+
+int Surface::putImage(YUVPicture* pic) {
+ cout << "direct virtual call Surface::putImage "<<endl;
+ pic->print("Surface::putImage");
+ return false;
+}
+
+int Surface::checkEvent(int*) {
+ cout << "direct virtual call Surface::checkEvent "<<endl;
+ return false;
+}
+
+void Surface::config(const char* ,
+ const char* ,void* ) {
+ cout << "direct virtual call Surface::config"<<endl;
+}
+
diff --git a/mpeglib/lib/util/render/surface.h b/mpeglib/lib/util/render/surface.h
new file mode 100644
index 00000000..84de996a
--- /dev/null
+++ b/mpeglib/lib/util/render/surface.h
@@ -0,0 +1,55 @@
+/*
+ surface base class
+ 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 __SURFACE_H
+#define __SURFACE_H
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "yuvPicture.h"
+
+class ImageBase;
+
+class Surface {
+
+ public:
+ Surface();
+ virtual ~Surface();
+
+ virtual int isOpen();
+ virtual int open(int width, int height,const char *title, bool border=false);
+ virtual int close();
+ virtual int getHeight();
+ virtual int getWidth();
+ virtual int getDepth();
+ virtual int getImageMode();
+ virtual int x11WindowId();
+
+ virtual ImageBase *findImage(int imageMode);
+
+ virtual int openImage(int mode, YUVPicture* pic = NULL);
+ virtual int closeImage();
+ virtual int dither(YUVPicture* pic);
+ virtual int putImage(YUVPicture* pic);
+
+ virtual int checkEvent(int* mode);
+
+ // config surface
+ virtual void config(const char* key,
+ const char* value,void* user_data);
+
+
+};
+#endif
diff --git a/mpeglib/lib/util/render/x11/Makefile.am b/mpeglib/lib/util/render/x11/Makefile.am
new file mode 100644
index 00000000..97ab0d67
--- /dev/null
+++ b/mpeglib/lib/util/render/x11/Makefile.am
@@ -0,0 +1,48 @@
+# player - Makefile.am
+
+INCLUDES = $(all_includes)
+
+
+noinst_LTLIBRARIES = libutilx11.la
+
+
+noinst_HEADERS = initDisplay.h \
+ imageDeskX11.h imageDGAFull.h \
+ imageXVDesk.h x11Surface.h xinit.h
+
+libutilx11_la_SOURCES = initDisplay.cpp \
+ imageDeskX11.cpp \
+ imageDGAFull.cpp imageXVDesk.cpp \
+ x11Surface.cpp
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/mpeglib/lib/util/render/x11/imageDGAFull.cpp b/mpeglib/lib/util/render/x11/imageDGAFull.cpp
new file mode 100644
index 00000000..6e07b658
--- /dev/null
+++ b/mpeglib/lib/util/render/x11/imageDGAFull.cpp
@@ -0,0 +1,289 @@
+/*
+ xfree 4.0 dga fullscreen mode
+ Copyright (C) 2000 Martin Vogt, Christian Gerlach
+
+ 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 "imageDGAFull.h"
+
+#include <iostream>
+
+using namespace std;
+
+ImageDGAFull::ImageDGAFull() {
+
+ m_iMode = -1;
+ m_bIsActive = false;
+ lSupport=false;
+ m_pxWindow = NULL;
+ m_iImageMode = _IMAGE_NONE;
+ ditherWrapper=NULL;
+ supportedModes = _IMAGE_NONE;
+ setIdentifier("DGA");
+}
+
+
+ImageDGAFull::~ImageDGAFull() {
+ if (ditherWrapper != NULL) {
+ delete ditherWrapper;
+ }
+}
+
+void ImageDGAFull::init(XWindow *xWindow, YUVPicture*)
+{
+ int uid;
+
+ m_pxWindow = xWindow;
+ if (ditherWrapper == NULL) {
+ ditherWrapper=new DitherWrapper(xWindow->depth,
+ xWindow->redMask,
+ xWindow->greenMask,
+ xWindow->blueMask,
+ xWindow->pixel);
+ }
+
+#ifndef X11_DGA2
+ return;
+#endif
+
+#ifdef X11_DGA2
+ m_pDGAModes=NULL;
+ m_iNumberModes = 0;
+
+ m_iVideoWidth = xWindow->width;
+ m_iVideoHeight = xWindow->height;
+ uid=getuid();
+ if (uid != 0) {
+ //cout << "you are :"<<uid<<" and not root(0). DGA 2.0 needs root"<<endl;
+ return;
+ }
+
+ if ((m_pDisplay =xWindow->display)==NULL ) {
+ fprintf( stderr, " cannot connect to X server %s\n", XDisplayName(NULL));
+ return;
+ }
+
+ m_iScreen = DefaultScreen(xWindow->display);
+
+
+ if (!XF86DGAQueryVersion(xWindow->display,
+ &m_iMajorVersion, &m_iMinorVersion)) {
+ fprintf(stderr, "Unable to query video extension version\n");
+ return ;
+ }
+ printf("DGA version %d.%d detected!\n", m_iMajorVersion, m_iMinorVersion);
+
+ // Fail if the extension version in the server is too old
+ if (m_iMajorVersion < DGA_MINMAJOR ||
+ (m_iMajorVersion == DGA_MINMAJOR && m_iMinorVersion < DGA_MINMINOR)) {
+ fprintf(stderr, "Xserver is running an old XFree86-DGA version"
+ " (%d.%d)\n", m_iMajorVersion, m_iMinorVersion);
+ fprintf(stderr, "Minimum required version is %d.%d\n",
+ DGA_MINMAJOR, DGA_MINMINOR);
+ return ;
+ }
+
+ if (!XF86DGAQueryExtension(m_pDisplay, &m_iEventBase, &m_iErrorBase)) {
+ fprintf(stderr, "Unable to query video extension information\n");
+ return ;
+ }
+ printf("Event base %d\n", m_iEventBase);
+ printf("Error base %d\n", m_iErrorBase);
+
+ lSupport=true;
+ supportedModes = _IMAGE_FULL;
+#endif
+}
+
+int ImageDGAFull::support() {
+ return lSupport;
+}
+
+
+int ImageDGAFull::openImage(int mode) {
+#ifdef X11_DGA2
+ int width, bank, ram;
+ m_bAllowZoom = IS_DOUBLE(mode);
+ m_iImageMode = mode;
+
+ /* Open access to the framebuffer */
+ if ( ! XDGAOpenFramebuffer(m_pDisplay,m_iScreen) ) {
+ return(false);
+ }
+
+ findMode(m_pxWindow->width, m_pxWindow->height, m_pxWindow->depth);
+ m_pDevice = XDGASetMode(m_pDisplay, m_iScreen, m_pDGAModes[m_iMode].num);
+
+
+ XDGASelectInput(m_pDisplay, m_iScreen,
+ KeyPressMask | ButtonPressMask | PointerMotionMask);
+
+ XF86DGAGetVideo(m_pDisplay,m_iScreen,&m_pAddr,&width,&bank,&ram);
+
+
+ if(bank < (ram * 1024)) {
+ XF86DGASetVidPage(m_pxWindow->display,
+ DefaultScreen(m_pxWindow->display), 0);
+ }
+
+ XF86DGASetViewPort(m_pxWindow->display,
+ DefaultScreen(m_pxWindow->display),0,0);
+
+
+ printf("Offset:%8x\n",m_iOffsetScreen);
+ m_pStartAddr = m_pAddr + m_iOffsetScreen;
+ m_iOffsetLine = (m_iBytesPerLine - m_iBytesPerRow) / m_iBytesPerPixel;
+ cout << "LineOffset: " << m_iOffsetLine << endl;
+
+ // Clear the screen
+ memset(m_pAddr, 0, m_iBytesPerLine * m_iScreenHeight);
+ /* char *pos = m_pStartAddr;
+ int end = (m_bZoom) ? 2*m_iVideoHeight : m_iVideoHeight;
+ for (int line=0 ; line<end ; line++) {
+ memset(pos, 80, m_iBytesPerRow);
+ pos += m_iBytesPerRow + m_iOffsetLine * m_iBytesPerPixel;
+ }
+ sleep(2);*/
+
+ m_bIsActive = true;
+#endif
+ return true;
+}
+
+
+int ImageDGAFull::closeImage() {
+#ifdef X11_DGA2
+ m_bIsActive = false;
+ stop();
+
+ // delete resources
+ if (m_pDGAModes != NULL) {
+ delete m_pDGAModes;
+ m_pDGAModes=NULL;
+ }
+#endif
+ return true;
+}
+
+
+unsigned char* ImageDGAFull::address() {
+ return (unsigned char*) m_pStartAddr;
+}
+
+
+int ImageDGAFull::offset() {
+ return m_iOffsetLine;
+}
+
+
+void ImageDGAFull::ditherImage(YUVPicture* pic) {
+
+ int useMode = (m_bZoom) ? m_iImageMode : m_iImageMode & (!_IMAGE_DOUBLE);
+
+ ditherWrapper->doDither(pic,m_pxWindow->depth,useMode,
+ address(),offset());
+}
+
+
+void ImageDGAFull::putImage() {
+
+ if (event())
+ closeImage();
+}
+
+
+int ImageDGAFull::findMode(int width, int height, int bpp) {
+#ifdef X11_DGA2
+ int minBorder = INT_MAX;
+ int yBorder=0;
+ int border;
+
+ // TODO: also check the y-axis
+
+ m_iMode = -1;
+ m_iNumberModes = 0;
+ m_pDGAModes = XDGAQueryModes(m_pDisplay, m_iScreen, &m_iNumberModes);
+ printf("Number modes: %d\n", m_iNumberModes);
+
+ for (int count=0 ; count<m_iNumberModes ; count++) {
+
+
+ if (m_pDGAModes[count].depth != bpp)
+ continue;
+
+ printf("Mode: %d %dx%d \t bpp %d\n",
+ count,
+ m_pDGAModes[count].viewportWidth,
+ m_pDGAModes[count].viewportHeight,
+ m_pDGAModes[count].bitsPerPixel);
+
+ // test normal video
+ border = m_pDGAModes[count].viewportWidth - width;
+ if ((border >= 0) && (border < minBorder)) {
+ minBorder = border;
+ m_iMode = count;
+ m_bZoom = false;
+ yBorder = m_pDGAModes[count].viewportHeight - height;
+ }
+
+ // test zoomed video
+ if (m_bAllowZoom) {
+ border = m_pDGAModes[count].viewportWidth - 2 * width;
+ if ((border >= 0) && (border < minBorder)) {
+ minBorder = border;
+ m_iMode = count;
+ m_bZoom = true;
+ yBorder = m_pDGAModes[count].viewportHeight-2*height;
+ }
+ }
+ }
+
+ if (m_iMode != -1) {
+ m_iScreenWidth = m_pDGAModes[m_iMode].viewportWidth;
+ m_iScreenHeight = m_pDGAModes[m_iMode].viewportHeight;
+
+ m_iBytesPerPixel = m_pDGAModes[m_iMode].bitsPerPixel / 8;
+ m_iBytesPerLine = m_pDGAModes[m_iMode].bytesPerScanline;
+ m_iBytesPerRow = width * m_iBytesPerPixel;
+ if (m_bZoom) {
+ m_iBytesPerRow += m_iBytesPerRow;
+ }
+
+ m_iOffsetScreen = minBorder * (m_iBytesPerPixel / 2) +
+ (yBorder / 2) * m_iBytesPerLine;
+ }
+
+ cout << "Best Mode: " << m_iMode << endl;
+ cout << "Border Size: " << minBorder / 2 << endl;
+ cout << "Zoom: " << m_bZoom << endl;
+ cout << "Bytes per Line: " << m_iBytesPerLine << endl;
+ cout << "Bytes per Row: " << m_iBytesPerRow << endl;
+ cout << "Bytes per Pixel:" << m_iBytesPerPixel << endl;
+ cout << "Total offset: " << m_iOffsetScreen << endl;
+#endif
+ return (m_iMode != -1);
+}
+
+
+
+int ImageDGAFull::event() {
+ XEvent event;
+ return XCheckTypedEvent(m_pDisplay, ButtonPress + m_iEventBase, &event);
+}
+
+void ImageDGAFull::stop() {
+#ifdef X11_DGA2
+ m_bIsActive = false;
+ XF86DGADirectVideo(m_pDisplay, m_iScreen, 0);
+
+ XUngrabPointer(m_pDisplay, CurrentTime);
+ XUngrabKeyboard(m_pDisplay, CurrentTime);
+#endif
+}
diff --git a/mpeglib/lib/util/render/x11/imageDGAFull.h b/mpeglib/lib/util/render/x11/imageDGAFull.h
new file mode 100644
index 00000000..ddb8f493
--- /dev/null
+++ b/mpeglib/lib/util/render/x11/imageDGAFull.h
@@ -0,0 +1,131 @@
+/*
+ xfree 4.0 dga fullscreen mode
+ Copyright (C) 2000 Martin Vogt, Christian Gerlach
+
+ 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 __IMAGEDGAFULL_H
+#define __IMAGEDGAFULL_H
+#include "xinit.h"
+
+#include "../imageBase.h"
+
+
+
+#include <stdio.h>
+#include <unistd.h>
+#include <limits.h>
+#include <sys/types.h>
+
+
+
+
+#define DGA_MINMAJOR 2
+#define DGA_MINMINOR 0
+
+
+
+
+/**
+
+ Displays and renders X11 images in software with the help
+ of the ditherWrapper class. It switches to xfree 4.0 dga 2.0
+ and needs root priviliges for that
+
+*/
+
+
+class ImageDGAFull : public ImageBase {
+
+
+ XWindow* m_pxWindow;
+
+ // DGA status
+ int m_iMajorVersion;
+ int m_iMinorVersion;
+ int m_iEventBase;
+ int m_iErrorBase;
+
+ int m_iScreen;
+
+ Display *m_pDisplay;
+
+ int m_iNumberModes;
+
+#ifdef X11_DGA2
+ XDGAMode *m_pDGAModes;
+ XDGADevice *m_pDevice;
+#endif
+
+ int m_iScreenWidth;
+ int m_iScreenHeight;
+
+ char *m_pAddr; // Base address of the screen
+
+ // DGA parameter
+ int m_iVideoWidth;
+ int m_iVideoHeight;
+
+ int m_iBytesPerLine;
+ int m_iBytesPerRow; // Size of one image line
+ int m_iBytesPerPixel;
+ int m_iOffsetScreen;
+ int m_iOffsetLine;
+ char *m_pStartAddr; // Start address for a centered image
+
+ int m_iImageMode;
+ int m_iMode;
+ bool m_bZoom;
+ bool m_bAllowZoom;
+
+ bool m_bIsActive;
+
+ int lSupport;
+ DitherWrapper* ditherWrapper;
+
+
+ public:
+ ImageDGAFull();
+ ~ImageDGAFull();
+
+ void init(XWindow *xWindow, YUVPicture* pic = NULL);
+
+ int support();
+
+ int openImage(int mode);
+ int closeImage();
+
+ void ditherImage(YUVPicture* pic);
+ void putImage();
+
+ int active() { return m_bIsActive; }
+
+ private:
+
+ // Tries to find a fullscreen-mode which matches the resolution best
+ int findMode(int width, int height, int bpp);
+
+ // Returns TRUE if an event is waiting
+ int event();
+
+ // Returns the start address of the upper left corner of the video frame
+ unsigned char *address();
+
+ // Number of bytes from the end of a row to the beginning of next one
+ int offset();
+
+ // Disables DGA-View (performs a mode-switch if neccesary)
+ void stop();
+
+
+
+};
+
+#endif
diff --git a/mpeglib/lib/util/render/x11/imageDeskX11.cpp b/mpeglib/lib/util/render/x11/imageDeskX11.cpp
new file mode 100644
index 00000000..9607d749
--- /dev/null
+++ b/mpeglib/lib/util/render/x11/imageDeskX11.cpp
@@ -0,0 +1,439 @@
+/*
+ standard and shared mem X11 images
+ 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 "imageDeskX11.h"
+
+#include <iostream>
+
+using namespace std;
+
+static int lXerror;
+
+static int dummy(Display* , XErrorEvent*) {
+ lXerror=true;
+ return true;
+}
+
+
+
+ImageDeskX11::ImageDeskX11() {
+ lSupport=true;
+ supportedModes = _IMAGE_DESK | _IMAGE_DOUBLE | _IMAGE_FULL;
+ setIdentifier("Standard X11");
+ xWindow = NULL;
+ ditherWrapper=NULL;
+#ifdef X11_XVIDMODE
+ iOldMode = -1;
+ vm_modelines = NULL;
+#endif
+}
+
+
+ImageDeskX11::~ImageDeskX11() {
+ destroyImage();
+ if (ditherWrapper != NULL) {
+ delete ditherWrapper;
+ }
+}
+
+
+void ImageDeskX11::init(XWindow* xWindow, YUVPicture*)
+{
+ videoaccesstype=VIDEO_XI_NONE;
+ this->xWindow=xWindow;
+ virtualscreen=NULL;
+ ximage=NULL;
+ imageMode=_IMAGE_NONE;
+ if (ditherWrapper == NULL) {
+ ditherWrapper=new DitherWrapper(xWindow->depth,
+ xWindow->redMask,
+ xWindow->greenMask,
+ xWindow->blueMask,
+ xWindow->pixel);
+ }
+
+#ifdef X11_SHARED_MEM
+ shmseginfo=NULL;
+#endif
+}
+
+int ImageDeskX11::support() {
+ return lSupport;
+}
+
+
+int ImageDeskX11::openImage(int mode) {
+
+ if (xWindow == NULL) {
+ cout << "ImageDeskX11::openImage - call init before open!" << endl;
+ return false;
+ }
+
+ closeImage();
+ imageMode = mode;
+ int err;
+
+ if ((err=createImage(VIDEO_XI_SHMSTD,imageMode)) != ERR_XI_OK) {
+ printf("\nX initialisation error:\n *** %s\n",ERR_XI_STR[err]);
+ printf("check ipcs and delete resources with ipcrm\n");
+ if ((err=createImage(VIDEO_XI_STANDARD,imageMode)) != ERR_XI_OK) {
+ printf("\nX initialisation error:\n *** %s\n",ERR_XI_STR[err]);
+ videoaccesstype=VIDEO_XI_NONE;
+ } else {
+ lSupport=true;
+ }
+ } else {
+ lSupport=true;
+ }
+ switch(videoaccesstype) {
+ case VIDEO_XI_STANDARD:
+ //printf(" # using conventional Xlib calls.\n\n");
+ break;
+ case VIDEO_XI_SHMSTD:
+ //printf(" # Using Xlib shared memory extension %d.%d\n\n",
+ //XShmMajor,XShmMinor);
+ break;
+ default:
+ cout << "could not create image->no video output possible"<<endl;
+
+ }
+
+ iOffsetX = iOffsetY = 0;
+ int w = xWindow->width;
+ int h = xWindow->height;
+ if (IS_FULL(imageMode)) {
+ switchMode(xWindow->width, xWindow->height, IS_DOUBLE(imageMode));
+ iOffsetX = (iWidth - w) / 2;
+ iOffsetY = (iHeight - h) / 2;
+ if (bZoom) {
+ iOffsetX -= w / 2;
+ iOffsetY -= h / 2;
+ }
+ XResizeWindow(xWindow->display, xWindow->window, iWidth, iHeight);
+ } else if (IS_DOUBLE(imageMode)) {
+ XResizeWindow(xWindow->display, xWindow->window,
+ xWindow->width * 2, xWindow->height * 2);
+ }
+
+ if (lSupport==true) {
+ return true;
+ }
+ return false;
+}
+
+
+int ImageDeskX11::closeImage() {
+ destroyImage();
+
+#ifdef X11_XVIDMODE
+ if (iOldMode != -1) {
+ cout << "switch back to original videomode" << endl;
+ XF86VidModeSwitchToMode(xWindow->display,XDefaultScreen(xWindow->display),
+ vm_modelines[iOldMode]);
+ XFlush(xWindow->display);
+ iOldMode=-1;
+ }
+#endif
+
+ return true;
+}
+
+
+void ImageDeskX11::ditherImage(YUVPicture* pic) {
+ if (xWindow == NULL) {
+ cout << "ImageDeskX11::ditherImage - you have to call init first!" << endl;
+ return;
+ }
+
+ ditherWrapper->doDither(pic,xWindow->depth,imageMode,
+ virtualscreen,0);
+}
+
+
+void ImageDeskX11::putImage(){
+ if (xWindow == NULL) {
+ cout << "ImageDeskX11::putImage - you have to call init first!" << endl;
+ return;
+ }
+
+
+ int height=xWindow->height;
+ int width=xWindow->width;
+
+ if (imageMode & _IMAGE_DOUBLE) {
+ height=2*height;
+ width=2*width;
+ }
+
+#ifdef X11_SHARED_MEM
+ switch(videoaccesstype) {
+ case VIDEO_XI_SHMSTD:
+ XShmPutImage(xWindow->display,xWindow->window,
+ xWindow->gc,ximage,
+ 0, 0, iOffsetX, iOffsetY, width, height, False);
+ XSync(xWindow->display,false); /* true not needed, done by XPending */
+ break;
+
+
+ case VIDEO_XI_STANDARD:
+#endif
+ XPutImage(xWindow->display,xWindow->window,
+ xWindow->gc, ximage,
+ 0, 0, iOffsetX, iOffsetY, width, height);
+ XSync(xWindow->display,false); /* true not needed, done by XPending */
+#ifdef X11_SHARED_MEM
+ break;
+ }
+#endif
+}
+
+
+
+int ImageDeskX11::createImage(int createType,int mode) {
+
+ if (xWindow == NULL) {
+ cout << "ImageDeskX11::createImage - you have to call init first!" << endl;
+ return false;
+ }
+
+ videoaccesstype=VIDEO_XI_NONE;
+
+#ifdef X11_SHARED_MEM
+ if(XShmQueryVersion(xWindow->display,&XShmMajor,&XShmMinor,&XShmPixmaps)) {
+ if (XShmPixmaps==True) {
+ if (createType & VIDEO_XI_SHMSTD) {
+ videoaccesstype=VIDEO_XI_SHMSTD;
+ }
+ }
+ } else {
+ if (createType & VIDEO_XI_SHMSTD) {
+ return ERR_XI_NOSHAREDMEMORY;
+ }
+ }
+#endif
+ if (videoaccesstype == VIDEO_XI_NONE) {
+ videoaccesstype=createType;
+ }
+
+ switch(videoaccesstype)
+ {
+#ifdef X11_SHARED_MEM
+
+
+ case VIDEO_XI_SHMSTD:
+
+ lXerror=false;
+ XSetErrorHandler(dummy);
+
+ shmseginfo=(XShmSegmentInfo *)malloc(sizeof(XShmSegmentInfo));
+ if(!shmseginfo)
+ return ERR_XI_SHMALLOC;
+
+ memset(shmseginfo,0, sizeof(XShmSegmentInfo));
+
+ if (imageMode & _IMAGE_DOUBLE) {
+ ximage=XShmCreateImage(xWindow->display,xWindow->visual,
+ xWindow->depth,
+ ZPixmap,NULL,shmseginfo,2*xWindow->width,
+ 2*xWindow->height);
+ } else {
+ ximage=XShmCreateImage(xWindow->display,xWindow->visual,
+ xWindow->depth,
+ ZPixmap,NULL,shmseginfo,xWindow->width,
+ xWindow->height);
+ }
+
+ if(!ximage)
+ return ERR_XI_SHMXIMAGE;
+
+ shmseginfo->shmid=shmget(IPC_PRIVATE,
+ ximage->bytes_per_line*
+ ximage->height,IPC_CREAT|0777);
+
+ if(shmseginfo->shmid<0)
+ return ERR_XI_SHMSEGINFO;
+
+ shmseginfo->shmaddr=(char*)shmat(shmseginfo->shmid,NULL,0);
+ ximage->data=shmseginfo->shmaddr;
+ virtualscreen=(unsigned char *)ximage->data;
+
+ if(!virtualscreen)
+ return ERR_XI_SHMVIRTALLOC;
+
+ shmseginfo->readOnly=False;
+
+ XShmAttach(xWindow->display,shmseginfo);
+ XSync(xWindow->display, False);
+ XSetErrorHandler(NULL);
+ XFlush(xWindow->display);
+ if (lXerror) {
+ cout << "ERR_XI_SHMATTACH -2"<<endl;
+ return ERR_XI_SHMATTACH;
+ }
+
+ break;
+#endif
+
+ case VIDEO_XI_STANDARD:
+ if (mode & _IMAGE_DOUBLE) {
+ virtualscreen=(unsigned char *)
+ malloc(xWindow->screensize*sizeof(char)*4);
+
+ if(virtualscreen==NULL)
+ return ERR_XI_VIRTALLOC;
+
+ ximage=XCreateImage(xWindow->display,xWindow->visual,
+ xWindow->depth,ZPixmap,
+ 0,(char*)virtualscreen,
+ 2*xWindow->width,2*xWindow->height,
+ 32,2*xWindow->width*xWindow->pixelsize);
+ } else {
+ virtualscreen=(unsigned char *)
+ malloc(xWindow->screensize*sizeof(char));
+
+ if(virtualscreen==NULL)
+ return ERR_XI_VIRTALLOC;
+
+ ximage=XCreateImage(xWindow->display,xWindow->visual,
+ xWindow->depth,ZPixmap,
+ 0,(char*)virtualscreen,
+ xWindow->width,xWindow->height,
+ 32,xWindow->width*xWindow->pixelsize);
+ }
+
+ if(!ximage)
+ return ERR_XI_XIMAGE;
+ break;
+
+ default:
+ return ERR_XI_FAILURE;
+
+ }
+
+ if ( (videoaccesstype == VIDEO_XI_STANDARD) ||
+ (videoaccesstype == VIDEO_XI_SHMSTD) ) {
+#ifndef WORDS_BIGENDIAN
+ ximage->byte_order = LSBFirst;
+ ximage->bitmap_bit_order = LSBFirst;
+#else
+ ximage->byte_order = MSBFirst;
+ ximage->bitmap_bit_order = MSBFirst;
+#endif
+
+ }
+ return ERR_XI_OK;
+}
+
+
+
+int ImageDeskX11::destroyImage() {
+ if(xWindow && xWindow->display && xWindow->window) {
+ switch(videoaccesstype) {
+#ifdef X11_SHARED_MEM
+ case VIDEO_XI_SHMSTD:
+ if (shmseginfo) {
+ XShmDetach(xWindow->display,shmseginfo);
+ if(ximage) {
+ XDestroyImage(ximage);
+ ximage=NULL;
+ }
+ if(shmseginfo->shmaddr) {
+ shmdt(shmseginfo->shmaddr);
+ shmseginfo->shmaddr=NULL;
+ }
+ if(shmseginfo->shmid>=0)
+ shmctl(shmseginfo->shmid,IPC_RMID,NULL);
+
+ free(shmseginfo);
+ }
+ shmseginfo=NULL;
+ break;
+
+#endif
+ case VIDEO_XI_STANDARD:
+ if(ximage) {
+ XDestroyImage(ximage);
+ ximage=NULL;
+ /*
+ XDestroyImage function calls frees both the image structure
+ and the data pointed to by the image structure.
+ */
+ virtualscreen=NULL;
+ }
+ break;
+
+ default:
+ // cout << "no open window to close"<<endl;
+ break;
+ }
+ }
+ videoaccesstype=VIDEO_XI_NONE;
+ imageMode=_IMAGE_NONE;
+ return true;
+}
+
+
+bool ImageDeskX11::switchMode(int width, int , bool zoom)
+{
+ iWidth = xWindow->screenptr->width;
+ iHeight = xWindow->screenptr->height;
+
+#ifdef X11_XVIDMODE
+ iOldMode = -1;
+ int vm_count,i;
+
+ cout << "Find best matching videomode ..." << endl;
+
+ if (!XF86VidModeGetAllModeLines(xWindow->display,XDefaultScreen(xWindow->display),
+ &vm_count,&vm_modelines)) {
+ return false;
+ }
+
+ int bestMode = -1;
+ int border, minBorder = INT_MAX;
+
+ for (i = 0; i < vm_count; i++) {
+ printf("mode %d: %dx%d\n",i, vm_modelines[i]->hdisplay,vm_modelines[i]->vdisplay);
+
+ if (xWindow->screenptr->width == vm_modelines[i]->hdisplay)
+ iOldMode = i;
+
+ border = vm_modelines[i]->hdisplay - width;
+ if ((border > 0) && (border < minBorder)) {
+ bestMode = i;
+ minBorder = border;
+ bZoom = false;
+ }
+ if (zoom) {
+ border = vm_modelines[i]->hdisplay - 2 * width;
+ if ((border > 0) && (border < minBorder)) {
+ bestMode = i;
+ minBorder = border;
+ bZoom = true;
+ }
+ }
+ }
+ cout << "best mode: " << bestMode << endl;
+
+ iWidth = vm_modelines[bestMode]->hdisplay;
+ iHeight = vm_modelines[bestMode]->vdisplay;
+
+ if (XF86VidModeSwitchToMode(xWindow->display,XDefaultScreen(xWindow->display),
+ vm_modelines[bestMode])) {
+ XF86VidModeSetViewPort(xWindow->display,XDefaultScreen(xWindow->display), 0, 0);
+ XFlush(xWindow->display);
+ return true;
+ }
+#endif
+ return false;
+}
diff --git a/mpeglib/lib/util/render/x11/imageDeskX11.h b/mpeglib/lib/util/render/x11/imageDeskX11.h
new file mode 100644
index 00000000..efbd4e90
--- /dev/null
+++ b/mpeglib/lib/util/render/x11/imageDeskX11.h
@@ -0,0 +1,85 @@
+/*
+ standard and shared mem X11 images
+ 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 __IMAGEDESKX11_H
+#define __IMAGEDESKX11_H
+#include <limits.h>
+#include "xinit.h"
+
+#include "../imageBase.h"
+
+#define VIDEO_XI_NONE 0x00 /* No access defined */
+#define VIDEO_XI_STANDARD 0x01 /* Use standard Xlib calls */
+#define VIDEO_XI_SHMSTD 0X02 /* Use Xlib shared memory extension */
+
+/**
+
+ Displays and renders X11 images in software with the help
+ of the ditherWrapper class.
+*/
+
+
+class ImageDeskX11 : public ImageBase {
+
+#ifdef X11_SHARED_MEM
+ XShmSegmentInfo *shmseginfo;
+#endif
+
+ unsigned char *virtualscreen;
+ int videoaccesstype;
+ XImage *ximage;
+ int lSupport;
+
+ int XShmMajor,XShmMinor;
+ Bool XShmPixmaps;
+
+ XWindow* xWindow;
+ int imageMode;
+ DitherWrapper* ditherWrapper;
+
+ int iOffsetX;
+ int iOffsetY;
+ int iWidth;
+ int iHeight;
+
+#ifdef X11_XVIDMODE
+ XF86VidModeModeInfo **vm_modelines;
+
+ int iOldMode;
+#endif
+
+ bool bZoom;
+
+ public:
+ ImageDeskX11();
+ ~ImageDeskX11();
+
+ void init(XWindow* xWindow, YUVPicture* pic = NULL);
+
+ int support();
+
+ int openImage(int ditherSize);
+ int closeImage();
+
+ void ditherImage(YUVPicture* pic);
+ void putImage();
+
+ private:
+ int createImage(int createType,int size);
+ int destroyImage();
+
+ bool switchMode(int width, int height, bool zoom);
+
+};
+
+#endif
diff --git a/mpeglib/lib/util/render/x11/imageXVDesk.cpp b/mpeglib/lib/util/render/x11/imageXVDesk.cpp
new file mode 100644
index 00000000..e087ba40
--- /dev/null
+++ b/mpeglib/lib/util/render/x11/imageXVDesk.cpp
@@ -0,0 +1,405 @@
+/*
+ xfree 4.0 XV extension desk mode
+ 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 "imageXVDesk.h"
+
+#include <iostream>
+
+using namespace std;
+
+ImageXVDesk::ImageXVDesk() {
+
+ lSupport=false;
+
+ ditherWrapper=NULL;
+ supportedModes = _IMAGE_NONE;
+ setIdentifier("XV");
+
+ xWindow = NULL;
+
+#ifdef X11_XV
+ keepRatio = false;
+
+#endif
+}
+
+
+ImageXVDesk::~ImageXVDesk() {
+ if (ditherWrapper != NULL) {
+ delete ditherWrapper;
+ }
+ freeImage();
+}
+
+void ImageXVDesk::init(XWindow* xWindow, YUVPicture*)
+{
+#ifdef X11_XV
+ this->xWindow=xWindow;
+
+ xv_port=-1;
+ shmem_flag = 0;
+ yuv_image=NULL;
+ yuv_shminfo.shmaddr=NULL;
+ yuv_shminfo.shmid=-1;
+
+ if (XShmQueryExtension(xWindow->display)) shmem_flag = 1;
+ if (!shmem_flag) {
+ printf("no shmem available.\n");
+ return;
+ }
+
+
+ if (haveXVSupport(xWindow)==true) {
+ supportedModes = _IMAGE_DESK | _IMAGE_DOUBLE | _IMAGE_FULL | _IMAGE_RESIZE;
+ lSupport=true;
+ } else {
+ return;
+ }
+
+ if (ditherWrapper == NULL) {
+ ditherWrapper=new Dither2YUV();
+ }
+ imageID = -1;
+#endif
+}
+
+int ImageXVDesk::support() {
+ return lSupport;
+}
+
+int ImageXVDesk::openImage(int imageMode) {
+
+
+ if (imageMode & _IMAGE_FULL) {
+ XResizeWindow(xWindow->display, xWindow->window,
+ xWindow->screenptr->width, xWindow->screenptr->height);
+ setKeepRatio(true);
+ } else if (imageMode & _IMAGE_DOUBLE) {
+ XResizeWindow(xWindow->display, xWindow->window,
+ xWindow->width * 2, xWindow->height * 2);
+ setKeepRatio(false);
+ } else {
+ setKeepRatio(false);
+ }
+
+ return true;
+}
+
+
+int ImageXVDesk::closeImage() {
+ freeImage();
+ return true;
+}
+
+void ImageXVDesk::ditherImage(YUVPicture* pic) {
+
+#ifdef X11_XV
+ int x_return;
+ int y_return;
+ int height, dy;
+ unsigned int border_width_return;
+ unsigned int depth_return;
+ unsigned int _w;
+ unsigned int _h;
+ Window _dw;
+
+ if (xWindow == NULL) {
+ cout << "ImageXVDesk::ditherImage - you have to call before dithering an image!" << endl;
+ return;
+ }
+
+ // check for not supported formats and if possible convert them
+ int inputType=pic->getImageType();
+ if (inputType == PICTURE_RGB_FLIPPED) {
+ cout << "xv for flipped rgb not implemented"<<endl;
+ return;
+ }
+
+ // create xv image
+ int id;
+ if (imageID != pic->getImageType()) {
+ imageID = pic->getImageType();
+ switch (imageID) {
+ case PICTURE_YUVMODE_CR_CB:
+ case PICTURE_YUVMODE_CB_CR:
+ case PICTURE_RGB:
+ id = GUID_YUV12_PLANAR;
+ break;
+ case PICTURE_YUVMODE_YUY2:
+ id = GUID_YUY2_PACKED;
+ break;
+ case PICTURE_YUVMODE_UYVY:
+ id = GUID_UYVY_PACKED;
+ break;
+ default:
+ cout << "unknown type for yuv image!" << endl;
+ return;
+ }
+ freeImage();
+
+ createImage(id);
+ }
+
+ XGetGeometry(xWindow->display,(Drawable)xWindow->window,
+ &_dw, &x_return, &y_return, &_w, &_h,
+ &border_width_return, &depth_return);
+
+ // now dither the image
+
+ // we (currently) cannot create yuvPicture _in_
+ // the shared segment here we copy it
+
+ unsigned char* image=pic->getImagePtr();
+ if (inputType == PICTURE_RGB) {
+ ditherWrapper->doDither(pic,
+ DefaultDepth(xWindow->display,xWindow->screennum),
+ _SIZE_NORMAL, (unsigned char*) yuv_image->data, 0);
+ } else {
+ memcpy(yuv_image->data,image,pic->getImageSize());
+ }
+
+ if (keepRatio) {
+ height = (_w * yuv_image->height) / yuv_image->width;
+ dy = (((int) _h) - height + 1) / 2;
+ XvShmPutImage(xWindow->display, xv_port,xWindow->window,
+ xWindow->gc, yuv_image,
+ 0, 0, yuv_image->width, yuv_image->height,
+ 0, dy, _w, height, False);
+ if (dy > 0) {
+ XFillRectangle(xWindow->display, xWindow->window,xWindow->gc,
+ 0, 0, _w, dy);
+ XFillRectangle(xWindow->display, xWindow->window,xWindow->gc,
+ 0, height+dy-1, _w, dy+1);
+ }
+ } else {
+ XvShmPutImage(xWindow->display, xv_port,xWindow->window,
+ xWindow->gc, yuv_image,
+ 0, 0, yuv_image->width, yuv_image->height,
+ 0, 0, _w, _h, False);
+ }
+#endif
+}
+
+
+void ImageXVDesk::putImage() {
+
+ //XFlush(xWindow->display);
+ XSync(xWindow->display, false);
+}
+
+void ImageXVDesk::setKeepRatio(bool enable)
+{
+#ifdef X11_XV
+ keepRatio = enable;
+#endif
+}
+
+
+int ImageXVDesk::haveXVSupport(XWindow* xWindow) {
+#ifdef X11_XV
+ int ret;
+ unsigned int p_version=0;
+ unsigned int p_release=0;
+ unsigned int p_request_base=0;
+ unsigned int p_event_base=0;
+ unsigned int p_error_base=0;
+
+ unsigned int p_num_adaptors=0;
+
+ /**------------------------------- XV ------------------------------------*/
+
+ /** query and print Xvideo properties */
+
+ ret = XvQueryExtension(xWindow->display,
+ &p_version, &p_release, &p_request_base,
+ &p_event_base, &p_error_base);
+ if (ret != Success) {
+ if (ret == XvBadExtension) {
+ printf("XvBadExtension returned at XvQueryExtension.\n");
+ } else if (ret == XvBadAlloc) {
+ printf("XvBadAlloc returned at XvQueryExtension.\n");
+ } else {
+ printf("other error happened at XvQueryExtension.\n");
+ }
+ return false;
+ }
+ /*
+ printf("========================================\n");
+ printf("XvQueryExtension returned the following:\n");
+ printf("p_version : %u\n", p_version);
+ printf("p_release : %u\n", p_release);
+ printf("p_request_base : %u\n", p_request_base);
+ printf("p_event_base : %u\n", p_event_base);
+ printf("p_error_base : %u\n", p_error_base);
+ printf("========================================\n");
+ */
+
+ ret = XvQueryAdaptors(xWindow->display, DefaultRootWindow(xWindow->display),
+ &p_num_adaptors, &ai);
+
+ if (ret != Success) {
+ if (ret == XvBadExtension) {
+ printf("XvBadExtension returned at XvQueryExtension.\n");
+ } else if (ret == XvBadAlloc) {
+ printf("XvBadAlloc returned at XvQueryExtension.\n");
+ } else {
+ printf("other error happaned at XvQueryAdaptors.\n");
+ }
+ return false;
+ }
+ /*
+ printf("=======================================\n");
+ printf("XvQueryAdaptors returned the following:\n");
+ printf("%d adaptors available.\n", p_num_adaptors);
+ */
+ if (p_num_adaptors == 0) {
+ //cout << "no adaptors found. XV not possible"<<endl;
+ return false;
+ }
+
+ unsigned int i;
+ unsigned int j;
+
+ for (i = 0; i < p_num_adaptors; i++) {
+ /*
+ printf(" name: %s\n"
+ " type: %s%s%s%s%s\n"
+ " ports: %ld\n"
+ " first port: %ld\n",
+ ai[i].name,
+ (ai[i].type & XvInputMask) ? "input | " : "",
+ (ai[i].type & XvOutputMask) ? "output | " : "",
+ (ai[i].type & XvVideoMask) ? "video | " : "",
+ (ai[i].type & XvStillMask) ? "still | " : "",
+ (ai[i].type & XvImageMask) ? "image | " : "",
+ ai[i].num_ports,
+ ai[i].base_id);
+ */
+ xv_port = ai[i].base_id;
+
+ //printf("adaptor %d ; format list:\n", i);
+ for (j = 0; j < ai[i].num_formats; j++) {
+ /*
+ printf(" depth=%d, visual=%ld\n",
+ ai[i].formats[j].depth,
+ ai[i].formats[j].visual_id);
+ */
+ }
+ unsigned int p;
+ unsigned int encodings;
+ int attributes;
+ int formats;
+
+ for (p = ai[i].base_id; p < ai[i].base_id+ai[i].num_ports; p++) {
+
+ //printf(" encoding list for port %d\n", p);
+ if (XvQueryEncodings(xWindow->display, p, &encodings, &ei) != Success) {
+ //printf("XvQueryEncodings failed.\n");
+ continue;
+ }
+ for (j = 0; j < encodings; j++) {
+ /*
+ printf(" id=%ld, name=%s, size=%ldx%ld, numerator=%d, denominator=%d\n",
+ ei[j].encoding_id, ei[j].name, ei[j].width, ei[j].height,
+ ei[j].rate.numerator, ei[j].rate.denominator);
+ */
+ }
+ XvFreeEncodingInfo(ei);
+ int k;
+ //printf(" attribute list for port %d\n", p);
+ at = XvQueryPortAttributes(xWindow->display, p, &attributes);
+ for (k = 0; k < attributes; k++) {
+ /*
+ printf(" name: %s\n"
+ " flags: %s%s\n"
+ " min_color: %i\n"
+ " max_color: %i\n",
+ at[k].name,
+ (at[k].flags & XvGettable) ? " get" : "",
+ (at[k].flags & XvSettable) ? " set" : "",
+ at[k].min_value, at[k].max_value);
+ */
+ }
+ if (at)
+ XFree(at);
+
+ //printf(" image format list for port %d\n", p);
+ fo = XvListImageFormats(xWindow->display, p, &formats);
+ for (k = 0; k < formats; k++) {
+ /*
+ printf(" 0x%x (%4.4s) %s\n",
+ fo[k].id,
+ (char *)&fo[k].id,
+ (fo[k].format == XvPacked) ? "packed" : "planar");
+ */
+ }
+ if (fo)
+ XFree(fo);
+ }
+ printf("\n");
+ }
+ if (p_num_adaptors > 0)
+ XvFreeAdaptorInfo(ai);
+ if (xv_port == -1) {
+ return false;
+ }
+#endif
+ return true;
+
+}
+
+
+void ImageXVDesk::freeImage() {
+#ifdef X11_XV
+ if (xWindow == NULL) {
+ return;
+ }
+ if (yuv_shminfo.shmid >=0) {
+ XShmDetach(xWindow->display,&yuv_shminfo);
+ if(yuv_shminfo.shmaddr) {
+ shmdt(yuv_shminfo.shmaddr);
+ XFree(yuv_image);
+ yuv_shminfo.shmaddr=NULL;
+ }
+ XSync(xWindow->display, False);
+ yuv_shminfo.shmid=-1;
+ }
+#endif
+}
+
+
+void ImageXVDesk::createImage(int id) {
+#ifdef X11_XV
+ if (xWindow == NULL) {
+ cout << "ImageXVDesk::freeImage - you have to call init before creating an image!" << endl;
+ return;
+ }
+
+ yuv_image = XvShmCreateImage(xWindow->display, xv_port,
+ id, 0,
+ xWindow->width,
+ xWindow->height, &yuv_shminfo);
+
+ yuv_shminfo.shmid = shmget(IPC_PRIVATE,
+ yuv_image->data_size, IPC_CREAT | 0777);
+ yuv_shminfo.shmaddr = yuv_image->data =
+ (char*)shmat(yuv_shminfo.shmid, 0, 0);
+ yuv_shminfo.readOnly = False;
+
+ if (!XShmAttach(xWindow->display, &yuv_shminfo)) {
+ printf("XShmAttach failed !\n");
+ lSupport=false;
+ return;
+ }
+ shmctl(yuv_shminfo.shmid, IPC_RMID, 0);
+#endif
+}
diff --git a/mpeglib/lib/util/render/x11/imageXVDesk.h b/mpeglib/lib/util/render/x11/imageXVDesk.h
new file mode 100644
index 00000000..44124428
--- /dev/null
+++ b/mpeglib/lib/util/render/x11/imageXVDesk.h
@@ -0,0 +1,88 @@
+/*
+ xfree 4.0 XV extension desk mode
+ 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 __IMAGEXVDESK_H
+#define __IMAGEXVDESK_H
+
+#include "xinit.h"
+
+#include "../imageBase.h"
+#include "../dither2YUV/dither2YUV.h"
+
+#include <stdio.h>
+
+#if !defined(__NetBSD__)
+#include <semaphore.h>
+#endif
+
+//#undef X11_XV
+
+#define GUID_YUV12_PLANAR 0x32315659
+#define GUID_I420_PLANAR 0x30323449
+#define GUID_YUY2_PACKED 0x32595559
+#define GUID_UYVY_PACKED 0x59565955
+
+/**
+ The XV extension dither yuv images in hardware and allows
+ scaling of images.
+ But its currently not supported by many drivers.
+
+*/
+
+
+class ImageXVDesk : public ImageBase {
+
+#ifdef X11_XV
+ XvAdaptorInfo *ai;
+ XvEncodingInfo *ei;
+ XvAttribute *at;
+ XvImageFormatValues *fo;
+
+ XvImage *yuv_image;
+ bool keepRatio;
+
+ int xv_port;
+ int imageID;
+
+ int shmem_flag;
+ XShmSegmentInfo yuv_shminfo;
+#endif
+ Dither2YUV* ditherWrapper;
+
+ int lSupport;
+ XWindow* xWindow;
+
+ public:
+ ImageXVDesk();
+ ~ImageXVDesk();
+
+ void init(XWindow* xWindow, YUVPicture* pic = NULL);
+
+ int support();
+
+ int openImage(int imageMode);
+ int closeImage();
+
+ void ditherImage(YUVPicture* pic);
+ void putImage();
+
+ void setKeepRatio(bool enable);
+
+ private:
+ int haveXVSupport(XWindow* xWindow);
+ void freeImage();
+ void createImage(int id);
+
+};
+
+#endif
diff --git a/mpeglib/lib/util/render/x11/initDisplay.cpp b/mpeglib/lib/util/render/x11/initDisplay.cpp
new file mode 100644
index 00000000..d0029eb6
--- /dev/null
+++ b/mpeglib/lib/util/render/x11/initDisplay.cpp
@@ -0,0 +1,255 @@
+/*
+ here are the different initialisation routines for different displays
+ Copyright (C) 1999 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 "initDisplay.h"
+
+#include <iostream>
+
+using namespace std;
+
+
+
+static unsigned long wpixel[256];
+
+
+
+
+/*
+ *--------------------------------------------------------------
+ *
+ * InitColorDisplay --
+ *
+ * Initialized display for full color output.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *--------------------------------------------------------------
+ */
+
+void initColorDisplay(XWindow* xwindow) {
+ XWindowAttributes winattr;
+
+
+ XGetWindowAttributes(xwindow->display, xwindow->window, &winattr);
+
+ xwindow->redMask = winattr.visual->red_mask;
+ xwindow->greenMask = winattr.visual->green_mask;
+ xwindow->blueMask = winattr.visual->blue_mask;
+}
+
+
+
+
+
+
+
+/*
+ *--------------------------------------------------------------
+ *
+ * FindFullColorVisual
+ *
+ * Returns a pointer to a full color bit visual on the display
+ *
+ * Results:
+ * See above.
+ *
+ * Side effects:
+ * Unknown.
+ *
+ *--------------------------------------------------------------
+ */
+Visual* FindFullColorVisual (Display* dpy,int* depth) {
+ XVisualInfo vinfo;
+ XVisualInfo *vinfo_ret;
+ int numitems, maxdepth;
+
+#if defined(__cplusplus) || defined(c_plusplus)
+ vinfo.c_class = TrueColor;
+#else
+ vinfo.class = TrueColor;
+#endif
+
+ vinfo_ret = XGetVisualInfo(dpy, VisualClassMask, &vinfo, &numitems);
+
+ if (numitems == 0) return NULL;
+
+ maxdepth = 0;
+ while(numitems > 0) {
+ if (vinfo_ret[numitems-1].depth > maxdepth) {
+ maxdepth = vinfo_ret[numitems-1 ].depth;
+ }
+ numitems--;
+ }
+ XFree((void *) vinfo_ret);
+
+ if (maxdepth < 16) return NULL;
+
+ if (XMatchVisualInfo(dpy, DefaultScreen(dpy), maxdepth,
+ TrueColor, &vinfo)) {
+ *depth = maxdepth;
+ return vinfo.visual;
+ }
+
+ return NULL;
+}
+
+
+/*
+ *--------------------------------------------------------------
+ *
+ * CreateFullColorWindow
+ *
+ * Creates a window capable of handling 32 bit color.
+ *
+ * Results:
+ * See above.
+ *
+ * Side effects:
+ * Unknown.
+ *
+ *--------------------------------------------------------------
+ */
+void CreateFullColorWindow (XWindow* xwindow) {
+ int depth;
+ Visual *visual;
+ XSetWindowAttributes xswa;
+ unsigned long mask;
+ unsigned int c_class;
+ int screen;
+ Display *dpy=xwindow->display;
+ /*
+ int x = xinfo->hints.x,
+ y = xinfo->hints.y;
+ unsigned int w = xinfo->hints.width,
+ h = xinfo->hints.height;
+ */
+ screen = XDefaultScreen(dpy);
+ c_class = InputOutput; /* Could be InputOnly */
+ if (xwindow->visual == NULL) {
+ xwindow->visual = visual = FindFullColorVisual (dpy, &depth);
+ xwindow->depth = depth;
+ } else {
+ visual=xwindow->visual;
+ depth=xwindow->depth;
+ }
+
+ if (visual == NULL) {
+ cout << "visual is null"<<endl;
+ return;
+ }
+ mask = CWBackPixel | CWColormap | CWBorderPixel;
+ if (xwindow->colormap==0) {
+ xswa.colormap = XCreateColormap(dpy,
+ XRootWindow(dpy, screen),
+ visual, AllocNone);
+ } else xswa.colormap = xwindow->colormap;
+ xswa.background_pixel = BlackPixel(dpy, DefaultScreen(dpy));
+ xswa.border_pixel = WhitePixel(dpy, DefaultScreen(dpy));
+ XSetWindowColormap(xwindow->display,xwindow->window,xwindow->colormap);
+
+
+ /*
+ xwindow->window = XCreateWindow(dpy, RootWindow(dpy, screen), x, y, w, h,
+ (unsigned int) 1, depth, c_class,
+ visual, mask, &xswa);
+ */
+}
+
+
+
+
+
+
+
+/*
+ *--------------------------------------------------------------
+ *
+ * InitSimpleDisplay --
+ *
+ * Initialized display, sets up colormap, etc. Use for 8 Bit color
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *--------------------------------------------------------------
+ */
+
+void initSimpleDisplay(XWindow* xwindow) {
+ int ncolors = LUM_RANGE*CB_RANGE*CR_RANGE;
+ XColor xcolor;
+ int i, lum_num, cr_num, cb_num;
+ unsigned char r, g, b;
+ Colormap dcmap;
+ Display *display;
+ ColorTable8Bit colorTable8Bit;
+
+ display = xwindow->display;
+
+
+ xwindow->colormap = XDefaultColormap(display, DefaultScreen(display));
+ dcmap = xwindow->colormap;
+
+ xcolor.flags = DoRed | DoGreen | DoBlue;
+
+
+ //if (xinfo->owncmFlag) goto create_map;
+
+retry_alloc_colors:
+ for (i=0; i<ncolors; i++) {
+
+ lum_num = (i / (CR_RANGE*CB_RANGE))%LUM_RANGE;
+ cr_num = (i / CB_RANGE)%CR_RANGE;
+ cb_num = i % CB_RANGE;
+
+ colorTable8Bit.ConvertColor(lum_num, cr_num, cb_num, &r, &g, &b);
+
+ xcolor.red = r * 256;
+ xcolor.green = g * 256;
+ xcolor.blue = b * 256;
+
+ if ((XAllocColor(display,xwindow->colormap , &xcolor) == 0
+ && xwindow->colormap == dcmap)) {
+ int j;
+ unsigned long tmp_pixel;
+ XWindowAttributes xwa;
+
+ // Free colors.
+ for (j = 0; j < i; j ++) {
+ tmp_pixel = wpixel[j];
+ XFreeColors(display,xwindow->colormap , &tmp_pixel, 1, 0);
+ }
+
+
+ //create_map:
+ XGetWindowAttributes(display, xwindow->window, &xwa);
+ xwindow->colormap = XCreateColormap(display, xwindow->window,
+ xwa.visual, AllocNone);
+ XSetWindowColormap(display, xwindow->window,xwindow->colormap );
+
+ goto retry_alloc_colors;
+ }
+ xwindow->pixel[i]=xcolor.pixel;
+ wpixel[i] = xcolor.pixel;
+ }
+
+}
+
+
diff --git a/mpeglib/lib/util/render/x11/initDisplay.h b/mpeglib/lib/util/render/x11/initDisplay.h
new file mode 100644
index 00000000..62841f19
--- /dev/null
+++ b/mpeglib/lib/util/render/x11/initDisplay.h
@@ -0,0 +1,34 @@
+/*
+ here are the different initialisation routines for different displays
+ Copyright (C) 1999 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 __INITDISPLAY_H
+#define __INITDISPLAY_H
+
+#include "math.h"
+#include "xinit.h"
+#include "../dither/colorTable8Bit.h"
+
+
+
+extern void initColorDisplay(XWindow* xwindow);
+extern void initSimpleDisplay(XWindow* xwindow);
+
+// helper functions
+Visual *FindFullColorVisual (Display *dpy ,int *depth);
+void CreateFullColorWindow (XWindow* xwindow);
+
+
+
+#endif
diff --git a/mpeglib/lib/util/render/x11/x11Surface.cpp b/mpeglib/lib/util/render/x11/x11Surface.cpp
new file mode 100644
index 00000000..d7b8f052
--- /dev/null
+++ b/mpeglib/lib/util/render/x11/x11Surface.cpp
@@ -0,0 +1,389 @@
+/*
+ surface wrapper for X11 Window
+ 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 "x11Surface.h"
+
+#include <iostream>
+
+using namespace std;
+
+const char *ERR_XI_STR[] = {
+ "X initialisation OK!",
+ "No Shared Memory available",
+ "cannot open Display",
+ "bad color depth",
+ "can't create Window",
+ "can't alloc memory for virtual screen",
+ "cannot create XImage",
+ "can't alloc memory for Shared memory segment info",
+ "cannot create Shared Memory XImage",
+ "Shared memory segment info error",
+ "Shared memory virtual screen allocation failed",
+ "cannot attach Shared Memory segment to display"
+};
+
+
+#ifndef KDE_USE_FINAL
+static int dummy(Display* , XErrorEvent*) {
+ cout << "received x11 error!"<<endl;
+ return true;
+}
+#endif
+
+X11Surface::X11Surface() {
+ xWindow=(XWindow *)malloc(sizeof(XWindow));
+ xWindow->lOpen=false;
+ xWindow->x = xWindow->y = 0;
+ xWindow->window = 0;
+ m_windowIdAvailable = false;
+
+ imageMode=_IMAGE_NONE;
+
+ imageCurrent=NULL;
+ xWindow->lOpen=false;
+
+
+ xWindow->display=XOpenDisplay(NULL);
+ if (xWindow->display)
+ XFlush(xWindow->display);
+ xWindow->redMask=0;
+ xWindow->greenMask=0;
+ xWindow->blueMask=0;
+ lXVAllow=true;
+
+ images=0;
+ imageList = new ImageBase* [4];
+ imageList[images++] = new ImageXVDesk();
+ imageList[images++] = new ImageDGAFull();
+ imageList[images++] = new ImageDeskX11();
+ imageList[images] = NULL;
+}
+
+
+X11Surface::~X11Surface() {
+ close();
+ if (xWindow->display)
+ XCloseDisplay(xWindow->display);
+ free(xWindow);
+
+ for (int count=0 ; count<images ; count++) {
+ if (imageList[count] != NULL)
+ delete imageList[count];
+ }
+ delete [] imageList;
+}
+
+
+int X11Surface::getHeight() {
+ return xWindow->height;
+}
+
+
+int X11Surface::getWidth() {
+ return xWindow->width;
+}
+
+int X11Surface::isOpen() {
+ return xWindow->lOpen;
+}
+
+int X11Surface::x11WindowId() {
+ if(m_windowIdAvailable)
+ return xWindow->window;
+ else
+ return -1;
+}
+
+int X11Surface::open(int width, int height,const char *title, bool border) {
+
+ close();
+ xWindow->width=width;
+ xWindow->height=height;
+
+ if(!xWindow->display) {
+ printf("\nX initialisation error:\n *** %s\n",ERR_XI_STR[ERR_XI_DISPLAY]);
+ printf("check ipcs and delete resources with ipcrm\n");
+ exit(0);
+ }
+
+ xWindow->screennum=DefaultScreen(xWindow->display);
+ xWindow->screenptr=DefaultScreenOfDisplay(xWindow->display);
+ xWindow->visual=DefaultVisualOfScreen(xWindow->screenptr);
+ xWindow->depth=DefaultDepth(xWindow->display,xWindow->screennum);
+
+ switch(xWindow->depth) {
+ case 8:
+ xWindow->pixelsize=1;
+ break;
+ case 16:
+ xWindow->pixelsize=2;
+ break;
+ case 24:
+ xWindow->pixelsize=4;
+ break;
+ case 32:
+ xWindow->pixelsize=4;
+ break;
+ default:
+ cout << "unknown pixelsize for depth:"<<xWindow->depth<<endl;
+ exit(0);
+ }
+
+ XColor background, ignored;
+ XAllocNamedColor (xWindow->display,
+ DefaultColormap (xWindow->display, xWindow->screennum),
+ "black", &background, &ignored);
+
+ XSetWindowAttributes attributes;
+ attributes.background_pixel=background.pixel;
+ attributes.backing_store=NotUseful;
+ attributes.override_redirect=True;
+
+ xWindow->window=XCreateWindow(xWindow->display,
+ RootWindowOfScreen(xWindow->screenptr),
+ 0,0,
+ xWindow->width,
+ xWindow->height,0,
+ xWindow->depth,
+ InputOutput, xWindow->visual,
+ (border) ? CWBackingStore : CWBackPixel|CWOverrideRedirect,
+ &attributes);
+
+ m_windowIdAvailable = true;
+ if(!xWindow->window) {
+ printf("\nX initialisation error:\n *** %s\n",ERR_XI_STR[ERR_XI_WINDOW]);
+ printf("check ipcs and delete resources with ipcrm\n");
+ return false;
+ }
+
+ WM_DELETE_WINDOW = XInternAtom(xWindow->display, "WM_DELETE_WINDOW", False);
+ XSetWMProtocols(xWindow->display, xWindow->window, &WM_DELETE_WINDOW, 1);
+
+ XSetErrorHandler(dummy);
+
+ XStoreName(xWindow->display,xWindow->window,title);
+ XSelectInput(xWindow->display,xWindow->window,
+ ExposureMask|KeyPressMask|KeyReleaseMask|ButtonPressMask);
+ xWindow->gc=XCreateGC(xWindow->display,xWindow->window,0,NULL);
+ XMapRaised(xWindow->display,xWindow->window);
+
+ if (xWindow->depth >= 16) {
+ initColorDisplay(xWindow);
+
+ } else {
+ // depth is <= 8
+ // allocate memory for dithertables
+ // gets the rgb masks
+ initColorDisplay(xWindow);
+ // create 8 bit dithertables
+ // create private colormap
+ initSimpleDisplay(xWindow);
+
+ }
+
+ xWindow->palette=NULL;
+ xWindow->screensize=xWindow->height*xWindow->width*xWindow->pixelsize;
+ xWindow->lOpen=true;
+
+ for (int count=0 ; count<images ; count++) {
+ if (imageList[count] != NULL)
+ imageList[count]->init(xWindow);
+ }
+
+ return true;
+}
+
+
+int X11Surface::close() {
+ if (isOpen()==false) {
+ return true;
+ }
+ closeImage();
+
+ XFreeGC(xWindow->display,xWindow->gc);
+ XDestroyWindow(xWindow->display,xWindow->window);
+
+ xWindow->lOpen=false;
+
+
+ return true;
+}
+
+ImageBase *X11Surface::findImage(int mode) {
+ for (int count=0 ; count<images ; count++) {
+ if ((imageList[count] == NULL) || (IS_DISABLED(imageList[count])))
+ continue;
+
+ if (imageList[count]->supportedModes & mode)
+ return imageList[count];
+ }
+ return NULL;
+}
+
+ImageBase **X11Surface::getModes() {
+ return imageList;
+}
+
+void X11Surface::setModes(ImageBase **modes) {
+ imageList = modes;
+}
+
+int X11Surface::openImage(int mode, YUVPicture*) {
+ if (imageMode != _IMAGE_NONE) {
+ cout << "bad open error X11Surface::openImage"<<endl;
+ return false;
+ }
+ if (mode == _IMAGE_NONE) {
+ cout << "X11Surface::openImage - no valid mode specified"<<endl;
+ return false;
+ }
+
+ ImageBase *newImage=findImage(mode);
+
+ if (newImage == NULL) {
+ cout << " X11Surface::openImage - no matching image found"<<endl;
+ imageMode=_IMAGE_NONE;
+ } else {
+ /*
+ printf("Best image found: %s\n", newImage->getIdentifier());
+ printf("\tsupported modes: desk=%d, double=%d, full=%d, resize=%d\n",
+ HAS_DESK(newImage),
+ HAS_DOUBLE(newImage),
+ HAS_FULL(newImage),
+ HAS_RESIZE(newImage));
+ */
+
+ open(xWindow->width, xWindow->height, "mpeglib", !(mode & _IMAGE_FULL));
+ newImage->openImage(mode);
+ if (!IS_FULL(mode)) {
+ XMoveWindow(xWindow->display, xWindow->window,
+ xWindow->x, xWindow->y);
+
+ XSizeHints hints;
+ hints.flags = PMaxSize;
+ if (HAS_RESIZE(newImage)) {
+ hints.max_width = INT_MAX;
+ hints.max_height = INT_MAX;
+ } else {
+ hints.max_width = xWindow->width;
+ hints.max_height = xWindow->height;
+ }
+ XSetWMNormalHints(xWindow->display, xWindow->window, &hints);
+ }
+
+ imageMode=mode;
+ }
+ imageCurrent = newImage;
+ XSync(xWindow->display,true);
+ return (imageCurrent != NULL);
+}
+
+
+int X11Surface::closeImage() {
+
+ if ((imageMode == _IMAGE_NONE) || (!xWindow->lOpen))
+ return false;
+
+ ImageBase *old = imageCurrent;
+ imageCurrent=NULL;
+
+ XWindowAttributes attr;
+ Window junkwin;
+
+ if (!IS_FULL(imageMode)) {
+ if (!XGetWindowAttributes(xWindow->display, xWindow->window, &attr))
+ cout << "Can't get window attributes." << endl;
+
+ XTranslateCoordinates (xWindow->display, xWindow->window, attr.root,
+ -attr.border_width,
+ -attr.border_width,
+ &xWindow->x, &xWindow->y, &junkwin);
+ }
+
+ imageMode=_IMAGE_NONE;
+ old->closeImage();
+
+ return true;
+}
+
+
+int X11Surface::dither(YUVPicture* pic) {
+ if (imageCurrent != NULL) {
+ imageCurrent->ditherImage(pic);
+ }
+ return true;
+}
+
+
+int X11Surface::putImage(YUVPicture* ) {
+ if (imageCurrent != NULL) {
+ imageCurrent->putImage();
+ }
+ return true;
+}
+
+
+int X11Surface::getDepth() {
+ return xWindow->depth;
+}
+
+int X11Surface::getImageMode() {
+ return imageMode;
+}
+
+int X11Surface::checkEvent(int* newMode) {
+ XEvent event;
+
+ if (isOpen()==false)
+ return false;
+
+ // check if we forward the call to the FULLSCREEN mode
+ if (!imageCurrent->active()) {
+ if (IS_FULL(imageMode)) {
+ *newMode=imageMode ^ _IMAGE_FULL;
+ return true;
+ }
+ }
+
+ // normal X11 images use the X11 event queue
+ if (XCheckTypedWindowEvent(xWindow->display,
+ xWindow->window,ButtonPress,&event)) {
+ if (event.xbutton.button == Button1) {
+ if (findImage(_IMAGE_DOUBLE) != NULL)
+ *newMode = imageMode ^ _IMAGE_DOUBLE;
+ } else if (event.xbutton.button == Button3) {
+ if (findImage(_IMAGE_FULL) != NULL)
+ *newMode = imageMode ^ _IMAGE_DESK ^ _IMAGE_FULL;
+ }
+ return true;
+ }
+ // now check if there are unneeded events in the queue,
+ // then delete them
+ int eventCnt=XPending(xWindow->display);
+ if (eventCnt > 10) {
+ XSync(xWindow->display,true);
+ }
+ return false;
+
+
+}
+
+
+
+void X11Surface::config(const char* key,
+ const char* value, void* ) {
+ if (strcmp(key,"xvAllow")==0) {
+ lXVAllow=atoi(value);
+ }
+}
+
diff --git a/mpeglib/lib/util/render/x11/x11Surface.h b/mpeglib/lib/util/render/x11/x11Surface.h
new file mode 100644
index 00000000..54a6582d
--- /dev/null
+++ b/mpeglib/lib/util/render/x11/x11Surface.h
@@ -0,0 +1,79 @@
+/*
+ surface wrapper for X11 Window
+ 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 __X11SURFACE_H
+#define __X11SURFACE_H
+
+#include <limits.h>
+#include "xinit.h"
+#include "../surface.h"
+#include "initDisplay.h"
+#include "../dither/ditherWrapper.h"
+#include "imageDeskX11.h"
+#include "imageDGAFull.h"
+#include "imageXVDesk.h"
+
+
+
+class X11Surface : public Surface {
+
+ int lOpen;
+ int imageMode;
+
+ XWindow* xWindow;
+
+ ImageBase** imageList;
+ int images;
+
+ ImageBase* imageCurrent;
+
+ Atom WM_DELETE_WINDOW;
+ Atom WM_RESIZE_WINDOW;
+ int lXVAllow;
+
+ public:
+ X11Surface();
+ ~X11Surface();
+
+ int isOpen();
+ int open(int width, int height,const char *title, bool border = false);
+ int close();
+ int getHeight();
+ int getWidth();
+ int getDepth();
+ int getImageMode();
+ int x11WindowId();
+
+ ImageBase *findImage(int mode);
+
+ // these functions grant access to the supported images. be careful when changing
+ // entries, because these are no copies. they are the original values!
+ ImageBase **getModes();
+ void setModes(ImageBase **modes);
+
+ int openImage(int mode, YUVPicture* pic = NULL);
+ int closeImage();
+ int dither(YUVPicture* pic);
+ int putImage(YUVPicture* pic);
+
+ int checkEvent(int* mode);
+
+ void config(const char* key,
+ const char* value,void* user_data);
+
+
+ private:
+ int initX11();
+ bool m_windowIdAvailable;
+};
+#endif
diff --git a/mpeglib/lib/util/render/x11/xinit.h b/mpeglib/lib/util/render/x11/xinit.h
new file mode 100644
index 00000000..c42c290f
--- /dev/null
+++ b/mpeglib/lib/util/render/x11/xinit.h
@@ -0,0 +1,99 @@
+
+#ifndef __XINIT_H__
+#define __XINIT_H__
+
+#define __USE_X_SHAREDMEMORY__
+
+#include <pthread.h>
+
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/keysym.h>
+#include <X11/Xatom.h>
+
+
+
+#ifdef X11_SHARED_MEM
+#include <X11/extensions/XShm.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#endif
+
+
+#ifdef X11_XV
+#include <X11/extensions/Xv.h>
+#include <X11/extensions/Xvlib.h>
+#include <X11/extensions/XShm.h>
+#endif
+
+#ifdef X11_XVIDMODE
+#include <X11/extensions/xf86vmode.h>
+#endif
+
+#ifdef X11_DGA2
+#include <X11/extensions/xf86dga.h>
+#endif
+
+#define ERR_XI_FAILURE 0xFF
+#define ERR_XI_OK 0x00
+#define ERR_XI_NOSHAREDMEMORY 0x01
+#define ERR_XI_DISPLAY 0x02
+#define ERR_XI_BADDEPTH 0x03
+#define ERR_XI_WINDOW 0x04
+#define ERR_XI_VIRTALLOC 0x05
+#define ERR_XI_XIMAGE 0x06
+#define ERR_XI_SHMALLOC 0x07
+#define ERR_XI_SHMXIMAGE 0x08
+#define ERR_XI_SHMSEGINFO 0x09
+#define ERR_XI_SHMVIRTALLOC 0x0A
+#define ERR_XI_SHMATTACH 0x0B
+
+
+
+
+#define PIXEL unsigned long
+
+extern const char *ERR_XI_STR[];
+
+struct XWindow {
+
+ Display *display;
+ Window window;
+ Screen *screenptr;
+ int screennum;
+ Visual *visual;
+ GC gc;
+
+ Colormap colormap;
+ PIXEL *palette;
+ int colorcells;
+
+ int x;
+ int y;
+ int width;
+ int height;
+ int depth;
+ int pixelsize;
+ int screensize;
+ int lOpen;
+
+ // colorMask
+ unsigned int redMask;
+ unsigned int greenMask;
+ unsigned int blueMask;
+
+ // colortable for 8 bit colormap
+ // (created with interference by the XServer)
+ unsigned char pixel[256];
+
+};
+
+
+#endif /* __XINIT_H__ */
diff --git a/mpeglib/lib/util/render/yuvPicture.cpp b/mpeglib/lib/util/render/yuvPicture.cpp
new file mode 100644
index 00000000..e79d3bde
--- /dev/null
+++ b/mpeglib/lib/util/render/yuvPicture.cpp
@@ -0,0 +1,253 @@
+/*
+ describes a picture in yuv format
+ 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 "yuvPicture.h"
+
+#include <iostream>
+
+using namespace std;
+
+static int instanceCnt=0;
+
+YUVPicture::YUVPicture(int width,int height) {
+ this->width=width;
+ this->height=height;
+
+ instance=instanceCnt;
+ instanceCnt++;
+ imagePtr=NULL;
+
+ setImageType(PICTURE_YUVMODE_CR_CB);
+
+
+ startTimeStamp=new TimeStamp();
+ waitTime=new TimeStamp();
+ earlyTime=new TimeStamp();
+ mpegType=-1;
+
+}
+
+
+YUVPicture::~YUVPicture() {
+ delete imagePtr;
+ delete earlyTime;
+ delete startTimeStamp;
+ delete waitTime;
+}
+
+
+
+int YUVPicture::getHeight() {
+ return height;
+}
+
+
+int YUVPicture::getWidth() {
+ return width;
+}
+
+
+
+int YUVPicture::getLumLength() {
+ return lumLength;
+}
+
+
+int YUVPicture::getColorLength() {
+ return colorLength;
+}
+
+int YUVPicture::getImageSize() {
+ return imageSize;
+}
+
+
+
+
+
+
+
+void YUVPicture::print(const char* title) {
+ cout << title <<":";
+ printf(" instance:%d ",instance);
+ printf(" width:%d ",width);
+ printf(" height:%d ",height);
+ cout <<" picPerSec:"<<picPerSec;
+ switch(mpegType) {
+ case 1:
+ printf("I_FRAME ");
+ break;
+ case 2:
+ printf("P_FRAME ");
+ break;
+ case 3:
+ printf("B_FRAME ");
+ break;
+ case 4:
+ printf("D_FRAME ");
+ break;
+ default:
+ printf("<unknown> ");
+ }
+ printf("\n");
+
+
+}
+
+
+void YUVPicture::setPicturePerSecond(float val) {
+ this->picPerSec=val;
+}
+
+
+float YUVPicture::getPicturePerSecond() {
+ return picPerSec;
+}
+
+
+void YUVPicture::setStartTimeStamp(TimeStamp* aStamp) {
+ aStamp->copyTo(startTimeStamp);
+}
+
+
+TimeStamp* YUVPicture::getStartTimeStamp() {
+ return startTimeStamp;
+}
+
+void YUVPicture::setWaitTime(TimeStamp* aStamp) {
+ aStamp->copyTo(waitTime);
+}
+
+
+TimeStamp* YUVPicture::getWaitTime() {
+ return waitTime;
+}
+
+void YUVPicture::setEarlyTime(TimeStamp* earlyTime) {
+ this->earlyTime=earlyTime;
+}
+
+
+TimeStamp* YUVPicture::getEarlyTime() {
+ return earlyTime;
+}
+
+
+
+void YUVPicture::setMpegPictureType(int type) {
+ this->mpegType=type;
+}
+
+
+int YUVPicture::getMpegPictureType() {
+ return mpegType;
+}
+
+
+void YUVPicture::setImageType(int imageType) {
+
+
+ //
+ // Reset everything
+ //
+
+ if (imagePtr != NULL) {
+ delete [] imagePtr;
+ imagePtr=NULL;
+ }
+ this->imageType=imageType;
+
+ lumLength=0;
+ colorLength=0;
+ Cr_mode=NULL;
+ Cb_mode=NULL;
+ luminance_mode=NULL;
+
+
+ //
+ // YUV Images
+ //
+ if ( (imageType == PICTURE_YUVMODE_CR_CB) ||
+ (imageType == PICTURE_YUVMODE_CB_CR) ) {
+
+
+ lumLength=width * height;
+ colorLength=width * height / 4;
+ imageSize=lumLength+colorLength+colorLength;
+
+ // the 64 is some "security" space
+ imagePtr=new unsigned char[imageSize+64];
+
+ if (imagePtr == NULL) {
+ cout << "cannot create image"<<endl;
+ exit(0);
+ }
+
+ // now caculate pointers to start addresses of lum/Cr/Cb blocks
+ // we need the yuvPtr for direct dither in hardware
+ // this should save a memcpy
+
+ luminance = imagePtr;
+ Cr = imagePtr+lumLength;
+ Cb = imagePtr+lumLength+colorLength;
+
+
+ if ( (luminance == NULL) ||
+ (Cr == NULL) ||
+ (Cb == NULL) ) {
+ cout << "allocation luminance/Cr/Cb error"<<endl;
+ exit(0);
+ }
+
+ switch(imageType) {
+ case PICTURE_YUVMODE_CR_CB:
+ Cr_mode=Cr;
+ Cb_mode=Cb;
+ luminance_mode=imagePtr;
+ break;
+ case PICTURE_YUVMODE_CB_CR:
+ Cr_mode=Cb;
+ Cb_mode=Cr;
+ luminance_mode=imagePtr;
+ break;
+ default:
+ cout << "unknown yuv mode:"<<imageType<<endl;
+ }
+ }
+ else if ( (imageType == PICTURE_YUVMODE_YUY2) ||
+ (imageType == PICTURE_YUVMODE_UYVY) ) {
+ // these yuv-modes are packed
+
+ imageSize=width * height * 2;
+
+ // the 64 is some "security" space
+ imagePtr=new unsigned char[imageSize+64];
+
+ if (imagePtr == NULL) {
+ cout << "cannot create image"<<endl;
+ exit(0);
+ }
+ }
+
+ //
+ // RGB Imcdages
+ //
+
+ if ( (imageType == PICTURE_RGB) ||
+ (imageType == PICTURE_RGB_FLIPPED) ){
+ imageSize=width*height*4;
+ imagePtr=new unsigned char[imageSize];
+ }
+ memset(imagePtr,0,imageSize);
+}
diff --git a/mpeglib/lib/util/render/yuvPicture.h b/mpeglib/lib/util/render/yuvPicture.h
new file mode 100644
index 00000000..1995b473
--- /dev/null
+++ b/mpeglib/lib/util/render/yuvPicture.h
@@ -0,0 +1,110 @@
+/*
+ describes a picture in yuv format
+ 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 __YUVPICTURE_H
+#define __YUVPICTURE_H
+
+
+extern "C" {
+#include <stdio.h>
+#include <string.h>
+}
+
+#include "../timeStamp.h"
+
+#define PICTURE_NO_TYPE -1
+
+#define PICTURE_YUVMODE_CR_CB 1
+#define PICTURE_YUVMODE_CB_CR 2
+#define PICTURE_RGB 3
+#define PICTURE_RGB_FLIPPED 4
+#define PICTURE_YUVMODE_YUY2 5
+#define PICTURE_YUVMODE_UYVY 6
+
+class YUVPicture {
+
+ unsigned char* imagePtr; /* Pointer to complete yuv image */
+
+ unsigned char* luminance; /* Luminance plane. */
+ unsigned char* Cr; /* Cr plane. */
+ unsigned char* Cb; /* Cb plane. */
+
+
+ int width;
+ int height;
+
+ float picPerSec;
+ int lumLength;
+ int colorLength;
+ int imageSize;
+
+ TimeStamp* startTimeStamp;
+ TimeStamp* waitTime;
+ TimeStamp* earlyTime;
+
+ int mpegType;
+ int instance;
+ int imageType;
+
+ unsigned char* image_mode; /* start Pointer to complete image */
+ unsigned char* luminance_mode; /* Luminace plane. */
+ unsigned char* Cr_mode; /* Cr plane. */
+ unsigned char* Cb_mode; /* Cb plane. */
+
+ public:
+ YUVPicture(int width,int height);
+ ~YUVPicture();
+
+ //
+ // For YUV Images
+ //
+ inline unsigned char* getLuminancePtr() {return luminance_mode;}
+ inline unsigned char* getCrPtr() {return Cr_mode;}
+ inline unsigned char* getCbPtr() {return Cb_mode;}
+
+ // general
+ inline unsigned char* getImagePtr() {return imagePtr;}
+
+ // use these to swap the image Types
+ inline int getImageType() { return imageType; }
+ void setImageType(int mode);
+
+
+ int getHeight();
+ int getWidth();
+
+ int getLumLength();
+ int getColorLength();
+ int getImageSize();
+
+ void setPicturePerSecond(float val);
+ float getPicturePerSecond();
+
+
+ void setStartTimeStamp(TimeStamp* timeStamp);
+ TimeStamp* getStartTimeStamp();
+
+ void setWaitTime(TimeStamp* waitTime);
+ TimeStamp* getWaitTime();
+
+ void setEarlyTime(TimeStamp* earlyTime);
+ TimeStamp* getEarlyTime();
+
+ void setMpegPictureType(int type);
+ int getMpegPictureType();
+
+
+ void print(const char* title);
+};
+#endif
diff --git a/mpeglib/lib/util/syncClock.cpp b/mpeglib/lib/util/syncClock.cpp
new file mode 100644
index 00000000..6e03bc4b
--- /dev/null
+++ b/mpeglib/lib/util/syncClock.cpp
@@ -0,0 +1,59 @@
+/*
+ basic synchronisation Classs
+ 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 "syncClock.h"
+
+#include <iostream>
+
+using namespace std;
+
+SyncClock::SyncClock() {
+}
+
+
+SyncClock::~SyncClock() {
+}
+
+
+
+int SyncClock::getSyncMode() {
+ cout << "direct virtual call SyncClock::getSyncMode"<<endl;
+ return __SYNC_NONE;
+}
+
+
+void SyncClock::setSyncMode(int) {
+ cout << "direct virtual call SyncClock::setSyncMode"<<endl;
+}
+
+
+
+int SyncClock::syncAudio(double ,double ) {
+ cout << "direct virtual call SyncClock::syncAudio"<<endl;
+ return true;
+}
+
+
+int SyncClock::syncVideo(double,double,
+ TimeStamp*,
+ TimeStamp*) {
+ cout << "direct virtual call SyncClock::syncVideo"<<endl;
+ return true;
+}
+
+
+
+void SyncClock::print(char*) {
+ cout << "direct virtual call print"<<endl;
+}
+
diff --git a/mpeglib/lib/util/syncClock.h b/mpeglib/lib/util/syncClock.h
new file mode 100644
index 00000000..4b6bc2bb
--- /dev/null
+++ b/mpeglib/lib/util/syncClock.h
@@ -0,0 +1,61 @@
+/*
+ basic synchronisation Classs
+ 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 __SYNCCLOCK_H
+#define __SYNCCLOCK_H
+
+#include "timeWrapper.h"
+#include "abstract/abs_thread.h"
+#include "timeStamp.h"
+#include <errno.h>
+
+#define __SYNC_NONE 0
+#define __SYNC_AUDIO 1
+#define __SYNC_VIDEO 2
+#define __SYNC_BOTH 3
+
+
+/**
+ The idea is similar to this:
+ We start a clock and selext a synchronisation mode.
+ (AUDIO,VIDEO,BOTH,NONE)
+ Assume we select AUDIO. When the audio thread delivers an SCR
+ and an PTS, we set the SCR from this set, as the new
+ time reference fo rthis clock.
+ If a video thread enters the class, with an SCR,PTS we wait,
+ or directly return if the PTS is in time or out of time,
+ but we never set the SCR.
+*/
+
+class SyncClock {
+
+
+ public:
+ SyncClock();
+ virtual ~SyncClock();
+
+ virtual int getSyncMode();
+ virtual void setSyncMode(int syncMode);
+
+
+ virtual int syncAudio(double pts,double scr);
+ virtual int syncVideo(double pts,double scr,
+ class TimeStamp* earlyTime,
+ class TimeStamp* waitTime);
+
+ virtual void print(char* text);
+
+
+};
+#endif
diff --git a/mpeglib/lib/util/syncClockMPEG.cpp b/mpeglib/lib/util/syncClockMPEG.cpp
new file mode 100644
index 00000000..53ae7e2d
--- /dev/null
+++ b/mpeglib/lib/util/syncClockMPEG.cpp
@@ -0,0 +1,221 @@
+/*
+ synchronisation of audio/video (PTS) against system clock stamps (SCR)
+ 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 "syncClockMPEG.h"
+
+
+#include <iostream>
+
+using namespace std;
+
+
+SyncClockMPEG::SyncClockMPEG() {
+ syncMode=__SYNC_NONE;
+ abs_thread_mutex_init(&scrMut);
+ abs_thread_mutex_init(&changeMut);
+ lastSCR=0.0;
+ lastPTS=0.0;
+ jitter=0.0;
+ oldjitter=0.0;
+
+ TimeWrapper::gettimeofday(&lastPTS_time);
+
+
+}
+
+
+SyncClockMPEG::~SyncClockMPEG() {
+ abs_thread_mutex_destroy(&changeMut);
+ abs_thread_mutex_destroy(&scrMut);
+}
+
+
+
+int SyncClockMPEG::getSyncMode() {
+ return syncMode;
+}
+
+
+void SyncClockMPEG::setSyncMode(int syncMode) {
+ this->syncMode=syncMode;
+}
+
+
+
+int SyncClockMPEG::syncAudio(double pts,double scr) {
+ switch(syncMode) {
+ case __SYNC_AUDIO:
+ markLastPTSTime(scr,pts);
+ break;
+ default:
+ cout << "syncMode not implemented:"<<syncMode<<endl;
+ }
+ return true;
+}
+
+
+int SyncClockMPEG::syncVideo(double pts,double scr,
+ TimeStamp* earlyTime,
+ TimeStamp* waitTime) {
+ int back;
+ switch(syncMode) {
+ case __SYNC_AUDIO:
+ back=gowait(scr,pts,earlyTime,waitTime);
+ return back;
+ break;
+ case __SYNC_NONE:
+ return true;
+ default:
+ cout << "syncMode not implemented"<<endl;
+ }
+ return true;
+}
+
+
+void SyncClockMPEG::lockSyncClock() {
+ abs_thread_mutex_lock(&changeMut);
+ abs_thread_mutex_lock(&scrMut);
+ abs_thread_mutex_unlock(&changeMut);
+
+}
+
+
+void SyncClockMPEG::unlockSyncClock() {
+ abs_thread_mutex_unlock(&scrMut);
+}
+
+
+double SyncClockMPEG::getPTSTime(double* window) {
+ lockSyncClock();
+ double currentPTS;
+ timeval_t current_time;
+ timeval_t passed_time;
+ TimeWrapper::gettimeofday(&current_time);
+
+ a_Minus_b_Is_C(&current_time,&lastPTS_time,&passed_time);
+ currentPTS=lastPTS+timeval2Double(&passed_time);
+ *window=jitter+oldjitter;
+
+
+ unlockSyncClock();
+ return currentPTS;
+}
+
+
+void SyncClockMPEG::markLastPTSTime(double ,double pts) {
+ double tmp;
+ double expect_time=getPTSTime(&tmp);
+
+ lockSyncClock();
+ oldjitter=jitter;
+ jitter=expect_time-pts;
+
+ TimeWrapper::gettimeofday(&lastPTS_time);
+ lastPTS=pts;
+
+
+ unlockSyncClock();
+ /*
+ cout << "(audio) pts stream:"<<pts
+ << " expect:"<<expect_time<<" jitter:"<<jitter<<endl;
+ */
+
+}
+
+
+int SyncClockMPEG::a_Minus_b_Is_C(timeval_t* a,timeval_t* b,timeval_t* c){
+ c->tv_usec=a->tv_usec;
+ c->tv_sec=a->tv_sec;
+
+ c->tv_usec-=b->tv_usec;
+ c->tv_sec-=b->tv_sec;
+
+ if (c->tv_usec <= 0) {
+ c->tv_usec=c->tv_usec+1000000;
+ c->tv_sec--;
+ }
+ if (c->tv_usec >= 1000000) {
+ c->tv_usec=c->tv_usec-1000000;
+ c->tv_sec++;
+ }
+ return true;
+}
+
+
+double SyncClockMPEG::timeval2Double(timeval_t* a) {
+ return (double)a->tv_sec+(double)(a->tv_usec)/1000000.0;
+}
+
+
+void SyncClockMPEG::double2Timeval(double a,timeval_t* dest) {
+ dest->tv_sec=(int)a;
+ dest->tv_usec=(int)(1000000.0*(double)(a-(double)dest->tv_sec));
+}
+
+
+int SyncClockMPEG::gowait(double ,double pts,
+ TimeStamp* earlyTime,TimeStamp* ) {
+ double window;
+ double currentPTS=getPTSTime(&window);
+ double diff_time;
+
+ // in window we have the jitter
+ // diff_time is positive when we are in the future
+ diff_time=pts-(currentPTS+window);
+
+
+
+ // tolerate one frame (for 25 frames/s) in the future
+ // but wait a bit
+ if (diff_time > 0.0) {
+ diff_time=diff_time/4.0;
+
+ double2Timeval(diff_time,earlyTime->getTime());
+ if (diff_time > 1) {
+ // cannot be, we assume stange clock error
+ earlyTime->set(1,0);
+ }
+
+ return true;
+ }
+
+ earlyTime->set(0,0);
+ // one frame late, display it, without waiting
+ // and hope we catch up
+ if (diff_time > -0.04) {
+ return true;
+ }
+ /*
+ cout << "(video) pts stream:"<<pts
+ << " pts expect:"<<currentPTS
+ << " window:"<<window<<endl;
+ */
+ return false;
+}
+
+
+void SyncClockMPEG::printTime(timeval_t* a,char* text) {
+ cout << text
+ << "time(sec):"<<a->tv_sec
+ << "time(usec)"<<a->tv_usec<<endl;
+}
+
+void SyncClockMPEG::print(char* text) {
+ cout << text
+ << " lastPTS:"<<lastPTS
+ << " lastSCR:"<<lastSCR
+ << " jitter:"<<jitter;
+ printTime(&lastPTS_time,(char*)"lastPTS_time");
+ printTime(&lastSCR_time,(char*)"lastSCR_time");
+}
diff --git a/mpeglib/lib/util/syncClockMPEG.h b/mpeglib/lib/util/syncClockMPEG.h
new file mode 100644
index 00000000..1a812c45
--- /dev/null
+++ b/mpeglib/lib/util/syncClockMPEG.h
@@ -0,0 +1,77 @@
+/*
+ synchronisation of audio/video (PTS) against system clock stamps (SCR)
+ 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 __SYNCCLOCKMPEG_H
+#define __SYNCCLOCKMPEG_H
+
+
+#include "syncClock.h"
+
+/**
+ The idea is similar to this:
+ We start a clock and selext a synchronisation mode.
+ (AUDIO,VIDEO,BOTH,NONE)
+ Assume we select AUDIO. When the audio thread delivers an SCR
+ and an PTS, we set the SCR from this set, as the new
+ time reference fo rthis clock.
+ If a video thread enters the class, with an SCR,PTS we wait,
+ or directly return if the PTS is in time or out of time,
+ but we never set the SCR.
+*/
+
+class SyncClockMPEG : public SyncClock {
+
+ int syncMode;
+ double lastSCR;
+ double lastPTS;
+ double jitter;
+ double oldjitter;
+ timeval_t lastSCR_time;
+ timeval_t lastPTS_time;
+ timeval_t drift_time;
+
+ public:
+ SyncClockMPEG();
+ ~SyncClockMPEG();
+
+ int getSyncMode();
+ void setSyncMode(int syncMode);
+
+
+ int syncAudio(double pts,double scr);
+ int syncVideo(double pts,double scr,
+ class TimeStamp* earlyTime,class TimeStamp* waitTime);
+
+ void print(char* text);
+
+ double getPTSTime(double* window);
+ private:
+
+ void printTime(timeval_t* a,char* text);
+ void markLastPTSTime(double scr,double pts);
+ int gowait(double scr,double pts,
+ class TimeStamp* earlyTime,class TimeStamp* waitTime);
+ int a_Minus_b_Is_C(timeval_t* a,timeval_t* b,timeval_t* c);
+ double timeval2Double(timeval_t* a);
+ void double2Timeval(double a,timeval_t* dest);
+
+ void lockSyncClock();
+ void unlockSyncClock();
+
+ abs_thread_mutex_t scrMut;
+ abs_thread_mutex_t changeMut;
+
+
+};
+#endif
+
diff --git a/mpeglib/lib/util/timeStamp.cpp b/mpeglib/lib/util/timeStamp.cpp
new file mode 100644
index 00000000..2804cc5b
--- /dev/null
+++ b/mpeglib/lib/util/timeStamp.cpp
@@ -0,0 +1,273 @@
+/*
+ class for managing byte positions and associated time positions
+ Copyright (C) 1999 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 "timeStamp.h"
+
+#include <iostream>
+
+using namespace std;
+
+
+TimeStamp::TimeStamp() {
+ key=0;
+ keylen=0;
+ time.tv_sec=0;
+ time.tv_usec=0;
+
+ ptsTimeStamp=0.0;
+ scrTimeStamp=0.0;
+ videoFrameCounter=0;
+ dtsTimeStamp=0.0;
+ lPTSFlag=false;
+
+}
+
+
+TimeStamp::~TimeStamp() {
+}
+
+
+void TimeStamp::copyTo(TimeStamp* dest) {
+ dest->setKey(key,keylen);
+ dest->setTime(&time);
+ dest->setPTSTimeStamp(ptsTimeStamp);
+ dest->setVideoFrameCounter(videoFrameCounter);
+
+ dest->setSCRTimeStamp(scrTimeStamp);
+ dest->setDTSTimeStamp(dtsTimeStamp);
+ dest->setSyncClock(syncClock);
+ dest->setPTSFlag(lPTSFlag);
+}
+
+
+long TimeStamp::getKey() {
+ return key;
+}
+
+int TimeStamp::getKeyLen() {
+ return keylen;
+}
+
+void TimeStamp::setKey(long key,int len) {
+ this->key=key;
+ this->keylen=len;
+}
+
+
+void TimeStamp::setTime(timeval_t* newTime) {
+ time.tv_sec=newTime->tv_sec;
+ time.tv_usec=newTime->tv_usec;
+}
+
+
+void TimeStamp::gettimeofday() {
+ TimeWrapper::gettimeofday(&time);
+}
+
+
+timeval_t* TimeStamp::getTime() {
+ return &time;
+}
+
+
+void TimeStamp::waitForIt() {
+ timeval_t waitTime;
+
+ waitTime.tv_sec=time.tv_sec;
+ waitTime.tv_usec=time.tv_usec;
+
+ if (isPositive()) {
+ //cout << "wait:"<<waitTime.tv_sec<<" usec:"<<waitTime.tv_usec<<endl;
+ TimeWrapper::usleep(&waitTime);
+ }
+
+}
+
+void TimeStamp::addOffset(TimeStamp* stamp) {
+ addOffset(stamp->time.tv_sec,stamp->time.tv_usec);
+}
+
+void TimeStamp::addOffset(int sec,long usec) {
+ time.tv_sec=time.tv_sec+sec;
+ time.tv_usec=time.tv_usec+usec;
+ if (time.tv_usec >= 1000000) {
+ time.tv_usec-=1000000;
+ time.tv_sec++;
+ }
+ if (time.tv_usec < 0) {
+ time.tv_usec+=1000000;
+ time.tv_sec--;
+ }
+}
+
+void TimeStamp::minus(int sec,long usec) {
+
+ time.tv_usec-=usec;
+ time.tv_sec-=sec;
+ if (time.tv_usec <= 0) {
+ time.tv_usec=time.tv_usec+1000000;
+ time.tv_sec--;
+ }
+ if (time.tv_usec >= 1000000) {
+ time.tv_usec=time.tv_usec-1000000;
+ time.tv_sec++;
+ }
+
+}
+
+void TimeStamp::minus(TimeStamp* stamp,TimeStamp* dest) {
+
+ long sec=time.tv_sec;
+ long usec=time.tv_usec;
+
+ minus(stamp->time.tv_sec,stamp->time.tv_usec);
+
+ dest->set(time.tv_sec,time.tv_usec);
+ if (dest != this) {
+ time.tv_sec=sec;
+ time.tv_usec=usec;
+ }
+}
+
+
+int TimeStamp::lessThan(TimeStamp* stamp) {
+ return lessThan(stamp->time.tv_sec,stamp->time.tv_usec);
+}
+
+
+int TimeStamp::lessThan(int sec,long usec) {
+ int back=false;
+ if (time.tv_sec < sec) {
+ back=true;
+ } else {
+ if (time.tv_sec == sec) {
+ if (time.tv_usec < usec) {
+ back=true;
+ }
+ }
+ }
+ return back;
+}
+
+void TimeStamp::set(long sec,long usec) {
+ time.tv_sec=sec;
+ time.tv_usec=usec;
+}
+
+
+
+void TimeStamp::print(const char* name) {
+ cout << name
+ <<" lPTS:"<<lPTSFlag
+ <<" pts:"<<ptsTimeStamp
+ <<" dts:"<<dtsTimeStamp
+ <<" scr:"<<scrTimeStamp
+ <<" key:"<<key
+ <<" sec:"<<time.tv_sec
+ <<" usec:"<<time.tv_usec
+ <<" v-Minor:"<<videoFrameCounter<<endl;
+
+
+}
+
+
+
+
+
+int TimeStamp::isPositive() {
+ if ((time.tv_sec == 0) && (time.tv_usec == 0)) {
+ return false;
+ }
+ return ((time.tv_sec >= 0) && (time.tv_usec >= 0));
+}
+
+
+int TimeStamp::isNegative() {
+ if (time.tv_sec < 0) {
+ return true;
+ }
+ if (time.tv_usec < 0) {
+ return true;
+ }
+ return false;
+}
+
+
+int TimeStamp::getPTSFlag() {
+ return lPTSFlag;
+}
+
+void TimeStamp::setPTSFlag(int lPTSFlag) {
+ this->lPTSFlag=lPTSFlag;
+}
+
+double TimeStamp::getPTSTimeStamp() {
+ return ptsTimeStamp;
+}
+
+
+void TimeStamp::setPTSTimeStamp(double ptsTimeStamp) {
+ this->ptsTimeStamp=ptsTimeStamp;
+}
+
+
+double TimeStamp::getSCRTimeStamp() {
+ return scrTimeStamp;
+}
+
+
+void TimeStamp::setSCRTimeStamp(double scrTimeStamp) {
+ this->scrTimeStamp=scrTimeStamp;
+}
+
+
+double TimeStamp::getDTSTimeStamp() {
+ return dtsTimeStamp;
+}
+
+
+void TimeStamp::setDTSTimeStamp(double dtsTimeStamp) {
+ this->dtsTimeStamp=dtsTimeStamp;
+}
+
+int TimeStamp::getVideoFrameCounter() {
+ return videoFrameCounter;
+}
+
+
+void TimeStamp::setVideoFrameCounter(int nr) {
+ this->videoFrameCounter=nr;
+}
+
+
+
+double TimeStamp::getAsSeconds() {
+ return (double)time.tv_sec+(double)time.tv_usec/(double)1000000;
+}
+
+
+
+SyncClock* TimeStamp::getSyncClock() {
+ return syncClock;
+}
+
+void TimeStamp::setSyncClock(SyncClock* syncClock) {
+ this->syncClock=syncClock;
+}
+
+
+
+
+
+
+
diff --git a/mpeglib/lib/util/timeStamp.h b/mpeglib/lib/util/timeStamp.h
new file mode 100644
index 00000000..a45bb582
--- /dev/null
+++ b/mpeglib/lib/util/timeStamp.h
@@ -0,0 +1,92 @@
+/*
+ class for managing byte positions and associated time positions
+ Copyright (C) 1999 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 __TIMESTAMP_H
+#define __TIMESTAMP_H
+
+
+#include "syncClock.h"
+
+
+class TimeStamp {
+
+ long key;
+ int keylen;
+
+ int videoFrameCounter;
+
+ timeval_t time;
+
+ int lPTSFlag;
+
+ double ptsTimeStamp;
+ double scrTimeStamp;
+ double dtsTimeStamp;
+
+ class SyncClock* syncClock;
+
+ public:
+ TimeStamp();
+ ~TimeStamp();
+
+ void gettimeofday();
+ void set(long sec,long usec);
+
+ void addOffset(TimeStamp* stamp);
+ void addOffset(int sec,long usec);
+ void copyTo(TimeStamp* dest);
+
+ long getKey();
+ int getKeyLen();
+ void setKey(long key,int keylen);
+
+ int getPTSFlag();
+ void setPTSFlag(int lPTSFlag);
+
+
+ double getPTSTimeStamp();
+ void setPTSTimeStamp(double ptsTimeStamp);
+
+ double getDTSTimeStamp();
+ void setDTSTimeStamp(double dtsTimeStamp);
+
+ double getSCRTimeStamp();
+ void setSCRTimeStamp(double scrTimeStamp);
+
+ int getVideoFrameCounter();
+ void setVideoFrameCounter(int nr);
+
+ SyncClock* getSyncClock();
+ void setSyncClock(class SyncClock* syncClock);
+
+
+ void print(const char* name);
+ void minus(TimeStamp* stamp,TimeStamp* dest);
+ void minus(int sec,long usec);
+ int lessThan(TimeStamp* stamp);
+ int lessThan(int sec,long usec);
+ double getAsSeconds();
+
+ void waitForIt();
+ timeval_t* getTime();
+
+ int isPositive();
+ int isNegative();
+
+ private:
+ void setTime(timeval_t* newTime);
+ void normalize();
+
+
+};
+#endif
diff --git a/mpeglib/lib/util/timeStampArray.cpp b/mpeglib/lib/util/timeStampArray.cpp
new file mode 100644
index 00000000..730dc280
--- /dev/null
+++ b/mpeglib/lib/util/timeStampArray.cpp
@@ -0,0 +1,178 @@
+/*
+ class for managing byte positions and associated time positions
+ Copyright (C) 1999 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 <iostream>
+
+#include "timeStampArray.h"
+
+using namespace std;
+
+
+TimeStampArray::TimeStampArray(char* aName,int entries) {
+
+ writePos=0;
+ readPos=0;
+ fillgrade=0;
+ lastWritePos=0;
+ this->entries=entries;
+ if (entries < 1) {
+ cout << "TimeStampArray entries must be >= 1";
+ exit(0);
+ }
+
+
+ abs_thread_mutex_init(&writeInMut);
+ abs_thread_mutex_init(&changeMut);
+
+
+
+ name=strdup(aName);
+ int i;
+ tStampArray=new TimeStamp*[entries];
+
+ for(i=0;i<entries;i++) {
+ tStampArray[i]=new TimeStamp();
+ }
+
+}
+
+
+TimeStampArray::~TimeStampArray() {
+
+ int i;
+ for(i=0;i<entries;i++) {
+ delete tStampArray[i];
+ }
+ delete [] tStampArray;
+ if (name != NULL) {
+ free(name); // allocated with strdup
+ }
+ abs_thread_mutex_destroy(&writeInMut);
+ abs_thread_mutex_destroy(&changeMut);
+}
+
+TimeStamp* TimeStampArray::getReadTimeStamp() {
+ return tStampArray[readPos];
+}
+
+
+int TimeStampArray::getFillgrade() {
+ return fillgrade;
+}
+
+int TimeStampArray::insertTimeStamp(TimeStamp* src,long key,int len) {
+ if (src == NULL) {
+ return true;
+ }
+ lockStampArray();
+ int back=true;
+ src->copyTo(tStampArray[writePos]);
+ tStampArray[writePos]->setKey(key,len);
+ /*
+ if (fillgrade > 0) {
+ if (tStampArray[lastWritePos]->getKey() == key) {
+ unlockStampArray();
+ return;
+ }
+ }
+ */
+
+ lastWritePos=writePos;
+ writePos++;
+ fillgrade++;
+ if (writePos == entries) {
+ writePos=0;
+ }
+ if (fillgrade == entries) {
+ cout << name<<" TimeStampArray::array overfull forward"<<endl;
+ internalForward();
+ back=false;
+ }
+ unlockStampArray();
+ return back;
+}
+
+
+int TimeStampArray::bytesUntilNext(long key) {
+ lockStampArray();
+ TimeStamp* current=tStampArray[readPos];
+ int back=current->getKey()-key;
+ unlockStampArray();
+ return back;
+}
+
+TimeStamp* TimeStampArray::getTimeStamp(long key) {
+ lockStampArray();
+ TimeStamp* back=tStampArray[readPos];
+ if (key > back->getKey()+back->getKeyLen()) {
+ if (fillgrade > 1) {
+ internalForward();
+ unlockStampArray();
+ return getTimeStamp(key);
+ }
+ }
+
+ /*
+ if (back->getKey() > key) {
+ cout << "key "<<key<<" too big"<<back->getKey()-key<<endl;
+ back->print("key access");
+ }
+ */
+ unlockStampArray();
+ /* maybe we should return NULL here to indicate
+ that there is no valid timestamp */
+ /* This would need a check for every getTimeStamp call
+ I think returning the last available stamp is ok
+ */
+ return back;
+}
+
+
+void TimeStampArray::forward() {
+ lockStampArray();
+ internalForward();
+ unlockStampArray();
+}
+
+
+
+void TimeStampArray::clear() {
+ lockStampArray();
+ writePos=0;
+ readPos=0;
+ fillgrade=0;
+ unlockStampArray();
+}
+
+
+void TimeStampArray::lockStampArray() {
+
+ abs_thread_mutex_lock(&changeMut);
+ abs_thread_mutex_lock(&writeInMut);
+ abs_thread_mutex_unlock(&changeMut);
+
+}
+
+
+void TimeStampArray::unlockStampArray() {
+ abs_thread_mutex_unlock(&writeInMut);
+}
+
+
+void TimeStampArray::internalForward() {
+ readPos++;
+ fillgrade--;
+ if (readPos == entries) {
+ readPos=0;
+ }
+}
diff --git a/mpeglib/lib/util/timeStampArray.h b/mpeglib/lib/util/timeStampArray.h
new file mode 100644
index 00000000..8b117652
--- /dev/null
+++ b/mpeglib/lib/util/timeStampArray.h
@@ -0,0 +1,85 @@
+/*
+ class for managing byte positions and associated time positions
+ Copyright (C) 1999 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 __TIMESTAMPARRAY_H
+#define __TIMESTAMPARRAY_H
+
+#include "abstract/abs_thread.h"
+#include "timeStamp.h"
+
+
+/**
+ This class deals with the problem to sync audio and video.
+ Both streams are decoded in different threads, sometimes
+ the video is decoded faster than the audio and sometimes
+ not.
+ <p>
+ You need a general mechanism to decide, which is faster.
+ It works like this:
+ <p>
+ When the mpeg stream is split in video/audio part the split thread
+ writes the video/audio data to the inputInterface.
+ Additionally it writes a timestamp to the interface.
+ The interface counts the bytes and forward the bytes/timeStamp
+ pait to this class.
+ Later when the threads write to the outputInterface the ask
+ this class (with the bytePostions) which timestamp it
+ has and hass the data and the timestamp to the outputInterface.
+ There we can decide what to do with the data.
+ <p>
+ 1) audio faster than video = drop video picture
+ <p>
+ 2) video faster than audio - wait for audio.
+*/
+
+
+
+class TimeStampArray {
+
+ TimeStamp** tStampArray;
+
+ int lastWritePos;
+ int writePos;
+ int readPos;
+ int fillgrade;
+ char* name;
+ int entries;
+
+ abs_thread_mutex_t writeInMut;
+ abs_thread_mutex_t changeMut;
+
+
+ public:
+ TimeStampArray(char* name,int entries);
+ ~TimeStampArray();
+
+
+ int insertTimeStamp(TimeStamp* src,long key,int len);
+ TimeStamp* getReadTimeStamp();
+ TimeStamp* getTimeStamp(long key);
+ int getFillgrade();
+ void forward();
+ void clear();
+
+ int bytesUntilNext(long key);
+
+ private:
+ void lockStampArray();
+ void unlockStampArray();
+ void internalForward();
+
+
+
+};
+#endif
+
diff --git a/mpeglib/lib/util/timeWrapper.cpp b/mpeglib/lib/util/timeWrapper.cpp
new file mode 100644
index 00000000..adf87681
--- /dev/null
+++ b/mpeglib/lib/util/timeWrapper.cpp
@@ -0,0 +1,77 @@
+/*
+ wrapps calls to usleep, gettimeofday,...
+ 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 "timeWrapper.h"
+
+#if defined WIN32
+// usec goes from 0 -> 1000000 (one Million) under Unix
+int gettimeofday(struct timeval *tv, struct timezone *tz) {
+ if(tv) {
+ struct _timeb tb;
+ _ftime(&tb);
+ tv->tv_sec=tb.time;
+ tv->tv_usec=1000*tb.millitm;
+ }
+ return(0);
+}
+
+void abs_usleep(const timeval* tm) {
+ _sleep((tm->tv_usec / 1000) + (tm->tv_sec * 1000));
+}
+#endif
+
+#ifndef WIN32
+
+void abs_usleep(struct timeval* tm) {
+ select(0,NULL,NULL,NULL,tm);
+}
+
+#endif
+
+TimeWrapper::TimeWrapper() {
+}
+
+
+TimeWrapper::~TimeWrapper() {
+}
+
+void TimeWrapper::sleep(int sec) {
+ timeval_t time;
+ time.tv_sec=sec;
+ time.tv_usec=0;
+ TimeWrapper::usleep(&time);
+}
+
+void TimeWrapper::usleep(unsigned long usec) {
+ timeval_t time;
+ time.tv_sec=0;
+ time.tv_usec=usec;
+ TimeWrapper::usleep(&time);
+}
+
+void TimeWrapper::usleep(timeval_t* time) {
+ struct timeval waitTime;
+ waitTime.tv_sec=time->tv_sec;
+ waitTime.tv_usec=time->tv_usec;
+ /*Threads and usleep does not work, select is very portable*/
+ ::abs_usleep(&waitTime);
+}
+
+
+void TimeWrapper::gettimeofday(timeval_t* time) {
+ struct timeval waitTime;
+ ::gettimeofday(&waitTime,NULL);
+ time->tv_sec=waitTime.tv_sec;
+ time->tv_usec=waitTime.tv_usec;
+}
diff --git a/mpeglib/lib/util/timeWrapper.h b/mpeglib/lib/util/timeWrapper.h
new file mode 100644
index 00000000..608d5bd0
--- /dev/null
+++ b/mpeglib/lib/util/timeWrapper.h
@@ -0,0 +1,44 @@
+/*
+ wrapps calls to usleep, gettimeofday,...
+ 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 __TIMEWRAPPER_H
+#define __TIMEWRAPPER_H
+
+#if defined WIN32
+#include <winsock.h>
+#include <sys/timeb.h>
+#else
+#include <unistd.h>
+#include <sys/time.h>
+#include <strings.h>
+#endif
+
+#include <kdemacros.h>
+
+typedef struct timeval_s {
+ long tv_sec; /* seconds */
+ long tv_usec; /* microseconds */
+} timeval_t;
+
+class KDE_EXPORT TimeWrapper {
+
+ public:
+ TimeWrapper();
+ ~TimeWrapper();
+ static void sleep(int sec);
+ static void usleep(unsigned long usec);
+ static void usleep(timeval_t* time);
+ static void gettimeofday(timeval_t* time);
+
+};
+#endif