TsStreamFileSource* TsStreamFileSource::createNew(UsageEnvironment& env, wchar_t const* fileName, unsigned preferredFrameSize, unsigned playTimePerFrame, int channelType) { LogDebug(L"ts:open %s", fileName); FileReader* reader; if (wcsstr(fileName, L".tsbuffer")!=NULL) { //MultiFileReader::MultiFileReader(BOOL useFileNext, BOOL useDummyWrites, CCritSec* pFilterLock, BOOL useRandomAccess, BOOL extraLogging): reader = new MultiFileReader(FALSE, FALSE, NULL, TRUE, FALSE); reader->SetTimeshift(true); } else { reader = new FileReader(); reader->SetTimeshift(false); } reader->SetFileName(fileName); reader->OpenFile(); Boolean deleteFidOnClose = true; TsStreamFileSource* newSource = new TsStreamFileSource(env, (FILE*)reader, deleteFidOnClose, preferredFrameSize, playTimePerFrame, channelType); __int64 fileSize = reader->GetFileSize(); if (fileSize < 0) fileSize = 0; newSource->fFileSize = fileSize; LogDebug("ts:size %I64d", fileSize); return newSource; }
void TsStreamFileSource::seekToByteRelative(int64_t offset) { FileReader* reader = (FileReader*)fFid; LogDebug("ts:seek rel %I64d/%I64d", offset, reader->GetFileSize()); offset/=188LL; offset*=188LL; reader->SetFilePointer((int64_t)offset, FILE_CURRENT); m_buffer.Clear(); }
TsStreamFileSource* TsStreamFileSource::createNew(UsageEnvironment& env, FILE* fid, Boolean deleteFidOnClose, unsigned preferredFrameSize, unsigned playTimePerFrame, int channelType) { if (fid == NULL) return NULL; TsStreamFileSource* newSource = new TsStreamFileSource(env, fid, deleteFidOnClose, preferredFrameSize, playTimePerFrame, channelType); FileReader* reader = (FileReader*)fid; __int64 fileSize = reader->GetFileSize(); if (fileSize < 0) fileSize = 0; newSource->fFileSize = fileSize; LogDebug("ts:createNew size %I64d", fileSize); return newSource; }
void TsStreamFileSource::doGetNextFrame() { //if (feof(fFid) || ferror(fFid)) { // handleClosure(this); // return; //} FileReader* reader = (FileReader*)fFid; // Try to read as many bytes as will fit in the buffer provided // (or "fPreferredFrameSize" if less) if (fPreferredFrameSize > 0 && fPreferredFrameSize < fMaxSize) { fMaxSize = fPreferredFrameSize; } long lReadBytes = 0; if (m_buffer.DequeFromBuffer(fTo,fMaxSize, &lReadBytes)!=S_OK) { if (reader->GetTimeshift()) { //Timeshifting is theoretically endless, so send NULL TS packets as there is not enough real data to send if (m_buffer.GetNullTsBuffer(fTo,fMaxSize, &lReadBytes)!=S_OK) { LogDebug("ts:GetNullTsBuffer() timeout, closing stream"); //See TSBuffer.cpp for timeout value handleClosure(this); return; } } else //It's a recording, so not endless - assume end-of-file { LogDebug("ts:eof reached, closing stream"); handleClosure(this); return; } } fFrameSize = lReadBytes; __int64 fileSize = reader->GetFileSize(); if (fileSize < 0) fileSize = 0; fFileSize = fileSize; // Set the 'presentation time': if (fPlayTimePerFrame > 0 && fPreferredFrameSize > 0) { if (fPresentationTime.tv_sec == 0 && fPresentationTime.tv_usec == 0) { // This is the first frame, so use the current time: gettimeofday(&fPresentationTime, NULL); } else { // Increment by the play time of the previous data: unsigned uSeconds = fPresentationTime.tv_usec + fLastPlayTime; fPresentationTime.tv_sec += uSeconds/1000000; fPresentationTime.tv_usec = uSeconds%1000000; } // Remember the play time of this data: fLastPlayTime = (fPlayTimePerFrame*fFrameSize)/fPreferredFrameSize; fDurationInMicroseconds = fLastPlayTime; } else { // We don't know a specific play time duration for this data, // so just record the current time as being the 'presentation time': gettimeofday(&fPresentationTime, NULL); } // Switch to another task, and inform the reader that he has data: nextTask() = envir().taskScheduler().scheduleDelayedTask(0, (TaskFunc*)FramedSource::afterGetting, this); }