Skip to content

Commit

Permalink
VideoPlayer: rework speed and tempo
Browse files Browse the repository at this point in the history
  • Loading branch information
FernetMenta authored and popcornmix committed Jul 12, 2017
1 parent 5bca05e commit 43d079b
Show file tree
Hide file tree
Showing 23 changed files with 238 additions and 99 deletions.
2 changes: 0 additions & 2 deletions xbmc/Application.cpp
Expand Up @@ -2179,8 +2179,6 @@ bool CApplication::OnAction(const CAction &action)
if (action.GetID() == ACTION_PLAYER_FORWARD || action.GetID() == ACTION_PLAYER_REWIND)
{
float playSpeed = m_pPlayer->GetPlaySpeed();
if (playSpeed >= 0.75 && playSpeed <= 1.55)
playSpeed = 1;

if (action.GetID() == ACTION_PLAYER_REWIND && (playSpeed == 1)) // Enables Rewinding
playSpeed *= -2;
Expand Down
26 changes: 18 additions & 8 deletions xbmc/ApplicationPlayer.cpp
Expand Up @@ -122,7 +122,6 @@ PlayBackRet CApplicationPlayer::OpenFile(const CFileItem& item, const CPlayerOpt
m_audioStreamUpdate.SetExpired();
m_videoStreamUpdate.SetExpired();
m_subtitleStreamUpdate.SetExpired();
m_speedUpdate.SetExpired();
}
return iResult;
}
Expand Down Expand Up @@ -245,7 +244,6 @@ void CApplicationPlayer::Pause()
if (player)
{
player->Pause();
m_speedUpdate.SetExpired();
}
}

Expand Down Expand Up @@ -478,6 +476,13 @@ void CApplicationPlayer::SetSpeed(float speed)
player->SetSpeed(speed);
}

void CApplicationPlayer::SetTempo(float tempo)
{
std::shared_ptr<IPlayer> player = GetInternal();
if (player)
player->SetTempo(tempo);
}

void CApplicationPlayer::DoAudioWork()
{
std::shared_ptr<IPlayer> player = GetInternal();
Expand Down Expand Up @@ -721,20 +726,25 @@ void CApplicationPlayer::SetPlaySpeed(float speed)
return ;

SetSpeed(speed);
m_speedUpdate.SetExpired();
}

float CApplicationPlayer::GetPlaySpeed()
{
if (!m_speedUpdate.IsTimePast())
return m_fPlaySpeed;
std::shared_ptr<IPlayer> player = GetInternal();
if (player)
{
return CDataCacheCore::GetInstance().GetSpeed();
}
else
return 0;
}

