diff options
author | enen92 <92enen@gmail.com> | 2022-05-07 12:56:00 +0100 |
---|---|---|
committer | enen92 <92enen@gmail.com> | 2022-05-08 12:41:09 +0100 |
commit | b7157562b126139dd10e0f5195a892e2f958f2d6 (patch) | |
tree | f3db8e4e6c5989cf9707349428d03557e5c4e68c | |
parent | c4357207d65bf1af8e852769495aed8922a41b70 (diff) |
[GUI][Info] Add Player.HasPerformedSeek(interval)
-rw-r--r-- | xbmc/GUIInfoManager.cpp | 12 | ||||
-rw-r--r-- | xbmc/cores/DataCacheCore.cpp | 18 | ||||
-rw-r--r-- | xbmc/cores/DataCacheCore.h | 20 | ||||
-rw-r--r-- | xbmc/cores/VideoPlayer/Process/ProcessInfo.cpp | 7 | ||||
-rw-r--r-- | xbmc/cores/VideoPlayer/Process/ProcessInfo.h | 5 | ||||
-rw-r--r-- | xbmc/cores/VideoPlayer/VideoPlayer.cpp | 15 | ||||
-rw-r--r-- | xbmc/guilib/guiinfo/GUIInfoLabels.h | 2 | ||||
-rw-r--r-- | xbmc/guilib/guiinfo/PlayerGUIInfo.cpp | 16 | ||||
-rw-r--r-- | xbmc/network/upnp/UPnPPlayer.cpp | 1 |
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: |