Skip to content

Commit

Permalink
[package] [mediacenter-osmc] Add PVR improvements
Browse files Browse the repository at this point in the history
Signed-off-by: Sam Nazarko <email@samnazarko.co.uk>
  • Loading branch information
samnazarko committed Mar 31, 2017
1 parent 024b05b commit 6b020da
Show file tree
Hide file tree
Showing 4 changed files with 486 additions and 0 deletions.
186 changes: 186 additions & 0 deletions package/mediacenter-osmc/patches/all-095-fix-channel-selection.patch
@@ -0,0 +1,186 @@
From cbd96778cf947793f709c0e8508a085f5f101f2e Mon Sep 17 00:00:00 2001
From: Kai Sommerfeld <kai.sommerfeld@gmx.com>
Date: Sun, 19 Mar 2017 15:24:13 +0100
Subject: [PATCH] [PVR] Guide window: Fix event/channel selection after channel
group switch.

---
xbmc/epg/GUIEPGGridContainer.cpp | 53 +++++++++++++++++-----------------
xbmc/epg/GUIEPGGridContainer.h | 1 -
xbmc/epg/GUIEPGGridContainerModel.cpp | 3 ++
xbmc/epg/GUIEPGGridContainerModel.h | 1 +
xbmc/pvr/windows/GUIWindowPVRGuide.cpp | 15 +++++-----
5 files changed, 38 insertions(+), 35 deletions(-)

diff --git a/xbmc/epg/GUIEPGGridContainer.cpp b/xbmc/epg/GUIEPGGridContainer.cpp
index 44ff0dd..ec3c4b04 100644
--- a/xbmc/epg/GUIEPGGridContainer.cpp
+++ b/xbmc/epg/GUIEPGGridContainer.cpp
@@ -346,14 +346,6 @@ void CGUIEPGGridContainer::RenderItem(float posX, float posY, CGUIListItem *item
g_graphicsContext.RestoreOrigin();
}

