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);
}