float CApplicationPlayer::GetPlayTempo()
{
std::shared_ptr<IPlayer> player = GetInternal();
if (player)
{
m_fPlaySpeed = player->GetSpeed();
m_speedUpdate.Set(1000);
return m_fPlaySpeed;
return CDataCacheCore::GetInstance().GetTempo();
}
else
return 0;
Expand Down
6 changes: 3 additions & 3 deletions xbmc/ApplicationPlayer.h
Expand Up @@ -60,8 +60,6 @@ class CApplicationPlayer
int m_iVideoStream;
XbmcThreads::EndTime m_subtitleStreamUpdate;
int m_iSubtitleStream;
XbmcThreads::EndTime m_speedUpdate;
float m_fPlaySpeed;

public:
CApplicationPlayer();
Expand All @@ -72,10 +70,12 @@ class CApplicationPlayer
void ClosePlayerGapless(std::string &playername);
void CreatePlayer(const std::string &player, IPlayerCallback& callback);
std::string GetCurrentPlayer();
float GetPlaySpeed();
float GetPlaySpeed();
float GetPlayTempo();
bool HasPlayer() const;
PlayBackRet OpenFile(const CFileItem& item, const CPlayerOptions& options);
void SetPlaySpeed(float speed);
void SetTempo(float tempo);

void FrameMove();
void Render(bool clear, uint32_t alpha = 255, bool gui = true);
Expand Down
19 changes: 13 additions & 6 deletions xbmc/GUIInfoManager.cpp
Expand Up @@ -6089,7 +6089,12 @@ std::string CGUIInfoManager::GetLabel(int info, int contextWindow, std::string *
break;
case PLAYER_PLAYSPEED:
if(g_application.m_pPlayer->IsPlaying())
strLabel = StringUtils::Format("%.2f", g_application.m_pPlayer->GetPlaySpeed());
{
float speed = g_application.m_pPlayer->GetPlaySpeed();
if (speed == 1.0)
speed = g_application.m_pPlayer->GetPlayTempo();
strLabel = StringUtils::Format("%.2f", speed);
}
break;
case MUSICPLAYER_TITLE:
case MUSICPLAYER_ALBUM:
Expand Down Expand Up @@ -7182,7 +7187,7 @@ bool CGUIInfoManager::GetBool(int condition1, int contextWindow, const CGUIListI
case PLAYER_PLAYING:
{
float speed = g_application.m_pPlayer->GetPlaySpeed();
bReturn = (speed >= 0.75 && speed <= 1.55);
bReturn = (speed == 1.0);
}
break;
case PLAYER_PAUSED:
Expand Down Expand Up @@ -7238,8 +7243,9 @@ bool CGUIInfoManager::GetBool(int condition1, int contextWindow, const CGUIListI
break;
case PLAYER_IS_TEMPO:
{
float tempo = g_application.m_pPlayer->GetPlayTempo();
float speed = g_application.m_pPlayer->GetPlaySpeed();
bReturn = (speed >= 0.75 && speed <= 1.55 && speed != 1);
bReturn = (speed == 1.0 && tempo != 1.0);
}
break;
case PLAYER_RECORDING:
Expand Down Expand Up @@ -7956,8 +7962,9 @@ std::string CGUIInfoManager::GetMultiInfoLabel(const GUIInfo &info, int contextW
CDateTime time(CDateTime::GetCurrentDateTime());
int playTimeRemaining = GetPlayTimeRemaining();
float speed = g_application.m_pPlayer->GetPlaySpeed();
if (speed >= 0.75 && speed <= 1.55)
playTimeRemaining /= speed;
float tempo = g_application.m_pPlayer->GetPlayTempo();
if (speed == 1.0)
playTimeRemaining /= tempo;
time += CDateTimeSpan(0, 0, 0, playTimeRemaining);
return LocalizeTime(time, (TIME_FORMAT)info.GetData1());
}
Expand All @@ -7971,7 +7978,7 @@ std::string CGUIInfoManager::GetMultiInfoLabel(const GUIInfo &info, int contextW
{
std::string strTime;
float speed = g_application.m_pPlayer->GetPlaySpeed();
if (speed < 0.8 || speed > 1.5)
if (speed != 1.0)
strTime = StringUtils::Format("%s (%ix)", GetCurrentPlayTime((TIME_FORMAT)info.GetData1()).c_str(), (int)speed);
else
strTime = GetCurrentPlayTime();
Expand Down
22 changes: 22 additions & 0 deletions xbmc/cores/DataCacheCore.cpp
Expand Up @@ -237,6 +237,28 @@ bool CDataCacheCore::CDataCacheCore::IsSeeking()
return m_stateInfo.m_stateSeeking;
}

void CDataCacheCore::SetSpeed(float tempo, float speed)
{
CSingleLock lock(m_stateSection);

m_stateInfo.m_tempo = tempo;
m_stateInfo.m_speed = speed;
}

float CDataCacheCore::GetSpeed()
{
CSingleLock lock(m_stateSection);

return m_stateInfo.m_speed;
}

float CDataCacheCore::GetTempo()
{
CSingleLock lock(m_stateSection);

return m_stateInfo.m_tempo;
}

bool CDataCacheCore::IsPlayerStateChanged()
{
CSingleLock lock(m_stateSection);
Expand Down
5 changes: 5 additions & 0 deletions xbmc/cores/DataCacheCore.h
Expand Up @@ -66,6 +66,9 @@ class CDataCacheCore
// player states
void SetStateSeeking(bool active);
bool IsSeeking();
void SetSpeed(float tempo, float speed);
float GetSpeed();
float GetTempo();
bool IsPlayerStateChanged();
void SetGuiRender(bool gui);
bool GetGuiRender();
Expand Down Expand Up @@ -110,5 +113,7 @@ class CDataCacheCore
bool m_stateSeeking;
bool m_renderGuiLayer;
bool m_renderVideoLayer;
float m_tempo;
float m_speed;
} m_stateInfo;
};
7 changes: 2 additions & 5 deletions xbmc/cores/ExternalPlayer/ExternalPlayer.cpp
Expand Up @@ -38,6 +38,7 @@
#include "utils/Variant.h"
#include "ServiceBroker.h"
#include "cores/AudioEngine/Interfaces/AE.h"
#include "cores/DataCacheCore.h"
#include "input/InputManager.h"
#if defined(TARGET_WINDOWS)
#include "utils/CharsetConverter.h"
Expand Down Expand Up @@ -575,11 +576,7 @@ int64_t CExternalPlayer::GetTotalTime() // in milliseconds
void CExternalPlayer::SetSpeed(float speed)
{
m_speed = speed;
}

float CExternalPlayer::GetSpeed()
{
return m_speed;
CDataCacheCore::GetInstance().SetSpeed(1.0, speed);
}

std::string CExternalPlayer::GetPlayerState()
Expand Down
1 change: 0 additions & 1 deletion xbmc/cores/ExternalPlayer/ExternalPlayer.h
Expand Up @@ -60,7 +60,6 @@ class CExternalPlayer : public IPlayer, public CThread
int64_t GetTime() override;
int64_t GetTotalTime() override;
void SetSpeed(float speed) override;
float GetSpeed() override;
void DoAudioWork() override {}

std::string GetPlayerState() override;
Expand Down
2 changes: 1 addition & 1 deletion xbmc/cores/IPlayer.h
Expand Up @@ -326,7 +326,7 @@ class IPlayer
virtual int GetSourceBitrate(){ return 0;}
virtual bool GetStreamDetails(CStreamDetails &details){ return false;}
virtual void SetSpeed(float speed) = 0;
virtual float GetSpeed() = 0;
virtual void SetTempo(float tempo) { };
virtual bool SupportsTempo() { return false; }

//Returns true if not playback (paused or stopped being filled)
Expand Down
10 changes: 3 additions & 7 deletions xbmc/cores/RetroPlayer/RetroPlayer.cpp
Expand Up @@ -21,6 +21,7 @@
#include "RetroPlayer.h"
#include "RetroPlayerAudio.h"
#include "RetroPlayerVideo.h"
#include "cores/DataCacheCore.h"
#include "cores/VideoPlayer/Process/ProcessInfo.h"
#include "games/addons/playback/IGameClientPlayback.h"
#include "games/addons/GameClient.h"
Expand Down Expand Up @@ -324,14 +325,9 @@ void CRetroPlayer::SetSpeed(float speed)

if (m_gameClient->GetPlayback()->GetSpeed() != 0.0)
CloseOSD();
}
}

float CRetroPlayer::GetSpeed()
{
if (m_gameClient)
return static_cast<float>(m_gameClient->GetPlayback()->GetSpeed());
return 0;
CDataCacheCore::GetInstance().SetSpeed(1.0, speed);
}
}

bool CRetroPlayer::OnAction(const CAction &action)
Expand Down
1 change: 0 additions & 1 deletion xbmc/cores/RetroPlayer/RetroPlayer.h
Expand Up @@ -107,7 +107,6 @@ namespace RETRO
//virtual int GetSourceBitrate() override { return 0; }
bool GetStreamDetails(CStreamDetails &details) override;
void SetSpeed(float speed) override;
float GetSpeed() override;
//virtual bool IsCaching() const override { return false; }
//virtual int GetCacheLevel() const override { return -1; }
//virtual bool IsInMenu() const override { return false; }
Expand Down
23 changes: 23 additions & 0 deletions xbmc/cores/VideoPlayer/DVDMessage.h
Expand Up @@ -248,6 +248,29 @@ class CDVDMsgPlayerSeekChapter : public CDVDMsg
int m_iChapter;
};

