void TsStreamFileSource::seekToTimeAbsolute(CRefTime& seekTime, CTsDuration& duration) { FileReader* reader = (FileReader*)fFid; double startTime = seekTime.Millisecs(); startTime /= 1000.0f; LogDebug("StreamingServer:: Seek-> %f/%f", startTime, duration.Duration().Millisecs()/1000.0f); CTsFileSeek seek(duration); seek.SetFileReader(reader); for(int i(0) ; i < 4 ; i++) { bool eof = seek.Seek(seekTime); if (eof) { REFERENCE_TIME rollBackTime = reader->GetTimeshift() ? 5000000 : 30000000; // 0.5s/3s //reached end-of-file, try to seek to an earlier position if ((seekTime.m_time - rollBackTime) > 0) { seekTime.m_time -= rollBackTime; } else { break; //very short file.... } } else { break; //we've succeeded } } m_buffer.Clear(); }
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); }