00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #if (defined(__WIN32__) || defined(_WIN32)) && !defined(_WIN32_WCE)
00022 #include <io.h>
00023 #include <fcntl.h>
00024 #define READ_FROM_FILES_SYNCHRONOUSLY 1
00025
00026
00027
00028
00029
00030
00031
00032
00033 #endif
00034
00035 #include "ByteStreamFileSource.hh"
00036 #include "InputFile.hh"
00037 #include "GroupsockHelper.hh"
00038
00040
00041 ByteStreamFileSource*
00042 ByteStreamFileSource::createNew(UsageEnvironment& env, char const* fileName,
00043 unsigned preferredFrameSize,
00044 unsigned playTimePerFrame) {
00045 FILE* fid = OpenInputFile(env, fileName);
00046 if (fid == NULL) return NULL;
00047
00048 Boolean deleteFidOnClose = fid == stdin ? False : True;
00049 ByteStreamFileSource* newSource
00050 = new ByteStreamFileSource(env, fid, deleteFidOnClose,
00051 preferredFrameSize, playTimePerFrame);
00052 newSource->fFileSize = GetFileSize(fileName, fid);
00053
00054 return newSource;
00055 }
00056
00057 ByteStreamFileSource*
00058 ByteStreamFileSource::createNew(UsageEnvironment& env, FILE* fid,
00059 Boolean deleteFidOnClose,
00060 unsigned preferredFrameSize,
00061 unsigned playTimePerFrame) {
00062 if (fid == NULL) return NULL;
00063
00064 ByteStreamFileSource* newSource
00065 = new ByteStreamFileSource(env, fid, deleteFidOnClose,
00066 preferredFrameSize, playTimePerFrame);
00067 newSource->fFileSize = GetFileSize(NULL, fid);
00068
00069 return newSource;
00070 }
00071
00072 void ByteStreamFileSource::seekToByteAbsolute(u_int64_t byteNumber) {
00073 SeekFile64(fFid, (int64_t)byteNumber, SEEK_SET);
00074 }
00075
00076 void ByteStreamFileSource::seekToByteRelative(int64_t offset) {
00077 SeekFile64(fFid, offset, SEEK_CUR);
00078 }
00079
00080 ByteStreamFileSource::ByteStreamFileSource(UsageEnvironment& env, FILE* fid,
00081 Boolean deleteFidOnClose,
00082 unsigned preferredFrameSize,
00083 unsigned playTimePerFrame)
00084 : FramedFileSource(env, fid), fPreferredFrameSize(preferredFrameSize),
00085 fPlayTimePerFrame(playTimePerFrame), fLastPlayTime(0), fFileSize(0),
00086 fDeleteFidOnClose(deleteFidOnClose), fHaveStartedReading(False) {
00087 }
00088
00089 ByteStreamFileSource::~ByteStreamFileSource() {
00090 if (fFid == NULL) return;
00091
00092 #ifndef READ_FROM_FILES_SYNCHRONOUSLY
00093 envir().taskScheduler().turnOffBackgroundReadHandling(fileno(fFid));
00094 #endif
00095
00096 if (fDeleteFidOnClose) fclose(fFid);
00097 }
00098
00099 void ByteStreamFileSource::doGetNextFrame() {
00100 if (feof(fFid) || ferror(fFid)) {
00101 handleClosure(this);
00102 return;
00103 }
00104
00105 #ifdef READ_FROM_FILES_SYNCHRONOUSLY
00106 doReadFromFile();
00107 #else
00108 if (!fHaveStartedReading) {
00109
00110 envir().taskScheduler().turnOnBackgroundReadHandling(fileno(fFid),
00111 (TaskScheduler::BackgroundHandlerProc*)&fileReadableHandler, this);
00112 fHaveStartedReading = True;
00113 }
00114 #endif
00115 }
00116
00117 void ByteStreamFileSource::doStopGettingFrames() {
00118 #ifndef READ_FROM_FILES_SYNCHRONOUSLY
00119 envir().taskScheduler().turnOffBackgroundReadHandling(fileno(fFid));
00120 fHaveStartedReading = False;
00121 #endif
00122 }
00123
00124 void ByteStreamFileSource::fileReadableHandler(ByteStreamFileSource* source, int ) {
00125 if (!source->isCurrentlyAwaitingData()) {
00126 source->doStopGettingFrames();
00127 return;
00128 }
00129 source->doReadFromFile();
00130 }
00131
00132 void ByteStreamFileSource::doReadFromFile() {
00133
00134
00135 if (fPreferredFrameSize > 0 && fPreferredFrameSize < fMaxSize) {
00136 fMaxSize = fPreferredFrameSize;
00137 }
00138 fFrameSize = fread(fTo, 1, fMaxSize, fFid);
00139 if (fFrameSize == 0) {
00140 handleClosure(this);
00141 return;
00142 }
00143
00144
00145 if (fPlayTimePerFrame > 0 && fPreferredFrameSize > 0) {
00146 if (fPresentationTime.tv_sec == 0 && fPresentationTime.tv_usec == 0) {
00147
00148 gettimeofday(&fPresentationTime, NULL);
00149 } else {
00150
00151 unsigned uSeconds = fPresentationTime.tv_usec + fLastPlayTime;
00152 fPresentationTime.tv_sec += uSeconds/1000000;
00153 fPresentationTime.tv_usec = uSeconds%1000000;
00154 }
00155
00156
00157 fLastPlayTime = (fPlayTimePerFrame*fFrameSize)/fPreferredFrameSize;
00158 fDurationInMicroseconds = fLastPlayTime;
00159 } else {
00160
00161
00162 gettimeofday(&fPresentationTime, NULL);
00163 }
00164
00165
00166 #ifdef READ_FROM_FILES_SYNCHRONOUSLY
00167
00168 nextTask() = envir().taskScheduler().scheduleDelayedTask(0,
00169 (TaskFunc*)FramedSource::afterGetting, this);
00170 #else
00171
00172
00173 FramedSource::afterGetting(this);
00174 #endif
00175 }