コード例 #1
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);
}
コード例 #2
0
ファイル: paplayer_linux.cpp プロジェクト: Castlecard/plex
bool PAPlayer::HandleFFwdRewd()
{
  if (!m_IsFFwdRewding && m_iSpeed == 1)
    return true;  // nothing to do
  if (m_IsFFwdRewding && m_iSpeed == 1)
  { // stop ffwd/rewd
    m_IsFFwdRewding = false;
    SetVolume(g_stSettings.m_nVolumeLevel);
    m_bytesSentOut = 0;
    FlushStreams();
    return true;
  }
  // we're definitely fastforwarding or rewinding
  int snippet = m_BytesPerSecond / 2;
  if ( m_bytesSentOut >= snippet )
  {
    // Calculate time to seek to if we do FF/RW
    __int64 time = GetTime();

    // Is our offset inside the track range?
    if (time >= 0 && time <= m_decoder[m_currentDecoder].TotalTime())
    { // just set next position to read
      m_IsFFwdRewding = true;
      time += m_currentFile->m_lStartOffset * 1000 / 75;
      m_clock.SetClock(m_decoder[m_currentDecoder].Seek(time));
      FlushStreams();
      SetVolume(g_stSettings.m_nVolumeLevel - VOLUME_FFWD_MUTE); // override xbmc mute
    }
    else if (time < 0)
    { // ...disable seeking and start the track again
      ToFFRW(1);
      time = m_currentFile->m_lStartOffset * 1000 / 75;
      m_clock.SetClock(m_decoder[m_currentDecoder].Seek(time));
      FlushStreams();
      SetVolume(g_stSettings.m_nVolumeLevel); // override xbmc mute
    } // is our next position greater then the end sector...
    else //if (time > m_codec->m_TotalTime)
    {
      // restore volume level so the next track isn't muted
      SetVolume(g_stSettings.m_nVolumeLevel);
      CLog::Log(LOGDEBUG, "PAP Player: End of track reached while seeking");
      return false;
    }
  }
  return true;
}
コード例 #3
0
ファイル: ApplicationPlayer.cpp プロジェクト: B0k0/xbmc
void CApplicationPlayer::SetPlaySpeed(int iSpeed, bool bApplicationMuted)
{
  boost::shared_ptr<IPlayer> player = GetInternal();
  if (!player)
    return;

  if (!IsPlayingAudio() && !IsPlayingVideo())
    return ;
  if (m_iPlaySpeed == iSpeed)
    return ;
  if (!CanSeek())
    return;
  if (IsPaused())
  {
    if (
      ((m_iPlaySpeed > 1) && (iSpeed > m_iPlaySpeed)) ||
      ((m_iPlaySpeed < -1) && (iSpeed < m_iPlaySpeed))
    )
    {
      iSpeed = m_iPlaySpeed; // from pause to ff/rw, do previous ff/rw speed
    }
    Pause();
  }
  m_iPlaySpeed = iSpeed;

  ToFFRW(m_iPlaySpeed);

  // if player has volume control, set it.
  if (ControlsVolume())
  {
    if (m_iPlaySpeed == 1)
    { // restore volume
      player->SetVolume(g_application.GetVolume(false));
    }
    else
    { // mute volume
      player->SetVolume(VOLUME_MINIMUM);
    }
    player->SetMute(bApplicationMuted);
  }
}
コード例 #4
0
ファイル: PAPlayer.cpp プロジェクト: huigll/xbmc
inline bool PAPlayer::ProcessStream(StreamInfo *si, double &delay, double &buffer)
{
  /* if playback needs to start on this stream, do it */
  if (si == m_currentStream && !si->m_started)
  {
    si->m_started = true;
    si->m_stream->RegisterAudioCallback(m_audioCallback);
    if (!si->m_isSlaved)
      si->m_stream->Resume();
    si->m_stream->FadeVolume(0.0f, 1.0f, m_upcomingCrossfadeMS);
    m_callback.OnPlayBackStarted();
  }

  /* if we have not started yet and the stream has been primed */
  unsigned int space = si->m_stream->GetSpace();
  if (!si->m_started && !space)
    return true;

  /* see if it is time yet to FF/RW or a direct seek */
  if (!si->m_playNextTriggered && ((m_playbackSpeed != 1 && si->m_framesSent >= si->m_seekNextAtFrame) || si->m_seekFrame > -1))
  {
    int64_t time = (int64_t)0;
    /* if its a direct seek */
    if (si->m_seekFrame > -1)
    {
      time = (int64_t)((float)si->m_seekFrame / (float)si->m_sampleRate * 1000.0f);
      si->m_framesSent = (int)(si->m_seekFrame - ((float)si->m_startOffset * (float)si->m_sampleRate) / 1000.0f);
      si->m_seekFrame  = -1;
      m_playerGUIData.m_time = time; //update for GUI
    }
    /* if its FF/RW */
    else
    {
      si->m_framesSent      += si->m_sampleRate * (m_playbackSpeed  - 1);
      si->m_seekNextAtFrame  = si->m_framesSent + si->m_sampleRate / 2;
      time = (int64_t)(((float)si->m_framesSent / (float)si->m_sampleRate * 1000.0f) + (float)si->m_startOffset);
    }

    /* if we are seeking back before the start of the track start normal playback */
    if (time < si->m_startOffset || si->m_framesSent < 0)
    {
      time = si->m_startOffset;
      si->m_framesSent      = (int)(si->m_startOffset * si->m_sampleRate / 1000);
      si->m_seekNextAtFrame = 0;
      ToFFRW(1);
    }

    si->m_decoder.Seek(time);
  }

  int status = si->m_decoder.GetStatus();
  if (status == STATUS_ENDED   ||
      status == STATUS_NO_FILE ||
      si->m_decoder.ReadSamples(PACKET_SIZE) == RET_ERROR ||
      ((si->m_endOffset) && (si->m_framesSent / si->m_sampleRate >= (si->m_endOffset - si->m_startOffset) / 1000)))
  {
    CLog::Log(LOGINFO, "PAPlayer::ProcessStream - Stream Finished");
    return false;
  }

  if (!QueueData(si))
    return false;

  /* update the delay time if we are running */
  if (si->m_started)
  {
    if (si->m_stream->IsBuffering())
      delay = 0.0;
    else
      delay = std::min(delay , si->m_stream->GetDelay());
    buffer = std::min(buffer, si->m_stream->GetCacheTotal());
  }

  return true;
}
コード例 #5
0
ファイル: PAPlayer.cpp プロジェクト: KeTao/kodi-cmake
inline bool PAPlayer::ProcessStream(StreamInfo *si, double &freeBufferTime)
{
  /* if playback needs to start on this stream, do it */
  if (si == m_currentStream && !si->m_started)
  {
    si->m_started = true;
    si->m_stream->RegisterAudioCallback(m_audioCallback);
    if (!si->m_isSlaved)
      si->m_stream->Resume();
    si->m_stream->FadeVolume(0.0f, 1.0f, m_upcomingCrossfadeMS);
    m_callback.OnPlayBackStarted();
  }

  /* if we have not started yet and the stream has been primed */
  unsigned int space = si->m_stream->GetSpace();
  if (!si->m_started && !space)
    return true;

  /* see if it is time yet to FF/RW or a direct seek */
  if (!si->m_playNextTriggered && ((m_playbackSpeed != 1 && si->m_framesSent >= si->m_seekNextAtFrame) || si->m_seekFrame > -1))
  {
    int64_t time = (int64_t)0;
    /* if its a direct seek */
    if (si->m_seekFrame > -1)
    {
      time = (int64_t)((float)si->m_seekFrame / (float)si->m_sampleRate * 1000.0f);
      si->m_framesSent = (int)(si->m_seekFrame - ((float)si->m_startOffset * (float)si->m_sampleRate) / 1000.0f);
      si->m_seekFrame  = -1;
      m_playerGUIData.m_time = time; //update for GUI
      si->m_seekNextAtFrame = 0;
    }
    /* if its FF/RW */
    else
    {
      si->m_framesSent      += si->m_sampleRate * (m_playbackSpeed  - 1);
      si->m_seekNextAtFrame  = si->m_framesSent + si->m_sampleRate / 2;
      time = (int64_t)(((float)si->m_framesSent / (float)si->m_sampleRate * 1000.0f) + (float)si->m_startOffset);
    }

    /* if we are seeking back before the start of the track start normal playback */
    if (time < si->m_startOffset || si->m_framesSent < 0)
    {
      time = si->m_startOffset;
      si->m_framesSent      = 0;
      si->m_seekNextAtFrame = 0;
      ToFFRW(1);
    }

    si->m_decoder.Seek(time);
  }

  int status = si->m_decoder.GetStatus();
  if (status == STATUS_ENDED   ||
      status == STATUS_NO_FILE ||
      si->m_decoder.ReadSamples(PACKET_SIZE) == RET_ERROR ||
      ((si->m_endOffset) && (si->m_framesSent / si->m_sampleRate >= (si->m_endOffset - si->m_startOffset) / 1000)))
  {
    if (si == m_currentStream && m_continueStream)
    {
      // update current stream with info of next track
      si->m_startOffset = m_FileItem->m_lStartOffset * 1000 / 75;
      if (m_FileItem->m_lEndOffset)
        si->m_endOffset = m_FileItem->m_lEndOffset * 1000 / 75;
      else
        si->m_endOffset = 0;
      si->m_framesSent = 0;

      int64_t streamTotalTime = si->m_decoder.TotalTime() - si->m_startOffset;
      if (si->m_endOffset)
        streamTotalTime = si->m_endOffset - si->m_startOffset;

      // calculate time when to prepare next stream
      si->m_prepareNextAtFrame = 0;
      if (streamTotalTime >= TIME_TO_CACHE_NEXT_FILE + m_defaultCrossfadeMS)
        si->m_prepareNextAtFrame = (int)((streamTotalTime - TIME_TO_CACHE_NEXT_FILE - m_defaultCrossfadeMS) * si->m_sampleRate / 1000.0f);

      si->m_prepareTriggered = false;
      si->m_playNextAtFrame = 0;
      si->m_playNextTriggered = false;
      si->m_seekNextAtFrame = 0;

      //update the current stream to start playing the next track at the correct frame.
      UpdateStreamInfoPlayNextAtFrame(m_currentStream, m_upcomingCrossfadeMS);

      UpdateGUIData(si);
      m_callback.OnPlayBackStarted();
      m_continueStream = false;
    }
    else
    {
      CLog::Log(LOGINFO, "PAPlayer::ProcessStream - Stream Finished");
      return false;
    }
  }

  if (!QueueData(si))
    return false;

  /* update free buffer time if we are running */
  if (si->m_started)
  {
    if (si->m_stream->IsBuffering())
      freeBufferTime = 1.0;
    else
    {
      double free_space = (double)(si->m_stream->GetSpace() / si->m_bytesPerSample) / si->m_sampleRate;
      freeBufferTime = std::max(freeBufferTime , free_space);
    }
  }

  return true;
}