aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorenen92 <92enen@gmail.com>2022-05-07 12:56:00 +0100
committerenen92 <92enen@gmail.com>2022-05-08 12:41:09 +0100
commitb7157562b126139dd10e0f5195a892e2f958f2d6 (patch)
treef3db8e4e6c5989cf9707349428d03557e5c4e68c
parentc4357207d65bf1af8e852769495aed8922a41b70 (diff)
[GUI][Info] Add Player.HasPerformedSeek(interval)
-rw-r--r--xbmc/GUIInfoManager.cpp12
-rw-r--r--xbmc/cores/DataCacheCore.cpp18
-rw-r--r--xbmc/cores/DataCacheCore.h20
-rw-r--r--xbmc/cores/VideoPlayer/Process/ProcessInfo.cpp7
-rw-r--r--xbmc/cores/VideoPlayer/Process/ProcessInfo.h5
-rw-r--r--xbmc/cores/VideoPlayer/VideoPlayer.cpp15
-rw-r--r--xbmc/guilib/guiinfo/GUIInfoLabels.h2
-rw-r--r--xbmc/guilib/guiinfo/PlayerGUIInfo.cpp16
-rw-r--r--xbmc/network/upnp/UPnPPlayer.cpp1
9 files changed, 90 insertions, 6 deletions
diff --git a/xbmc/GUIInfoManager.cpp b/xbmc/GUIInfoManager.cpp
index 1ae2877615..f1b4ab2e33 100644
--- a/xbmc/GUIInfoManager.cpp
+++ b/xbmc/GUIInfoManager.cpp
@@ -879,9 +879,17 @@ const infomap player_labels[] = {{"hasmedia", PLAYER_HAS_MEDIA},
/// while still making it clear they can have any value.
/// <p>
/// }
+/// \table_row3{ <b>`Player.HasPerformedSeek(interval)`</b>,
+/// \anchor Player_HasPerformedSeek
+/// _boolean_,
+/// @return **True** if the Player has performed a seek operation in the last provided second `interval`\, **False** otherwise.
+/// @param interval - the time interval (in seconds)
+/// <p><hr>
+/// @skinning_v20 **[New Boolean Condition]** \link Player_HasPerformedSeek `Player.HasPerformedSeek(interval)`\endlink
+/// <p>
+/// }
-
-const infomap player_param[] = {{ "art", PLAYER_ITEM_ART }};
+const infomap player_param[] = {{"art", PLAYER_ITEM_ART}, {"hasperformedseek", PLAYER_HASSEEKED}};
/// \page modules__infolabels_boolean_conditions
/// \table_row3{ <b>`Player.SeekTime`</b>,
diff --git a/xbmc/cores/DataCacheCore.cpp b/xbmc/cores/DataCacheCore.cpp
index 3f97abc181..200f0ec09e 100644
--- a/xbmc/cores/DataCacheCore.cpp
+++ b/xbmc/cores/DataCacheCore.cpp
@@ -320,6 +320,24 @@ bool CDataCacheCore::IsRenderClockSync()
}
// player states
+void CDataCacheCore::SeekFinished()
+{
+ std::unique_lock<CCriticalSection> lock(m_stateSection);
+ m_stateInfo.m_lastSeekTime = std::chrono::system_clock::now();
+}
+
+bool CDataCacheCore::HasPerformedSeek(int64_t lastSecondInterval) const
+{
+ std::unique_lock<CCriticalSection> lock(m_stateSection);
+ if (m_stateInfo.m_lastSeekTime == std::chrono::time_point<std::chrono::system_clock>{})
+ {
+ return false;
+ }
+ return (std::chrono::system_clock::now() - m_stateInfo.m_lastSeekTime) <
+ std::chrono::duration_cast<std::chrono::seconds>(
+ std::chrono::duration<int64_t>(lastSecondInterval));
+}
+
void CDataCacheCore::SetStateSeeking(bool active)
{
std::unique_lock<CCriticalSection> lock(m_stateSection);
diff --git a/xbmc/cores/DataCacheCore.h b/xbmc/cores/DataCacheCore.h
index 823967128f..8fdf63b936 100644
--- a/xbmc/cores/DataCacheCore.h
+++ b/xbmc/cores/DataCacheCore.h
@@ -12,10 +12,10 @@
#include "threads/CriticalSection.h"
#include <atomic>
+#include <chrono>
#include <string>
#include <vector>
-
class CDataCacheCore
{
public:
@@ -119,8 +119,21 @@ public:
bool IsRenderClockSync();
// player states
+ /*!
+ * @brief Notifies the cache core that a seek operation has finished
+ */
+ void SeekFinished();
+
void SetStateSeeking(bool active);
bool IsSeeking();
+
+ /*!
+ * @brief Checks if a seek has been performed in the last provided seconds interval
+ * @param lastSecondInterval - the last elapsed second interval to check for a seek operation
+ * @return true if a seek was performed in the lastSecondInterval, false otherwise
+ */
+ bool HasPerformedSeek(int64_t lastSecondInterval) const;
+
void SetSpeed(float tempo, float speed);
float GetSpeed();
float GetTempo();
@@ -288,7 +301,7 @@ protected:
bool m_isClockSync;
} m_renderInfo;
- CCriticalSection m_stateSection;
+ mutable CCriticalSection m_stateSection;
bool m_playerStateChanged = false;
struct SStateInfo
{
@@ -298,6 +311,9 @@ protected:
float m_tempo;
float m_speed;
bool m_frameAdvance;
+ /*! Time point of the last seek operation */
+ std::chrono::time_point<std::chrono::system_clock> m_lastSeekTime{
+ std::chrono::time_point<std::chrono::system_clock>{}};
} m_stateInfo;
struct STimeInfo
diff --git a/xbmc/cores/VideoPlayer/Process/ProcessInfo.cpp b/xbmc/cores/VideoPlayer/Process/ProcessInfo.cpp
index 483c13157b..6023afc86d 100644
--- a/xbmc/cores/VideoPlayer/Process/ProcessInfo.cpp
+++ b/xbmc/cores/VideoPlayer/Process/ProcessInfo.cpp
@@ -467,6 +467,13 @@ std::vector<AVPixelFormat> CProcessInfo::GetRenderFormats()
//******************************************************************************
// player states
//******************************************************************************
+void CProcessInfo::SeekFinished()
+{
+ std::unique_lock<CCriticalSection> lock(m_stateSection);
+ if (m_dataCache)
+ m_dataCache->SeekFinished();
+}
+
void CProcessInfo::SetStateSeeking(bool active)
{
std::unique_lock<CCriticalSection> lock(m_renderSection);
diff --git a/xbmc/cores/VideoPlayer/Process/ProcessInfo.h b/xbmc/cores/VideoPlayer/Process/ProcessInfo.h
index 31cf2eb691..62caaf1d9b 100644
--- a/xbmc/cores/VideoPlayer/Process/ProcessInfo.h
+++ b/xbmc/cores/VideoPlayer/Process/ProcessInfo.h
@@ -82,6 +82,11 @@ public:
virtual std::vector<AVPixelFormat> GetRenderFormats();
// player states
+ /*!
+ * @brief Notifies that a seek operation has finished
+ */
+ void SeekFinished();
+
void SetStateSeeking(bool active);
bool IsSeeking();
void SetStateRealtime(bool state);
diff --git a/xbmc/cores/VideoPlayer/VideoPlayer.cpp b/xbmc/cores/VideoPlayer/VideoPlayer.cpp
index ad754d947a..c46888b4b2 100644
--- a/xbmc/cores/VideoPlayer/VideoPlayer.cpp
+++ b/xbmc/cores/VideoPlayer/VideoPlayer.cpp
@@ -2623,6 +2623,7 @@ void CVideoPlayer::HandleMessages()
if (!msg.GetTrickPlay())
{
CServiceBroker::GetGUI()->GetInfoManager().GetInfoProviders().GetPlayerInfoProvider().SetDisplayAfterSeek(100000);
+ m_processInfo->SeekFinished();
SetCaching(CACHESTATE_FLUSH);
}
@@ -2679,7 +2680,10 @@ void CVideoPlayer::HandleMessages()
// set flag to indicate we have finished a seeking request
if(!msg.GetTrickPlay())
+ {
CServiceBroker::GetGUI()->GetInfoManager().GetInfoProviders().GetPlayerInfoProvider().SetDisplayAfterSeek();
+ m_processInfo->SeekFinished();
+ }
// dvd's will issue a HOP_CHANNEL that we need to skip
if(m_pInputStream->IsStreamType(DVDSTREAM_TYPE_DVD))
@@ -2692,6 +2696,7 @@ void CVideoPlayer::HandleMessages()
m_messenger.GetPacketCount(CDVDMsg::PLAYER_SEEK_CHAPTER) == 0)
{
CServiceBroker::GetGUI()->GetInfoManager().GetInfoProviders().GetPlayerInfoProvider().SetDisplayAfterSeek(100000);
+ m_processInfo->SeekFinished();
SetCaching(CACHESTATE_FLUSH);
CDVDMsgPlayerSeekChapter& msg(*std::static_pointer_cast<CDVDMsgPlayerSeekChapter>(pMsg));
@@ -2717,6 +2722,7 @@ void CVideoPlayer::HandleMessages()
m_callback.OnPlayBackSeekChapter(msg.GetChapter());
}
}
+ m_processInfo->SeekFinished();
CServiceBroker::GetGUI()->GetInfoManager().GetInfoProviders().GetPlayerInfoProvider().SetDisplayAfterSeek(2500, offset);
}
else if (pMsg->IsType(CDVDMsg::DEMUXER_RESET))
@@ -2861,6 +2867,7 @@ void CVideoPlayer::HandleMessages()
}
}
+ m_processInfo->SeekFinished();
CServiceBroker::GetGUI()->GetInfoManager().GetInfoProviders().GetPlayerInfoProvider().SetDisplayAfterSeek();
}
else if (pMsg->IsType(CDVDMsg::GENERAL_FLUSH))
@@ -2889,7 +2896,7 @@ void CVideoPlayer::HandleMessages()
if (speed != DVD_PLAYSPEED_PAUSE && m_playSpeed != DVD_PLAYSPEED_PAUSE && speed != m_playSpeed)
{
m_callback.OnPlayBackSpeedChanged(speed / DVD_PLAYSPEED_NORMAL);
-
+ m_processInfo->SeekFinished();
// notify GUI, skins may want to show the seekbar
CServiceBroker::GetGUI()->
GetInfoManager().GetInfoProviders().GetPlayerInfoProvider().SetDisplayAfterSeek();
@@ -4243,6 +4250,7 @@ bool CVideoPlayer::OnAction(const CAction &action)
CLog::Log(LOGDEBUG, " - pushed prev");
pMenus->OnPrevious();
CServiceBroker::GetGUI()->GetInfoManager().SetDisplayAfterSeek();
+ m_processInfo->SeekFinished();
return true;
}
break;
@@ -4252,6 +4260,7 @@ bool CVideoPlayer::OnAction(const CAction &action)
CLog::Log(LOGDEBUG, " - pushed next");
pMenus->OnNext();
CServiceBroker::GetGUI()->GetInfoManager().SetDisplayAfterSeek();
+ m_processInfo->SeekFinished();
return true;
}
break;
@@ -4287,6 +4296,7 @@ bool CVideoPlayer::OnAction(const CAction &action)
pMenus->OnNext();
CServiceBroker::GetGUI()->GetInfoManager().GetInfoProviders().GetPlayerInfoProvider().SetDisplayAfterSeek();
+ m_processInfo->SeekFinished();
return true;
case ACTION_PREV_ITEM:
THREAD_ACTION(action);
@@ -4297,6 +4307,7 @@ bool CVideoPlayer::OnAction(const CAction &action)
pMenus->OnPrevious();
CServiceBroker::GetGUI()->GetInfoManager().GetInfoProviders().GetPlayerInfoProvider().SetDisplayAfterSeek();
+ m_processInfo->SeekFinished();
return true;
case ACTION_PREVIOUS_MENU:
case ACTION_NAV_BACK:
@@ -4410,6 +4421,7 @@ bool CVideoPlayer::OnAction(const CAction &action)
{
m_messenger.Put(std::make_shared<CDVDMsgPlayerSeekChapter>(GetChapter() + 1));
CServiceBroker::GetGUI()->GetInfoManager().GetInfoProviders().GetPlayerInfoProvider().SetDisplayAfterSeek();
+ m_processInfo->SeekFinished();
return true;
}
else if (SeekScene(true))
@@ -4421,6 +4433,7 @@ bool CVideoPlayer::OnAction(const CAction &action)
{
m_messenger.Put(std::make_shared<CDVDMsgPlayerSeekChapter>(GetChapter() - 1));
CServiceBroker::GetGUI()->GetInfoManager().GetInfoProviders().GetPlayerInfoProvider().SetDisplayAfterSeek();
+ m_processInfo->SeekFinished();
return true;
}
else if (SeekScene(false))
diff --git a/xbmc/guilib/guiinfo/GUIInfoLabels.h b/xbmc/guilib/guiinfo/GUIInfoLabels.h
index f884b3b35a..f9d0d0d111 100644
--- a/xbmc/guilib/guiinfo/GUIInfoLabels.h
+++ b/xbmc/guilib/guiinfo/GUIInfoLabels.h
@@ -36,7 +36,7 @@
#define PLAYER_TIME 27
#define PLAYER_TIME_REMAINING 28
#define PLAYER_DURATION 29
-// unused 30
+#define PLAYER_HASPERFORMEDSEEK 30
#define PLAYER_SHOWINFO 31
#define PLAYER_VOLUME 32
#define PLAYER_MUTED 33
diff --git a/xbmc/guilib/guiinfo/PlayerGUIInfo.cpp b/xbmc/guilib/guiinfo/PlayerGUIInfo.cpp
index b4068fa328..e9d2e47996 100644
--- a/xbmc/guilib/guiinfo/PlayerGUIInfo.cpp
+++ b/xbmc/guilib/guiinfo/PlayerGUIInfo.cpp
@@ -28,6 +28,7 @@
#include "utils/Variant.h"
#include "utils/log.h"
+#include <charconv>
#include <cmath>
using namespace KODI::GUILIB::GUIINFO;
@@ -508,6 +509,21 @@ bool CPlayerGUIInfo::GetBool(bool& value, const CGUIListItem *gitem, int context
case PLAYER_SEEKING:
value = g_application.GetAppPlayer().GetSeekHandler().InProgress();
return true;
+ case PLAYER_HASPERFORMEDSEEK:
+ {
+ int requestedLastSecondInterval{0};
+ std::from_chars_result result =
+ std::from_chars(info.GetData3().data(), info.GetData3().data() + info.GetData3().size(),
+ requestedLastSecondInterval);
+ if (result.ec == std::errc::invalid_argument)
+ {
+ value = false;
+ return false;
+ }
+
+ value = CServiceBroker::GetDataCacheCore().HasPerformedSeek(requestedLastSecondInterval);
+ return true;
+ }
case PLAYER_PASSTHROUGH:
value = g_application.GetAppPlayer().IsPassthrough();
return true;
diff --git a/xbmc/network/upnp/UPnPPlayer.cpp b/xbmc/network/upnp/UPnPPlayer.cpp
index 701010f64f..e8476bb409 100644
--- a/xbmc/network/upnp/UPnPPlayer.cpp
+++ b/xbmc/network/upnp/UPnPPlayer.cpp
@@ -493,6 +493,7 @@ void CUPnPPlayer::SeekTime(int64_t ms)
, "REL_TIME", PLT_Didl::FormatTimeStamp((NPT_UInt32)(ms / 1000))
, m_delegate), failed);
+ CDataCacheCore::GetInstance().SeekFinished();
CServiceBroker::GetGUI()->GetInfoManager().GetInfoProviders().GetPlayerInfoProvider().SetDisplayAfterSeek();
return;
failed: