summaryrefslogtreecommitdiffstats
path: root/mpeglib/lib/input
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/input
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/input')
-rw-r--r--mpeglib/lib/input/Makefile.am37
-rw-r--r--mpeglib/lib/input/README15
-rw-r--r--mpeglib/lib/input/bufferInputStream.cpp288
-rw-r--r--mpeglib/lib/input/bufferInputStream.h88
-rw-r--r--mpeglib/lib/input/cddaInputStream.cpp225
-rw-r--r--mpeglib/lib/input/cddaInputStream.h85
-rw-r--r--mpeglib/lib/input/cdigrap.cpp100
-rw-r--r--mpeglib/lib/input/cdromAccess.cpp54
-rw-r--r--mpeglib/lib/input/cdromAccess_Empty.cpp47
-rw-r--r--mpeglib/lib/input/cdromAccess_Linux.cpp124
-rw-r--r--mpeglib/lib/input/cdromInputStream.cpp309
-rw-r--r--mpeglib/lib/input/cdromInputStream.h88
-rw-r--r--mpeglib/lib/input/cdromRawAccess.cpp113
-rw-r--r--mpeglib/lib/input/cdromRawAccess.h67
-rw-r--r--mpeglib/lib/input/cdromToc.cpp234
-rw-r--r--mpeglib/lib/input/cdromToc.h65
-rw-r--r--mpeglib/lib/input/fileAccessWrapper.cpp65
-rw-r--r--mpeglib/lib/input/fileAccessWrapper.h41
-rw-r--r--mpeglib/lib/input/fileInputStream.cpp148
-rw-r--r--mpeglib/lib/input/fileInputStream.h46
-rw-r--r--mpeglib/lib/input/httpInputStream.cpp327
-rw-r--r--mpeglib/lib/input/httpInputStream.h84
-rw-r--r--mpeglib/lib/input/inputDetector.cpp192
-rw-r--r--mpeglib/lib/input/inputDetector.h56
-rw-r--r--mpeglib/lib/input/inputPlugin.cpp92
-rw-r--r--mpeglib/lib/input/inputPlugin.h45
-rw-r--r--mpeglib/lib/input/inputStream.cpp135
-rw-r--r--mpeglib/lib/input/inputStream.h79
-rw-r--r--mpeglib/lib/input/simpleRingBuffer.cpp420
-rw-r--r--mpeglib/lib/input/simpleRingBuffer.h136
-rw-r--r--mpeglib/lib/input/threadSafeInputStream.cpp137
-rw-r--r--mpeglib/lib/input/threadSafeInputStream.h56
32 files changed, 3998 insertions, 0 deletions
diff --git a/mpeglib/lib/input/Makefile.am b/mpeglib/lib/input/Makefile.am
new file mode 100644
index 00000000..f7e849eb
--- /dev/null
+++ b/mpeglib/lib/input/Makefile.am
@@ -0,0 +1,37 @@
+# libinputplugin - Makefile.am
+
+EXTRA_DIST = cdromAccess_Linux.cpp cdromAccess_Empty.cpp \
+ cdigrap.cpp README
+
+INCLUDES = $(all_includes)
+
+noinst_LTLIBRARIES = libinput.la
+
+noinst_HEADERS = cdromToc.h cdromRawAccess.h \
+ simpleRingBuffer.h fileAccessWrapper.h
+
+kmpgincludedir = $(includedir)/$(THIS_LIB_NAME)/input
+
+kmpginclude_HEADERS = inputStream.h fileInputStream.h \
+ inputPlugin.h \
+ cdromInputStream.h bufferInputStream.h \
+ inputDetector.h httpInputStream.h \
+ threadSafeInputStream.h cddaInputStream.h
+
+
+
+libinput_la_SOURCES = inputStream.cpp fileInputStream.cpp \
+ inputPlugin.cpp \
+ cdromToc.cpp cdromRawAccess.cpp \
+ cdromInputStream.cpp \
+ bufferInputStream.cpp \
+ simpleRingBuffer.cpp \
+ cdromAccess.cpp inputDetector.cpp \
+ httpInputStream.cpp \
+ threadSafeInputStream.cpp \
+ cddaInputStream.cpp \
+ fileAccessWrapper.cpp
+
+# workaround for compile errors caused by linux/cdrom.h.
+# Linux kernel headers suck donkeyballs.
+KDE_CXXFLAGS = $(ENABLE_PERMISSIVE_FLAG)
diff --git a/mpeglib/lib/input/README b/mpeglib/lib/input/README
new file mode 100644
index 00000000..844a17bb
--- /dev/null
+++ b/mpeglib/lib/input/README
@@ -0,0 +1,15 @@
+
+
+Here is the abstraction of the inputplugin.
+Its a base class, with the usual open/seek/read methods.
+The only nice thing is the factory inputPlugin which
+creates you for a given url the correct class.
+
+
+All inputStreams can take a timeStamp. Its necessary for
+audio/video sync, but this must be supported
+by the outputplugin and the playerPlugin!
+Video is not that easy as audio :(
+
+
+
diff --git a/mpeglib/lib/input/bufferInputStream.cpp b/mpeglib/lib/input/bufferInputStream.cpp
new file mode 100644
index 00000000..68e502ff
--- /dev/null
+++ b/mpeglib/lib/input/bufferInputStream.cpp
@@ -0,0 +1,288 @@
+/*
+ reads input data
+ 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 "bufferInputStream.h"
+#include "simpleRingBuffer.h"
+
+
+BufferInputStream::BufferInputStream(int size,int minlinSize,
+ const char* name) {
+ ringBuffer=new SimpleRingBuffer(size,minlinSize);
+ leof=false;
+ bytePos=0;
+ fillgrade=0;
+ setUrl(name);
+ lLock=false;
+ abs_thread_mutex_init(&writeInMut);
+}
+
+
+BufferInputStream::~BufferInputStream() {
+ delete ringBuffer;
+ abs_thread_mutex_destroy(&writeInMut);
+}
+
+
+int BufferInputStream::open(const char*) {
+ leof=false;
+ setBlocking(true);
+ return true;
+}
+
+void BufferInputStream::close() {
+ leof=true;
+ setBlocking(false);
+}
+
+int BufferInputStream::eof() {
+ return (leof && (fillgrade==0));
+}
+
+int BufferInputStream::isOpen() {
+ return !leof;
+}
+
+void BufferInputStream::setBlocking(int lblock) {
+ ringBuffer->setCanWaitForSpace(lblock);
+ ringBuffer->setCanWaitForData(lblock);
+}
+
+int BufferInputStream::getHold() {
+ return lLock;
+}
+
+
+void BufferInputStream::setHold(int lLock) {
+ if (lLock) {
+ lockBuffer();
+ } else {
+ unlockBuffer();
+ }
+ this->lLock=lLock;
+}
+
+int BufferInputStream::read(char* ptr,int size) {
+ int i=0;
+ int n=size;
+ int canCopy=n;
+ char* readPtr;
+ // here we read even if leof is true
+ // we make sure that we empty the whole buffer!
+ while((eof()==false) && (n > 0)) {
+ canCopy=n;
+ ringBuffer->getReadArea(readPtr,canCopy);
+ if (canCopy <= 0){
+ ringBuffer->waitForData(1);
+ continue;
+ }
+ if (n < canCopy) {
+ canCopy=n;
+ }
+ memcpy((char*)ptr+i,readPtr,canCopy);
+ i=i+canCopy;
+ n=n-canCopy;
+ ringBuffer->forwardReadPtr(canCopy);
+ ringBuffer->forwardLockPtr(canCopy);
+ lockBuffer();
+ bytePos+=canCopy;
+ fillgrade-=canCopy;
+ unlockBuffer();
+ }
+ return i;
+}
+
+
+int BufferInputStream::write(char* ptr,int len,TimeStamp* stamp) {
+ int i=0;
+ int n=len;
+ int canWrite=n;
+ char* writePtr;
+
+ if (stamp) {
+ lockBuffer();
+ long key;
+ key=bytePos+fillgrade;
+ InputStream::insertTimeStamp(stamp,key,len);
+ unlockBuffer();
+ }
+ // if eof is set we do not insert any more data
+ // we do not call eof() !!!
+ while((leof==false) && (n > 0)) {
+ canWrite=n;
+ ringBuffer->getWriteArea(writePtr,canWrite);
+ if (canWrite <= 0){
+ ringBuffer->waitForSpace(1);
+ continue;
+ }
+ if (canWrite > n) {
+ canWrite=n;
+ }
+ memcpy(writePtr,(char*)ptr+i,canWrite);
+ i=i+canWrite;
+ n=n-canWrite;
+ ringBuffer->forwardWritePtr(canWrite);
+ lockBuffer();
+ fillgrade+=canWrite;
+ unlockBuffer();
+ }
+
+ return i;
+}
+
+
+
+int BufferInputStream::write(InputStream* input,int len,TimeStamp* stamp) {
+ int i=0;
+ int n=len;
+ int canWrite=n;
+ int didWrite;
+ char* writePtr;
+
+ if (stamp) {
+ lockBuffer();
+ long key;
+ key=bytePos+fillgrade;
+ InputStream::insertTimeStamp(stamp,key,len);
+ unlockBuffer();
+ }
+ // if eof is set we do not insert any more data
+ // we do not call eof() !!!
+ while((leof==false) && (n > 0)) {
+ canWrite=n;
+ ringBuffer->getWriteArea(writePtr,canWrite);
+ if (canWrite <= 0){
+ ringBuffer->waitForSpace(1);
+ continue;
+ }
+ if (canWrite > n) {
+ canWrite=n;
+ }
+ didWrite=input->read(writePtr,canWrite);
+ if (input->eof()) break;
+ i=i+didWrite;
+ n=n-didWrite;
+ ringBuffer->forwardWritePtr(didWrite);
+ lockBuffer();
+ fillgrade+=canWrite;
+ unlockBuffer();
+ }
+
+ return i;
+}
+
+
+
+long BufferInputStream::getByteLength() {
+ return ringBuffer->getFillgrade();
+}
+
+int BufferInputStream::getFillgrade() {
+ return ringBuffer->getFillgrade();
+}
+
+
+int BufferInputStream::getFreeRead() {
+ return ringBuffer->getFreeRead();
+}
+
+
+int BufferInputStream::getFreeSpace() {
+ return ringBuffer->getFreeWrite();
+}
+
+
+
+long BufferInputStream::getBytePosition() {
+ return bytePos;
+}
+
+void BufferInputStream::setBytePosition(long bytePos) {
+ this->bytePos=bytePos;
+}
+
+
+int BufferInputStream::seek(long) {
+ return false;
+}
+
+
+void BufferInputStream::clear() {
+
+ ringBuffer->emptyBuffer();
+ ringBuffer->exitWaitForData();
+ ringBuffer->exitWaitForSpace();
+ timeStampArray->clear();
+
+ lockBuffer();
+ bytePos=0;
+ fillgrade=0;
+ unlockBuffer();
+
+}
+
+
+
+
+// remote read extension
+int BufferInputStream::readRemote(char** ptr,int size) {
+ int n=0;
+ char* readPtr;
+ while((eof()==false)) {
+ n=size;
+ ringBuffer->getReadArea(readPtr,n);
+ if (n < size){
+ ringBuffer->waitForData(size);
+ if (ringBuffer->getCanWaitForData()==false) {
+ break;
+ }
+ continue;
+ }
+ break;
+ }
+ *ptr=readPtr;
+ return n;
+}
+
+
+void BufferInputStream::forwardReadPtr(int bytes) {
+
+ ringBuffer->forwardReadPtr(bytes);
+ ringBuffer->forwardLockPtr(bytes);
+ lockBuffer();
+ bytePos+=bytes;
+ fillgrade-=bytes;
+ unlockBuffer();
+ getTimeStamp(bytePos);
+}
+
+
+void BufferInputStream::setCanWaitForData(int lBlock) {
+ ringBuffer->setCanWaitForData(lBlock);
+}
+
+
+void BufferInputStream::lockBuffer() {
+ abs_thread_mutex_lock(&writeInMut);
+}
+
+
+void BufferInputStream::unlockBuffer() {
+ abs_thread_mutex_unlock(&writeInMut);
+}
+
+
+int BufferInputStream::getSize() {
+ return ringBuffer->getSize();
+}
+
+
diff --git a/mpeglib/lib/input/bufferInputStream.h b/mpeglib/lib/input/bufferInputStream.h
new file mode 100644
index 00000000..3bd3e691
--- /dev/null
+++ b/mpeglib/lib/input/bufferInputStream.h
@@ -0,0 +1,88 @@
+/*
+ reads input data
+ 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 __BUFFERINPUTSTREAM_H
+#define __BUFFERINPUTSTREAM_H
+
+#include "../util/abstract/abs_thread.h"
+
+#include "inputStream.h"
+
+
+class SimpleRingBuffer;
+
+class BufferInputStream : public InputStream {
+
+ SimpleRingBuffer* ringBuffer;
+ int leof;
+ long bytePos;
+ int fillgrade;
+ int lLock;
+ abs_thread_mutex_t writeInMut;
+
+ public:
+ BufferInputStream(int size,int minlinSize,const char* name);
+ ~BufferInputStream();
+
+ int open(const char* name);
+ void close();
+
+ int isOpen();
+
+
+ int eof();
+ void setBlocking(int lblock);
+ int read(char* ptr,int size);
+
+ // reads from a buffer
+ int write(char* ptr,int len,TimeStamp* stamp);
+
+ // this method directy read from another inputstream (faster);
+ int write(InputStream* ptr,int len,TimeStamp* stamp);
+
+ int seek(long bytePos);
+
+
+ long getByteLength();
+ long getBytePosition();
+
+ void setBytePosition(long bytePos);
+ int getFillgrade();
+ int getSize();
+ int getFreeRead();
+ int getFreeSpace();
+
+ void clear();
+
+ // remote read extension
+ // Note you _need_ to call always both methods
+ // readRemote and forwardReadPtr even if bytes==0!!!
+ // (we hold a resizeLock during this operation)
+ int readRemote(char** ptr,int size);
+ void forwardReadPtr(int bytes);
+ void setCanWaitForData(int lBlock);
+
+
+ // this method is only safe to call by the writer in the buffer
+ // a reader never should call this (segfault possible)
+ void resizeBuffer(int changeSize);
+
+ // for pause/play over loopback
+ int getHold();
+ void setHold(int lLock);
+
+ private:
+ void lockBuffer();
+ void unlockBuffer();
+
+};
+#endif
diff --git a/mpeglib/lib/input/cddaInputStream.cpp b/mpeglib/lib/input/cddaInputStream.cpp
new file mode 100644
index 00000000..9bc8f5f2
--- /dev/null
+++ b/mpeglib/lib/input/cddaInputStream.cpp
@@ -0,0 +1,225 @@
+/*
+ cdda input class based on cdparanoia
+ 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
+
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef CDDA_PARANOIA
+
+#include <iostream>
+
+using namespace std;
+
+#include "cddaInputStream.h"
+#include "inputDetector.h"
+
+
+void paranoiaCallback(long, int) {
+ //cout << "long:"<<a<<" int:"<<b<<endl;
+}
+
+CDDAInputStream::CDDAInputStream() {
+ drive = NULL;
+ paranoia=NULL;
+ device=NULL;
+ track=1;
+}
+
+
+CDDAInputStream::~CDDAInputStream() {
+ close();
+}
+
+// here we should encdoe the track Nr. as well
+// eg: /dev/cdrom#1
+int CDDAInputStream::getTrackAndDevice(const char* url) {
+ int matches=0;
+ // dest = "cdda:/dev/cdrom/track01.cda"
+ char* noprotoString=InputDetector::removeProtocol(url);
+ // noprotoString="/dev/cdrom/track01.cda"
+ char* filename=InputDetector::getFilename(noprotoString);
+ // filename="track01.cda"
+ char* filenameNoExt=InputDetector::getWithoutExtension(filename);
+ // filenameNoExt="track01"
+ char* dir=InputDetector::removeExtension(noprotoString,filename);
+ // dir="/dev/cdrom/"
+ device=InputDetector::removeSlash(dir);
+ track=1;
+ if (filenameNoExt != NULL) {
+ matches=sscanf(filenameNoExt,"track%02d",&track);
+ }
+ if (matches == 0) {
+ cout << "no trackNumber found using default"<<endl;
+ }
+ cout << "device:"<<device<<" track:"<<track<<endl;
+
+ if (noprotoString != NULL) {
+ delete noprotoString;
+ }
+ if (filename != NULL) {
+ delete filename;
+ }
+ if (filenameNoExt != NULL) {
+ delete filenameNoExt;
+ }
+ if (dir != NULL) {
+ delete dir;
+ }
+ if (device == NULL) {
+ cout << "no device found, using any"<<endl;
+ return false;
+ }
+ return true;
+}
+
+int CDDAInputStream::open(const char* dest) {
+ if (getTrackAndDevice(dest) == true) {
+ drive = cdda_identify(device, CDDA_MESSAGE_PRINTIT, 0);
+ }
+
+ if (drive == NULL) {
+ cout << "cdda_identify failed trying to find a device"<<endl;
+ drive=cdda_find_a_cdrom(CDDA_MESSAGE_PRINTIT, 0);
+ }
+ if (drive == NULL) {
+ cout << "nope. nothing found. give up"<<endl;
+ return false;
+ }
+ cout << "cdda_open -s"<<endl;
+ if (cdda_open(drive) != 0) {
+ cout << "cdda_open(drive) failed"<<endl;
+ close();
+ return false;
+ }
+ cout << "cdda_open -e"<<endl;
+
+ // debug things a bit
+ int trackCount = drive->tracks;
+ for (int i = 1; i <= trackCount; i++) {
+ if (IS_AUDIO(drive, i)) {
+ printf("track%02d.cda\n", i);
+ } else {
+ printf("no audio:%d\n",i);
+ }
+ }
+
+ paranoia = paranoia_init(drive);
+ if (paranoia == NULL) {
+ cout << "paranoia init failed"<<endl;
+ close();
+ return false;
+ }
+
+ firstSector=cdda_track_firstsector(drive, track);
+ lastSector=cdda_track_lastsector(drive, track);
+ currentSector=firstSector;
+ // paranoia && drive != NULL -> initialized!
+
+ int paranoiaLevel = PARANOIA_MODE_FULL ^ PARANOIA_MODE_NEVERSKIP;
+ paranoia_modeset(paranoia, paranoiaLevel);
+ cdda_verbose_set(drive, CDDA_MESSAGE_PRINTIT, CDDA_MESSAGE_PRINTIT);
+ paranoia_seek(paranoia, firstSector, SEEK_SET);
+
+ return true;
+}
+
+
+void CDDAInputStream::close() {
+ if (isOpen() == false) {
+ return;
+ }
+ cdda_close(drive);
+ drive=NULL;
+ if (paranoia != NULL) {
+ paranoia_free(paranoia);
+ paranoia = 0;
+ }
+ if (device != NULL) {
+ delete device;
+ device=NULL;
+ }
+}
+
+
+int CDDAInputStream::isOpen() {
+ return (drive != NULL);
+}
+
+
+int CDDAInputStream::eof() {
+ if (isOpen()==false) {
+ return true;
+ }
+ if (currentSector >= lastSector) {
+ return true;
+ }
+ return false;
+}
+
+
+int CDDAInputStream::read(char* dest,int len) {
+ if (len != 2*CD_FRAMESIZE_RAW) {
+ cout << "len must be 2*CD_FRAMESIZE_RAW"<<endl;
+ exit(0);
+ }
+ int16_t * buf = paranoia_read(paranoia, paranoiaCallback);
+ currentSector++;
+ if (buf == NULL) {
+ cout << "paranoia_read failed"<<endl;
+ close();
+ return 0;
+ }
+ memcpy(dest,buf,sizeof(int16_t)*CD_FRAMESIZE_RAW);
+ return CD_FRAMESIZE_RAW;
+}
+
+
+int CDDAInputStream::seek(long bytePos) {
+ int byteLength=getByteLength();
+ float ratio=(float)bytePos/(float)(byteLength+1);
+ float wantSector=ratio*(float)((lastSector-firstSector));
+ if (isOpen()) {
+ currentSector=(int)wantSector;
+ cout << "paranoia_seek:"<<currentSector<<endl;
+ paranoia_seek(paranoia, currentSector, SEEK_SET);
+ }
+ return true;
+}
+
+void CDDAInputStream::clear() {
+ cout << "direct virtual call CDDAInputStream::clear:"<<endl;
+}
+
+
+long CDDAInputStream::getByteLength() {
+ int sectors=lastSector-firstSector;
+ int bytes=sectors*CD_FRAMESIZE_RAW*sizeof(int16_t);
+ cout << "getByteLength:"<<bytes<<endl;
+ return bytes;
+}
+
+
+long CDDAInputStream::getBytePosition() {
+ int readSectors=currentSector-firstSector;
+ int bytes=readSectors*CD_FRAMESIZE_RAW*sizeof(int16_t);
+ return bytes;
+}
+
+#endif
+//CDDA_PARANOIA
+
+
+
+
+
diff --git a/mpeglib/lib/input/cddaInputStream.h b/mpeglib/lib/input/cddaInputStream.h
new file mode 100644
index 00000000..55989c65
--- /dev/null
+++ b/mpeglib/lib/input/cddaInputStream.h
@@ -0,0 +1,85 @@
+/*
+ cdda input class based on cdparanoia
+ 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 __CDDAINPUTSTREAM_H
+#define __CDDAINPUTSTREAM_H
+
+
+#include "inputStream.h"
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifndef CDDA_PARANOIA
+class CDDAInputStream : public InputStream {
+};
+#else
+
+#include <sys/types.h>
+typedef int16_t size16;
+typedef int32_t size32;
+
+extern "C" {
+#include <cdda_interface.h>
+#include <cdda_paranoia.h>
+void paranoiaCallback(long, int);
+}
+//#define CDDA_INCLUDE
+
+
+class CDDAInputStream : public InputStream {
+
+//#ifdef CDDA_INCLUDE
+ cdrom_paranoia * paranoia;
+ struct cdrom_drive * drive;
+//#else
+// void * drive;
+// void * paranoia;
+//#endif
+
+
+ char* device;
+ int track;
+
+ int firstSector;
+ int lastSector;
+ int currentSector;
+
+ public:
+ CDDAInputStream();
+ ~CDDAInputStream();
+
+ int open(const char* dest);
+ void close();
+ int isOpen();
+
+ int eof();
+ int read(char* ptr,int size);
+ int seek(long bytePos);
+ // clears possible input buffers
+ // (called by the decoderPlugin after a resyncCommit)
+ void clear();
+
+ long getByteLength();
+ long getBytePosition();
+ private:
+ int getTrackAndDevice(const char* url);
+
+};
+#endif
+//CDDA_PARANOIA
+
+#endif
diff --git a/mpeglib/lib/input/cdigrap.cpp b/mpeglib/lib/input/cdigrap.cpp
new file mode 100644
index 00000000..37d9de0e
--- /dev/null
+++ b/mpeglib/lib/input/cdigrap.cpp
@@ -0,0 +1,100 @@
+/**
+ graps cdis
+
+ Compile with
+
+ g++ -o cdigrap cdigrap.cpp -lmpeg
+
+*/
+#ifdef CONFIG_H
+#include "config.h"
+#endif
+#include "inputPlugin.h"
+
+#if defined(HAVE_GETOPT_H)
+#include <getopt.h>
+#endif
+
+void usage() {
+ cout << "cdigrab grabs video cds"<<endl;
+ cout << "Usage : cdigrab [s:b:f:h] cdi:/device"<<endl;
+ cout << endl;
+ cout << "-s : bytes start a positions <bytes>"<<endl;
+ cout << "-b : set block size (default: 32768)"<<endl;
+ cout << "-f : set filename (default: a.cdi)"<<endl;
+ cout << "-h : help"<<endl;
+ cout << "THIS SOFTWARE COMES WITH ABSOLUTELY NO WARRANTY! " \
+ << "USE AT YOUR OWN RISK!"<<endl;
+ cout << endl;
+}
+
+
+int main(int argn,char** args) {
+
+
+ if (argn <= 1) {
+ usage();
+ exit(0);
+ }
+ long startBytes=0;
+ int len=32768;
+ char *fname = strdup("a.cdi");
+ int c;
+
+ while(1) {
+ c = getopt (argn, args, "s:b:f:h");
+ if (c == -1) break;
+ switch(c) {
+ case 'h': {
+ usage();
+ exit(0);
+ }
+ case 's': {
+ startBytes=atoi(optarg);
+ break;
+ }
+ case 'b': {
+ len=atoi(optarg);
+ break;
+ }
+ case 'f': {
+ fname = strdup(optarg);
+ break;
+ }
+ default:
+ printf ("?? getopt returned character code 0%o ??\n", c);
+ usage();
+ exit(-1);
+ }
+ }
+ if (optind >= argn ) {
+ usage();
+ exit(-1);
+ }
+
+ InputStream* in=InputPlugin::createInputStream(args[optind]);
+
+ in->open(args[optind]);
+
+ if (startBytes != 0) {
+ cout << "seeking to :"<<startBytes<<endl;
+ in->seek(startBytes);
+ }
+ char* buffer=new char[len];
+ int cnt=0;
+ FILE* f=fopen(fname,"a+");
+ while(1) {
+ if (in->eof() == true) {
+ cout << "******* plugin->getStreamState() EOF"<<endl;
+ break;
+ }
+ in->read(buffer,len);
+ fwrite(buffer,len,1,f);
+ cnt++;
+ cout << "grapped:"<<cnt*len<<endl;
+ }
+ fclose(f);
+}
+
+
+
diff --git a/mpeglib/lib/input/cdromAccess.cpp b/mpeglib/lib/input/cdromAccess.cpp
new file mode 100644
index 00000000..98d49779
--- /dev/null
+++ b/mpeglib/lib/input/cdromAccess.cpp
@@ -0,0 +1,54 @@
+/*
+ * system dependent wrapper for access to cdrom
+ * 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
+ *
+ * $Id$
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+ #include <config.h>
+#endif
+
+
+
+#ifdef OS_AIX
+ #include "cdromAccess_Empty.cpp"
+#endif
+
+#ifdef OS_Linux
+ #include <sys/types.h>
+ #include "cdromAccess_Linux.cpp"
+#endif
+
+#ifdef OS_BSD
+ #include "cdromAccess_Empty.cpp"
+#endif
+
+#if defined(OS_IRIX) || defined(OS_IRIX64)
+ #include "cdromAccess_Empty.cpp"
+#endif
+
+#ifdef OS_HPUX
+ #include "cdromAccess_Empty.cpp"
+#endif
+
+#ifdef OS_SunOS
+ #include "cdromAccess_Empty.cpp"
+#endif
+
+#ifdef __BEOS__
+ #include "cdromAccess_Empty.cpp"
+#endif
+
+#ifdef WIN32
+ #include "cdromAccess_Empty.cpp"
+#endif
+
+
diff --git a/mpeglib/lib/input/cdromAccess_Empty.cpp b/mpeglib/lib/input/cdromAccess_Empty.cpp
new file mode 100644
index 00000000..63da4b69
--- /dev/null
+++ b/mpeglib/lib/input/cdromAccess_Empty.cpp
@@ -0,0 +1,47 @@
+/*
+ system dependent wrapper for access to cdrom (no system)
+ 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 "cdromToc.h"
+#include "cdromRawAccess.h"
+
+#include <iostream>
+using namespace std;
+
+
+int CDRomToc::getStartEnd(FILE* file,int& startToc,int& endToc) {
+ cout << "CDRomToc::getStartEnd not implemented on your system"<<endl;
+ return false;
+}
+
+
+int CDRomToc::readToc(FILE* file,int num,int& min,int& sec, int& frame) {
+ cout << "CDRomToc::readToc not implemented on your system"<<endl;
+ return false;
+}
+
+
+int CDRomToc::readLeadOut(FILE* file,int& min,int& sec, int& frame) {
+ cout << "CDRomToc::reatLeadOut not implemented on your system"<<endl;
+ return false;
+}
+
+
+
+int CDRomRawAccess::readDirect(int minute,int second, int frame) {
+
+
+ cout << "no CDRomRawAccess::read implemented for your system"<<endl;
+ lData=false;
+ return true;
+}
+
diff --git a/mpeglib/lib/input/cdromAccess_Linux.cpp b/mpeglib/lib/input/cdromAccess_Linux.cpp
new file mode 100644
index 00000000..a3bde622
--- /dev/null
+++ b/mpeglib/lib/input/cdromAccess_Linux.cpp
@@ -0,0 +1,124 @@
+/*
+ system dependent wrapper for access to cdrom (Linux)
+ 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
+
+ */
+
+#ifdef __STRICT_ANSI__
+#undef __STRICT_ANSI__
+#define _ANSI_WAS_HERE_
+#endif
+#include <linux/types.h>
+#include <linux/cdrom.h>
+#ifdef _ANSI_WAS_HERE_
+#define __STRICT_ANSI__
+#endif
+#include <sys/ioctl.h>
+
+#include "cdromToc.h"
+#include "cdromRawAccess.h"
+
+#include <iostream>
+
+using namespace std;
+
+/**
+ here you find an example how to port the access method
+ to your system.
+*/
+
+
+int CDRomToc::getStartEnd(FILE* file,int& startToc,int& endToc) {
+ struct cdrom_tochdr tochdr;
+ int fd=fileno(file);
+ if (ioctl(fd, CDROMREADTOCHDR, &tochdr) == -1) {
+ perror("ioctl cdromreadtochdr");
+ return false;
+ }
+
+ startToc=tochdr.cdth_trk0;
+ endToc=tochdr.cdth_trk1;
+ return true;
+}
+
+
+int CDRomToc::readToc(FILE* file,int num,int& min,int& sec, int& frame) {
+ struct cdrom_tocentry tocent;
+ int fd=fileno(file);
+ tocent.cdte_track = num;
+ tocent.cdte_format = CDROM_MSF;
+ if (ioctl(fd, CDROMREADTOCENTRY, &tocent) == -1 ) {
+ perror("ioctl cdromreadtocentry");
+ return false;
+ }
+ min=tocent.cdte_addr.msf.minute;
+ sec=tocent.cdte_addr.msf.second;
+ frame=tocent.cdte_addr.msf.frame;
+ return true;
+}
+
+
+int CDRomToc::readLeadOut(FILE* file,int& min,int& sec, int& frame) {
+ struct cdrom_tocentry tocent;
+ int fd=fileno(file);
+ tocent.cdte_track = CDROM_LEADOUT;
+ tocent.cdte_format = CDROM_MSF;
+ if (ioctl(fd, CDROMREADTOCENTRY, &tocent) == -1 ) {
+ perror("ioctl cdromreadLeadoutn");
+ return false;
+ }
+ min=tocent.cdte_addr.msf.minute;
+ sec=tocent.cdte_addr.msf.second;
+ frame=tocent.cdte_addr.msf.frame;
+ return true;
+}
+
+
+
+int CDRomRawAccess::readDirect(int minute,int second, int frame) {
+
+ // this comes from smpeg
+ // smpeg is an mpeg I player from lokigames www.lokigames.com
+
+ struct cdrom_msf *msf;
+ int fd=fileno(cdfile);
+
+ msf = (struct cdrom_msf*) data;
+ msf->cdmsf_min0 = minute;
+ msf->cdmsf_sec0 = second;
+ msf->cdmsf_frame0 = frame;
+ if (ioctl(fd, CDROMREADMODE2, msf) == -1) {
+ perror("ioctl cdromreadmode2");
+ cout << "min:"<<minute
+ << " sec:"<<second
+ << " frame:"<<frame<<endl;
+ return false;
+ } else {
+ //cout << "read success ****************"<<endl;
+ }
+
+ char* subheader=data+sizeof(int);
+
+
+ if ((subheader[1]==1) &&
+ (((subheader[2]==0x62) &&
+ (subheader[3]==0x0f)) || ((subheader[2]==0x64) &&
+ (subheader[3]==0x7f)))) {
+ lData=true;
+ dataStart=sizeof(int)+4;
+ } else {
+ lData=false;
+ }
+
+ len=2324;
+
+
+ return true;
+}
+
diff --git a/mpeglib/lib/input/cdromInputStream.cpp b/mpeglib/lib/input/cdromInputStream.cpp
new file mode 100644
index 00000000..1cf3f905
--- /dev/null
+++ b/mpeglib/lib/input/cdromInputStream.cpp
@@ -0,0 +1,309 @@
+/*
+ reads input data from cdrom
+ 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 "cdromInputStream.h"
+#include "cdromRawAccess.h"
+#include "cdromToc.h"
+#include <string.h>
+#include "inputDetector.h"
+
+#include <iostream>
+
+using namespace std;
+
+CDRomInputStream::CDRomInputStream() {
+ cdRomToc=new CDRomToc();
+ cdRomRawAccess=new CDRomRawAccess(cdRomToc);
+
+ buflen=0;
+ bufCurrent=NULL;
+
+ currentMinute=0;
+ currentSecond=2;
+ currentFrame=0;
+ byteCounter=0;
+}
+
+
+CDRomInputStream::~CDRomInputStream() {
+ delete cdRomRawAccess;
+ delete cdRomToc;
+}
+
+
+int CDRomInputStream::readCurrent() {
+ int ok=cdRomRawAccess->read(currentMinute,currentSecond,currentFrame);
+ if (ok==false) {
+ if (cdRomRawAccess->eof() == false) {
+ int pos=cdRomToc->getNextTocEntryPos(currentMinute,
+ currentSecond,
+ currentFrame);
+
+ // now try to read a few sectors
+ int cnt=0;
+ int back=false;
+
+ while(1) {
+ // jump forward
+ int i;
+ for(i=0;i<_CDROM_FRAMES-currentFrame;i++) {
+ next_sector();
+ }
+ cout << "trying next ..."<<endl;
+ ok=cdRomRawAccess->read(currentMinute,currentSecond,currentFrame);
+ if (ok) {
+ bufCurrent=cdRomRawAccess->getBufferStart();
+ buflen=cdRomRawAccess->getBufferLen();
+ return true;
+ }
+ cnt++;
+ if (cnt > 100) {
+ break;
+ }
+ }
+ cout << "last possible jump"<<endl;
+ if (pos > 1) {
+ TocEntry* tocEntry=cdRomToc->getTocEntry(pos-1);
+ currentMinute=tocEntry->minute;
+ currentSecond=tocEntry->second;
+ currentFrame=tocEntry->frame;
+ back=cdRomRawAccess->read(currentMinute,currentSecond,currentFrame);
+ if (back) {
+ bufCurrent=cdRomRawAccess->getBufferStart();
+ buflen=cdRomRawAccess->getBufferLen();
+ }
+ }
+ return back;
+ }
+ return false;
+ }
+ bufCurrent=cdRomRawAccess->getBufferStart();
+ buflen=cdRomRawAccess->getBufferLen();
+ return true;
+}
+
+
+int CDRomInputStream::getByteDirect() {
+ int back;
+ if (buflen==0) {
+ fillBuffer();
+ }
+ if (buflen==0){
+ return EOF;
+ }
+ back=*bufCurrent;
+ buflen--;
+ bufCurrent++;
+ byteCounter++;
+ return back;
+}
+
+
+int CDRomInputStream::read(char* ptr,int size) {
+ char* dest=(char*)ptr;
+ int bytesRead=0;
+ int doRead=size;
+ int canRead;
+
+ while(eof() == false) {
+ if (buflen == 0) {
+ if (fillBuffer() == false) {
+ return 0;
+ }
+ continue;
+ }
+ canRead=buflen;
+ if (doRead < canRead) {
+ canRead=doRead;
+ }
+ memcpy((void*)dest,(void*)bufCurrent,canRead);
+ buflen-=canRead;
+ bufCurrent+=canRead;
+ bytesRead+=canRead;
+ dest+=canRead;
+ doRead-=canRead;
+ if (doRead == 0) {
+ byteCounter+=bytesRead;
+ return bytesRead;
+ }
+ }
+ return 0;
+}
+
+int CDRomInputStream::eof() {
+ return cdRomRawAccess->eof();
+}
+
+
+
+
+long CDRomInputStream::getBytePosition() {
+ return byteCounter;
+}
+
+
+void CDRomInputStream::print() {
+}
+
+
+void CDRomInputStream::next_sector() {
+ currentFrame++;
+ if (currentFrame>=_CDROM_FRAMES) {
+ currentFrame = 0;
+ currentSecond++;
+ if (currentSecond>=_CDROM_SECS) {
+ currentSecond = 0;
+ currentMinute++;
+ }
+ }
+}
+
+int CDRomInputStream::open(const char* file) {
+ cout << "CDRomInputStream::open:"<<file<<endl;
+ char* noExtension=InputDetector::getWithoutExtension(file);
+ cout << "CDRomInputStream::noExt:"<<noExtension<<endl;
+ if (noExtension == NULL) {
+ return false;
+ }
+ cdRomToc->open(noExtension);
+ cdRomRawAccess->open(noExtension);
+ if (isOpen()==false) {
+ return false;
+ }
+ setUrl(noExtension);
+ int entries=cdRomToc->getTocEntries();
+ cdRomToc->print();
+ if (entries == 1) {
+ cerr << "only lead out"<<endl;
+ }
+
+ // cdRomRawAccess->insertTocEntry(0,2,0);
+ //cdRomToc->insertTocEntry(1,13,5);
+
+ TocEntry* tocEntry=cdRomToc->getTocEntry(0);
+ currentMinute=tocEntry->minute;
+ currentSecond=tocEntry->second;
+ currentFrame=tocEntry->frame;
+ delete noExtension;
+
+ return readCurrent();
+}
+
+
+void CDRomInputStream::close() {
+ cdRomRawAccess->close();
+ byteCounter=0;
+ setUrl(NULL);
+}
+
+
+int CDRomInputStream::isOpen() {
+ return cdRomRawAccess->isOpen();
+}
+
+
+
+
+long CDRomInputStream::getBytePos(int min,int sec) {
+ long back;
+ // 2324 is the size of a cdfram
+ back=sec*_CDROM_FRAMES*2324;
+ back=back+min*60*_CDROM_FRAMES*2324;
+ cout << "CDRomInputStream::getByteLength"<<back<<endl;
+ return back;
+}
+
+long CDRomInputStream::getByteLength() {
+ // we get the length out of the toc and then multiply like hell
+ long totalSecs=cdRomToc->getEndSecond();
+ long min=totalSecs/60;
+ long sec=totalSecs-60*min;
+
+ long back=getBytePos(min,sec);
+
+ return back;
+}
+
+
+int CDRomInputStream::seek(long posInBytes) {
+ int entries=cdRomToc->getTocEntries();
+
+ TocEntry* firstEntry;
+ if (entries == 0) {
+ return false;
+ }
+ if (posInBytes < 0) {
+ return false;
+ }
+ firstEntry=cdRomToc->getTocEntry(0);
+
+ long startByte=getBytePos(firstEntry->minute,firstEntry->second+1);
+
+ posInBytes=posInBytes+startByte;
+
+
+ float fmin=(float)posInBytes/(float)(60*_CDROM_FRAMES*2324);
+ int min=(int)fmin;
+
+
+ long sec=posInBytes-min*(60*_CDROM_FRAMES*2324);
+ sec=sec/(_CDROM_FRAMES*2324);
+
+ byteCounter=posInBytes;
+ if (cdRomRawAccess->read(min,sec,0)==false) {
+ return false;
+ }
+ setTimePos(min*60+sec);
+
+ return true;
+}
+
+
+int CDRomInputStream::setTimePos(int second) {
+ currentFrame=0;
+ currentMinute=second/60;
+ currentSecond=second%60;
+
+ return fillBuffer();
+}
+
+
+
+
+
+int CDRomInputStream::fillBuffer() {
+ int maxNoData=30;
+ int cnt=0;
+ if (buflen==0) {
+ while (cnt < maxNoData) {
+ next_sector();
+ if (readCurrent() == false) {
+ return false;
+ }
+ if (cdRomRawAccess->isData() == false) {
+ // cerr << "no data"<<endl;
+ cnt++;
+ } else {
+ return true;
+ }
+ }
+ return false;
+ }
+ return true;
+}
+
+
+
+
+
+
diff --git a/mpeglib/lib/input/cdromInputStream.h b/mpeglib/lib/input/cdromInputStream.h
new file mode 100644
index 00000000..cda18efe
--- /dev/null
+++ b/mpeglib/lib/input/cdromInputStream.h
@@ -0,0 +1,88 @@
+/*
+ reads input data from cdrom
+ 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 __VIDEOCDINPUTSTREAM_H
+#define __VIDEOCDINPUTSTREAM_H
+
+
+
+#include "inputStream.h"
+
+
+
+#define _CDROM_FRAMES 75
+#define _CDROM_SECS 60
+
+
+/**
+ This is necessary because CD-I or VCD disks are not correctly
+ mounted by the linux kernel.
+ Windows seems to do it correct (sometimes, the other time it nearly crash)
+ During my test I found out that CD-I and VCD seems to be different.
+ One works with the CD-I loader the other with the VCD loader.
+
+ This class tries to find out if its a CD-I / VCD stream.
+ Then you can set the interface and load from this interface.
+
+ This class depends on the reader routines from xreadcdi/ xreadvcd,
+ Author: Ales Makarov <xmakarov@sun.felk.cvut.cz>
+ FTP : ftp://mca.sh.cvut.cz/pub/readvcd/
+
+ The code is used in a few other packages, in which I looked as well.
+
+*/
+
+class CDRomRawAccess;
+class CDRomToc;
+
+class CDRomInputStream : public InputStream{
+
+ CDRomRawAccess* cdRomRawAccess;
+ CDRomToc* cdRomToc;
+
+ int buflen;
+ char* bufCurrent;
+
+ int currentFrame;
+ int currentMinute;
+ int currentSecond;
+ long byteCounter;
+
+ public:
+ CDRomInputStream();
+ ~CDRomInputStream();
+
+ int open(const char* dest);
+ void close();
+ int isOpen();
+
+ int eof();
+ int read(char* ptr,int size);
+ int seek(long bytePos);
+
+ long getByteLength();
+ long getBytePosition();
+
+ void print();
+
+ private:
+ long getBytePos(int min,int sec);
+
+ int setTimePos(int posInTime);
+ int getByteDirect();
+ void next_sector();
+ int readCurrent();
+ int fillBuffer();
+};
+#endif
diff --git a/mpeglib/lib/input/cdromRawAccess.cpp b/mpeglib/lib/input/cdromRawAccess.cpp
new file mode 100644
index 00000000..b0df4747
--- /dev/null
+++ b/mpeglib/lib/input/cdromRawAccess.cpp
@@ -0,0 +1,113 @@
+/*
+ reads raw input data from cdrom (system dependent)
+ 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 "cdromRawAccess.h"
+
+using namespace std;
+
+CDRomRawAccess::CDRomRawAccess(CDRomToc* cdromToc) {
+ cdfile=NULL;
+ lOpen=false;
+ leof=true;
+ this->cdromToc=cdromToc;
+ lData=false;
+ dataStart=0;
+ len=0;
+}
+
+
+CDRomRawAccess::~CDRomRawAccess() {
+ close();
+}
+
+
+
+char* CDRomRawAccess::getBufferStart() {
+ return (char*)(data+dataStart);
+}
+
+int CDRomRawAccess::getBufferLen() {
+ if (eof()) {
+ return 0;
+ }
+ return len;
+}
+
+int CDRomRawAccess::open(const char* filename) {
+ if (isOpen()) {
+ close();
+ }
+ if (filename==NULL) {
+ filename=(char*)"/dev/cdrom";
+ }
+ if (strlen(filename) <= 1) {
+ filename="/dev/cdrom";
+ }
+ char* openfile=strchr(filename,'/');
+ cout << "openfile:"<<openfile<<endl;
+ cdfile=fopen(openfile, "rb");
+ lOpen=false;
+
+ if (cdfile == NULL) {
+ perror("open CDRomRawAccess");
+ } else {
+ lOpen=true;
+ leof=false;
+ }
+ return lOpen;
+}
+
+
+int CDRomRawAccess::eof() {
+ return leof;
+}
+
+
+int CDRomRawAccess::read(int minute,int second, int frame) {
+ if (isOpen()==false) {
+ cerr << "CDRomRawAccess not open"<<endl;
+ return false;
+ }
+
+ int lInRange=cdromToc->isInRange(minute,second,frame);
+ if (lInRange == false) {
+ if (minute*60+second+1 > cdromToc->getEndSecond()) {
+ leof=true;
+ }
+ return false;
+ }
+ return readDirect(minute,second,frame);
+}
+
+
+void CDRomRawAccess::close() {
+ if (isOpen()) {
+ fclose(cdfile);
+ lOpen=false;
+ leof=true;
+ }
+}
+
+int CDRomRawAccess::isData() {
+ return lData;
+}
+
+int CDRomRawAccess::isOpen() {
+ return lOpen;
+}
+
+
+
+
diff --git a/mpeglib/lib/input/cdromRawAccess.h b/mpeglib/lib/input/cdromRawAccess.h
new file mode 100644
index 00000000..d089a85b
--- /dev/null
+++ b/mpeglib/lib/input/cdromRawAccess.h
@@ -0,0 +1,67 @@
+/*
+ reads raw input data from cdrom (system dependent)
+ 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 __CDROMRAWACCESS_H
+#define __CDROMRAWACCESS_H
+
+#include "cdromToc.h"
+#include "inputStream.h"
+
+
+/**
+ Here we have a system wrapper for raw cdrom access.
+ Currently this is tested on Linux.
+*/
+
+
+
+
+
+class CDRomRawAccess {
+
+ CDRomToc* cdromToc;
+ char data[2352];
+ int dataStart;
+ int len;
+ int lData;
+
+ public:
+ CDRomRawAccess(CDRomToc* cdromToc);
+ virtual ~CDRomRawAccess();
+
+ // overload this for new Systems
+ virtual int readDirect(int minute,int second, int frame);
+
+ // wrapper for readDirect
+ int read(int minute,int second, int frame);
+
+ char* getBufferStart();
+ int getBufferLen();
+
+ int open(const char* filename);
+ int eof();
+ void close();
+ int isOpen();
+
+ int isData();
+
+ private:
+ FILE* cdfile;
+ int lOpen;
+ int leof;
+ int buflen;
+};
+
+#endif
+
+
diff --git a/mpeglib/lib/input/cdromToc.cpp b/mpeglib/lib/input/cdromToc.cpp
new file mode 100644
index 00000000..919ecdc8
--- /dev/null
+++ b/mpeglib/lib/input/cdromToc.cpp
@@ -0,0 +1,234 @@
+/*
+ reads toc from cdrom (system dependent)
+ 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 "cdromToc.h"
+
+#include <iostream>
+
+using namespace std;
+
+CDRomToc::CDRomToc() {
+ maxEntries=0;
+}
+
+
+CDRomToc::~CDRomToc() {
+}
+
+
+void CDRomToc::insertTocEntry(int minute,int second,int frame) {
+ int i;
+ int j;
+ if (isElement(minute,second,frame)) {
+ return;
+ }
+
+ i=getNextTocEntryPos(minute,second,frame);
+
+ // now shift from i to end
+ if (maxEntries == 100) {
+ cerr << "maximum of toc entries reached"<<endl;
+ exit(0);
+ }
+ for (j=maxEntries;j>i;j--) {
+ tocEntries[j].minute=tocEntries[j-1].minute;
+ tocEntries[j].second=tocEntries[j-1].second;
+ tocEntries[j].frame=tocEntries[j-1].frame;
+ }
+ maxEntries++;
+
+ tocEntries[i].minute=minute;
+ tocEntries[i].second=second;
+ tocEntries[i].frame=frame;
+ calculateRange();
+}
+
+
+int CDRomToc::getNextTocEntryPos(int minute,int second,int frame) {
+ int i;
+ if (maxEntries == 0) {
+ return 0;
+ }
+
+ for (i=0;i<maxEntries;i++) {
+ if (tocEntries[i].minute <= minute) {
+ continue;
+ } else {
+ break;
+ }
+ if (tocEntries[i].second <= second) {
+ continue;
+ } else {
+ break;
+ }
+ if (tocEntries[i].frame <= frame) {
+ continue;
+ }
+ break;
+ }
+ return i;
+}
+
+
+
+int CDRomToc::isElement(int minute,int second,int frame) {
+ int i;
+
+ for (i=0;i<maxEntries;i++) {
+ if (tocEntries[i].minute == minute) {
+ if (tocEntries[i].second == second) {
+ if (tocEntries[i].frame == frame) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+}
+
+
+
+
+
+
+int CDRomToc::getTocEntries() {
+ return maxEntries;
+}
+
+
+TocEntry* CDRomToc::getTocEntry(int entry) {
+ return &(tocEntries[entry]);
+}
+
+
+void CDRomToc::print() {
+ int i;
+ cerr << "******* printing TOC [START]"<<endl;
+ for(i=0;i<maxEntries;i++) {
+ cerr << "i:"<<i
+ <<" M:"<<tocEntries[i].minute
+ <<" S:"<<tocEntries[i].second
+ <<" F:"<<tocEntries[i].frame<<endl;
+ }
+ cerr << "******* printing TOC [END}"<<endl;
+}
+
+
+int CDRomToc::isInRange(int minute,int second,int) {
+ long val=minute*60+second;
+ if (val < startByte) {
+ return false;
+ }
+ if (val > endByte) {
+ return false;
+ }
+ return true;
+}
+
+int CDRomToc::calculateRange() {
+
+
+ if (maxEntries < 2) {
+ cout << "no two elemts in toc"<<endl;
+ return false;
+ }
+ startByte=tocEntries[0].minute*60*+tocEntries[0].second;
+
+ // do a safty end because of the kernel bug
+ int minute=tocEntries[maxEntries-1].minute;
+ int second=tocEntries[maxEntries-1].second-20;
+ if (second < 0) {
+ minute--;
+ second=60+second;
+ }
+ if (minute < 0) {
+ endByte=0;
+ return true;
+ }
+
+ endByte=minute*60+second;
+
+ return true;
+
+}
+
+
+int CDRomToc::getEndSecond() {
+ return endByte;
+}
+
+
+
+
+int CDRomToc::open(const char* openfile) {
+ int i;
+ int pos=0;
+ maxEntries=0;
+ const char* filename=strchr(openfile,'/');
+ FILE* file =fopen(filename, "rb");
+ if (file == NULL) {
+ perror("open");
+ return false;
+ }
+ cout << "reading toc on:"<<filename<<" openfile:"<<openfile<<endl;
+
+ int startToc=0;
+ int endToc=0;
+
+ if (getStartEnd(file,startToc,endToc) == false) {
+ cout << "getStartEnd in CDRomToc failed"<<endl;
+ fclose(file);
+ return false;
+ }
+ cout << "startToc:"<<startToc<<" endToc:"<<endToc<<endl;
+ cout << "reading toc -2"<<endl;
+ /* read individual tracks */
+ int min;
+ int sec;
+ int frame;
+
+ for (i=startToc; i<=endToc; i++) {
+ int min;
+ int sec;
+ int frame;
+
+ if (readToc(file,i,min,sec,frame) == false) {
+ cout << "error in CDRomToc::readToc"<<endl;
+ fclose(file);
+ return false;
+ }
+ cout << "min:"<<min<<endl;
+ cout << "sec:"<<sec<<endl;
+ cout << "frame:"<<frame<<endl;
+
+ insertTocEntry(min,sec,frame);
+ pos++;
+ }
+
+
+ /* read the lead-out track */
+ if (readLeadOut(file,min,sec,frame) == false) {
+ cout << "error in CDRomToc::reatLeadOut"<<endl;
+ return false;
+ }
+ pos++;
+ insertTocEntry(min,sec,frame);
+
+ maxEntries=pos;
+
+ fclose(file);
+
+ return true;
+}
+
diff --git a/mpeglib/lib/input/cdromToc.h b/mpeglib/lib/input/cdromToc.h
new file mode 100644
index 00000000..20b60e10
--- /dev/null
+++ b/mpeglib/lib/input/cdromToc.h
@@ -0,0 +1,65 @@
+/*
+ reads toc from cdrom (system dependent)
+ 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 __CDROMTOC_H
+#define __CDROMTOC_H
+
+extern "C" {
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+}
+
+struct TocEntry {
+ int minute;
+ int second;
+ int frame;
+};
+
+
+class CDRomToc {
+
+ TocEntry tocEntries[100];
+ int maxEntries;
+ int startByte;
+ int endByte;
+
+ public:
+ CDRomToc();
+ virtual ~CDRomToc();
+ int open(const char* device);
+ int getTocEntries();
+ TocEntry* getTocEntry(int entry);
+ void insertTocEntry(int minute,int second,int frame);
+ int getNextTocEntryPos(int minute,int second,int frame);
+ int isInRange(int minute,int second,int frame);
+ int isElement(int minute,int second,int frame);
+
+ int getEndSecond();
+
+ void print();
+
+ private:
+ // platform specific calls.
+ int getStartEnd(FILE* file,int& start, int& end);
+ int readToc(FILE* file,int num,int& min,int& sec, int& frame);
+ int readLeadOut(FILE* file,int& min,int& sec, int& frame);
+
+
+
+
+ int calculateRange();
+
+};
+
+#endif
diff --git a/mpeglib/lib/input/fileAccessWrapper.cpp b/mpeglib/lib/input/fileAccessWrapper.cpp
new file mode 100644
index 00000000..246807a8
--- /dev/null
+++ b/mpeglib/lib/input/fileAccessWrapper.cpp
@@ -0,0 +1,65 @@
+/*
+ wraps an inputStream for the splayFileBuffer.
+ 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 "fileAccessWrapper.h"
+
+#include <iostream>
+
+using namespace std;
+
+FileAccessWrapper::FileAccessWrapper(InputStream* input) {
+ this->input=input;
+}
+
+
+FileAccessWrapper::~FileAccessWrapper() {
+
+}
+
+
+int FileAccessWrapper::open(const char*) {
+ cout << "FileAccessWrapper open not implemented"<<endl;
+ exit(0);
+}
+
+
+void FileAccessWrapper::close() {
+ cout << "FileAccessWrapper close not implemented"<<endl;
+ exit(0);
+}
+
+
+int FileAccessWrapper::read(char* dest,int len) {
+ return input->read(dest,len);
+}
+
+int FileAccessWrapper::eof() {
+ return input->eof();
+}
+
+
+int FileAccessWrapper::seek(long pos) {
+ return input->seek(pos);
+}
+
+
+long FileAccessWrapper::getBytePosition() {
+ return input->getBytePosition();
+}
+
+
+long FileAccessWrapper::getByteLength() {
+ return input->getByteLength();
+}
+
diff --git a/mpeglib/lib/input/fileAccessWrapper.h b/mpeglib/lib/input/fileAccessWrapper.h
new file mode 100644
index 00000000..d7882abb
--- /dev/null
+++ b/mpeglib/lib/input/fileAccessWrapper.h
@@ -0,0 +1,41 @@
+/*
+ wraps an inputStream for the splayFileBuffer.
+ 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 __FILEACCESSWRAPPER_H
+#define __FILEACCESSWRAPPER_H
+
+
+#include "../util/file/fileAccess.h"
+#include "inputStream.h"
+
+
+class FileAccessWrapper : public FileAccess {
+
+ InputStream* input;
+
+ public:
+ FileAccessWrapper(InputStream* input);
+ virtual ~FileAccessWrapper();
+
+ int open(const char* file);
+ void close();
+ int read(char* dest,int len);
+ int eof();
+ int seek(long pos);
+ long getBytePosition();
+ long getByteLength();
+
+};
+
+
+#endif
diff --git a/mpeglib/lib/input/fileInputStream.cpp b/mpeglib/lib/input/fileInputStream.cpp
new file mode 100644
index 00000000..77c31ed6
--- /dev/null
+++ b/mpeglib/lib/input/fileInputStream.cpp
@@ -0,0 +1,148 @@
+/*
+ reads input data
+ 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 "fileInputStream.h"
+
+#include <iostream>
+
+using namespace std;
+
+FileInputStream::FileInputStream() {
+ file=NULL;
+ lopen=false;
+ fileLen=0;
+}
+
+
+FileInputStream::~FileInputStream() {
+ close();
+}
+
+
+int FileInputStream::open(const char* dest) {
+
+ close();
+ if (dest == NULL) {
+ return false;
+ }
+ setUrl(dest);
+ if (strlen(dest) == 1) {
+ if (strncmp(dest,"-",1)==0) {
+ file=::fdopen(0,"rb");
+ }
+ }
+ // load out of current dir if no full path is given
+ if (file == NULL) {
+ file=fopen(dest,"rb");
+ }
+ fileLen=0;
+ if (file == NULL) {
+ cout <<"cannot open file:"<< dest<<endl;
+
+ } else {
+ lopen=true;
+ struct stat fileStat;
+ stat(dest,&fileStat);
+ fileLen=(long)fileStat.st_size;
+ }
+ int back=(file!=NULL);
+ return back;
+}
+
+
+void FileInputStream::close() {
+ if (isOpen()) {
+ ::fclose(file);
+ file=NULL;
+ lopen=false;
+ }
+}
+
+
+int FileInputStream::isOpen() {
+ return lopen;
+}
+
+
+int FileInputStream::eof() {
+ if (isOpen()==false){
+ return true;
+ }
+ int back=true;
+ if (file != NULL) {
+ back=feof(file);
+ }
+
+ return back;
+}
+
+
+int FileInputStream::read(char* ptr,int size) {
+ int bytesRead=-1;
+ if (isOpen()) {
+ if (size <= 0) {
+ cout << "size is <= 0!"<<endl;
+ return 0;
+ }
+ if (file != NULL) {
+ bytesRead=fread(ptr,1,size,file);
+ }
+ } else {
+ cerr << "read on not open file want:"<<size<<endl;
+ return 0;
+ }
+ return bytesRead;
+}
+
+
+int FileInputStream::seek(long posInBytes) {
+ int back=true;
+ if (isOpen()==false) {
+ return false;
+ }
+ long pos=-1;
+ if (file != NULL) {
+ pos=fseek(file,posInBytes,SEEK_SET);
+ }
+
+ if (pos < 0) {
+ cout <<"seek error in FileInputStream::seek"<<endl;
+ back=false;
+ }
+ return back;
+}
+
+
+long FileInputStream::getByteLength() {
+ return fileLen;
+}
+
+
+long FileInputStream::getBytePosition() {
+ int back=0;
+ if (isOpen()) {
+ if (file != NULL) {
+ back=ftell(file);
+ }
+ }
+ return back;
+}
+
+
+
+void FileInputStream::print() {
+ printf("pos in file:%8x\n",(int)getBytePosition());
+}
+
+
diff --git a/mpeglib/lib/input/fileInputStream.h b/mpeglib/lib/input/fileInputStream.h
new file mode 100644
index 00000000..ea421a55
--- /dev/null
+++ b/mpeglib/lib/input/fileInputStream.h
@@ -0,0 +1,46 @@
+/*
+ reads input data
+ 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 __FILEINPUTSTREAM_H
+#define __FILEINPUTSTREAM_H
+
+
+
+#include "inputStream.h"
+
+
+
+class FileInputStream : public InputStream{
+
+ FILE* file;
+ int lopen;
+ long fileLen;
+ public:
+ FileInputStream();
+ ~FileInputStream();
+
+ int open(const char* dest);
+ void close();
+ int isOpen();
+
+ int eof();
+ int read(char* ptr,int size);
+ int seek(long bytePos);
+
+ long getByteLength();
+ long getBytePosition();
+
+ void print();
+
+};
+#endif
diff --git a/mpeglib/lib/input/httpInputStream.cpp b/mpeglib/lib/input/httpInputStream.cpp
new file mode 100644
index 00000000..df2f09c4
--- /dev/null
+++ b/mpeglib/lib/input/httpInputStream.cpp
@@ -0,0 +1,327 @@
+/*
+ reads input data
+ 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 "httpInputStream.h"
+
+#ifndef INADDR_NONE
+#define INADDR_NONE 0xffffffff
+#endif
+
+#include <iostream>
+
+using namespace std;
+
+static const char *httpstr="http://";
+
+
+
+static char *strndup(char *src,int num) {
+ char *dst;
+
+ if(!(dst=(char *)malloc(num+1)))return NULL;
+ dst[num]='\0';
+
+ return strncpy(dst, src, num);
+}
+
+static char *url2hostport(char *url,char **hname,
+ unsigned long *hip,unsigned int *port) {
+ char *cptr;
+ struct hostent *myhostent;
+ struct in_addr myaddr;
+ int isip=1;
+
+ if(!(strncmp(url,httpstr,7)))url+=7;
+ cptr=url;
+ while(*cptr && *cptr!=':' && *cptr!='/') {
+ if((*cptr<'0' || *cptr>'9') && *cptr!='.')isip=0;
+ cptr++;
+ }
+ if(!(*hname=strndup(url,cptr-url))) {
+ *hname=NULL;
+ return NULL;
+ }
+ if(!isip)
+ {
+ if (!(myhostent=gethostbyname(*hname)))return NULL;
+ memcpy(&myaddr,myhostent->h_addr,sizeof(myaddr));
+ *hip=myaddr.s_addr;
+ }
+ else if((*hip=inet_addr(*hname))==INADDR_NONE)return NULL;
+ if(!*cptr || *cptr=='/') {
+ *port=80;
+ return cptr;
+ }
+ *port=atoi(++cptr);
+ while(*cptr && *cptr!='/')cptr++;
+ return cptr;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+HttpInputStream::HttpInputStream() {
+
+ proxyurl=NULL;
+ proxyip=0;
+ lopen=false;
+ byteCnt=0;
+}
+
+
+HttpInputStream::~HttpInputStream() {
+ close();
+}
+
+
+int HttpInputStream::open(const char* filename) {
+ close();
+ if (filename == NULL) {
+ return false;
+ }
+ /*
+ int matchPos=InputStream::getPath(filename,"http");
+ if (matchPos=0) {
+ return false;
+ }
+ */
+
+ char* filename2=strdup(filename);
+ if((fp=http_open(filename2))==NULL) {
+ cout << "seterrorcode(SOUND_ERROR_FILEOPENFAIL)"<<endl;
+ delete filename2;
+ return false;
+ }
+ delete filename2;
+ lopen=true;
+ setUrl(filename);
+ return lopen;
+}
+
+
+void HttpInputStream::close() {
+ if (isOpen()) {
+ ::fclose(fp);
+ }
+ lopen=false;
+ setUrl(NULL);
+}
+
+
+int HttpInputStream::isOpen() {
+ return lopen;
+}
+
+
+int HttpInputStream::eof() {
+ if (isOpen()==false){
+ return true;
+ }
+ return feof(fp);
+}
+
+
+int HttpInputStream::read(char* ptr,int size) {
+ int bytesRead=0;
+ if (isOpen()) {
+ bytesRead=fread(ptr, 1,size, fp);
+ if (ferror(fp) != 0){
+ cout <<"http fread error"<<endl;
+ } else {
+ byteCnt+=bytesRead;
+ }
+ }
+ return bytesRead;
+}
+
+int HttpInputStream::seek(long posInBytes) {
+ cout << "HttpInputStream::setBytePos not implemented:"<<posInBytes<<endl;
+ return false;
+}
+
+
+
+long HttpInputStream::getByteLength() {
+ cout << "HttpInputStream::getByteLength not implemented"<<endl;
+ return 0;
+}
+
+
+
+void HttpInputStream::print() {
+ printf("pos in file:%8x\n",(int)ftell(fp));
+}
+
+
+int HttpInputStream::writestring(int fd, char *string) {
+ int result,bytes=strlen(string);
+
+ while (bytes) {
+ if((result=SOCKETWRITEFUNC(fd,string,bytes))<0 && errno!=EINTR) {
+ cout << "writestring fail -1"<<endl;
+ return false;
+ }
+ else if(result==0) {
+ cout << "writestring fail -2"<<endl;
+ return false;
+ }
+ string += result;
+ bytes -= result;
+ }
+ return true;
+}
+
+
+
+FILE* HttpInputStream::http_open(char *url) {
+ char *purl=NULL,*host,*request,*sptr;
+ char agent[50];
+ int linelength;
+ unsigned long myip;
+ unsigned int myport;
+ int sock;
+ int relocate=0,numrelocs=0;
+ struct sockaddr_in server;
+ FILE *myfile;
+ if (url == NULL) {
+ cout << "cannot open NULL http_open"<<endl;
+ return NULL;
+ }
+ if (strlen(url)==0) {
+ cout << "zero length http_open"<<endl;
+ return NULL;
+ }
+
+ if(!proxyip)
+ {
+ if(!proxyurl)
+ if(!(proxyurl=getenv("MP3_HTTP_PROXY")))
+ if(!(proxyurl=getenv("http_proxy")))
+ proxyurl = getenv("HTTP_PROXY");
+ if (proxyurl && proxyurl[0] && strcmp(proxyurl, "none"))
+ {
+ if (!(url2hostport(proxyurl, &host, &proxyip, &proxyport)))
+ {
+ cout << "seterrorcode(SOUND_ERROR_UNKNOWNPROXY)"<<endl;;
+ return NULL;
+ }
+ if(host)free(host);
+ }
+ else
+ proxyip = INADDR_NONE;
+ }
+
+ if((linelength=strlen(url)+100)<1024)
+ linelength=1024;
+ if(!(request=(char *)malloc(linelength)) || !(purl=(char *)malloc(1024)))
+ {
+ cout << "seterrorcode(SOUND_ERROR_MEMORYNOTENOUGH)"<<endl;
+ return NULL;
+ }
+ strncpy(purl,url,1023);
+ purl[1023]='\0';
+ do{
+ strcpy(request,"GET ");
+ if(proxyip!=INADDR_NONE)
+ {
+ if(strncmp(url,httpstr,7))
+ strcat(request,httpstr);
+ strcat(request,purl);
+ myport=proxyport;
+ myip=proxyip;
+ }
+ else
+ {
+ if(!(sptr=url2hostport(purl,&host,&myip,&myport)))
+ {
+ cout << "seterrorcode(SOUND_ERROR_UNKNOWNHOST)"<<endl;;
+ return NULL;
+ }
+ if (host)
+ free (host);
+ strcat (request, sptr);
+ }
+ sprintf (agent, " HTTP/1.0\r\nUser-Agent: %s/%s\r\n\r\n",
+ "Splay","0.6");
+ strcat (request, agent);
+ server.sin_family = AF_INET;
+ server.sin_port = htons(myport);
+ server.sin_addr.s_addr = myip;
+ if((sock=socket(PF_INET,SOCK_STREAM,6))<0) {
+ cout <<"seterrorcode(SOUND_ERROR_SOCKET)"<<endl;
+ return NULL;
+ }
+ if(connect(sock,(struct sockaddr *)&server,sizeof(server))) {
+ cout <<"seterrorcode(SOUND_ERROR_CONNECT)"<<endl;
+ return NULL;
+ }
+ if(!writestring(sock,request))return NULL;
+ if(!(myfile=::fdopen(sock, "rb"))) {
+ cout << "seterrorcode(SOUND_ERROR_FDOPEN)"<<endl;
+ return NULL;
+ };
+ relocate=false;
+ purl[0]='\0';
+ if(!readstring(request,linelength-1,myfile))return NULL;
+ if((sptr=strchr(request,' '))) {
+ switch(sptr[1]) {
+ case '3':relocate=true;
+ case '2':break;
+ default:
+ cout <<"seterrorcode(SOUND_ERROR_HTTPFAIL)"<<endl;
+ return NULL;
+ }
+ }
+ do {
+ if(!readstring(request,linelength-1,myfile))return NULL;
+ if(!strncmp(request,"Location:",9))
+ strncpy (purl,request+10,1023);
+ } while (request[0]!='\r' && request[0]!='n');
+ } while(relocate && purl[0] && numrelocs++<5);
+ if(relocate) {
+ cout << "seterrorcode(SOUND_ERROR_TOOMANYRELOC)"<<endl;
+ return NULL;
+ }
+ free(purl);
+ free(request);
+ return myfile;
+}
+
+long HttpInputStream::getBytePosition() {
+ return 0;
+}
+
+int HttpInputStream::readstring(char *string,int maxlen,FILE *f) {
+ char *result;
+
+ do{
+ result=fgets(string,maxlen,f);
+ }while(!result && errno==EINTR);
+ if(!result)
+ {
+ cout << "seterrorcode(SOUND_ERROR_FILEREADFAIL)"<<endl;
+ return false;
+ }
+
+ return true;
+}
diff --git a/mpeglib/lib/input/httpInputStream.h b/mpeglib/lib/input/httpInputStream.h
new file mode 100644
index 00000000..78ec10f0
--- /dev/null
+++ b/mpeglib/lib/input/httpInputStream.h
@@ -0,0 +1,84 @@
+/*
+ reads input data
+ 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 __HTTPINPUTSTREAM_H
+#define __HTTPINPUTSTREAM_H
+
+
+#include "inputStream.h"
+
+#ifndef __STRICT_ANSI__
+#define __STRICT_ANSI__
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+
+
+
+#if defined WIN32
+#include <io.h>
+#define SOCKETWRITEFUNC _write
+#else
+
+extern "C" {
+#include <netdb.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+ }
+#define SOCKETWRITEFUNC write
+#endif
+
+#include <sys/types.h>
+#include <errno.h>
+
+class HttpInputStream : public InputStream{
+
+ long byteCnt;
+
+ public:
+ HttpInputStream();
+ ~HttpInputStream();
+
+ int open(const char* dest);
+ void close();
+ int isOpen();
+
+ int eof();
+ int read(char* ptr,int size);
+ int seek(long bytePos);
+
+ long getByteLength();
+ long getBytePosition();
+
+ void print();
+
+ private:
+
+ FILE* fp;
+ int size;
+
+ int writestring(int fd,char *string);
+ int readstring(char *string,int maxlen,FILE *f);
+ FILE* http_open(char *url);
+
+ char* proxyurl;
+ unsigned long proxyip;
+ unsigned int proxyport;
+
+ int lopen;
+
+};
+#endif
diff --git a/mpeglib/lib/input/inputDetector.cpp b/mpeglib/lib/input/inputDetector.cpp
new file mode 100644
index 00000000..28bcad5c
--- /dev/null
+++ b/mpeglib/lib/input/inputDetector.cpp
@@ -0,0 +1,192 @@
+/*
+ returns inputtype for a given string
+ 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 "inputDetector.h"
+
+#include <iostream>
+
+using namespace std;
+
+static const char *filestrglobal1="/";
+static const char *filestrglobal2="./";
+
+typedef struct prot2type_s {
+ const char* name;
+ int type;
+} prot2type;
+
+static prot2type protocols[]= { {"http:" , __INPUT_HTTP },
+ {"cdi:" , __INPUT_CDI },
+ {"vcd:" , __INPUT_CDI },
+ {"file:" , __INPUT_FILE },
+ {"cdda:" , __INPUT_CDDA },
+ {"audiocd:", __INPUT_CDDA },
+ {NULL , __INPUT_UNKNOWN} };
+
+
+InputDetector::InputDetector() {
+}
+
+
+InputDetector::~InputDetector() {
+}
+
+int InputDetector::getProtocolPos(int type,const char* url) {
+ prot2type* current=protocols;
+ int i=0;
+ while(current->name != NULL) {
+ if (current->type == type) {
+ int len=strlen(current->name);
+ if (strncmp(url,current->name,len)==0) {
+ return i;
+ }
+ }
+ i++;
+ current++;
+ }
+ return -1;
+}
+
+int InputDetector::getProtocolType(const char* url) {
+ prot2type* current=protocols;
+ int n=strlen(url);
+ if (n > 0) {
+ while(current->name != NULL) {
+ int k=strlen(current->name);
+ if (n >= k) {
+ if (strncmp(url,current->name,k)==0) {
+ return current->type;
+ }
+ }
+ current++;
+ }
+ }
+ return __INPUT_UNKNOWN;
+}
+
+int InputDetector::getInputType(const char* url) {
+ int back=__INPUT_FILE;
+
+ if (url == NULL) {
+ return back;
+ }
+
+ back=InputDetector::getProtocolType(url);
+ if (back == __INPUT_UNKNOWN) {
+ back = __INPUT_FILE;
+ }
+
+ return back;
+
+}
+
+char* InputDetector::removeProtocol(const char* url) {
+ int type=InputDetector::getProtocolType(url);
+ int n=strlen(url);
+ if (n == 0) {
+ return NULL;
+ }
+ if (type == __INPUT_UNKNOWN) {
+ return strdup(url);
+ }
+ int pos=InputDetector::getProtocolPos(type,url);
+ if (pos == -1) {
+ return NULL;
+ }
+ const char* name=protocols[pos].name;
+ int k=strlen(name);
+ if (n >= k) {
+ return strdup(url+k);
+ }
+ return NULL;
+
+}
+
+char* InputDetector::getExtension(const char* url) {
+ if (url == NULL) {
+ cout << "get url NULL"<<endl;
+ return NULL;
+ }
+ char* back=NULL;
+ char* extStart=strrchr(url,'.');
+ if (extStart != NULL) {
+ cout << "extStart:"<<extStart<<endl;
+ back=strdup(extStart);
+ }
+ return back;
+}
+
+char* InputDetector::removeExtension(const char* url,char* extension) {
+ if (url == NULL) {
+ cout << "removeExtension url NULL"<<endl;
+ return NULL;
+ }
+ if (extension == NULL) {
+ cout << "removeExtension extension NULL"<<endl;
+ return strdup(url);
+ }
+ char* back=NULL;
+ int nExt=strlen(extension);
+ int nUrl=strlen(url);
+ cout << "extension:"<<extension<<" url:"<<url<<endl;
+ if (nUrl >= nExt) {
+ if(strncmp(url+nUrl-nExt,extension,nExt)==0) {
+ back=new char[nUrl-nExt+1];
+ back[nUrl-nExt]=0;
+ strncpy(back,url,nUrl-nExt);
+ }
+ }
+ cout << "removeExt:"<<back<<endl;
+ return back;
+
+}
+
+char* InputDetector::getWithoutExtension(const char* url) {
+ char* extension=NULL;
+ char* back=NULL;
+ if (url == NULL) {
+ return NULL;
+ }
+ extension=InputDetector::getExtension(url);
+ if (extension == NULL) {
+ back=strdup(url);
+ } else {
+ back=InputDetector::removeExtension(url,extension);
+ delete extension;
+ }
+ return back;
+}
+
+char* InputDetector::getFilename(const char* url) {
+ if (url == NULL) {
+ return NULL;
+ }
+ char* startSlash=strrchr(url,'/');
+ if (startSlash == NULL) {
+ return NULL;
+ }
+ if (strlen(startSlash) == 1) {
+ return NULL;
+ }
+ startSlash++;
+ if (*startSlash == 0) {
+ return NULL;
+ }
+ return strdup(startSlash);
+}
+
+
+char* InputDetector::removeSlash(const char* url) {
+ return InputDetector::removeExtension(url,(char*)"/");
+}
diff --git a/mpeglib/lib/input/inputDetector.h b/mpeglib/lib/input/inputDetector.h
new file mode 100644
index 00000000..f4c3e47d
--- /dev/null
+++ b/mpeglib/lib/input/inputDetector.h
@@ -0,0 +1,56 @@
+/*
+ returns inputtype for a given string
+ 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 __INPUTDETECTOR_H
+#define __INPUTDETECTOR_H
+
+
+
+#define __INPUT_UNKNOWN 0
+#define __INPUT_FILE 1
+#define __INPUT_HTTP 2
+#define __INPUT_CDI 3
+#define __INPUT_BUFFER 4
+#define __INPUT_CDDA 5
+
+extern "C" {
+#include <string.h>
+}
+
+
+class InputDetector {
+
+
+ public:
+ InputDetector();
+ ~InputDetector();
+
+ static int getInputType(const char* url);
+
+ static int getProtocolType(const char* url);
+ // returns new allocated string without protocol specifier
+ static char* removeProtocol(const char* url);
+ static char* getWithoutExtension(const char* url);
+ static char* getExtension(const char* url);
+ static char* removeExtension(const char* url,char* extension);
+ static char* removeSlash(const char* url);
+ static char* getFilename(const char* url);
+
+ private:
+ static int getProtocolPos(int type,const char* url);
+
+};
+
+#endif
+
diff --git a/mpeglib/lib/input/inputPlugin.cpp b/mpeglib/lib/input/inputPlugin.cpp
new file mode 100644
index 00000000..f3a33002
--- /dev/null
+++ b/mpeglib/lib/input/inputPlugin.cpp
@@ -0,0 +1,92 @@
+/*
+ C interface creator for input_plugins
+ 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 "inputPlugin.h"
+
+#include <iostream>
+
+using namespace std;
+
+
+InputPlugin::InputPlugin() {
+}
+
+
+InputPlugin::~InputPlugin() {
+}
+
+
+
+int InputPlugin::getInputType(const char* dest) {
+ return InputDetector::getInputType(dest);
+}
+
+
+InputStream* InputPlugin::createInputStream(int inputType) {
+ // make checks which input routine to use
+ InputStream* inputStream;
+ int method;
+
+ inputStream=NULL;
+ method=inputType;
+
+ switch(method) {
+ case __INPUT_FILE: {
+ inputStream=new FileInputStream();
+ break;
+ }
+ case __INPUT_CDDA: {
+ inputStream=new CDDAInputStream();
+ break;
+ }
+
+ case __INPUT_HTTP: {
+ inputStream=new HttpInputStream();
+ break;
+ }
+ case __INPUT_CDI: {
+ inputStream=new CDRomInputStream();
+ break;
+ }
+ default:
+ cout << "error cannot create default input stream"<<endl;
+ exit(0);
+ }
+
+ return inputStream;
+}
+
+InputStream* InputPlugin::createInputStream(int inputType,int lThreadSafe) {
+ InputStream* input=InputPlugin::createInputStream(inputType);
+ if (lThreadSafe == false) {
+ return input;
+ }
+ InputStream* tsInput=new ThreadSafeInputStream(input);
+ return tsInput;
+}
+
+
+InputStream* InputPlugin::createInputStream(const char* dest) {
+ int method;
+
+ method=InputPlugin::getInputType(dest);
+ return (InputPlugin::createInputStream(method));
+}
+
+
+InputStream* InputPlugin::createInputStream(const char* dest,int lThreadSafe) {
+ int method;
+
+ method=InputPlugin::getInputType(dest);
+ return (InputPlugin::createInputStream(method,lThreadSafe));
+}
diff --git a/mpeglib/lib/input/inputPlugin.h b/mpeglib/lib/input/inputPlugin.h
new file mode 100644
index 00000000..5ac68307
--- /dev/null
+++ b/mpeglib/lib/input/inputPlugin.h
@@ -0,0 +1,45 @@
+/*
+ C interface creator for input_plugins
+ 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 __INPUTPLUGIN_H
+#define __INPUTPLUGIN_H
+
+#include "httpInputStream.h"
+#include "fileInputStream.h"
+#include "cdromInputStream.h"
+#include "bufferInputStream.h"
+#include "threadSafeInputStream.h"
+#include "cddaInputStream.h"
+#include <string.h>
+
+#include "inputDetector.h"
+#include <kdemacros.h>
+
+#define _INPUT_THREADSAFE 1
+
+class KDE_EXPORT InputPlugin {
+
+ public:
+ InputPlugin();
+ ~InputPlugin();
+
+ static InputStream* createInputStream(int inputType);
+ static InputStream* createInputStream(int inputType,int lThreadSafe);
+ static InputStream* createInputStream(const char* dest);
+ static InputStream* createInputStream(const char* dest,int lThreadSafe);
+ static int getInputType(const char* dest);
+
+};
+#endif
diff --git a/mpeglib/lib/input/inputStream.cpp b/mpeglib/lib/input/inputStream.cpp
new file mode 100644
index 00000000..7eb9943b
--- /dev/null
+++ b/mpeglib/lib/input/inputStream.cpp
@@ -0,0 +1,135 @@
+/*
+ generic input 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 "inputStream.h"
+#include "../util/mmx/mmx.h"
+
+#include <iostream>
+
+using namespace std;
+
+
+InputStream::InputStream() {
+ timeStampArray=new TimeStampArray((char*)"Input",3000);
+ urlBuffer=new DynBuffer(20);
+ // 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();
+}
+
+
+
+InputStream::~InputStream() {
+ delete timeStampArray;
+ delete urlBuffer;
+
+}
+
+
+int InputStream::open(const char* dest) {
+ cout << "direct virtual call InputStream::open:"<<dest<<endl;
+ return false;
+}
+
+
+void InputStream::close() {
+ cout << "direct virtual call InputStream::close"<<endl;
+ exit(0);
+}
+
+
+int InputStream::isOpen() {
+ cout << "direct virtual call InputStream::isOpen"<<endl;
+ exit(0);
+ return false;
+}
+
+
+int InputStream::eof() {
+ cout << "direct virtual call InputStream::eof"<<endl;
+ exit(0);
+ return true;
+}
+
+
+int InputStream::read(char* ,int ) {
+ cout << "direct virtual call InputStream::read"<<endl;
+ exit(0);
+ return 0;
+}
+
+
+int InputStream::seek(long bytePos) {
+ cout << "direct virtual call InputStream::seek:"<<bytePos<<endl;
+ exit(0);
+ return false;
+}
+
+void InputStream::clear() {
+ cout << "direct virtual call InputStream::clear:"<<endl;
+ exit(0);
+}
+
+
+long InputStream::getByteLength() {
+ cout << "direct virtual call InputStream::getByteLength"<<endl;
+ return 0;
+}
+
+
+long InputStream::getBytePosition() {
+ cout << "direct virtual call InputStream::getBytePosition"<<endl;
+ return 0;
+}
+
+
+void InputStream::insertTimeStamp(TimeStamp* src,long key,int len) {
+ timeStampArray->insertTimeStamp(src,key,len);
+}
+
+TimeStamp* InputStream::getTimeStamp(long key) {
+ return timeStampArray->getTimeStamp(key);
+}
+
+
+int InputStream::bytesUntilNext(long key) {
+ return timeStampArray->bytesUntilNext(key);
+}
+
+void InputStream::print() {
+ cout << "direct virtual call InputStream::print"<<endl;
+}
+
+
+
+
+
+char* InputStream::getUrl() {
+ return urlBuffer->getData();
+}
+
+
+void InputStream::setUrl(const char* url) {
+ urlBuffer->clear();
+ if (url != NULL) {
+ urlBuffer->append(url);
+ }
+}
+
+
+
+
+
diff --git a/mpeglib/lib/input/inputStream.h b/mpeglib/lib/input/inputStream.h
new file mode 100644
index 00000000..e232e99b
--- /dev/null
+++ b/mpeglib/lib/input/inputStream.h
@@ -0,0 +1,79 @@
+/*
+ generic input 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 __MPEGLIBINPUTSTREAM_H
+#define __MPEGLIBINPUTSTREAM_H
+
+
+extern "C" {
+#include <string.h>
+#include <stdio.h>
+#include <sys/stat.h>
+}
+
+#include "../util/timeStampArray.h"
+#include "../util/dynBuffer.h"
+
+
+
+
+/**
+ The abstraction for the input stream. In derived classes
+ we implement http,file and cdi access.
+*/
+
+
+class InputStream {
+
+
+
+ public:
+ InputStream();
+
+
+ virtual ~InputStream();
+
+ virtual int open(const char* dest);
+ virtual void close();
+ virtual int isOpen();
+
+ virtual int eof();
+ virtual int read(char* ptr,int size);
+ virtual int seek(long bytePos);
+ // clears possible input buffers
+ // (called by the decoderPlugin after a resyncCommit)
+ virtual void clear();
+
+ virtual long getByteLength();
+ virtual long getBytePosition();
+
+ virtual void insertTimeStamp(TimeStamp* src,long key,int len);
+ virtual TimeStamp* getTimeStamp(long key);
+ virtual int bytesUntilNext(long key);
+ virtual void print();
+ char* getUrl();
+
+
+
+ protected:
+ DynBuffer* urlBuffer;
+
+
+ class TimeStampArray* timeStampArray;
+ void setUrl(const char* url);
+
+
+};
+#endif
diff --git a/mpeglib/lib/input/simpleRingBuffer.cpp b/mpeglib/lib/input/simpleRingBuffer.cpp
new file mode 100644
index 00000000..71c92329
--- /dev/null
+++ b/mpeglib/lib/input/simpleRingBuffer.cpp
@@ -0,0 +1,420 @@
+/*
+ a thread safe ring buffer without dependencies
+ 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 "simpleRingBuffer.h"
+#include <string.h>
+
+#include <iostream>
+
+using namespace std;
+
+static int instanceCnt=0;
+
+SimpleRingBuffer::SimpleRingBuffer(int size,int minLinSize) {
+ abs_thread_mutex_init(&mut);
+ abs_thread_cond_init(&dataCond);
+ abs_thread_cond_init(&spaceCond);
+
+ instance=instanceCnt;
+ instanceCnt++;
+ this->size=size;
+ startPos=(char*)malloc(size);
+ readPos=startPos;
+ writePos=startPos;
+ lockPos=startPos;
+
+ lockgrade=0;
+ fillgrade=0;
+ linAvail=size;
+ lastPos=(startPos+size-1);
+ eofPos=lastPos+1;
+
+ canWrite=size;
+ canRead=0;
+
+ minLinBuf=new char[minLinSize];
+ this->minLinBufSize=minLinSize;
+ waitMinData=0;
+ waitMinSpace=0;
+ lWaitForData=false;
+ lWaitForSpace=false;
+
+ readBytes=0;
+ writeBytes=0;
+
+ lCanWaitForData=true;
+ lCanWaitForSpace=true;
+}
+
+
+SimpleRingBuffer::~SimpleRingBuffer() {
+ // The user of this class must take care that the threads
+ // have exited!
+ free(startPos);
+ delete [] minLinBuf;
+ abs_thread_mutex_destroy(&mut);
+ abs_thread_cond_destroy(&dataCond);
+ abs_thread_cond_destroy(&spaceCond);
+}
+
+
+int SimpleRingBuffer::getSize() {
+ return size;
+}
+
+
+int SimpleRingBuffer::getWriteArea(char* &ptr,int &size) {
+
+ // When we are in this area the following
+ // can happen by the other thread
+ // fillgrade is decreased (because reader fowards)
+ // readPos is changed.
+
+ ptr=writePos;
+ size=canWrite;
+
+ return size;
+}
+
+
+void SimpleRingBuffer::updateCanWrite() {
+ if (lockPos < writePos) {
+ canWrite=eofPos-writePos;
+ //printf("1 c:%d l:%p w:%p",canWrite,lockPos,writePos);
+ } else if (lockPos > writePos) {
+ canWrite=lockPos-writePos;
+ //printf("2 c:%d l:%p w:%p",canWrite,lockPos,writePos);
+ } else {
+ if (fillgrade > 0) {
+ canWrite=0;
+ } else {
+ canWrite=eofPos-writePos;
+ }
+ //printf("2 c:%d ",canWrite);
+
+ }
+ if (canWrite < 0) {
+ printf("error canWrite:%d fill:%d lock:%p start:%p eof:%p write:%p\n",
+ canWrite,fillgrade,lockPos,startPos,eofPos,writePos);
+ }
+
+}
+
+
+void SimpleRingBuffer::updateCanRead() {
+ canRead=fillgrade-lockgrade;
+ int currentSpace=size-fillgrade;
+ if (currentSpace >= waitMinSpace) {
+ abs_thread_cond_signal(&spaceCond);
+ }
+ if (canRead < 0) {
+ printf("error canRead:%d fillgrade:%d lockgrade:%d \n",
+ canRead,fillgrade,lockgrade);
+ }
+
+}
+
+
+void SimpleRingBuffer::forwardLockPtr(int nBytes) {
+ abs_thread_mutex_lock(&mut);
+
+ if (fillgrade < lockgrade) {
+ printf("1:fillgrade:%d < lockgrade:%d\n",fillgrade,lockgrade);
+ }
+ fillgrade-=nBytes;
+ lockgrade-=nBytes;
+ if (fillgrade < lockgrade) {
+ printf("2:fillgrade:%d < lockgrade:%d nBytes:%d\n",
+ fillgrade,lockgrade,nBytes);
+ }
+ lockPos=lockPos+nBytes;
+ if (lockPos > lastPos) { // we expects that we had a linAvail part
+ // if user forwards more than buffer boundary
+ nBytes=lockPos-lastPos;
+ lockPos=startPos+nBytes-1;
+ }
+ updateCanWrite();
+ updateCanRead();
+
+ abs_thread_mutex_unlock(&mut);
+ return;
+}
+
+
+void SimpleRingBuffer::forwardWritePtr(int nBytes) {
+ abs_thread_mutex_lock(&mut);
+
+ fillgrade=fillgrade+nBytes;
+ if (fillgrade < lockgrade) {
+ printf("3:fillgrade:%d < lockgrade:%d nBytes:%d\n",
+ fillgrade,lockgrade,nBytes);
+ }
+ writeBytes+=nBytes;
+ writePos=writePos+nBytes;
+ if(writePos >= eofPos) {
+ if (writePos == eofPos) {
+ writePos=startPos;
+ } else {
+ cout << "writePos > eofPos ! forward error:"<<(eofPos-writePos)
+ <<" bytes"<<endl;
+ }
+ }
+
+ updateCanWrite();
+ updateCanRead();
+ if (fillgrade >= waitMinData) {
+ abs_thread_cond_signal(&dataCond);
+ }
+ abs_thread_mutex_unlock(&mut);
+}
+
+
+int SimpleRingBuffer::waitForSpace(int bytes){
+ abs_thread_mutex_lock(&mut);
+ int back=0;
+ waitMinSpace=bytes;
+ if (waitMinSpace > size) {
+ waitMinSpace=size;
+ }
+ if (waitMinSpace < 0) {
+ cout << "negative waitForSpace"<<endl;
+ waitMinSpace=0;
+ }
+ int currentSpace=size-fillgrade;
+ if (lCanWaitForSpace) {
+ if (currentSpace < waitMinSpace) {
+ lWaitForSpace=true;
+ // it is not possible to wait for data/space simultanously
+ if (lWaitForData == true) {
+ abs_thread_cond_signal(&dataCond);
+ }
+ abs_thread_cond_wait(&spaceCond,&mut);
+ lWaitForSpace=false;
+ }
+ }
+ if (size-fillgrade >= waitMinSpace) {
+ back=1;
+ }
+ abs_thread_mutex_unlock(&mut);
+ return back;
+}
+
+
+void SimpleRingBuffer::exitWaitForSpace(){
+ abs_thread_mutex_lock(&mut);
+ abs_thread_cond_signal(&spaceCond);
+ abs_thread_mutex_unlock(&mut);
+}
+
+void SimpleRingBuffer::setCanWaitForSpace(int lCanWaitForSpace) {
+ abs_thread_mutex_lock(&mut);
+ this->lCanWaitForSpace=lCanWaitForSpace;
+ abs_thread_cond_signal(&spaceCond);
+ abs_thread_mutex_unlock(&mut);
+
+}
+
+
+
+void SimpleRingBuffer::forwardReadPtr(int nBytes) {
+ abs_thread_mutex_lock(&mut);
+ readBytes+=nBytes;
+ readPos+=nBytes;
+ linAvail=linAvail-nBytes;
+ lockgrade+=nBytes;
+ if (readPos > lastPos) { // we expects that we had a linAvail part
+ // if user forwards more than buffer boundary
+ nBytes=readPos-lastPos;
+ readPos=startPos+nBytes-1;
+ linAvail=lastPos+1-readPos;
+ }
+ if (fillgrade < lockgrade) {
+ printf("5:fillgrade:%d < lockgrade:%d nBytes:%d\n",
+ fillgrade,lockgrade,nBytes);
+ }
+ updateCanRead();
+ abs_thread_mutex_unlock(&mut);
+}
+
+
+
+int SimpleRingBuffer::getReadArea(char* &ptr,int &readSize) {
+ int pSize=readSize;
+ ptr=readPos;
+
+ if (canRead == 0) {
+ readSize=0;
+ return 0;
+ }
+ if (pSize < 0) {
+ cout << "Generic Memory Info invalid"<<endl;
+ pSize=size/2;
+ }
+ //
+ // Now the part the we deliver a minimum buffer if it is
+ // possible
+ //
+
+ if ( (pSize > linAvail) &&
+ (minLinBufSize >linAvail) &&
+ (canRead > linAvail) ) {
+ int copySize;
+ copySize=canRead; // we cannot copy more than this
+ if (copySize > pSize) { // if it is too much reduche it
+ copySize=pSize;
+ }
+ if (copySize > minLinBufSize) { // if it does not fit in buffer->reduce
+ copySize=minLinBufSize;
+ }
+ memcpy(minLinBuf,readPos,linAvail);
+ memcpy(minLinBuf+linAvail,startPos,copySize-linAvail);
+ readSize=copySize;
+ ptr=minLinBuf;
+ return copySize;
+ }
+
+ // linAvail part end
+
+ int copyBytes=linAvail;
+ if (canRead < copyBytes) {
+ copyBytes=canRead;
+ }
+ if (copyBytes >= pSize) {
+ readSize=pSize;
+ } else {
+ readSize=copyBytes;
+ }
+ return readSize;
+}
+
+
+
+void SimpleRingBuffer::exitWaitForData(){
+ abs_thread_mutex_lock(&mut);
+ abs_thread_cond_signal(&dataCond);
+ abs_thread_mutex_unlock(&mut);
+}
+
+
+
+int SimpleRingBuffer::waitForData(int bytes){
+ abs_thread_mutex_lock(&mut);
+ int back=0;
+ waitMinData=bytes;
+ if (waitMinData > size) {
+ waitMinData=size;
+ }
+ if (waitMinData < 0) {
+ cout << "negative waitForData"<<endl;
+ waitMinData=0;
+ }
+ if (lCanWaitForData) {
+ if (fillgrade < waitMinData) {
+ lWaitForData=true;
+ // it is not possible to wait for data space simultanously
+ if (lWaitForSpace == true) {
+ abs_thread_cond_signal(&spaceCond);
+ }
+ abs_thread_cond_wait(&dataCond,&mut);
+ lWaitForData=false;
+ }
+ }
+ if (fillgrade >= waitMinData) {
+ back=1;
+ }
+ abs_thread_mutex_unlock(&mut);
+ return back;
+}
+
+int SimpleRingBuffer::getCanWaitForData() {
+ return lCanWaitForData;
+}
+
+
+void SimpleRingBuffer::setCanWaitForData(int lCanWaitForData) {
+ abs_thread_mutex_lock(&mut);
+ this->lCanWaitForData=lCanWaitForData;
+ abs_thread_cond_signal(&dataCond);
+ abs_thread_mutex_unlock(&mut);
+
+}
+
+void SimpleRingBuffer::emptyBuffer() {
+ abs_thread_mutex_lock(&mut);
+ writePos=readPos;
+ if (fillgrade < lockgrade) {
+ printf("4:fillgrade:%d < lockgrade:%d\n",fillgrade,lockgrade);
+ }
+ linAvail=lastPos+1-writePos;
+ fillgrade=lockgrade;
+ updateCanRead();
+ updateCanWrite();
+ readBytes=0;
+ writeBytes=0;
+ if (size-fillgrade >= waitMinSpace) {
+ abs_thread_cond_signal(&spaceCond);
+ }
+ if (fillgrade >= waitMinData) {
+ abs_thread_cond_signal(&dataCond);
+ }
+ abs_thread_mutex_unlock(&mut);
+}
+
+
+int SimpleRingBuffer::getFillgrade() {
+ return fillgrade;
+}
+
+
+int SimpleRingBuffer::getReadBytes() {
+ return readBytes;
+}
+
+
+int SimpleRingBuffer::getWriteBytes() {
+ return writeBytes;
+}
+
+
+int SimpleRingBuffer::getFreeRead() {
+ return fillgrade;
+}
+
+int SimpleRingBuffer::getFreeWrite() {
+ return size-fillgrade;
+}
+
+void SimpleRingBuffer::resizeBuffer(int changeSize) {
+ abs_thread_mutex_lock(&mut);
+ int lPos=lockPos-startPos;
+ int wPos=writePos-startPos;
+ int rPos=readPos-startPos;
+ startPos=(char *)realloc(startPos,changeSize);
+ size=changeSize;
+ readPos=startPos+lPos;
+ writePos=startPos+wPos;
+ lockPos=startPos+rPos;
+
+ lastPos=(startPos+size-1);
+ eofPos=lastPos+1;
+
+ linAvail=lastPos+1-readPos;
+
+ updateCanWrite();
+ updateCanRead();
+ abs_thread_mutex_unlock(&mut);
+
+
+}
diff --git a/mpeglib/lib/input/simpleRingBuffer.h b/mpeglib/lib/input/simpleRingBuffer.h
new file mode 100644
index 00000000..101725bf
--- /dev/null
+++ b/mpeglib/lib/input/simpleRingBuffer.h
@@ -0,0 +1,136 @@
+/*
+ a thread safe ring buffer without dependencies
+ 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 _SIMPLERINGBUFFER_H
+#define _SIMPLERINGBUFFER_H
+
+#include "../util/abstract/abs_thread.h"
+
+extern "C" {
+ #include <stdio.h>
+}
+
+/**
+ Note to parameter minLinBufSize in Constructor:
+ <p>
+ If the fillgrade is sufficient we can delivier at least
+ this amount of bytes with one "fill"
+ (If the fillgrade is not suffficient we can only deliever fillgrade)
+ This values adresses the problem that a ring buffer cannot
+ deliever linear memory the whole time(eg. if you read near the
+ upper end)
+ <p>
+ If the requested Buffersize by the device is smaller than
+ this number you can be sure that you get exactly
+ your preferred buffersize. not more not less.(but
+ only if the fillgrade allows this)
+*/
+
+
+
+
+class SimpleRingBuffer {
+
+
+ public:
+
+ SimpleRingBuffer(int ringBufferSize, int minLinBufferSize);
+ virtual ~SimpleRingBuffer();
+
+ // Writer thread can call these:
+
+ int getWriteArea(char* &ptr,int &size);
+ void forwardWritePtr(int bytes);
+ int waitForSpace(int minSpace);
+ void exitWaitForSpace();
+ void setCanWaitForSpace(int lCanWaitForSpace);
+
+
+ // Reader thread these:
+
+ void forwardReadPtr(int bytes);
+ int getReadArea(char* &ptr,int &size);
+ int waitForData(int minData);
+ void exitWaitForData();
+ void setCanWaitForData(int lCanWaitForData);
+ int getCanWaitForData();
+
+
+ // and the lockPos
+ void forwardLockPtr(int bytes);
+
+
+ // both:
+
+ int getFillgrade(); // return how much buffer between reader/writer
+ void emptyBuffer(); // frees the space between them
+ int getFreeRead();
+ int getFreeWrite();
+
+ int getSize();
+ int getReadBytes();
+ int getWriteBytes();
+
+ // make sure that no one calls getReadArea/getWriteArea
+ void resizeBuffer(int changeSize);
+ private:
+ void updateCanWrite();
+ void updateCanRead();
+
+ int size;
+
+ int lockgrade;
+ int fillgrade;
+
+ char* readPos;
+ char* writePos;
+ char* lockPos;
+
+ char* startPos;
+
+ char* lastPos;
+ char* eofPos;
+ int canWrite;
+ int canRead;
+
+ int waitMinData;
+ int waitMinSpace;
+
+ abs_thread_mutex_t mut;
+ abs_thread_cond_t dataCond;
+ abs_thread_cond_t spaceCond;
+
+ int insertBlock;
+ int readBlock;
+ int linAvail;
+
+ char* minLinBuf;
+ int minLinBufSize;
+ int lWaitForData;
+ int lWaitForSpace;
+
+ // statistic purpose:
+ int readBytes;
+ int writeBytes;
+
+ int lCanWaitForSpace;
+ int lCanWaitForData;
+ int instance;
+};
+
+#endif
+
+
+
diff --git a/mpeglib/lib/input/threadSafeInputStream.cpp b/mpeglib/lib/input/threadSafeInputStream.cpp
new file mode 100644
index 00000000..8b18a4c5
--- /dev/null
+++ b/mpeglib/lib/input/threadSafeInputStream.cpp
@@ -0,0 +1,137 @@
+/*
+ thread safe wrapper for input 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 "threadSafeInputStream.h"
+
+
+ThreadSafeInputStream::ThreadSafeInputStream(InputStream* input) {
+ threadQueue=new ThreadQueue();
+ this->input=input;
+}
+
+
+ThreadSafeInputStream::~ThreadSafeInputStream() {
+ delete threadQueue;
+ delete input;
+}
+
+
+
+int ThreadSafeInputStream::open(const char* dest) {
+ int back;
+ threadQueue->waitForExclusiveAccess();
+ back=input->open(dest);
+ threadQueue->releaseExclusiveAccess();
+ return back;
+}
+
+
+void ThreadSafeInputStream::close() {
+ threadQueue->waitForExclusiveAccess();
+ input->close();
+ threadQueue->releaseExclusiveAccess();
+}
+
+
+int ThreadSafeInputStream::isOpen() {
+ int back;
+ threadQueue->waitForExclusiveAccess();
+ back=input->isOpen();
+ threadQueue->releaseExclusiveAccess();
+ return back;
+}
+
+
+int ThreadSafeInputStream::eof() {
+ int back;
+ threadQueue->waitForExclusiveAccess();
+ back=input->eof();
+ threadQueue->releaseExclusiveAccess();
+ return back;
+}
+
+
+int ThreadSafeInputStream::read(char* buf,int len) {
+ int back;
+ threadQueue->waitForExclusiveAccess();
+ back=input->read(buf,len);
+ threadQueue->releaseExclusiveAccess();
+ return back;
+}
+
+
+int ThreadSafeInputStream::seek(long bytePos) {
+ int back;
+ threadQueue->waitForExclusiveAccess();
+ back=input->seek(bytePos);
+ threadQueue->releaseExclusiveAccess();
+ return back;
+}
+
+void ThreadSafeInputStream::clear() {
+ threadQueue->waitForExclusiveAccess();
+ input->clear();
+ threadQueue->releaseExclusiveAccess();
+}
+
+
+long ThreadSafeInputStream::getByteLength() {
+ long back;
+ threadQueue->waitForExclusiveAccess();
+ back=input->getByteLength();
+ threadQueue->releaseExclusiveAccess();
+ return back;
+}
+
+
+long ThreadSafeInputStream::getBytePosition() {
+ long back;
+ threadQueue->waitForExclusiveAccess();
+ back=input->getBytePosition();
+ threadQueue->releaseExclusiveAccess();
+ return back;
+}
+
+
+void ThreadSafeInputStream::insertTimeStamp(TimeStamp* src,long key,int len) {
+ threadQueue->waitForExclusiveAccess();
+ input->insertTimeStamp(src,key,len);
+ threadQueue->releaseExclusiveAccess();
+}
+
+
+TimeStamp* ThreadSafeInputStream::getTimeStamp(long key) {
+ TimeStamp* back;
+ threadQueue->waitForExclusiveAccess();
+ back=input->getTimeStamp(key);
+ threadQueue->releaseExclusiveAccess();
+ return back;
+}
+
+
+int ThreadSafeInputStream::bytesUntilNext(long key) {
+ int back;
+ threadQueue->waitForExclusiveAccess();
+ back=input->bytesUntilNext(key);
+ threadQueue->releaseExclusiveAccess();
+ return back;
+}
+
+void ThreadSafeInputStream::print() {
+ threadQueue->waitForExclusiveAccess();
+ input->print();
+ threadQueue->releaseExclusiveAccess();
+}
+
+
+
diff --git a/mpeglib/lib/input/threadSafeInputStream.h b/mpeglib/lib/input/threadSafeInputStream.h
new file mode 100644
index 00000000..0a29637b
--- /dev/null
+++ b/mpeglib/lib/input/threadSafeInputStream.h
@@ -0,0 +1,56 @@
+/*
+ thread safe wrapper for input 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 __THREADSAFEINPUTSTREAM_H
+#define __THREADSAFEINPUTSTREAM_H
+
+// read INTRO in threadQueue.h
+// This class makes the inputStream (given in constructor)
+// threadsafe by wrapping each call with a threadqueue.
+//
+// Important NOTE: the input pointer is the owned by this class !!!
+// which means: we call delete on it!
+
+#include "../util/abstract/threadQueue.h"
+#include "inputStream.h"
+
+
+class ThreadSafeInputStream : public InputStream {
+
+ ThreadQueue* threadQueue;
+ InputStream* input;
+
+ public:
+ ThreadSafeInputStream(InputStream* input);
+ ~ThreadSafeInputStream();
+
+
+ int open(const char* dest);
+ void close();
+ int isOpen();
+
+ int eof();
+ int read(char* ptr,int size);
+ int seek(long bytePos);
+ void clear();
+
+ long getByteLength();
+ long getBytePosition();
+
+ void insertTimeStamp(TimeStamp* src,long key,int len);
+ TimeStamp* getTimeStamp(long key);
+ int bytesUntilNext(long key);
+ void print();
+
+};
+#endif