Exemplo n.º 1
0
void PAPlayer::Process()
{
  if (!m_startEvent.WaitMSec(100))
  {
    CLog::Log(LOGDEBUG, "PAPlayer::Process - Failed to receive start event");
    return;
  }

  CLog::Log(LOGDEBUG, "PAPlayer::Process - Playback started");  
  while(m_isPlaying && !m_bStop)
  {
    /* this needs to happen outside of any locks to prevent deadlocks */
    if (m_signalSpeedChange)
    {
      m_callback.OnPlayBackSpeedChanged(m_playbackSpeed);
      m_signalSpeedChange = false;
    }

    double delay  = 100.0;
    double buffer = 100.0;
    ProcessStreams(delay, buffer);

    double watermark = buffer * 0.5;
    if (delay < buffer && delay > watermark)
      CThread::Sleep(MathUtils::round_int((delay - watermark) * 1000.0));

    GetTimeInternal(); //update for GUI
  }
}
Exemplo n.º 2
0
void PAPlayer::Process()
{
  if (!m_startEvent.WaitMSec(100))
  {
    CLog::Log(LOGDEBUG, "PAPlayer::Process - Failed to receive start event");
    return;
  }

  CLog::Log(LOGDEBUG, "PAPlayer::Process - Playback started");  
  while(m_isPlaying && !m_bStop)
  {
    /* this needs to happen outside of any locks to prevent deadlocks */
    if (m_signalSpeedChange)
    {
      m_callback.OnPlayBackSpeedChanged(m_playbackSpeed);
      m_signalSpeedChange = false;
    }

    double freeBufferTime = 0.0;
    ProcessStreams(freeBufferTime);

    // if none of our streams wants at least 10ms of data, we sleep
    if (freeBufferTime < 0.01)
    {
      CThread::Sleep(10);
    }

    GetTimeInternal(); //update for GUI
  }

  if(m_isFinished && !m_bStop)
    m_callback.OnPlayBackEnded();
  else
    m_callback.OnPlayBackStopped();
}
Exemplo n.º 3
0
 static void CALLBACK AdvisePeriodicCallback (UINT uTimerID, UINT uMsg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2)
 {
     HANDLE hSemaphore = (HANDLE)dwUser;
     UINT startTime = *((UINT*)hSemaphore);
     if((LONGLONG)startTime * 10000 - GetTimeInternal() < 0)
         return; // not yet
     ReleaseSemaphore(hSemaphore, 1, nullptr);
 }
Exemplo n.º 4
0
 static HRESULT STDMETHODCALLTYPE MyGetTime              (IReferenceClock* pThis, REFERENCE_TIME *pTime)
 {
     //return GetTime(pThis, pTime);
     if(!pTime)
         return E_POINTER;
     *pTime = GetTimeInternal();
     debuglog(LCF_TIMERS|LCF_TIMEGET|LCF_FREQUENT, __FUNCTION__ " called (%d).\n", (DWORD)*pTime);
     return S_OK;
 }
Exemplo n.º 5
0
 static HRESULT STDMETHODCALLTYPE MyGetTime(IReferenceClock* pThis, REFERENCE_TIME *pTime)
 {
     //return GetTime(pThis, pTime);
     if (!pTime)
         return E_POINTER;
     *pTime = GetTimeInternal();
     ENTER(*pTime);
     return S_OK;
 }