class CDVDMsgPlayerSetSpeed : public CDVDMsg
{
public:
struct SpeedParams
{
int m_speed;
bool m_isTempo;
};

CDVDMsgPlayerSetSpeed(SpeedParams params)
: CDVDMsg(PLAYER_SETSPEED)
, m_params(params)
{}

float GetSpeed() const { return m_params.m_speed; }
float IsTempo() const { return m_params.m_isTempo; }

private:

SpeedParams m_params;

};

////////////////////////////////////////////////////////////////////////////////
//////
////// DEMUXER_ Messages
Expand Down
64 changes: 64 additions & 0 deletions xbmc/cores/VideoPlayer/Process/ProcessInfo.cpp
Expand Up @@ -424,6 +424,70 @@ bool CProcessInfo::IsSeeking()
return m_stateSeeking;
}

void CProcessInfo::SetSpeed(float speed)
{
CSingleLock lock(m_stateSection);

m_speed = speed;
m_newSpeed = speed;

if (m_dataCache)
m_dataCache->SetSpeed(m_newTempo, speed);
}

void CProcessInfo::SetNewSpeed(float speed)
{
CSingleLock lock(m_stateSection);

m_newSpeed = speed;

if (m_dataCache)
m_dataCache->SetSpeed(m_tempo, speed);
}

