summaryrefslogtreecommitdiffstats
path: root/mpeglib/lib/output
diff options
context:
space:
mode:
authortoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
committertoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
commite2de64d6f1beb9e492daf5b886e19933c1fa41dd (patch)
tree9047cf9e6b5c43878d5bf82660adae77ceee097a /mpeglib/lib/output
downloadtdemultimedia-e2de64d6f1beb9e492daf5b886e19933c1fa41dd.tar.gz
tdemultimedia-e2de64d6f1beb9e492daf5b886e19933c1fa41dd.zip
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdemultimedia@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'mpeglib/lib/output')
-rw-r--r--mpeglib/lib/output/Makefile.am52
-rw-r--r--mpeglib/lib/output/artsOutputStream.cpp205
-rw-r--r--mpeglib/lib/output/artsOutputStream.h123
-rw-r--r--mpeglib/lib/output/audioData.cpp100
-rw-r--r--mpeglib/lib/output/audioData.h71
-rw-r--r--mpeglib/lib/output/audioDataArray.cpp138
-rw-r--r--mpeglib/lib/output/audioDataArray.h55
-rw-r--r--mpeglib/lib/output/audioTime.cpp154
-rw-r--r--mpeglib/lib/output/audioTime.h68
-rw-r--r--mpeglib/lib/output/avSyncer.cpp386
-rw-r--r--mpeglib/lib/output/avSyncer.h96
-rw-r--r--mpeglib/lib/output/dspX11OutputStream.cpp236
-rw-r--r--mpeglib/lib/output/dspX11OutputStream.h89
-rw-r--r--mpeglib/lib/output/outPlugin.cpp71
-rw-r--r--mpeglib/lib/output/outPlugin.h44
-rw-r--r--mpeglib/lib/output/outputStream.cpp238
-rw-r--r--mpeglib/lib/output/outputStream.h151
-rw-r--r--mpeglib/lib/output/performance.cpp50
-rw-r--r--mpeglib/lib/output/performance.h34
-rw-r--r--mpeglib/lib/output/pluginInfo.cpp65
-rw-r--r--mpeglib/lib/output/pluginInfo.h48
-rw-r--r--mpeglib/lib/output/threadSafeOutputStream.cpp153
-rw-r--r--mpeglib/lib/output/threadSafeOutputStream.h67
-rw-r--r--mpeglib/lib/output/windowOut.cpp64
-rw-r--r--mpeglib/lib/output/windowOut.h53
-rw-r--r--mpeglib/lib/output/yuvDumper.cpp81
-rw-r--r--mpeglib/lib/output/yuvDumper.h51
27 files changed, 2943 insertions, 0 deletions
diff --git a/mpeglib/lib/output/Makefile.am b/mpeglib/lib/output/Makefile.am
new file mode 100644
index 00000000..e430550e
--- /dev/null
+++ b/mpeglib/lib/output/Makefile.am
@@ -0,0 +1,52 @@
+# liboutplugin - Makefile.am
+
+INCLUDES = $(all_includes)
+
+
+noinst_LTLIBRARIES = liboutput.la
+
+noinst_HEADERS = windowOut.h \
+ audioData.h audioDataArray.h \
+ performance.h yuvDumper.h
+
+kmpgincludedir = $(includedir)/$(THIS_LIB_NAME)/output
+
+kmpginclude_HEADERS = outputStream.h pluginInfo.h \
+ outPlugin.h dspX11OutputStream.h \
+ artsOutputStream.h audioTime.h \
+ avSyncer.h threadSafeOutputStream.h
+
+
+liboutput_la_SOURCES = outPlugin.cpp outputStream.cpp \
+ dspX11OutputStream.cpp \
+ windowOut.cpp \
+ audioTime.cpp \
+ audioData.cpp audioDataArray.cpp \
+ avSyncer.cpp performance.cpp \
+ artsOutputStream.cpp \
+ pluginInfo.cpp yuvDumper.cpp \
+ threadSafeOutputStream.cpp
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/mpeglib/lib/output/artsOutputStream.cpp b/mpeglib/lib/output/artsOutputStream.cpp
new file mode 100644
index 00000000..571dd258
--- /dev/null
+++ b/mpeglib/lib/output/artsOutputStream.cpp
@@ -0,0 +1,205 @@
+/*
+ output to arts
+ 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 "artsOutputStream.h"
+#include "windowOut.h"
+#include "avSyncer.h"
+#include "../util/abstract/threadQueue.h"
+
+
+ArtsOutputStream::ArtsOutputStream(void (*streamStateChangeCallback)(void*)) {
+
+ audioTime=new AudioTime();
+ x11Window=new WindowOut();
+ privateBufferSize=1024*32;
+
+ // we can dynamically change the buffer size,
+ // over a config switch in avSyncer
+ // but for now this should be ok
+ // Arts must pass the total size of the audiobuffer
+ // from /dev/dsp + connected nodes
+ // or arts need a video interface
+ stream=new BufferInputStream(privateBufferSize,1024*64,"artsLoopback");
+ avSyncer=new AVSyncer(privateBufferSize);
+
+ // with the ThreadQueue we protect all calls to the
+ // x11 output. This is necessary, because arts may call
+ // in the future "config" entries to switch the video
+ // mode (full,double,desktop)
+ threadQueue=new ThreadQueue();
+ // we set it, but its never used !
+ this->streamStateChangeCallback=streamStateChangeCallback;
+}
+
+
+ArtsOutputStream::~ArtsOutputStream() {
+ delete stream;
+ delete audioTime;
+ delete x11Window;
+ delete avSyncer;
+ delete threadQueue;
+}
+
+
+
+
+int ArtsOutputStream::audioSetup(int freq,int stereo,
+ int sign,int big,int sampleSize) {
+ audioTime->setFormat(stereo,sampleSize,freq,sign,big);
+ avSyncer->audioSetup(freq,stereo,sign,big,sampleSize);
+
+ OutputStream::audioSetup(freq,stereo,sign,big,sampleSize);
+
+ return true;
+}
+
+AudioTime* ArtsOutputStream::getAudioTime() {
+ return audioTime;
+}
+
+
+void ArtsOutputStream::audioClose() {
+ audioTime->setTime(0.0);
+ // if we close this stream the thread is kicked out.
+ stream->close();
+ stream->clear();
+ avSyncer->audioClose();
+}
+
+void ArtsOutputStream::audioFlush() {
+ OutputStream::audioFlush();
+ audioClose();
+}
+
+
+void ArtsOutputStream::audioOpen() {
+ audioTime->setTime(0.0);
+ // if we close this stream the thread is kicked out.
+ stream->open("artsLoopback");
+}
+
+
+int ArtsOutputStream::audioPlay(TimeStamp* startStamp,
+ TimeStamp* endStamp,char *buffer, int size) {
+ int write=size;
+
+
+ // we call this for stream state handling
+ OutputStream::audioPlay(startStamp,endStamp,buffer,size);
+
+ // store sync information
+ avSyncer->audioPlay(startStamp,endStamp,buffer,size);
+
+
+ // here we simulate our own blocking audio device
+ if (stream->isOpen()==false) {
+ audioTime->sleepWrite(size);
+ } else {
+ write=stream->write(buffer,size,startStamp);
+ }
+ return write;
+
+}
+
+
+int ArtsOutputStream::read(char** buffer,int bytes) {
+ int back=stream->readRemote(buffer,bytes);
+ return back;
+}
+
+
+void ArtsOutputStream::forwardReadPtr(int bytes) {
+ audioTime->forwardTime(bytes);
+ stream->forwardReadPtr(bytes);
+
+}
+
+
+
+
+int ArtsOutputStream::getPreferredDeliverSize() {
+ return avSyncer->getPreferredDeliverSize();
+}
+
+
+int ArtsOutputStream::openWindow(int width, int height,const char *title) {
+ threadQueue->waitForExclusiveAccess();
+ int back=x11Window->openWindow(width,height,title);
+ threadQueue->releaseExclusiveAccess();
+
+ return back;
+}
+
+int ArtsOutputStream::x11WindowId() {
+ return x11Window->x11WindowId();
+}
+
+void ArtsOutputStream::closeWindow() {
+ threadQueue->waitForExclusiveAccess();
+ x11Window->closeWindow();
+ threadQueue->releaseExclusiveAccess();
+}
+
+void ArtsOutputStream::flushWindow() {
+ threadQueue->waitForExclusiveAccess();
+ x11Window->flushWindow();
+ threadQueue->releaseExclusiveAccess();
+}
+
+
+PictureArray* ArtsOutputStream::lockPictureArray() {
+ PictureArray* back;
+ threadQueue->waitForExclusiveAccess();
+ back=x11Window->lockPictureArray();
+ threadQueue->releaseExclusiveAccess();
+ return back;
+}
+
+
+void ArtsOutputStream::unlockPictureArray(PictureArray* pictureArray) {
+
+
+ YUVPicture* pic=pictureArray->getYUVPictureCallback();
+ if (avSyncer->syncPicture(pic)==false) {
+ return;
+ }
+ threadQueue->waitForExclusiveAccess();
+ x11Window->unlockPictureArray(pictureArray);
+ threadQueue->releaseExclusiveAccess();
+
+}
+
+int ArtsOutputStream::getBufferFillgrade() {
+ return stream->getFillgrade();
+}
+
+int ArtsOutputStream::getFrameusec() {
+ return avSyncer->getFrameusec();
+}
+
+
+
+void ArtsOutputStream::setAudioBufferSize(int size) {
+ avSyncer->setAudioBufferSize(privateBufferSize+size);
+}
+
+
+void ArtsOutputStream::config(const char* key,const char* value,
+ void* user_data) {
+
+ threadQueue->waitForExclusiveAccess();
+ avSyncer->config(key,value,user_data);
+ x11Window->config(key,value,user_data);
+ threadQueue->releaseExclusiveAccess();
+}
diff --git a/mpeglib/lib/output/artsOutputStream.h b/mpeglib/lib/output/artsOutputStream.h
new file mode 100644
index 00000000..757022fd
--- /dev/null
+++ b/mpeglib/lib/output/artsOutputStream.h
@@ -0,0 +1,123 @@
+/*
+ output to arts
+ 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 __ARTSOUTPUTSTREAM_H
+#define __ARTSOUTPUTSTREAM_H
+
+#include "outputStream.h"
+#include "../input/bufferInputStream.h"
+#include "audioTime.h"
+
+
+class WindowOut;
+class AVSyncer;
+
+
+
+
+/**
+ a word about synchronisation: Arts currently has not asynchronous
+ starting of stream, which means, poll if stream is initialized
+ or set a callbackfunction.
+
+ mpeglib is threaded and would not have much problems
+ with a "callback" but currently we only support blocking wait
+ for initilisation.
+
+ I think, if people realize that smooth mixing of streams
+ is impossible(because of the blocking start behaviour),
+ this will become a desired feature :-)
+
+*/
+
+
+/**
+ This class offers a blocking device, its behaviour is similar
+ to /dev/dsp we use a buffer to store the pcm data, if
+ we open/close the buffer the stored data is removed
+ and the blocking thread is "kicked"
+
+ Arts must first wait for an init signal. it has its own
+ method to check for eof. during seek we close this
+ device, after seek we reopen it.
+
+ close and open have the same functionality, they simply
+ clear the buffer.
+*/
+
+
+
+class ArtsOutputStream : public OutputStream {
+
+ BufferInputStream* stream;
+ AudioTime* audioTime;
+
+ void (*streamStateChangeCallback)(void*);
+
+ WindowOut* x11Window;
+ AVSyncer* avSyncer;
+ int privateBufferSize;
+ class ThreadQueue* threadQueue;
+
+ public:
+ ArtsOutputStream(void (*streamStateChangeCallback)(void*));
+ ~ArtsOutputStream();
+
+ // Audio part
+
+ int audioSetup(int freq,int stereo,int sign,int big,int sampleSize);
+ void audioClose();
+ void audioOpen();
+ void audioFlush();
+
+ int audioPlay(TimeStamp* startStamp,
+ TimeStamp* endStamp,char *buffer, int size);
+
+
+ AudioTime* getAudioTime();
+
+ int getPreferredDeliverSize();
+
+ // Video part
+
+ int openWindow(int width, int height,const char *title);
+ int x11WindowId();
+ void closeWindow();
+ void flushWindow();
+
+ PictureArray* lockPictureArray();
+ void unlockPictureArray(PictureArray* pictureArray);
+
+ int getFrameusec();
+
+ void config(const char* key,const char* value,void* user_data);
+
+ // Remote read extension
+
+ int read(char** buffer,int bytes);
+ void forwardReadPtr(int bytes);
+
+ // buffer control
+ int getBufferFillgrade();
+
+ // sync control
+ void setAudioBufferSize(int size);
+
+ private:
+ void sendSignal(int state,int value);
+ void initStream();
+
+};
+#endif
diff --git a/mpeglib/lib/output/audioData.cpp b/mpeglib/lib/output/audioData.cpp
new file mode 100644
index 00000000..d28e74cf
--- /dev/null
+++ b/mpeglib/lib/output/audioData.cpp
@@ -0,0 +1,100 @@
+/*
+ describes a paket oriented audioData, because Im fed up
+ 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 "audioData.h"
+
+#include <iostream>
+
+using namespace std;
+
+AudioData::AudioData() {
+ pcmLen=0;
+ audioTime=new AudioTime();
+ start=new TimeStamp();
+ end=new TimeStamp();
+ writeStamp=new TimeStamp();
+}
+
+
+AudioData::~AudioData() {
+ delete audioTime;
+ delete start;
+ delete end;
+ delete writeStamp;
+}
+
+
+void AudioData::copyTo(AudioData* dest) {
+ dest->setAudioTime(getAudioTime());
+ dest->setStart(getStart());
+ dest->setEnd(getEnd());
+ dest->setWrite(getWrite());
+ dest->setPCMLen(getPCMLen());
+}
+
+
+int AudioData::getPCMLen(){
+ return pcmLen;
+}
+
+void AudioData::setPCMLen(int pcmLen) {
+ this->pcmLen=pcmLen;
+}
+
+void AudioData::setAudioTime(AudioTime* aTime) {
+ aTime->copyTo(audioTime);
+}
+
+AudioTime* AudioData::getAudioTime() {
+ return audioTime;
+}
+
+
+void AudioData::setStart(TimeStamp* s) {
+ s->copyTo(start);
+}
+
+
+TimeStamp* AudioData::getStart() {
+ return start;
+}
+
+void AudioData::setEnd(TimeStamp* e) {
+ e->copyTo(end);
+}
+
+
+TimeStamp* AudioData::getEnd() {
+ return end;
+}
+
+void AudioData::setWrite(TimeStamp* e) {
+ e->copyTo(writeStamp);
+}
+
+
+TimeStamp* AudioData::getWrite() {
+ return writeStamp;
+}
+
+
+
+void AudioData::print() {
+ cout << "AudioData::print [START]"<<endl;
+ start->print("audioData start");
+ end->print("audioData end");
+ cout << "pcmlen:"<<pcmLen<<endl;
+ cout << "AudioData::print [END]"<<endl;
+}
diff --git a/mpeglib/lib/output/audioData.h b/mpeglib/lib/output/audioData.h
new file mode 100644
index 00000000..ff6c8242
--- /dev/null
+++ b/mpeglib/lib/output/audioData.h
@@ -0,0 +1,71 @@
+/*
+ describes a paket oriented audioData, because Im fed up
+ 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 __AUDIODATA_H
+#define __AUDIODATA_H
+
+#include "../util/timeStamp.h"
+#include "audioTime.h"
+
+
+#define _AUDIODATA_MAX_SIZE 8192
+
+
+/**
+ My attempt to encapsulate all this stupid things which deals
+ with timing, synchronisation, length, stamps and everything
+ unimaginable else.
+*/
+
+
+
+class AudioData {
+
+
+ AudioTime* audioTime;
+ TimeStamp* start;
+ TimeStamp* end;
+ TimeStamp* writeStamp;
+
+ int pcmLen;
+
+ public:
+ AudioData();
+ ~AudioData();
+
+ void copyTo(AudioData* dest);
+
+
+ int getPCMLen();
+ void setPCMLen(int pcmLen);
+
+ void setAudioTime(AudioTime* audioTime);
+ AudioTime* getAudioTime();
+
+ void setStart(TimeStamp* start);
+ TimeStamp* getStart();
+
+ void setWrite(TimeStamp* writeStamp);
+ TimeStamp* getWrite();
+
+
+ void setEnd(TimeStamp* end);
+ TimeStamp* getEnd();
+
+ void print();
+};
+#endif
+
+
+
diff --git a/mpeglib/lib/output/audioDataArray.cpp b/mpeglib/lib/output/audioDataArray.cpp
new file mode 100644
index 00000000..a0b91ec1
--- /dev/null
+++ b/mpeglib/lib/output/audioDataArray.cpp
@@ -0,0 +1,138 @@
+/*
+ fifo for audioData
+ 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 "audioDataArray.h"
+
+#include <iostream>
+
+using namespace std;
+
+
+AudioDataArray::AudioDataArray(int entries) {
+
+ this->entries=entries;
+ fillgrade=0;
+ readPos=0;
+ writePos=0;
+ pcmSum=0;
+ abs_thread_mutex_init(&writeInMut);
+ abs_thread_mutex_init(&changeMut);
+
+ audioDataArray=new AudioData*[entries];
+
+ int i;
+ for(i=0;i<entries;i++) {
+ audioDataArray[i]=new AudioData();
+ }
+
+ abs_thread_mutex_init(&writeInMut);
+ abs_thread_mutex_init(&changeMut);
+
+}
+
+AudioDataArray::~AudioDataArray() {
+
+ int i;
+ for(i=0;i<entries;i++) {
+ delete audioDataArray[i];
+ }
+
+ delete audioDataArray;
+
+ abs_thread_mutex_destroy(&writeInMut);
+ abs_thread_mutex_destroy(&changeMut);
+
+}
+
+
+
+
+void AudioDataArray::lockStampArray() {
+
+ abs_thread_mutex_lock(&changeMut);
+ abs_thread_mutex_lock(&writeInMut);
+ abs_thread_mutex_unlock(&changeMut);
+
+}
+
+
+void AudioDataArray::unlockStampArray() {
+ abs_thread_mutex_unlock(&writeInMut);
+}
+
+
+void AudioDataArray::internalForward() {
+ pcmSum=pcmSum-readAudioData()->getPCMLen();
+ readPos++;
+ fillgrade--;
+ if (readPos == entries-1) {
+ readPos=0;
+ }
+}
+
+int AudioDataArray::getPCMSum() {
+ return pcmSum;
+}
+
+
+
+int AudioDataArray::insertAudioData(AudioData* src) {
+ lockStampArray();
+
+ int back=true;
+ src->copyTo(audioDataArray[writePos]);
+ pcmSum+=src->getPCMLen();
+
+ writePos++;
+ fillgrade++;
+ if (writePos == entries-1) {
+ writePos=0;
+ }
+ if (fillgrade == entries) {
+ cout <<" Audiodata::array overfull forward"<<endl;
+ internalForward();
+ back=false;
+ }
+ unlockStampArray();
+ return back;
+}
+
+
+AudioData* AudioDataArray::readAudioData() {
+ return audioDataArray[readPos];
+}
+
+
+int AudioDataArray::getFillgrade() {
+ return fillgrade;
+}
+
+
+void AudioDataArray::forward() {
+ lockStampArray();
+ internalForward();
+ unlockStampArray();
+}
+
+
+void AudioDataArray::clear() {
+ lockStampArray();
+ fillgrade=0;
+ readPos=0;
+ writePos=0;
+ pcmSum=0;
+ unlockStampArray();
+}
+
+
diff --git a/mpeglib/lib/output/audioDataArray.h b/mpeglib/lib/output/audioDataArray.h
new file mode 100644
index 00000000..81cebfee
--- /dev/null
+++ b/mpeglib/lib/output/audioDataArray.h
@@ -0,0 +1,55 @@
+/*
+ fifo for audioData
+ 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 __AUDIODATAARRAY_H
+#define __AUDIODATAARRAY_H
+
+#include "../util/abstract/abs_thread.h"
+#include "audioData.h"
+
+
+class AudioDataArray {
+
+ AudioData** audioDataArray;
+ int fillgrade;
+ int entries;
+
+ int writePos;
+ int readPos;
+ int pcmSum;
+
+ public:
+ AudioDataArray(int entries);
+ ~AudioDataArray();
+
+ int insertAudioData(AudioData* src);
+ AudioData* readAudioData();
+
+ int getFillgrade();
+ int getPCMSum();
+ void forward();
+ void clear();
+
+ private:
+ void lockStampArray();
+ void unlockStampArray();
+ void internalForward();
+
+ abs_thread_mutex_t writeInMut;
+ abs_thread_mutex_t changeMut;
+
+
+
+};
+#endif
diff --git a/mpeglib/lib/output/audioTime.cpp b/mpeglib/lib/output/audioTime.cpp
new file mode 100644
index 00000000..f4ed2e9c
--- /dev/null
+++ b/mpeglib/lib/output/audioTime.cpp
@@ -0,0 +1,154 @@
+/*
+ defines the format of an audio stream
+ 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 "audioTime.h"
+
+#include <iostream>
+
+using namespace std;
+
+
+AudioTime::AudioTime(){
+ time=0.0;
+}
+
+
+AudioTime::~AudioTime() {
+}
+
+
+void AudioTime::setFormat(int stereo,int samplesize,int speed,int sign, int bigendian) {
+ setStereo(stereo);
+ setSampleSize(samplesize);
+ setSpeed(speed);
+ setSign(sign);
+ setBigendian(bigendian);
+}
+
+
+int AudioTime::getStereo() {
+ return stereo;
+}
+
+
+int AudioTime::getSampleSize() {
+ return samplesize;
+}
+
+
+int AudioTime::getSpeed() {
+ return speed;
+}
+
+int AudioTime::getSign() {
+ return _sign;
+}
+
+int AudioTime::getBigendian() {
+ return _bigendian;
+}
+
+void AudioTime::setStereo(int stereo) {
+ this->stereo=stereo;
+}
+
+
+void AudioTime::setSampleSize(int samplesize) {
+ this->samplesize=samplesize;
+}
+
+
+void AudioTime::setSpeed(int speed) {
+ this->speed=speed;
+}
+
+void AudioTime::setSign(int sign) {
+ this->_sign=sign;
+}
+
+void AudioTime::setBigendian(int bigendian) {
+ this->_bigendian = bigendian;
+}
+
+float AudioTime::getTime() {
+ return time;
+}
+
+
+void AudioTime::setTime(float time) {
+ this->time=time;
+}
+
+
+void AudioTime::forwardTime(int bytes){
+ time+=calculateTime(bytes);
+}
+
+
+float AudioTime::calculateTime(int bytes) {
+ float back=0;
+
+ bytes=bytes/(samplesize/8);
+ if (stereo==1) {
+ bytes=bytes/2;
+ }
+ if (speed != 0) {
+ back=(float)bytes/(float)speed;
+ }
+ return back;
+}
+
+
+/**
+ How much byte we need for time usecs?
+*/
+int AudioTime::calculateBytes(float time) {
+ float back=time;
+
+ if (speed != 0) {
+ back=back*(float)speed;
+ }
+ back=back*(float)(samplesize/8);
+ if (stereo==1) {
+ back=back*2.0;
+ }
+ return (int)back;
+}
+
+
+
+void AudioTime::sleepWrite(int size) {
+ timeval_t time;
+ float timeLength=calculateTime(size);
+ time.tv_sec=(long)timeLength;
+ time.tv_usec=(long)(1000000*(timeLength-time.tv_sec));
+ TimeWrapper::usleep(&time);
+}
+
+
+void AudioTime::print() {
+ cout << "AudioTime-begin-"<<endl;
+ cout << "stereo:"<<getStereo()<<" sampleSize:"<<getSampleSize()
+ << " speed: "<<getSpeed()<<endl;
+
+ cout << "AudioTime-end-"<<endl;
+
+}
+
+
+void AudioTime::copyTo(AudioTime* dest) {
+ dest->setStereo(getStereo());
+ dest->setSampleSize(getSampleSize());
+ dest->setSpeed(getSpeed());
+}
+
diff --git a/mpeglib/lib/output/audioTime.h b/mpeglib/lib/output/audioTime.h
new file mode 100644
index 00000000..3b16bb02
--- /dev/null
+++ b/mpeglib/lib/output/audioTime.h
@@ -0,0 +1,68 @@
+/*
+ defines the format of an audio stream
+ 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 __AUDIOTIME_H
+#define __AUDIOTIME_H
+
+#include "../util/timeWrapper.h"
+
+class AudioTime {
+
+ int stereo;
+ int samplesize;
+ int speed;
+ int _sign;
+ int _bigendian;
+ float time;
+
+ public:
+ AudioTime();
+ ~AudioTime();
+
+ //cd-quality:true,16,44100
+ void setFormat(int stereo,int samplesize,int speed,int sign=true, int bigendian=false);
+
+ int getStereo();
+ int getSampleSize();
+ int getSpeed();
+ int getSign();
+ int getBigendian();
+
+ void setStereo(int stereo);
+ void setSampleSize(int samplesize);
+ void setSpeed(int speed);
+ void setSign(int sign);
+ void setBigendian(int bigendian);
+
+
+ float getTime();
+ void setTime(float time);
+ void forwardTime(int bytes);
+
+ // do not modify the internal time
+ float calculateTime(int bytes);
+ int calculateBytes(float time);
+
+ void sleepWrite(int size);
+
+
+ void copyTo(AudioTime* audioTime);
+ void print();
+
+};
+
+
+
+#endif
diff --git a/mpeglib/lib/output/avSyncer.cpp b/mpeglib/lib/output/avSyncer.cpp
new file mode 100644
index 00000000..ca12a21e
--- /dev/null
+++ b/mpeglib/lib/output/avSyncer.cpp
@@ -0,0 +1,386 @@
+/*
+ encapsulates the syncing methods, to use it in other classes
+ 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 "avSyncer.h"
+
+#include "audioDataArray.h"
+#include "performance.h"
+
+#include <iostream>
+
+using namespace std;
+
+AVSyncer::AVSyncer(int bufferSize) {
+ oneFrameTime=0;
+ onePicFrameInAudioBytes=8192;
+ this->bufferSize=bufferSize;
+
+ abs_thread_mutex_init(&writeInMut);
+ abs_thread_mutex_init(&changeMut);
+
+
+ audioDataInsert=new AudioData();
+ audioDataArray=new AudioDataArray(400);
+ audioDataCurrent=audioDataArray->readAudioData();
+
+ startAudio=new TimeStamp();
+ endAudio=new TimeStamp();
+ audioTime=new AudioTime();
+ lAudioRunning=false;
+ performance=new Performance();
+
+ waitTime=new TimeStamp();
+ diffTime=new TimeStamp();
+ videoTimeStamp=new TimeStamp();
+
+ lPerformance=false;
+ lavSync=true;
+
+
+}
+
+
+AVSyncer::~AVSyncer() {
+ delete audioDataArray;
+ delete audioDataInsert;
+ delete audioTime;
+ delete startAudio;
+ delete endAudio;
+ abs_thread_mutex_destroy(&writeInMut);
+ abs_thread_mutex_destroy(&changeMut);
+ delete waitTime;
+ delete diffTime;
+ delete performance;
+ delete videoTimeStamp;
+}
+
+
+
+int AVSyncer::audioSetup(int frequency,int stereo,int sign,
+ int big,int sixteen) {
+ audioTime->setFormat(stereo,sixteen,frequency,sign,big);
+ setAudioRunning(true);
+ return true;
+}
+
+
+int AVSyncer::audioPlay(TimeStamp* startStamp,
+ TimeStamp* endStamp,char* , int size) {
+
+
+
+
+ audioDataInsert->setStart(startStamp);
+ audioDataInsert->setEnd(endStamp);
+ audioDataInsert->setAudioTime(audioTime);
+ audioDataInsert->setPCMLen(size);
+
+ setAudioSync(audioDataInsert);
+ return size;
+}
+
+
+
+void AVSyncer::audioClose(void) {
+ lockSyncData();
+ setAudioRunning(false);
+ audioDataArray->clear();
+ unlockSyncData();
+}
+
+
+
+
+
+int AVSyncer::getPreferredDeliverSize() {
+ return onePicFrameInAudioBytes;
+}
+
+
+
+int AVSyncer::getFrameusec() {
+ lockSyncData();
+ int back=oneFrameTime;
+ unlockSyncData();
+ return back;
+}
+
+void AVSyncer::setAudioBufferSize(int size) {
+ bufferSize=size;
+}
+
+
+void AVSyncer::config(const char* key,const char* value,void*) {
+ if (strcmp(key,"-s")==0) {
+ if (strcmp(value,"on")==0) {
+ lavSync=true;
+ cout << "******** lavSync on"<<endl;
+ } else {
+ lavSync=false;
+ cout << "******** lavSync off"<<endl;
+ }
+ }
+ if (strcmp(key,"-p")==0) {
+ cout << "setting perfomance test true"<<endl;
+ lPerformance=true;
+ }
+
+}
+
+
+
+void AVSyncer::setAudioSync(AudioData* audioData) {
+
+ lockSyncData();
+
+ if (onePicFrameInAudioBytes <= 0) {
+ // no video present, we cannot calculate audio
+ // pcm length
+ //cout << "no video present, we cannot calculate audio pcm length"<<endl;
+ unlockSyncData();
+ return;
+ }
+ // buffersize is the simulated size of /dev/dsp
+
+
+
+ // we implement a fifo hopefully
+ // we check the right audio pts time out
+ // when /dev/dsp acutally plays it.
+ audioDataArray->insertAudioData(audioData);
+ int pcmSum=audioDataArray->getPCMSum();
+ if (pcmSum >= bufferSize) {
+ audioDataCurrent=audioDataArray->readAudioData();
+ setAudioRunning(true);
+ audioDataArray->forward();
+ }
+ TimeStamp* startAudio=audioDataCurrent->getStart();
+ int lpts=startAudio->getPTSFlag();
+
+ if (lpts==true) {
+ SyncClock* syncClock=startAudio->getSyncClock();
+ if (syncClock != NULL) {
+ double pts=startAudio->getPTSTimeStamp();
+ double scr=startAudio->getSCRTimeStamp();
+
+ syncClock->syncAudio(pts,scr);
+
+ } else {
+ cout <<"syncClock == NULL (audio)"<<endl;
+ }
+ } else {
+ //cout << "lpts is false"<<endl;
+ }
+ unlockSyncData();
+
+}
+
+
+
+int AVSyncer::syncPicture(YUVPicture* syncPic) {
+ if (syncPic == NULL) {
+ cout << "syncPic == NULL"<<endl;
+ return false;
+ }
+
+ float picPerSec=syncPic->getPicturePerSecond();
+ int oneFrameTime=0;
+
+ if (picPerSec > 0.0) {
+ oneFrameTime=(int) (1000000.0/picPerSec);
+ } else {
+ syncPic->print("picPersec is 0");
+ return true;
+ }
+
+ if (lPerformance==true) {
+ waitTime->set(0,0);
+ syncPic->setWaitTime(waitTime);
+ performance->incPictureCount();
+ return true;
+ }
+
+ int lpacketSync=true;
+
+ videoTimeStamp->gettimeofday();
+ diffTime->minus(videoTimeStamp,videoTimeStamp);
+
+
+ if (lavSync==false) {
+ if (videoTimeStamp->isNegative()) {
+ diffTime->gettimeofday();
+ diffTime->addOffset(0,oneFrameTime);
+ cout << "skip time based"<<endl;
+ return false;
+ }
+ }
+
+
+
+ videoTimeStamp->copyTo(waitTime);
+
+ TimeStamp* earlyTime=syncPic->getEarlyTime();
+ earlyTime->set(0,0);
+
+
+ if (lavSync) {
+
+ lpacketSync=avSync(syncPic->getStartTimeStamp(),
+ waitTime,
+ earlyTime,
+ syncPic->getPicturePerSecond());
+
+ }
+
+
+
+
+ if (lpacketSync == false) {
+ //cout << "skip"<<endl;
+ diffTime->gettimeofday();
+ diffTime->addOffset(0,oneFrameTime);
+ return false;
+ }
+
+ syncPic->setWaitTime(waitTime);
+
+ if (lavSync) {
+ waitTime->minus(videoTimeStamp,waitTime);
+ if (waitTime->isPositive()) {
+ diffTime->addOffset(waitTime);
+ }
+ }
+ diffTime->addOffset(0,oneFrameTime);
+ return true;
+
+
+}
+
+
+
+/**
+ Heart of the sync routine is here!
+
+ Currently its more in a state of "try/test"
+
+
+*/
+int AVSyncer::avSync(TimeStamp* startVideo,
+ TimeStamp* waitTime,
+ TimeStamp* earlyTime,
+ float picPerSec ) {
+
+
+ double videoStartPTSTime=startVideo->getPTSTimeStamp();
+ double videoStartSCRTime=startVideo->getSCRTimeStamp();
+ int videoFrameCounter=startVideo->getVideoFrameCounter();
+ double frameTime=0.0;
+
+
+
+ lockSyncData();
+ if (picPerSec > 0) {
+ oneFrameTime=(long)(1000000.0/picPerSec);
+ frameTime=1.0/picPerSec;
+ onePicFrameInAudioBytes=audioTime->calculateBytes(1.0/picPerSec);
+
+ }
+ if (lAudioRunning==false) {
+ waitTime->set(0,oneFrameTime);
+
+ unlockSyncData();
+ return true;
+ }
+
+
+ /*
+ startAudio->print("audio");
+ startVideo->print("video");
+ */
+
+
+
+
+
+
+ /*
+ cout << "audioStartAudioPacketNrMinor:"<<audioStartAudioPacketNrMinor<<endl;
+ cout << "audioStartPTSTime:"<<audioStartPTSTime<<endl;
+ cout << "audioStartEndPTSTime:"<<audioStartEndPTSTime<<endl;
+ cout << "videoStartPTSTime:"<<videoStartPTSTime<<endl;
+ */
+
+
+ /**
+ Here we make sure that we sync over an audio packet only one
+ time.
+ */
+
+ waitTime->set(0,0);
+ SyncClock* syncClock=startVideo->getSyncClock();
+ int back=false;
+ double addPts=videoFrameCounter*frameTime;
+ double pts=videoStartPTSTime+addPts;
+
+ if (syncClock != NULL) {
+
+ back=syncClock->syncVideo(pts,
+ videoStartSCRTime,earlyTime,waitTime);
+ } else {
+ cout << "syncClock == NULL (video)"<<endl;
+ }
+ unlockSyncData();
+
+ if (back==true) {
+ //earlyTime->print("earlyTime");
+ earlyTime->waitForIt();
+ /*
+ double tmp;
+ double time=syncClock->getPTSTime(&tmp);
+ cout << "time after wait:"<<time<<endl;
+ */
+ }
+ /*
+ if (back == false) {
+ cout <<"real pts:"<<videoStartPTSTime
+ <<" calc pts"<<pts
+ <<" frameNo:"<<videoFrameCounter
+ <<" frameTime:"<<frameTime<<endl;
+ }
+ */
+
+
+
+ return back;
+
+}
+
+int AVSyncer::getAudioRunning() {
+ return lAudioRunning;
+}
+
+
+void AVSyncer::setAudioRunning(int lAudioRunning) {
+ this->lAudioRunning=lAudioRunning;
+}
+
+
+void AVSyncer::lockSyncData() {
+ abs_thread_mutex_lock(&changeMut);
+ abs_thread_mutex_lock(&writeInMut);
+ abs_thread_mutex_unlock(&changeMut);
+}
+
+void AVSyncer::unlockSyncData() {
+ abs_thread_mutex_unlock(&writeInMut);
+}
diff --git a/mpeglib/lib/output/avSyncer.h b/mpeglib/lib/output/avSyncer.h
new file mode 100644
index 00000000..b5a7ae7d
--- /dev/null
+++ b/mpeglib/lib/output/avSyncer.h
@@ -0,0 +1,96 @@
+/*
+ encapsulates the syncing methods, to use it in other classes
+ 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 __AVSYNCER_H
+#define __AVSYNCER_H
+
+#include <stdlib.h>
+
+#include "../util/render/yuvPicture.h"
+#include "../util/syncClock.h"
+#include "audioTime.h"
+
+class Performance;
+class AudioDataArray;
+class AudioData;
+
+class AVSyncer {
+
+ AudioData* audioDataInsert;
+ AudioData* audioDataCurrent;
+ AudioDataArray* audioDataArray;
+ Performance* performance;
+
+ AudioTime* audioTime;
+ int onePicFrameInAudioBytes;
+ int oneFrameTime;
+
+ int lAudioRunning;
+
+ abs_thread_mutex_t writeInMut;
+ abs_thread_mutex_t changeMut;
+
+
+ int bufferSize;
+
+ TimeStamp* startAudio;
+ TimeStamp* endAudio;
+
+ TimeStamp* videoTimeStamp;
+ TimeStamp* diffTime;
+ TimeStamp* waitTime;
+
+ int lPerformance;
+ int lavSync;
+ int lastAudioPacket;
+ double pts_jitter;
+
+
+ public:
+ AVSyncer(int bufferSize);
+ ~AVSyncer();
+
+ // audio
+ int audioSetup(int frequency,int stereo,int sign,int big,int sixteen);
+ int audioPlay(TimeStamp* startStamp,
+ TimeStamp* endStamp,char *buffer, int size);
+ void audioClose(void);
+ void setAudioBufferSize(int size);
+
+ int getPreferredDeliverSize();
+
+ // video
+ int getFrameusec();
+ int syncPicture(YUVPicture* syncPic);
+
+ void config(const char* key,const char* value,void* user_data);
+
+
+
+ private:
+ int getAudioRunning();
+ void setAudioRunning(int lAudioRunning);
+
+ void lockSyncData();
+ void unlockSyncData();
+ void setAudioSync(AudioData* audioData);
+
+ // methods which belong not to the OutputStream interface
+ int avSync(TimeStamp* startVideoStamp,
+ TimeStamp* waitTime,
+ TimeStamp* earlyTime,
+ float picPerSec);
+
+};
+#endif
diff --git a/mpeglib/lib/output/dspX11OutputStream.cpp b/mpeglib/lib/output/dspX11OutputStream.cpp
new file mode 100644
index 00000000..05503ffa
--- /dev/null
+++ b/mpeglib/lib/output/dspX11OutputStream.cpp
@@ -0,0 +1,236 @@
+/*
+ concret OutputClass
+ 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 "dspX11OutputStream.h"
+#include "../util/audio/dspWrapper.h"
+#include "windowOut.h"
+#include "avSyncer.h"
+#include "yuvDumper.h"
+
+#include <iostream>
+
+using namespace std;
+
+DspX11OutputStream::DspX11OutputStream(int bufferSize) {
+ dspWrapper=new DSPWrapper();
+ x11Window=new WindowOut();
+ avSyncer=new AVSyncer(bufferSize);
+ yuvDumper=new YUVDumper();
+
+ audioTime=new AudioTime();
+
+ lPerformance=false;
+ lneedInit=false;
+ lVideoInit=false;
+ lBufferSet=false;
+ lYUVDump=false;
+}
+
+
+DspX11OutputStream::~DspX11OutputStream() {
+ delete dspWrapper;
+ delete x11Window;
+
+ delete avSyncer;
+ delete audioTime;
+ delete yuvDumper;
+}
+
+
+
+int DspX11OutputStream::audioSetup(int frequency,int stereo,
+ int sign,int big,int sixteen) {
+
+ dspWrapper->audioSetup(stereo,sixteen,sign,big,frequency);
+ audioTime->setFormat(stereo,sixteen,frequency,sign,big);
+ avSyncer->audioSetup(frequency,stereo,sign,big,sixteen);
+ if (dspWrapper->isOpenDevice() == true) {
+ if (lBufferSet==false) {
+ int size=dspWrapper->getAudioBufferSize();
+ avSyncer->setAudioBufferSize(size);
+ }
+ }
+ return true;
+}
+
+
+void DspX11OutputStream::audioClose(void) {
+ avSyncer->audioClose();
+ dspWrapper->closeDevice();
+}
+
+
+void DspX11OutputStream::audioOpen() {
+ if (dspWrapper->isOpenDevice() == false) {
+ dspWrapper->openDevice();
+ if (lBufferSet==false) {
+ int size=dspWrapper->getAudioBufferSize();
+ avSyncer->setAudioBufferSize(size);
+ }
+ }
+}
+
+
+
+
+int DspX11OutputStream::audioPlay(TimeStamp* startStamp,
+ TimeStamp* endStamp,char *buffer, int size) {
+
+ if (lneedInit) {
+ cout << "FIXME. work on audioFrames!!"<<endl;
+ lneedInit=false;
+ }
+
+ if (lPerformance==false) {
+ //
+ // Now feed data smoothly into the dsp/avSyncer
+ //
+ int pos=0;
+ int rest=size;
+ int inc=getPreferredDeliverSize();
+ int len;
+
+ while (rest > 0) {
+ len=rest;
+ if (len>inc) {
+ len=inc;
+ }
+ if (dspWrapper->isOpenDevice()) {
+ if (dspWrapper->audioPlay(buffer,len) != len) {
+ cout << "write error to dsp"<<endl;
+ lneedInit=true;
+ return size-rest;
+ }
+ }
+
+ avSyncer->audioPlay(startStamp,endStamp,buffer,len);
+ buffer+=len;
+ rest-=len;
+ }
+ return size;
+ } else {
+ return size;
+ }
+}
+
+
+int DspX11OutputStream::getPreferredDeliverSize() {
+ if (avSyncer->getPreferredDeliverSize() <= 500) {
+ return 500;
+ }
+ return avSyncer->getPreferredDeliverSize();
+}
+
+
+int DspX11OutputStream::openWindow(int width, int height,const char *title) {
+ int back=x11Window->openWindow(width,height,title);
+ setOutputInit(true);
+ if (lYUVDump) {
+ yuvDumper->openWindow(width,height,title);
+ }
+ return back;
+}
+
+int DspX11OutputStream::x11WindowId() {
+ return x11Window->x11WindowId();
+}
+
+
+void DspX11OutputStream::closeWindow() {
+ x11Window->closeWindow();
+}
+
+void DspX11OutputStream::flushWindow() {
+ x11Window->flushWindow();
+}
+
+
+PictureArray* DspX11OutputStream::lockPictureArray() {
+ return x11Window->lockPictureArray();
+}
+
+
+void DspX11OutputStream::unlockPictureArray(PictureArray* pictureArray) {
+
+
+
+ YUVPicture* pic=pictureArray->getYUVPictureCallback();
+
+ if (lYUVDump) {
+ yuvDumper->unlockPictureArray(pictureArray);
+ }
+ if (avSyncer->syncPicture(pic)==false) {
+ return;
+ }
+
+ x11Window->unlockPictureArray(pictureArray);
+
+
+}
+
+int DspX11OutputStream::getFrameusec() {
+ return avSyncer->getFrameusec();
+}
+
+
+
+int DspX11OutputStream::getOutputInit() {
+ return lVideoInit;
+}
+
+
+void DspX11OutputStream::setOutputInit(int lInit) {
+ this->lVideoInit=lInit;
+}
+
+
+
+void DspX11OutputStream::config(const char* key,
+ const char* value,void* user_data) {
+
+ cout << "key:"<<key<<endl;
+ if (strcmp(key,"-s")==0) {
+ avSyncer->config(key,value,user_data);
+ }
+ if (strcmp(key,"-b")==0) {
+ lBufferSet=true;
+ int size=strtol(value,(char **)NULL,10);
+ cout << "simulated audio buffersize:"<<size<<" bytes"<<endl;
+ avSyncer->setAudioBufferSize(size);
+ }
+ if (strcmp(key,"-p")==0) {
+ lPerformance=true;
+ avSyncer->config(key,value,user_data);
+ }
+ if (strcmp(key,"yufDump")==0) {
+ int method=atoi(value);
+ switch(method) {
+ case 2:
+ yuvDumper->setMethod(_DUMP_YUV_AS_STREAM);
+ break;
+ default:
+ cout << "unknown dump method"<<endl;
+ }
+ lYUVDump=true;
+ }
+ x11Window->config(key,value,user_data);
+}
+
+
+AVSyncer* DspX11OutputStream::getAVSyncer() {
+ return avSyncer;
+}
+
+
+
diff --git a/mpeglib/lib/output/dspX11OutputStream.h b/mpeglib/lib/output/dspX11OutputStream.h
new file mode 100644
index 00000000..9b3eb859
--- /dev/null
+++ b/mpeglib/lib/output/dspX11OutputStream.h
@@ -0,0 +1,89 @@
+/*
+ concret OutputClass
+ 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 __DSPX11OUTPUTSTREAM_H
+#define __DSPX11OUTPUTSTREAM_H
+
+#include "outputStream.h"
+
+
+
+class DSPWrapper;
+class WindowOut;
+class AVSyncer;
+class AudioTime;
+class Performance;
+class YUVDumper;
+
+class DspX11OutputStream : public OutputStream {
+
+ DSPWrapper* dspWrapper;
+ WindowOut* x11Window;
+ AVSyncer* avSyncer;
+
+
+ int lBufferSet;
+ int lVideoInit;
+ int lavSync;
+ int lneedInit;
+ int lPerformance;
+ int lYUVDump;
+
+ AudioTime* audioTime;
+ YUVDumper* yuvDumper;
+
+ public:
+ DspX11OutputStream(int bufferSize);
+ ~DspX11OutputStream();
+
+ // Audio Output
+
+ int audioSetup(int frequency,int stereo,int sign,int big,int sixteen);
+ void audioClose();
+ void audioOpen();
+ int audioPlay(TimeStamp* startStamp,
+ TimeStamp* endStamp,char *buffer, int size);
+
+
+ int getPreferredDeliverSize();
+
+
+ // Video Output
+
+ int openWindow(int width, int height,const char *title);
+ int x11WindowId();
+ void closeWindow();
+ void flushWindow();
+
+ PictureArray* lockPictureArray();
+ void unlockPictureArray(PictureArray* pictureArray);
+
+ int getFrameusec();
+
+ int getDepth();
+ int getOutputInit();
+ void setOutputInit(int lInit);
+
+ void config(const char* key,const char* value,void* user_data);
+
+ // methods which do not belong to the outputStream intferface;
+ AVSyncer* getAVSyncer();
+
+
+};
+
+
+
+#endif
diff --git a/mpeglib/lib/output/outPlugin.cpp b/mpeglib/lib/output/outPlugin.cpp
new file mode 100644
index 00000000..cbae10ec
--- /dev/null
+++ b/mpeglib/lib/output/outPlugin.cpp
@@ -0,0 +1,71 @@
+/*
+ generic 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 "outPlugin.h"
+
+#include <iostream>
+
+using namespace std;
+
+
+OutPlugin::OutPlugin() {
+}
+
+
+OutPlugin::~OutPlugin() {
+}
+
+
+
+OutputStream* OutPlugin::createOutputStream(int outputType) {
+
+ // make checks which input routine to use
+ OutputStream* outputStream;
+ int method;
+
+ outputStream=NULL;
+ method=outputType;
+
+ switch(method) {
+ case _OUTPUT_LOCAL: {
+ outputStream=new DspX11OutputStream(1024*64);
+ break;
+ }
+ case _OUTPUT_ARTS: {
+ outputStream=new ArtsOutputStream(NULL);
+ break;
+ }
+ case _OUTPUT_EMPTY: {
+ outputStream=new OutputStream();
+ break;
+ }
+ default:
+ cout << "error cannot create default output stream"<<endl;
+ exit(0);
+ }
+
+ return outputStream;
+
+
+}
+
+OutputStream* OutPlugin::createOutputStream(int outputType,int lThreadSafe) {
+ OutputStream* output=OutPlugin::createOutputStream(outputType);
+ if (lThreadSafe==false) {
+ return output;
+ }
+ OutputStream* tsOutput=new ThreadSafeOutputStream(output);
+ return tsOutput;
+}
+
diff --git a/mpeglib/lib/output/outPlugin.h b/mpeglib/lib/output/outPlugin.h
new file mode 100644
index 00000000..b70620a6
--- /dev/null
+++ b/mpeglib/lib/output/outPlugin.h
@@ -0,0 +1,44 @@
+/*
+ generic 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 __OUTPLUGIN_H
+#define __OUTPLUGIN_H
+
+
+#include "dspX11OutputStream.h"
+#include "artsOutputStream.h"
+#include "threadSafeOutputStream.h"
+#include <kdemacros.h>
+
+#define _OUTPUT_LOCAL 1
+#define _OUTPUT_EMPTY 2
+#define _OUTPUT_YAF 3
+#define _OUTPUT_ARTS 4
+
+#define _OUTPUT_THREADSAFE 1
+
+class KDE_EXPORT OutPlugin {
+
+ public:
+ OutPlugin();
+ ~OutPlugin();
+
+ static OutputStream* createOutputStream(int outputType);
+ static OutputStream* createOutputStream(int outputType,int lThreadSafe);
+
+};
+#endif
+
+
+
+
diff --git a/mpeglib/lib/output/outputStream.cpp b/mpeglib/lib/output/outputStream.cpp
new file mode 100644
index 00000000..ef209cbc
--- /dev/null
+++ b/mpeglib/lib/output/outputStream.cpp
@@ -0,0 +1,238 @@
+/*
+ generic output class
+ 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 "outputStream.h"
+#include "../util/mmx/mmx.h"
+
+#include <iostream>
+
+using namespace std;
+
+OutputStream::OutputStream() {
+ // we call mm_support() here because it is the only position
+ // where we gurantee that not threads are
+ // running (the call is not thread safe)
+ // afer the call we never execute the asm part again
+ // and everything is fine
+ mm_support();
+ abs_thread_mutex_init(&stateChangeMut);
+ abs_thread_cond_init(&stateChangeCond);
+
+ audioState=0;
+ videoState=0;
+ audioInit();
+ videoInit();
+}
+
+
+OutputStream::~OutputStream() {
+ audioInit();
+ videoInit();
+ abs_thread_cond_destroy(&stateChangeCond);
+ abs_thread_mutex_destroy(&stateChangeMut);
+}
+
+
+int OutputStream::audioInit() {
+ sendSignal(_STREAM_MASK_IS_INIT,false,_STREAMTYPE_AUDIO);
+ sendSignal(_STREAM_MASK_IS_EOF,false,_STREAMTYPE_AUDIO);
+ sendSignal(_STREAM_MASK_IS_DATA,false,_STREAMTYPE_AUDIO);
+ return true;
+}
+
+
+int OutputStream::audioSetup(int ,int ,
+ int ,int ,int ) {
+ sendSignal(_STREAM_MASK_IS_INIT,true,_STREAMTYPE_AUDIO);
+ return true;
+}
+
+
+int OutputStream::audioPlay(TimeStamp* ,
+ TimeStamp* ,char* , int len) {
+ sendSignal(_STREAM_MASK_IS_DATA,true,_STREAMTYPE_AUDIO);
+ return len;
+}
+
+void OutputStream::audioFlush() {
+ sendSignal(_STREAM_MASK_IS_EOF,true,_STREAMTYPE_AUDIO);
+}
+
+
+void OutputStream::audioClose() {
+ cerr << "direct virtual call OutputStream::audioClose"<<endl;
+ exit(0);
+}
+
+void OutputStream::audioOpen() {
+ cerr << "direct virtual call OutputStream::audioOpen"<<endl;
+ exit(0);
+}
+
+
+
+void OutputStream::sendSignal(int signal,int value,int streamType) {
+ abs_thread_mutex_lock(&stateChangeMut);
+ int* modifyState=NULL;
+ switch(streamType) {
+ case _STREAMTYPE_AUDIO:
+ modifyState=&audioState;
+ break;
+ case _STREAMTYPE_VIDEO:
+ modifyState=&videoState;
+ break;
+ default:
+ cout << "unknown streamType:"<<streamType
+ <<" in OutputStream::sendSignal"<<endl;
+ exit(0);
+ }
+ // should we set the bit?
+ if (value==true) {
+ // set it with "or"
+ *modifyState|=signal;
+ } else {
+ // we should remove the bit
+ // is it currently set?
+ if (*modifyState & signal) {
+ // remove it
+ *modifyState-=signal;
+ }
+ }
+
+
+ abs_thread_cond_signal(&stateChangeCond);
+ abs_thread_mutex_unlock(&stateChangeMut);
+
+}
+
+
+int OutputStream::getPreferredDeliverSize() {
+ cerr << "direct virtual call OutputStream::getPreferredDeliverSize()"<<endl;
+ return 4096;
+}
+
+int OutputStream::videoInit() {
+ sendSignal(_STREAM_MASK_IS_INIT,false,_STREAMTYPE_VIDEO);
+ sendSignal(_STREAM_MASK_IS_EOF,false,_STREAMTYPE_VIDEO);
+ sendSignal(_STREAM_MASK_IS_DATA,false,_STREAMTYPE_VIDEO);
+ return true;
+}
+
+int OutputStream::openWindow(int , int ,const char* ) {
+ sendSignal(_STREAM_MASK_IS_INIT,true,_STREAMTYPE_VIDEO);
+ return true;
+}
+
+int OutputStream::x11WindowId() {
+ cout << "direct virtual call OutputStream::x11WindowId()" << endl;
+ return -1;
+}
+
+void OutputStream::closeWindow() {
+ cerr << "direct virtual call OutputStream::closeWindow"<<endl;
+ exit(0);
+}
+
+void OutputStream::flushWindow() {
+ sendSignal(_STREAM_MASK_IS_EOF,true,_STREAMTYPE_VIDEO);
+}
+
+
+PictureArray* OutputStream::lockPictureArray() {
+ cerr << "direct virtual call OutputStream::lockPictureArray"<<endl;
+ exit(0);
+ return NULL;
+}
+
+
+void OutputStream::unlockPictureArray(PictureArray* ) {
+ sendSignal(_STREAM_MASK_IS_DATA,true,_STREAMTYPE_VIDEO);
+}
+
+
+
+
+
+int OutputStream::getOutputInit() {
+ cerr << "direct virtual call OutputStream::getOutputInit"<<endl;
+ exit(0);
+ return false;
+}
+
+
+void OutputStream::setOutputInit(int lInit) {
+ cerr << "direct virtual call OutputStream::setOutputInit:"<<lInit<<endl;
+ exit(0);
+}
+
+
+
+void OutputStream::writeInfo(PluginInfo* ) {
+
+}
+
+
+void OutputStream::config(const char* key,
+ const char* value,void* user_data) {
+ cerr << "direct virtual call OutputStream::config"<<endl;
+ printf("key:%s\n",key);
+ printf("value:%s\n",value);
+ printf("user_data:%p\n",user_data);
+ exit(0);
+}
+
+int OutputStream::getFrameusec() {
+ cerr << "direct virtual call OutputStream::getFrameusec"<<endl;
+ return 0;
+}
+
+
+
+int OutputStream::waitStreamState(int method,int mask,int streamType) {
+
+ int* waitState=NULL;
+ switch(streamType) {
+ case _STREAMTYPE_AUDIO:
+ waitState=&audioState;
+ break;
+ case _STREAMTYPE_VIDEO:
+ waitState=&videoState;
+ break;
+ default:
+ cout << "unknown streamType:"<<streamType
+ <<" in OutputStream::waitStreamState"<<endl;
+ exit(0);
+ }
+
+ if (method == _OUTPUT_WAIT_METHOD_BLOCK) {
+ abs_thread_mutex_lock(&stateChangeMut);
+ while ((*waitState &= mask)==0) {
+ cout << "waitStreamState:"<<waitState<<endl;
+ cout << "mask:"<<mask<<endl;
+ abs_thread_cond_wait(&stateChangeCond,&stateChangeMut);
+ }
+ abs_thread_mutex_unlock(&stateChangeMut);
+ return true;
+ }
+
+ int back=false;
+ if (method == _OUTPUT_WAIT_METHOD_POLL) {
+ abs_thread_mutex_lock(&stateChangeMut);
+ back=*waitState;
+ abs_thread_mutex_unlock(&stateChangeMut);
+ return back;
+ }
+ cout << " OutputStream::waitStreamState method not implemented"<<endl;
+ exit(0);
+ return 0;
+}
diff --git a/mpeglib/lib/output/outputStream.h b/mpeglib/lib/output/outputStream.h
new file mode 100644
index 00000000..9ef538fd
--- /dev/null
+++ b/mpeglib/lib/output/outputStream.h
@@ -0,0 +1,151 @@
+/*
+ generic output class
+ 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 __OUTPUTSTREAM_H
+#define __OUTPUTSTREAM_H
+
+#include "../util/timeStamp.h"
+#include "pluginInfo.h"
+#include "../util/render/pictureArray.h"
+#include "../util/abstract/abs_thread.h"
+#include <kdemacros.h>
+
+#define _OUTPUT_WAIT_METHOD_BLOCK 1
+#define _OUTPUT_WAIT_METHOD_POLL 2
+#define _OUTPUT_WAIT_METHOD_CALLBACK 3
+
+
+#define _STREAM_MASK_IS_INIT 1
+#define _STREAM_MASK_IS_EOF 2
+#define _STREAM_MASK_IS_DATA 4
+
+#define _STREAM_MASK_ALL 1+2+4
+
+#define _STREAMTYPE_AUDIO 1
+#define _STREAMTYPE_VIDEO 2
+
+
+/**
+ Outputstream. A nice base class. Mostly obvious methods,
+ except PictureArray.
+ write your picture into this structure
+ and then put it on the surface with the unlock call.
+
+*/
+
+
+/**
+ life of stream states:
+ --------------
+ method flag additional calls
+ construct audioInit()
+
+
+
+ destruct audioInit()
+
+ audioInit isInit=false
+ isEof=false
+ isData=false
+
+ audioSetup isInit=true
+ audioFlush isEof=true
+ audioPlay isData=true
+
+
+ Note: after a call of streamInit we have an "invalid" state
+ obviously there is no stream where eof==false but
+ and has not been initialised.
+
+ another invalid state is audioInit->audioPlay
+
+*/
+
+
+
+
+class KDE_EXPORT OutputStream {
+
+ int audioState;
+ int videoState;
+ abs_thread_mutex_t stateChangeMut;
+ abs_thread_cond_t stateChangeCond;
+
+ public:
+ OutputStream();
+
+ virtual ~OutputStream();
+
+ // Audio Stream handling
+ virtual int audioInit();
+ virtual int audioSetup(int freq,int stereo,int sign,int big,int sampleSize);
+ virtual int audioPlay(TimeStamp* startStamp,
+ TimeStamp* endStamp,char *buffer, int size);
+ virtual void audioFlush();
+
+ // Audio device "/dev/dsp" handling
+ virtual void audioClose();
+ virtual void audioOpen();
+
+ // hack: FIX it
+ virtual int getPreferredDeliverSize();
+
+
+ // stream State handling
+
+ // we return the mask which triggerd (by "AND")
+ // or the current polled mask when method is POLL
+ // Note: you can only wait for "true" signals
+ virtual int waitStreamState(int method,int mask,int streamType);
+
+
+
+
+ // Video Output
+ virtual int videoInit();
+ virtual int openWindow(int width, int height,const char *title);
+ virtual int x11WindowId();
+ virtual void closeWindow();
+ virtual void flushWindow();
+
+
+ // get the current surfaces to draw into
+ virtual PictureArray* lockPictureArray();
+ virtual void unlockPictureArray(PictureArray* pictureArray);
+
+
+
+ // maybe not needed:
+ virtual int getFrameusec();
+ virtual int getOutputInit();
+ virtual void setOutputInit(int lInit);
+
+ // Info Output
+ virtual void writeInfo(class PluginInfo* pluginInfo);
+
+
+ // config Output
+ virtual void config(const char* key,
+ const char* value,void* user_data);
+
+ private:
+ void initStream();
+
+ protected:
+ // sometimes useful, but use with care
+ void sendSignal(int signal,int value,int streamType);
+
+};
+#endif
diff --git a/mpeglib/lib/output/performance.cpp b/mpeglib/lib/output/performance.cpp
new file mode 100644
index 00000000..9e2b7f92
--- /dev/null
+++ b/mpeglib/lib/output/performance.cpp
@@ -0,0 +1,50 @@
+/*
+ measures picture/second
+ 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 "performance.h"
+
+#include <iostream>
+
+using namespace std;
+
+
+Performance::Performance() {
+ picCnt=0;
+ startTime=new TimeStamp();
+ endTime=new TimeStamp();
+
+}
+
+
+Performance::~Performance() {
+ delete startTime;
+ delete endTime;
+}
+
+
+void Performance::incPictureCount() {
+ if (picCnt==0) {
+ startTime->gettimeofday();
+ }
+ picCnt++;
+ if (picCnt==200) {
+ endTime->gettimeofday();
+ TimeStamp diffTime;
+ endTime->minus(startTime,&diffTime);
+ double secs=(double)diffTime.getAsSeconds();
+
+ double picSec=(double)picCnt/secs;
+ cout << "picPerSec:"<<picSec<<" secs:"<<secs<<endl;
+ picCnt=0;
+ }
+}
diff --git a/mpeglib/lib/output/performance.h b/mpeglib/lib/output/performance.h
new file mode 100644
index 00000000..d7d54572
--- /dev/null
+++ b/mpeglib/lib/output/performance.h
@@ -0,0 +1,34 @@
+/*
+ measures picture/second
+ 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 __PERFORMANCE_H
+#define __PERFORMANCE_H
+
+#include "../util/timeStamp.h"
+
+class Performance {
+
+ int picCnt;
+ TimeStamp* startTime;
+ TimeStamp* endTime;
+
+
+ public:
+
+ Performance();
+ ~Performance();
+ void incPictureCount();
+
+};
+#endif
diff --git a/mpeglib/lib/output/pluginInfo.cpp b/mpeglib/lib/output/pluginInfo.cpp
new file mode 100644
index 00000000..c741852c
--- /dev/null
+++ b/mpeglib/lib/output/pluginInfo.cpp
@@ -0,0 +1,65 @@
+/*
+ add on information about 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 "pluginInfo.h"
+
+#include <iostream>
+
+using namespace std;
+
+
+PluginInfo::PluginInfo() {
+ musicName=new DynBuffer(20);
+
+ reset();
+
+}
+
+
+PluginInfo::~PluginInfo() {
+ delete musicName;
+}
+
+void PluginInfo::setLength(int sec) {
+ this->sec=sec;
+}
+
+
+int PluginInfo::getLength() {
+ return sec;
+}
+
+
+void PluginInfo::reset(){
+ sec=0;
+ musicName->clear();
+ musicName->append("none");
+}
+
+void PluginInfo::print() {
+ cerr << "length in sec:"<<sec<<endl;
+ cerr << "url:"<<getUrl()<<endl;
+}
+
+
+void PluginInfo::setUrl(char* name) {
+ musicName->clear();
+ if (name != NULL) {
+ musicName->append(name);
+ }
+}
+
+
+char* PluginInfo::getUrl() {
+ return musicName->getData();
+}
diff --git a/mpeglib/lib/output/pluginInfo.h b/mpeglib/lib/output/pluginInfo.h
new file mode 100644
index 00000000..7026fce9
--- /dev/null
+++ b/mpeglib/lib/output/pluginInfo.h
@@ -0,0 +1,48 @@
+/*
+ add on information about 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 __PLUGININFO_H
+#define __PLUGININFO_H
+
+#include "../util/dynBuffer.h"
+#include <kdemacros.h>
+
+/**
+ Here we have the base class for all additional information
+ about a plugin.
+ The len in time of the current song belongs here, as
+ well as the author, version number etc..
+*/
+
+
+class KDE_EXPORT PluginInfo {
+
+ int sec;
+ DynBuffer* musicName;
+
+
+ public:
+ PluginInfo();
+ ~PluginInfo();
+
+ void setLength(int sec);
+ int getLength();
+
+ void setUrl(char* name);
+ char* getUrl();
+
+ void reset();
+ void print();
+};
+#endif
diff --git a/mpeglib/lib/output/threadSafeOutputStream.cpp b/mpeglib/lib/output/threadSafeOutputStream.cpp
new file mode 100644
index 00000000..ec7ab510
--- /dev/null
+++ b/mpeglib/lib/output/threadSafeOutputStream.cpp
@@ -0,0 +1,153 @@
+/*
+ thread safe wrapper for output Stream
+ 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 "threadSafeOutputStream.h"
+
+
+ThreadSafeOutputStream::ThreadSafeOutputStream(OutputStream* output) {
+ threadQueueAudio=new ThreadQueue();
+ threadQueueVideo=new ThreadQueue();
+ this->output=output;
+}
+
+
+ThreadSafeOutputStream::~ThreadSafeOutputStream() {
+ delete threadQueueAudio;
+ delete threadQueueVideo;
+ delete output;
+}
+
+int ThreadSafeOutputStream::audioInit() {
+ int back;
+ threadQueueAudio->waitForExclusiveAccess();
+ back=output->audioInit();
+ threadQueueAudio->releaseExclusiveAccess();
+ return back;
+}
+
+
+int ThreadSafeOutputStream::audioSetup(int freq,int stereo,
+ int sign,int big,int sampleSize) {
+ int back;
+ threadQueueAudio->waitForExclusiveAccess();
+ back=output->audioSetup(freq,stereo,sign,big,sampleSize);
+ threadQueueAudio->releaseExclusiveAccess();
+ return back;
+}
+
+
+int ThreadSafeOutputStream::audioPlay(TimeStamp* start,
+ TimeStamp* end,char* buf, int len) {
+ int back;
+ threadQueueAudio->waitForExclusiveAccess();
+ back=output->audioPlay(start,end,buf,len);
+ threadQueueAudio->releaseExclusiveAccess();
+ return back;
+}
+
+void ThreadSafeOutputStream::audioFlush() {
+ threadQueueAudio->waitForExclusiveAccess();
+ output->audioFlush();
+ threadQueueAudio->releaseExclusiveAccess();
+}
+
+
+void ThreadSafeOutputStream::audioClose() {
+ threadQueueAudio->waitForExclusiveAccess();
+ output->audioClose();
+ threadQueueAudio->releaseExclusiveAccess();
+}
+
+void ThreadSafeOutputStream::audioOpen() {
+ threadQueueAudio->waitForExclusiveAccess();
+ output->audioOpen();
+ threadQueueAudio->releaseExclusiveAccess();
+}
+
+
+
+int ThreadSafeOutputStream::getPreferredDeliverSize() {
+ int back;
+ threadQueueAudio->waitForExclusiveAccess();
+ back=output->getPreferredDeliverSize();
+ threadQueueAudio->releaseExclusiveAccess();
+ return back;
+}
+
+int ThreadSafeOutputStream::videoInit() {
+ int back;
+ threadQueueVideo->waitForExclusiveAccess();
+ back=output->videoInit();
+ threadQueueVideo->releaseExclusiveAccess();
+ return back;
+}
+
+int ThreadSafeOutputStream::openWindow(int w, int h,const char* title) {
+ int back;
+ threadQueueVideo->waitForExclusiveAccess();
+ back=output->openWindow(w,h,title);
+ threadQueueVideo->releaseExclusiveAccess();
+ return back;
+}
+
+
+void ThreadSafeOutputStream::closeWindow() {
+ threadQueueVideo->waitForExclusiveAccess();
+ output->closeWindow();
+ threadQueueVideo->releaseExclusiveAccess();
+}
+
+void ThreadSafeOutputStream::flushWindow() {
+ threadQueueVideo->waitForExclusiveAccess();
+ output->flushWindow();
+ threadQueueVideo->releaseExclusiveAccess();
+}
+
+
+PictureArray* ThreadSafeOutputStream::lockPictureArray() {
+ PictureArray* back;
+ threadQueueVideo->waitForExclusiveAccess();
+ back=output->lockPictureArray();
+ threadQueueVideo->releaseExclusiveAccess();
+ return back;
+}
+
+
+void ThreadSafeOutputStream::unlockPictureArray(PictureArray* array) {
+ threadQueueVideo->waitForExclusiveAccess();
+ output->unlockPictureArray(array);
+ threadQueueVideo->releaseExclusiveAccess();
+}
+
+
+int ThreadSafeOutputStream::getFrameusec() {
+ int back;
+ threadQueueVideo->waitForExclusiveAccess();
+ back=output->getFrameusec();
+ threadQueueVideo->releaseExclusiveAccess();
+ return back;
+}
+
+void ThreadSafeOutputStream::config(const char* key,
+ const char* value,void* user_data) {
+
+ threadQueueVideo->waitForExclusiveAccess();
+ threadQueueAudio->waitForExclusiveAccess();
+ output->config(key,value,user_data);
+ threadQueueVideo->releaseExclusiveAccess();
+ threadQueueAudio->releaseExclusiveAccess();
+
+}
+
+
+
diff --git a/mpeglib/lib/output/threadSafeOutputStream.h b/mpeglib/lib/output/threadSafeOutputStream.h
new file mode 100644
index 00000000..c9852a37
--- /dev/null
+++ b/mpeglib/lib/output/threadSafeOutputStream.h
@@ -0,0 +1,67 @@
+/*
+ thread safe wrapper for output Stream
+ 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 __THREADSAFEOUTPUTSTREAM_H
+#define __THREADSAFEOUTPUTSTREAM_H
+
+// read INTRO in threadQueue.h
+// This class makes the outputStream (given in constructor)
+// threadsafe by wrapping each call with a threadqueue.
+//
+// Important NOTE: the output pointer is the owned by this class !!!
+// which means: we call delete on it!
+// More Important NOTES:
+//
+// We make the audio and video calls seperate threadsafe
+// and ONLY the config call threadsafe to both!
+
+#include "../util/abstract/threadQueue.h"
+#include "outputStream.h"
+
+
+class ThreadSafeOutputStream : public OutputStream {
+
+ ThreadQueue* threadQueueAudio;
+ ThreadQueue* threadQueueVideo;
+ OutputStream* output;
+
+ public:
+ ThreadSafeOutputStream(OutputStream* output);
+ ~ThreadSafeOutputStream();
+
+ // Thread safe Audio Stream handling
+ int audioInit();
+ int audioSetup(int freq,int stereo,int sign,int big,int sampleSize);
+ int audioPlay(TimeStamp* startStamp,
+ TimeStamp* endStamp,char *buffer, int size);
+ void audioFlush();
+ void audioClose();
+ void audioOpen();
+ int getPreferredDeliverSize();
+
+
+ // Video Output
+ int videoInit();
+ int openWindow(int width, int height,const char *title);
+ void closeWindow();
+ void flushWindow();
+ PictureArray* lockPictureArray();
+ void unlockPictureArray(PictureArray* pictureArray);
+ int getFrameusec();
+
+ // config Output
+ void config(const char* key,
+ const char* value,void* user_data);
+
+
+};
+#endif
diff --git a/mpeglib/lib/output/windowOut.cpp b/mpeglib/lib/output/windowOut.cpp
new file mode 100644
index 00000000..3e199095
--- /dev/null
+++ b/mpeglib/lib/output/windowOut.cpp
@@ -0,0 +1,64 @@
+/*
+ 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 "windowOut.h"
+
+
+
+
+
+
+
+WindowOut::WindowOut() {
+
+ renderMachine=new RenderMachine();
+
+}
+
+
+WindowOut::~WindowOut() {
+ delete renderMachine;
+}
+
+int WindowOut::openWindow(int width, int height,const char *title){
+ return renderMachine->openWindow(width,height,title);
+}
+
+int WindowOut::x11WindowId() {
+ return renderMachine->x11WindowId();
+}
+
+void WindowOut::flushWindow() {
+ renderMachine->flushWindow();
+}
+
+
+void WindowOut::closeWindow() {
+ renderMachine->closeWindow();
+}
+
+
+PictureArray* WindowOut::lockPictureArray() {
+ return renderMachine->lockPictureArray();
+}
+
+
+void WindowOut::unlockPictureArray(PictureArray* pictureArray) {
+ renderMachine->unlockPictureArray(pictureArray);
+}
+
+
+
+void WindowOut::config(const char* key, const char* value,void* user_data) {
+ renderMachine->config(key,value,user_data);
+}
diff --git a/mpeglib/lib/output/windowOut.h b/mpeglib/lib/output/windowOut.h
new file mode 100644
index 00000000..648d1dc4
--- /dev/null
+++ b/mpeglib/lib/output/windowOut.h
@@ -0,0 +1,53 @@
+/*
+ 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 __WINDOWOUT_H
+#define __WINDOWOUT_H
+
+
+#include "../util/abstract/abs_thread.h"
+#include "../util/timeStamp.h"
+#include "../util/render/renderMachine.h"
+
+/**
+ Stupid class. survivor of ancient days.
+*/
+
+
+class WindowOut {
+
+
+ RenderMachine* renderMachine;
+
+ public:
+ WindowOut();
+ ~WindowOut();
+
+ int openWindow(int width, int height,const char *title);
+ int x11WindowId();
+ void closeWindow();
+ void flushWindow();
+
+ // get the current surfaces to draw into
+ PictureArray* lockPictureArray();
+ void unlockPictureArray(PictureArray* pictureArray);
+
+ void config(const char* key, const char* value,void* user_data);
+
+
+ private:
+
+
+};
+#endif
diff --git a/mpeglib/lib/output/yuvDumper.cpp b/mpeglib/lib/output/yuvDumper.cpp
new file mode 100644
index 00000000..1962b151
--- /dev/null
+++ b/mpeglib/lib/output/yuvDumper.cpp
@@ -0,0 +1,81 @@
+/*
+ writes yuv images on HD
+ 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 "yuvDumper.h"
+
+YUVDumper::YUVDumper() {
+ picCnt=1;
+ method=_DUMP_YUV_AS_STREAM;
+}
+
+YUVDumper::~YUVDumper() {
+}
+
+
+int YUVDumper::openWindow(int w, int h,const char*) {
+
+ FILE* formatFile=fopen("stream.yuv.format","w+");
+ fprintf(formatFile,"Version 0.1\nw:%dh:%d\n",w,h);
+ fclose(formatFile);
+
+
+
+ if (method == _DUMP_YUV_AS_STREAM) {
+ FILE* outFile=fopen("stream.yuv","w+");
+ fclose(outFile);
+ }
+ return true;
+}
+
+void YUVDumper::closeWindow() {
+}
+
+
+void YUVDumper::flushWindow() {
+}
+
+
+int YUVDumper::getMethod() {
+ return method;
+}
+
+
+void YUVDumper::setMethod(int method) {
+ this->method=method;
+}
+
+void YUVDumper::unlockPictureArray(PictureArray* pictureArray) {
+ YUVPicture* pic=pictureArray->getYUVPictureCallback();
+ if (pic == NULL) {
+ return;
+ }
+
+ FILE* outFile=NULL;
+
+ if (method == _DUMP_YUV_AS_STREAM) {
+ outFile=fopen("stream.yuv","a+");
+ }
+
+ if (outFile == NULL) {
+ perror("fopen");
+ return;
+ }
+
+ int lumSize=pic->getLumLength();
+ int colorSize=pic->getColorLength();
+ fwrite(pic->getLuminancePtr(),1,lumSize,outFile);
+ fwrite(pic->getCrPtr(),1,colorSize,outFile);
+ fwrite(pic->getCbPtr(),1,colorSize,outFile);
+ fclose(outFile);
+
+}
diff --git a/mpeglib/lib/output/yuvDumper.h b/mpeglib/lib/output/yuvDumper.h
new file mode 100644
index 00000000..2e4880b0
--- /dev/null
+++ b/mpeglib/lib/output/yuvDumper.h
@@ -0,0 +1,51 @@
+/*
+ writes yuv images on HD
+ 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 __YUVDUMPER_H
+#define __YUVDUMPER_H
+
+#include "outputStream.h"
+
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <stdio.h>
+
+
+#define _DUMP_YUV_AS_STREAM 2
+
+
+class YUVDumper : public OutputStream {
+
+
+ int picCnt;
+ int method;
+
+ public:
+ YUVDumper();
+ ~YUVDumper();
+
+ // Video Output
+
+ int openWindow(int width, int height,const char *title);
+ void closeWindow();
+ void flushWindow();
+
+ void unlockPictureArray(PictureArray* pictureArray);
+ int getMethod();
+ void setMethod(int method);
+
+
+};
+
+#endif