Exemplo n.º 6
0
void PAPlayer::Process()
{
  if (!m_startEvent.WaitMSec(100))
  {
    CLog::Log(LOGDEBUG, "PAPlayer::Process - Failed to receive start event");
    return;
  }

  CLog::Log(LOGDEBUG, "PAPlayer::Process - Playback started");  
  while(m_isPlaying && !m_bStop)
  {
    /* this needs to happen outside of any locks to prevent deadlocks */
    if (m_signalSpeedChange)
    {
      m_callback.OnPlayBackSpeedChanged(m_playbackSpeed);
      m_signalSpeedChange = false;
    }

    double delay  = 100.0;
    double buffer = 100.0;
    ProcessStreams(delay, buffer);

    double watermark = buffer * 0.5;
#if defined(TARGET_DARWIN)
    // In CoreAudio the delay can be bigger then the buffer
    // because of delay from the HAL/Hardware
    // This is the case when the buffer is full (e.x. 1 sec)
    // and there is a HAL-Delay. In that case we would never sleep
    // but load one cpu core up to 100% (happens on osx/ios whenever
    // the first stream is finished and a prebuffered second stream
    // starts to play. A BIG FIXME HERE.
    if ((delay < buffer || buffer == 1) && delay > watermark)
#else
    if ((delay < buffer) && delay > watermark)
#endif
      CThread::Sleep(MathUtils::round_int((delay - watermark) * 1000.0));

    GetTimeInternal(); //update for GUI
  }

  // wait for any pending jobs to complete
  {
    CSharedLock lock(m_streamsLock);
    while (m_jobCounter > 0)
    {
      lock.Leave();
      m_jobEvent.WaitMSec(100);
      lock.Enter();
    }
  }

  if(m_isFinished && !m_bStop)
    m_callback.OnPlayBackEnded();
  else
    m_callback.OnPlayBackStopped();
}
Exemplo n.º 7
0
void PAPlayer::SeekTime(int64_t iTime /*=0*/)
{
  if (!CanSeek()) return;

  CSharedLock lock(m_streamsLock);
  if (!m_currentStream)
    return;

  int seekOffset = (int)(iTime - GetTimeInternal());

  if (m_playbackSpeed != 1)
    ToFFRW(1);

  m_currentStream->m_seekFrame = (int)((float)m_currentStream->m_sampleRate * ((float)iTime + (float)m_currentStream->m_startOffset) / 1000.0f);
  m_callback.OnPlayBackSeek((int)iTime, seekOffset);
}
Exemplo n.º 8
0
    static HRESULT STDMETHODCALLTYPE MyAdviseTime           (IReferenceClock* pThis, REFERENCE_TIME rtBaseTime, REFERENCE_TIME rtStreamTime, HANDLE hEvent, LPDWORD pdwAdviseCookie)
    {
        debuglog(LCF_TIMERS, __FUNCTION__ "(rtBaseTime=%d, rtStreamTime=%d) called.\n", (DWORD)(rtBaseTime/10000), (DWORD)(rtStreamTime/10000));
        //return AdviseTime(pThis, rtBaseTime, rtStreamTime, hEvent, pdwAdviseCookie);
        REFERENCE_TIME time = rtBaseTime + rtStreamTime;
//		if((ULONGLONG)time >= 86400000L)
//			return E_INVALIDARG;
        if(!pdwAdviseCookie)
            return E_POINTER;
        time -= GetTimeInternal();
        time /= 10000;
        *pdwAdviseCookie = (DWORD)MytimeSetEvent((UINT)time, 0, (LPTIMECALLBACK)hEvent, 0, TIME_ONESHOT | TIME_CALLBACK_EVENT_SET);
        if(!*pdwAdviseCookie)
            return E_OUTOFMEMORY;
        return S_OK;
    }
Exemplo n.º 9
0
    static HRESULT STDMETHODCALLTYPE MyAdvisePeriodic       (IReferenceClock* pThis, REFERENCE_TIME rtStartTime, REFERENCE_TIME rtPeriodTime, HANDLE hSemaphore, LPDWORD pdwAdviseCookie)
    {
        debuglog(LCF_TIMERS|LCF_DESYNC|LCF_UNTESTED, __FUNCTION__ "(rtStartTime=%d, rtPeriodTime=%d) called.\n", (DWORD)(rtStartTime/10000), (DWORD)(rtPeriodTime/10000));
        return AdvisePeriodic(pThis, rtStartTime, rtPeriodTime, hSemaphore, pdwAdviseCookie);
        // following is NYI (or at least, not tested so it's probably broken)
//		if((ULONGLONG)rtStartTime >= 86400000L)
//			return E_INVALIDARG;
        if(!pdwAdviseCookie || !hSemaphore)
            return E_POINTER;
        rtStartTime -= GetTimeInternal();
        rtStartTime /= 10000;
        rtPeriodTime /= 10000;
        *((UINT*)hSemaphore) = (UINT)rtStartTime; // kind of evil... stuff the start time in the "int unused" field of the HANDLE struct, since I can't dynamically allocate the data since I don't know what to hook to clean up when Unadvice doesn't get called.
        *pdwAdviseCookie = (DWORD)MytimeSetEvent((UINT)rtPeriodTime, 0, (LPTIMECALLBACK)AdvisePeriodicCallback, (DWORD_PTR)hSemaphore, TIME_PERIODIC | TIME_CALLBACK_FUNCTION);
        if(!*pdwAdviseCookie)
            return E_OUTOFMEMORY;
        return S_OK;
    }