float CProcessInfo::GetNewSpeed()
{
CSingleLock lock(m_stateSection);

return m_newSpeed;
}

void CProcessInfo::SetTempo(float tempo)
{
CSingleLock lock(m_stateSection);

m_tempo = tempo;
m_newTempo = tempo;

if (m_dataCache)
m_dataCache->SetSpeed(tempo, m_newSpeed);
}

void CProcessInfo::SetNewTempo(float tempo)
{
CSingleLock lock(m_stateSection);

m_newTempo = tempo;

if (m_dataCache)
m_dataCache->SetSpeed(tempo, m_speed);
}

float CProcessInfo::GetNewTempo()
{
CSingleLock lock(m_stateSection);

return m_newTempo;
}

bool CProcessInfo::IsTempoAllowed(float tempo)
{
if (tempo > 0.75 && tempo < 1.55)
return true;

return false;
}

void CProcessInfo::SetLevelVQ(int level)
{
m_levelVQ = level;
Expand Down
11 changes: 11 additions & 0 deletions xbmc/cores/VideoPlayer/Process/ProcessInfo.h
Expand Up @@ -87,6 +87,13 @@ class CProcessInfo
// player states
void SetStateSeeking(bool active);
bool IsSeeking();
void SetSpeed(float speed);
void SetNewSpeed(float speed);
float GetNewSpeed();
void SetTempo(float tempo);
void SetNewTempo(float tempo);
float GetNewTempo();
virtual bool IsTempoAllowed(float tempo);

void SetLevelVQ(int level);
int GetLevelVQ();
Expand Down Expand Up @@ -135,4 +142,8 @@ class CProcessInfo
std::atomic_int m_levelVQ;
std::atomic_bool m_renderGuiLayer;
std::atomic_bool m_renderVideoLayer;
float m_tempo;
float m_newTempo;
float m_speed;
float m_newSpeed;
};

0 comments on commit 43d079b

Please sign in to comment.