-void CGUIEPGGridContainer::ResetCoordinates()
-{
- m_channelCursor = 0;
- m_channelOffset = 0;
- m_blockCursor = 0;
- m_blockOffset = 0;
-}
-
bool CGUIEPGGridContainer::OnAction(const CAction &action)
{
switch (action.GetID())
@@ -603,9 +595,23 @@ void CGUIEPGGridContainer::UpdateItems()

if (prevSelectedEpgTag && (oldChannelIndex != 0 || oldBlockIndex != 0))
{
- if (m_gridModel->GetGridItem(newChannelIndex, newBlockIndex)->GetEPGInfoTag() != prevSelectedEpgTag)
+ if (newChannelIndex >= m_gridModel->ChannelItemsSize() ||
+ newBlockIndex >= m_gridModel->GetBlockCount() ||
+ m_gridModel->GetGridItem(newChannelIndex, newBlockIndex)->GetEPGInfoTag() != prevSelectedEpgTag)
+ {
m_gridModel->FindChannelAndBlockIndex(channelUid, broadcastUid, eventOffset, newChannelIndex, newBlockIndex);

+ if (newChannelIndex == CGUIEPGGridContainerModel::INVALID_INDEX ||
+ newBlockIndex == CGUIEPGGridContainerModel::INVALID_INDEX)
+ {
+ // previous selection is no longer in grid, goto channel 0 and now
+ SetInvalid();
+ GoToChannel(0);
+ GoToNow();
+ return;
+ }
+ }
+
// restore previous selection.
if (newChannelIndex == oldChannelIndex && newBlockIndex == oldBlockIndex)
{
@@ -1382,18 +1388,18 @@ void CGUIEPGGridContainer::SetTimelineItems(const std::unique_ptr<CFileItemList>

void CGUIEPGGridContainer::GoToChannel(int channelIndex)
{
- if (channelIndex > m_gridModel->ChannelItemsSize() - m_channelsPerPage)
- {
- // last page
- ScrollToChannelOffset(m_gridModel->ChannelItemsSize() - m_channelsPerPage);
- SetChannel(channelIndex - (m_gridModel->ChannelItemsSize() - m_channelsPerPage));
- }
- else if (channelIndex < m_channelsPerPage)
+ if (channelIndex < m_channelsPerPage)
{
// first page
ScrollToChannelOffset(0);
SetChannel(channelIndex);
}
+ else if (channelIndex > m_gridModel->ChannelItemsSize() - m_channelsPerPage)
+ {
+ // last page
+ ScrollToChannelOffset(m_gridModel->ChannelItemsSize() - m_channelsPerPage);
+ SetChannel(channelIndex - (m_gridModel->ChannelItemsSize() - m_channelsPerPage));
+ }
else
{
ScrollToChannelOffset(channelIndex - m_channelCursor);
@@ -1403,17 +1409,12 @@ void CGUIEPGGridContainer::GoToChannel(int channelIndex)

void CGUIEPGGridContainer::GoToBlock(int blockIndex)
{
- if (blockIndex > m_gridModel->GetBlockCount() - m_blocksPerPage)
+ int lastPage = m_gridModel->GetBlockCount() - m_blocksPerPage;
+ if (blockIndex > lastPage)
{
- // last block
- ScrollToBlockOffset(m_gridModel->GetBlockCount() - m_blocksPerPage);
- SetBlock(blockIndex - (m_gridModel->GetBlockCount() - m_blocksPerPage));
- }
- else if (blockIndex < m_blocksPerPage)
- {
- // first block
- ScrollToBlockOffset(0);
- SetBlock(blockIndex);
+ // last page
+ ScrollToBlockOffset(lastPage);
+ SetBlock(blockIndex - lastPage);
}
else
{
diff --git a/xbmc/epg/GUIEPGGridContainer.h b/xbmc/epg/GUIEPGGridContainer.h
index cf6a901..72be679 100644
--- a/xbmc/epg/GUIEPGGridContainer.h
+++ b/xbmc/epg/GUIEPGGridContainer.h
@@ -84,7 +84,6 @@ namespace EPG
void SetTimelineItems(const std::unique_ptr<CFileItemList> &items, const CDateTime &gridStart, const CDateTime &gridEnd);
void SetChannel(const PVR::CPVRChannelPtr &channel);
void SetChannel(const std::string &channel);
- void ResetCoordinates();

protected:
bool OnClick(int actionID);
diff --git a/xbmc/epg/GUIEPGGridContainerModel.cpp b/xbmc/epg/GUIEPGGridContainerModel.cpp
index 1abc733..69fd12d 100644
--- a/xbmc/epg/GUIEPGGridContainerModel.cpp
+++ b/xbmc/epg/GUIEPGGridContainerModel.cpp
@@ -272,6 +272,9 @@ void CGUIEPGGridContainerModel::FindChannelAndBlockIndex(int channelUid, unsigne
const CDateTimeSpan blockDuration(0, 0, MINSPERBLOCK, 0);
bool bFoundPrevChannel = false;

+ newChannelIndex = INVALID_INDEX;
+ newBlockIndex = INVALID_INDEX;
+
for (size_t channel = 0; channel < m_channelItems.size(); ++channel)
{
CDateTime gridCursor(m_gridStart); //reset cursor for new channel
diff --git a/xbmc/epg/GUIEPGGridContainerModel.h b/xbmc/epg/GUIEPGGridContainerModel.h
index 06e66ec..716816e 100644
--- a/xbmc/epg/GUIEPGGridContainerModel.h
+++ b/xbmc/epg/GUIEPGGridContainerModel.h
@@ -53,6 +53,7 @@ namespace EPG
void Refresh(const std::unique_ptr<CFileItemList> &items, const CDateTime &gridStart, const CDateTime &gridEnd, int iRulerUnit, int iBlocksPerPage, float fBlockSize);
void SetInvalid();

+ static const int INVALID_INDEX = -1;
void FindChannelAndBlockIndex(int channelUid, unsigned int broadcastUid, int eventOffset, int &newChannelIndex, int &newBlockIndex) const;

void FreeChannelMemory(int keepStart, int keepEnd);
diff --git a/xbmc/pvr/windows/GUIWindowPVRGuide.cpp b/xbmc/pvr/windows/GUIWindowPVRGuide.cpp
index 93e875c..2193f951 100644
--- a/xbmc/pvr/windows/GUIWindowPVRGuide.cpp
+++ b/xbmc/pvr/windows/GUIWindowPVRGuide.cpp
@@ -508,10 +508,16 @@ void CGUIWindowPVRGuide::GetViewNextItems(CFileItemList &items)

bool CGUIWindowPVRGuide::RefreshTimelineItems()
{
- if (m_bRefreshTimelineItems)
+ bool bRefreshTimelineItems;
{
+ CSingleLock lock(m_critSection);
+
+ bRefreshTimelineItems = m_bRefreshTimelineItems;
m_bRefreshTimelineItems = false;
+ }

+ if (bRefreshTimelineItems)
+ {
CGUIEPGGridContainer* epgGridContainer = GetGridControl();
if (epgGridContainer)
{
@@ -557,18 +563,11 @@ bool CGUIWindowPVRGuide::RefreshTimelineItems()
void CGUIWindowPVRGuide::GetViewTimelineItems(CFileItemList &items)
{
bool bRefresh = false;
-
{
CSingleLock lock(m_critSection);

- // group change detected reset grid coordinates and refresh grid items
if (!m_bRefreshTimelineItems && *m_cachedChannelGroup != *GetChannelGroup())
{
- CGUIEPGGridContainer* epgGridContainer = GetGridControl();
- if (!epgGridContainer)
- return;
-
- epgGridContainer->ResetCoordinates();
m_bRefreshTimelineItems = true;
bRefresh = true;
}
@@ -0,0 +1,189 @@
From 3bcba5bb2a8956ff6254f1c8308fd3215966ce84 Mon Sep 17 00:00:00 2001
From: Kai Sommerfeld <kai.sommerfeld@gmx.com>
Date: Sun, 19 Mar 2017 22:48:52 +0100
Subject: [PATCH] [PVR] Guide window: Implement asynchronous channel group
switching.

---
xbmc/pvr/windows/GUIWindowPVRGuide.cpp | 61 +++++++++++++++++++++++++---------
xbmc/pvr/windows/GUIWindowPVRGuide.h | 6 ++++
2 files changed, 52 insertions(+), 15 deletions(-)

diff --git a/xbmc/pvr/windows/GUIWindowPVRGuide.cpp b/xbmc/pvr/windows/GUIWindowPVRGuide.cpp
index 2193f951..b74cc36 100644
--- a/xbmc/pvr/windows/GUIWindowPVRGuide.cpp
+++ b/xbmc/pvr/windows/GUIWindowPVRGuide.cpp
@@ -19,6 +19,7 @@
*/

#include "ContextMenuManager.h"
+#include "dialogs/GUIDialogBusy.h"
#include "epg/GUIEPGGridContainer.h"
#include "GUIUserMessages.h"
#include "epg/EpgContainer.h"
@@ -41,8 +42,7 @@ using namespace PVR;
using namespace EPG;

CGUIWindowPVRGuide::CGUIWindowPVRGuide(bool bRadio) :
- CGUIWindowPVRBase(bRadio, bRadio ? WINDOW_RADIO_GUIDE : WINDOW_TV_GUIDE, "MyPVRGuide.xml"),
- m_cachedChannelGroup(new CPVRChannelGroup)
+ CGUIWindowPVRBase(bRadio, bRadio ? WINDOW_RADIO_GUIDE : WINDOW_TV_GUIDE, "MyPVRGuide.xml")
{
m_bRefreshTimelineItems = false;
g_EpgContainer.RegisterObserver(this);
@@ -68,15 +68,15 @@ void CGUIWindowPVRGuide::Init()
epgGridContainer->GoToNow();
}

- m_bRefreshTimelineItems = true;
StartRefreshTimelineItemsThread();
+ m_bRefreshTimelineItems = true; // force data update on window open/re-open
}

void CGUIWindowPVRGuide::ClearData()
{
{
CSingleLock lock(m_critSection);
- m_cachedChannelGroup.reset(new CPVRChannelGroup);
+ m_cachedChannelGroup.reset();
m_newTimeline.reset();
}

@@ -97,7 +97,6 @@ void CGUIWindowPVRGuide::OnInitWindow()
void CGUIWindowPVRGuide::OnDeinitWindow(int nextWindowID)
{
StopRefreshTimelineItemsThread();
- m_bRefreshTimelineItems = false;

CGUIWindowPVRBase::OnDeinitWindow(nextWindowID);
}
@@ -112,7 +111,10 @@ void CGUIWindowPVRGuide::StartRefreshTimelineItemsThread()
void CGUIWindowPVRGuide::StopRefreshTimelineItemsThread()
{
if (m_refreshTimelineItemsThread)
- m_refreshTimelineItemsThread->StopThread(false);
+ {
+ m_bRefreshTimelineItems = false;
+ m_refreshTimelineItemsThread->Stop();
+ }
}

void CGUIWindowPVRGuide::Notify(const Observable &obs, const ObservableMessage msg)
@@ -562,20 +564,22 @@ bool CGUIWindowPVRGuide::RefreshTimelineItems()

void CGUIWindowPVRGuide::GetViewTimelineItems(CFileItemList &items)
{
- bool bRefresh = false;
+ bool bRefreshTimelineItems = false;
+
{
CSingleLock lock(m_critSection);

- if (!m_bRefreshTimelineItems && *m_cachedChannelGroup != *GetChannelGroup())
+ if (m_cachedChannelGroup && *m_cachedChannelGroup != *GetChannelGroup())
{
+ // channel group change and not very first open of this window. force immediate update.
m_bRefreshTimelineItems = true;
- bRefresh = true;
+ bRefreshTimelineItems = true;
}
}

- // never call RefreshTimelineItems with locked mutex!
- if (bRefresh)
- RefreshTimelineItems();
+ // never call DoRefresh with locked mutex!
+ if (bRefreshTimelineItems)
+ m_refreshTimelineItemsThread->DoRefresh();

{
CSingleLock lock(m_critSection);
@@ -704,8 +708,23 @@ bool CGUIWindowPVRGuide::OnContextButtonDeleteTimer(CFileItem *item, CONTEXT_BUT

CPVRRefreshTimelineItemsThread::CPVRRefreshTimelineItemsThread(CGUIWindowPVRGuide *pGuideWindow)
: CThread("epg-grid-refresh-timeline-items"),
- m_pGuideWindow(pGuideWindow)
+ m_pGuideWindow(pGuideWindow),
+ m_ready(true),
+ m_done(false)
+{
+}
+
+void CPVRRefreshTimelineItemsThread::Stop()
{
+ StopThread(false);
+ m_ready.Set(); // wake up the worker thread to let it exit
+}
+
+void CPVRRefreshTimelineItemsThread::DoRefresh()
+{
+ m_ready.Set(); // wake up the worker thread
+ m_done.Reset();
+ CGUIDialogBusy::WaitOnEvent(m_done, 100, false);
}

void CPVRRefreshTimelineItemsThread::Process()
@@ -717,12 +736,19 @@ void CPVRRefreshTimelineItemsThread::Process()

while (!m_bStop)
{
+ m_done.Reset();
+
if (m_pGuideWindow->RefreshTimelineItems() && !m_bStop)
{
CGUIMessage m(GUI_MSG_REFRESH_LIST, m_pGuideWindow->GetID(), 0, ObservableMessageEpg);
KODI::MESSAGING::CApplicationMessenger::GetInstance().SendGUIMessage(m);
}

+ if (m_bStop)
+ break;
+
+ m_done.Set();
+
// in order to fill the guide window asap, use a short update interval until we the
// same amount of epg events for BOOSTED_SLEEPS_THRESHOLD + 1 times in a row .
if (iUpdatesWithoutChange < BOOSTED_SLEEPS_THRESHOLD)
@@ -736,11 +762,16 @@ void CPVRRefreshTimelineItemsThread::Process()

iLastEpgItemsCount = iCurrentEpgItemsCount;

- Sleep(1000); // boosted update cycle
+ m_ready.WaitMSec(1000); // boosted update cycle
}
else
{
- Sleep(5000); // normal update cycle
+ m_ready.WaitMSec(5000); // normal update cycle
}
+
+ m_ready.Reset();
}
+
+ m_ready.Reset();
+ m_done.Set();
}
diff --git a/xbmc/pvr/windows/GUIWindowPVRGuide.h b/xbmc/pvr/windows/GUIWindowPVRGuide.h
index d5a41fc..c4f0682 100644
--- a/xbmc/pvr/windows/GUIWindowPVRGuide.h
+++ b/xbmc/pvr/windows/GUIWindowPVRGuide.h
@@ -21,6 +21,7 @@

#include <atomic>
#include <memory>
+#include "threads/Event.h"
#include "threads/Thread.h"
#include "GUIWindowPVRBase.h"

@@ -99,7 +100,12 @@ namespace PVR

virtual void Process();

+ void DoRefresh();
+ void Stop();
+
private:
CGUIWindowPVRGuide *m_pGuideWindow;
+ CEvent m_ready;
+ CEvent m_done;
};
}

0 comments on commit 6b020da

Please sign in to comment.