Exemplo n.º 1
0
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();
}
Exemplo n.º 2
0
//
// Run
//
// Overriden to open the dump file
//
STDMETHODIMP EMReadFrameFilter::Run(REFERENCE_TIME tStart)
{
	IReferenceClock *pClock = m_pClock;
    CAutoLock cObjectLock(m_pLock);
	CRefTime agnusStreamTimeObject;
	StreamTime(agnusStreamTimeObject);
	long millisekunder = agnusStreamTimeObject.Millisecs();
    return CBaseFilter::Run(tStart);
}
Exemplo n.º 3
0
//
// SeekDone
//
STDMETHODIMP CDVBSub::SeekDone( CRefTime& rtSeek )
{
  // Notify reset observer (clears all cached subtitles on client side)
  if( m_pResetObserver )
  {
    (*m_pResetObserver)();
  }

  // milliseconds to PCR (90Khz)
  m_CurrentSeekPosition = rtSeek.Millisecs() * 90;
  LogDebugPTS( "SeekDone", m_CurrentSeekPosition );
  return S_OK;
}
Exemplo n.º 4
0
void CTsReaderFilter::SeekPreStart(CRefTime& rtAbsSeek)
{
  bool doSeek = true;
  CTsDuration tsduration=GetDuration();

  SetMediaPosition(rtAbsSeek.m_time) ;

  //Note that the seek timestamp (m_rtStart) is done in the range
  //from earliest - latest from GetAvailable()
  //We however would like the seek timestamp to be in the range 0-fileduration
  CRefTime rtSeek = rtAbsSeek;
  float seekTime = (float)rtSeek.Millisecs();
  seekTime /= 1000.0f;

  //get the earliest timestamp available in the file
  float earliesTimeStamp = 0;
  earliesTimeStamp = tsduration.StartPcr().ToClock() - tsduration.FirstStartPcr().ToClock();

  if (earliesTimeStamp < 0) earliesTimeStamp = 0;

  //correct the seek time
  seekTime -= earliesTimeStamp;
  if (seekTime < 0) seekTime = 0;

  seekTime *= 1000.0f;
  rtSeek = CRefTime((LONG)seekTime);
  // Now rtSeek contains the "relative" position from "0 to buffer/file duration"

  // Should we really seek ?
  
  // Because all skips generated after "Stop()" cause a lot of problem
  // This remove all these stupid skips. 
  if(m_State == State_Stopped)
  {   
    if ((m_bStoppedForUnexpectedSeek || (m_absSeekTime==rtAbsSeek)) && !m_bForceSeekOnStop && !m_bForceSeekAfterRateChange)
    {
//      LogDebug("CTsReaderFilter::--SeekStart() Stopped state -- No new seek %f", 
//      (float)rtSeek.Millisecs()/1000.0f);
      m_bStoppedForUnexpectedSeek=false ;
      m_seekTime = rtSeek ;
      m_absSeekTime = rtAbsSeek ;
      return ;
    }
  }

  if (((m_absSeekTime==rtAbsSeek) && !m_bStreamCompensated && !m_bForceSeekAfterRateChange) || (m_demultiplexer.IsMediaChanging() && !m_bOnZap && !m_bForceSeekOnStop && !m_bForceSeekAfterRateChange))  
  {
    doSeek = false;
    LogDebug("CTsReaderFilter::--SeekStart()-- No new seek %f ( Abs %f / %f ) - Stream compensated: %d, OnZap: %d, Force %d, Media changing: %d", 
		(float)rtSeek.Millisecs()/1000.0f, (float)rtAbsSeek.Millisecs()/1000.0f, (float)m_duration.EndPcr().ToClock(),m_bStreamCompensated,m_bOnZap,m_bForceSeekOnStop, m_demultiplexer.IsMediaChanging());
//	  m_bStreamCompensated=false ;
    m_bForceSeekOnStop = false ;
  }
  else
  {
    LogDebug("CTsReaderFilter::--SeekStart()-- LiveTv : %d, TimeShifting: %d %3.3f ( Abs %f / %f ), OnZap: %d, Force %d, ForceRC %d, Media changing %d",
		m_bLiveTv,m_bTimeShifting,(float)rtSeek.Millisecs()/1000.0,(float)rtAbsSeek.Millisecs()/1000.0f, (float)m_duration.EndPcr().ToClock(),m_bOnZap,m_bForceSeekOnStop,m_bForceSeekAfterRateChange,m_demultiplexer.IsMediaChanging());

    m_bForceSeekOnStop = false ;
    
    if (m_bForceSeekAfterRateChange)
    {
      m_bSeekAfterRcDone = true;
      m_bForceSeekAfterRateChange = false ; 
    }

    if (m_bTimeShifting)
    {
      LONG duration = m_duration.Duration().Millisecs() ;
      LONG seekTime = rtSeek.Millisecs() ;
      if (seekTime + 200 > duration) // End of timeshift buffer requested.
      {
        if (m_bLiveTv && !m_bAnalog  && (m_fileDuration != NULL)) doSeek=false ;       // Live & not analog & not RTSP do not seek
        m_bLiveTv=true ;
      }
      else
        m_bLiveTv=false ;

      LogDebug("Zap to File Seek : %d mS ( %f / %f ) LiveTv : %d, Seek : %d",GetTickCount()-m_lastPause, (float)seekTime/1000.0f, (float)duration/1000.0f, m_bLiveTv, doSeek);
    }

    m_seekTime=rtSeek ;
    m_absSeekTime = rtAbsSeek ;

    if (!doSeek && !m_bOnZap) return ;

//    m_demultiplexer.SetHoldAudio(true) ;
//    m_demultiplexer.SetHoldVideo(true) ;
 
    m_WaitForSeekToEof=1 ; // 

    m_demultiplexer.CallTeletextEventCallback(TELETEXT_EVENT_SEEK_START,TELETEXT_EVENTVALUE_NONE);
 
    // Stop threads ////

    if (GetAudioPin()->IsConnected())
    {
      //deliver a begin-flush to the codec filter so it stops asking for data
      GetAudioPin()->DeliverBeginFlush();

      //stop the thread
      GetAudioPin()->Stop();
    }

    if (GetVideoPin()->IsConnected())
    {
      //deliver a begin-flush to the codec filter so it stops asking for data
      GetVideoPin()->DeliverBeginFlush();

      //stop the thread
      GetVideoPin()->Stop();
    }

    m_bStreamCompensated=false ;
    m_demultiplexer.m_bAudioVideoReady=false ;

	  if (!m_bOnZap || !m_demultiplexer.IsNewPatReady() || m_bAnalog) // On zapping, new PAT has occured, we should not flush to avoid loosing data.
	  {                                                               //             new PAT has not occured, we should flush to avoid restart with old data.							
	    m_demultiplexer.FlushAudio() ;
	    m_demultiplexer.FlushVideo() ;
    }
    m_bOnZap=false ;
//    m_demultiplexer.SetHoldAudio(false) ;
//    m_demultiplexer.SetHoldVideo(false) ;

    //do the seek...
    if (doSeek && !m_demultiplexer.IsMediaChanging()&& !m_demultiplexer.IsAudioChanging()) Seek(rtSeek, true);

    //tell filter we're done with seeking
//    m_pTsReaderFilter->SeekDone(rtSeek);

    m_WaitForSeekToEof=0 ; // 

    if (m_fileDuration != NULL)
    {
      if (rtSeek >= m_duration.Duration())
      {
        rtSeek=m_duration.Duration();
      }
    }

    if (GetAudioPin()->IsConnected())
    {
      // deliver a end-flush to the codec filter so it will start asking for data again
      GetAudioPin()->DeliverEndFlush();

      // Update m_rtStart in case of has not seeked yet
      GetAudioPin()->SetStart(rtAbsSeek) ;

      // and restart the thread
      GetAudioPin()->Run();
    }

    if (GetVideoPin()->IsConnected())
    {
      //deliver a end-flush to the codec filter so it will start asking for data again
      GetVideoPin()->DeliverEndFlush();

      // Update m_rtStart in case of has not seeked yet
      GetVideoPin()->SetStart(rtAbsSeek) ;

      // and restart the thread
      GetVideoPin()->Run();
    }

    m_demultiplexer.CallTeletextEventCallback(TELETEXT_EVENT_SEEK_END,TELETEXT_EVENTVALUE_NONE);

    if (m_pDVBSubtitle)
    {
      m_pDVBSubtitle->SetFirstPcr(m_duration.FirstStartPcr().PcrReferenceBase);
      m_pDVBSubtitle->SeekDone(rtSeek);
    }
  }

  return ;
}
Exemplo n.º 5
0
//*********************************************************
// Seeks in the file to the specific timestamp
// refTime : timestamp. Should be 0 < timestamp < duration
//
// The method will make a guess where the timestamp is located in the file
// and do a PCR seek from there until it finds the correct timestamp
//
bool CTsFileSeek::Seek(CRefTime refTime)
{
  double fileDuration=(double)m_duration.Duration().Millisecs();
  double seekTimeStamp=(double)refTime.Millisecs();
  
  //sanity checks...
  if (seekTimeStamp < 0) seekTimeStamp=0;
  //if (seekTimeStamp > fileDuration) seekTimeStamp=fileDuration;

  //make a guess where should start looking in the file
  double percent=seekTimeStamp/fileDuration;
  __int64 filePos=(__int64)(m_reader->GetFileSize()*percent);

  filePos/=188;
  filePos*=188;

  seekTimeStamp /= 1000.0f; // convert to seconds.

  m_seekPid=m_duration.GetPid();
  LogDebug("FileSeek: seek to %f filepos:%x pid:%x", seekTimeStamp,(DWORD)filePos, m_seekPid);
  
  byte buffer[188*10];
  __int64 binaryMax=m_reader->GetFileSize();
  __int64 binaryMin=0;
  __int64 lastFilePos=0;
  int seekingIteration=0;
  __int64 firstFilePos=filePos;
  int noPCRIteration=0;
  bool noPCRloop = false;

  Reset() ;   // Reset "PacketSync"
  while (true)
  {
    //sanity checks
    if (filePos<=0)
    {
      //no need to seek for timestamp 0,
      //simply set the pointer at the beginning of the file
      m_reader->SetFilePointer(0,FILE_BEGIN);
      return false;
    }
    if (filePos+sizeof(buffer) > m_reader->GetFileSize())
    {
      //no need to seek when we want to seek to end of file
      //simply set the pointer at the end of the file
      m_reader->SetFilePointer(0,FILE_END);
      return false;
    }

    //set filepointer to filePos
    m_reader->SetFilePointer(filePos,FILE_BEGIN);

    //read buffer from file at position filePos
    DWORD dwBytesRead;
    if (!SUCCEEDED(m_reader->Read(buffer, sizeof(buffer),&dwBytesRead)))
    {
      LogDebug("FileSeek: read failed at filePos: %x - target time: %f, iterations: %d", (DWORD)filePos, seekTimeStamp, seekingIteration);
      return true;
    }
    if (dwBytesRead <= 0) //end-of-file
    {
      LogDebug("FileSeek: end-of-file at filePos: %x - target time: %f, iterations: %d", (DWORD)filePos, seekTimeStamp, seekingIteration);
      return true;
    }
    //process data
    m_pcrFound.Reset();
    OnRawData2(buffer,dwBytesRead);

    //did we find a pcr?
    if (m_pcrFound.IsValid)
    {
      //yes. pcr found
      double clockFound=m_pcrFound.ToClock();
      double diff = clockFound - seekTimeStamp;
      //LogDebug(" got %f at filepos %x diff %f ( %I64x, %I64x )", clockFound, (DWORD)filePos, diff, binaryMin, binaryMax);

      // Make sure that seeking position is at least the target one
      if (0 <= diff && diff <= SEEKING_ACCURACY)
      {
        LogDebug("FileSeek: stop seek: %f at %x - target: %f, diff: %f, iterations: %d",
          clockFound, (DWORD)filePos, seekTimeStamp, diff, seekingIteration);
        m_reader->SetFilePointer(filePos,FILE_BEGIN);
        return false;
      }

      noPCRIteration = 0;
      seekingIteration++;
      if( seekingIteration > MAX_SEEKING_ITERATIONS )
      {
        LogDebug("FileSeek: stop seek max iterations reached (%d): %f at %x - target: %f, diff: %f",
          MAX_SEEKING_ITERATIONS, clockFound, (DWORD)filePos, seekTimeStamp, diff);
          
        if (fabs(diff) < 2.0)
        {
          m_reader->SetFilePointer(filePos,FILE_BEGIN);
        }
        else
        {
          //Set the file pointer to the initial estimate - the best we can do...
          m_reader->SetFilePointer(firstFilePos,FILE_BEGIN);
        }
        return false;
      }

      // lower bound becomes valid
      if( clockFound > seekTimeStamp )
      {
        if (filePos < binaryMax) binaryMax = filePos-1;
      }
      else
      {
        if (filePos > binaryMin) binaryMin = filePos+1;
      }

      lastFilePos=filePos;
      filePos = binaryMin + ( binaryMax - binaryMin ) / 2;
      filePos/=188;
      filePos*=188;

      if (lastFilePos==filePos)
      {
        LogDebug("FileSeek: stop seek closer target found : %f at %x - target: %f, diff: %f",
          clockFound, (DWORD)filePos, seekTimeStamp, diff);
        m_reader->SetFilePointer(filePos,FILE_BEGIN);
        return false;
      }

      Reset() ;   // Random jump, Reset "PacketSync"
    }
    else // no first PCR
    {
      //move filepointer forward and continue searching for a PCR
      filePos += sizeof(buffer);
      noPCRIteration++;
      if (noPCRIteration > MAX_BUFFER_ITERATIONS)
      {
        if (noPCRloop) //second time this has happened
        {
          LogDebug("FileSeek: stop seek, no PCR found, max iterations reached (%d)", MAX_BUFFER_ITERATIONS);
          //Set the file pointer to the initial estimate - the best we can do...
          m_reader->SetFilePointer(firstFilePos,FILE_BEGIN);
          return false;
        }
        //Let's try looking for any PCR pid 
        //starting again from the initial position
        LogDebug("FileSeek: No PCR found (pid = %d), trying for any PCR pid", m_seekPid);
        m_seekPid = -1;
        filePos = firstFilePos;
        noPCRIteration = 0;
        noPCRloop = true;
      }
    }
  }
  return false;
}