aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjanbar <jlbarriere68@gmail.com>2015-10-17 14:08:06 +0200
committerjanbar <jlbarriere68@gmail.com>2015-10-20 17:42:41 +0200
commit2d09701ddfd168cc4b58d857a4aaa0f6e839f422 (patch)
tree54923b92a546f7b981d099b812ee28d09bf4e991
parent4f0c05987df97f1ae4c36804eb35a9dcb466050f (diff)
[PVR] Improve epg association by broadcast ID
Using a new map 'm_epgEvents' which is updated when receiving a new event and for new scanned EPG.
-rw-r--r--xbmc/epg/Epg.cpp14
-rw-r--r--xbmc/epg/Epg.h7
-rw-r--r--xbmc/epg/EpgContainer.cpp74
-rw-r--r--xbmc/epg/EpgContainer.h11
4 files changed, 104 insertions, 2 deletions
diff --git a/xbmc/epg/Epg.cpp b/xbmc/epg/Epg.cpp
index 0e20c98099..b43862f511 100644
--- a/xbmc/epg/Epg.cpp
+++ b/xbmc/epg/Epg.cpp
@@ -402,6 +402,7 @@ bool CEpg::UpdateEntries(const CEpg &epg, bool bStoreInDb /* = true */)
m_lastScanTime = CDateTime::GetCurrentDateTime().GetAsUTCDateTime();
m_bUpdateLastScanTime = true;
+ SetChanged(true);
NotifyObservers(ObservableMessageEpg);
return true;
@@ -864,3 +865,16 @@ bool CEpg::IsValid(void) const
return m_pvrChannel != NULL;
return true;
}
+
+std::vector<CEpgInfoTagPtr> CEpg::GetAllEventsWithBroadcastId() const
+{
+ CSingleLock lock(m_critSection);
+ std::vector<CEpgInfoTagPtr> events;
+ events.reserve(m_tags.size());
+ for (const auto &infoTag : m_tags)
+ {
+ if (infoTag.second->UniqueBroadcastID())
+ events.push_back(infoTag.second);
+ }
+ return events;
+}
diff --git a/xbmc/epg/Epg.h b/xbmc/epg/Epg.h
index 9fa0505ec0..7665cb4ab4 100644
--- a/xbmc/epg/Epg.h
+++ b/xbmc/epg/Epg.h
@@ -309,6 +309,13 @@ namespace EPG
* @return True when this EPG is valid and can be updated, false otherwise.
*/
bool IsValid(void) const;
+
+ /*!
+ * @brief Get all events with a valid broadcast Id
+ * @return the table of events
+ */
+ std::vector<CEpgInfoTagPtr> GetAllEventsWithBroadcastId() const;
+
protected:
CEpg(void);
diff --git a/xbmc/epg/EpgContainer.cpp b/xbmc/epg/EpgContainer.cpp
index a25238f935..e32759c9ef 100644
--- a/xbmc/epg/EpgContainer.cpp
+++ b/xbmc/epg/EpgContainer.cpp
@@ -109,6 +109,8 @@ void CEpgContainer::Clear(bool bClearDb /* = false */)
{
epgEntry.second->UnregisterObserver(this);
}
+ m_epgEvents.clear();
+ m_epgScans.clear();
m_epgs.clear();
m_iNextEpgUpdate = 0;
m_bStarted = false;
@@ -207,6 +209,8 @@ bool CEpgContainer::Stop(void)
void CEpgContainer::Notify(const Observable &obs, const ObservableMessage msg)
{
+ if (msg == ObservableMessageEpg)
+ UpdateEpgEvents();
SetChanged();
NotifyObservers(msg);
}
@@ -389,8 +393,9 @@ CEpgInfoTagPtr CEpgContainer::GetTagById(unsigned int iBroadcastId) const
{
CEpgInfoTagPtr retval;
CSingleLock lock(m_critSection);
- for (EPGMAP::const_iterator it = m_epgs.begin(); !retval && it != m_epgs.end(); ++it)
- retval = it->second->GetTag(iBroadcastId);
+ const auto &infoTag = m_epgEvents.find(iBroadcastId);
+ if (infoTag != m_epgEvents.end())
+ retval = infoTag->second;
return retval;
}
@@ -513,6 +518,7 @@ bool CEpgContainer::DeleteEpg(const CEpg &epg, bool bDeleteFromDatabase /* = fal
m_database.Delete(*epgEntry->second);
epgEntry->second->UnregisterObserver(this);
+ CleanupEpgEvents(epgEntry->second);
m_epgs.erase(epgEntry);
return true;
@@ -811,3 +817,67 @@ void CEpgContainer::UpdateRequest(int clientID, unsigned int channelID)
request.channelID = channelID;
m_updateRequests.push_back(request);
}
+
+void CEpgContainer::UpdateEpgEvents()
+{
+ CLog::Log(LOGDEBUG, "EPGContainer - %s", __FUNCTION__);
+ CSingleLock lock(m_critSection);
+ CDateTime now = CDateTime::GetUTCDateTime();
+ int count = 0;
+
+ // Purge old events from the map with daily frequency and in according with EPG setting 'LingerTime'
+ if (!m_lastEpgEventPurge.IsValid() || m_lastEpgEventPurge < (now - CDateTimeSpan(1,0,0,0)))
+ {
+ CDateTime purgeTime = now - CDateTimeSpan(0, g_advancedSettings.m_iEpgLingerTime / 60, g_advancedSettings.m_iEpgLingerTime % 60, 0);
+ for (auto event = m_epgEvents.begin(); event != m_epgEvents.end(); ++event)
+ {
+ if (event->second->EndAsUTC() < purgeTime)
+ {
+ m_epgEvents.erase(event);
+ ++count;
+ }
+ }
+ m_lastEpgEventPurge = now;
+ CLog::Log(LOGDEBUG, "EPGContainer - %s - %d item(s) purged", __FUNCTION__, count);
+ }
+
+ // Fill updated entries
+ count = 0;
+ for (const auto &epgEntry : m_epgs)
+ {
+ if (!epgEntry.second->IsValid())
+ continue;
+
+ int epgId = epgEntry.second->EpgID();
+ CDateTime epgScanTime = epgEntry.second->GetLastScanTime();
+
+ const auto &scan = m_epgScans.find(epgId);
+ if (scan != m_epgScans.end() && scan->second == epgScanTime)
+ continue;
+
+ if (scan == m_epgScans.end())
+ m_epgScans.insert(std::make_pair(epgId, epgScanTime));
+ else
+ scan->second = epgScanTime;
+
+ auto events = epgEntry.second->GetAllEventsWithBroadcastId();
+ for (const auto &infoTag : events)
+ {
+ m_epgEvents[infoTag->UniqueBroadcastID()] = infoTag;
+ ++count;
+ }
+ }
+ CLog::Log(LOGDEBUG, "EPGContainer - %s - %d item(s) updated", __FUNCTION__, count);
+}
+
+void CEpgContainer::CleanupEpgEvents(const CEpgPtr& epg)
+{
+ CSingleLock lock(m_critSection);
+ if (epg)
+ {
+ m_epgScans.erase(epg->EpgID());
+ auto events = epg->GetAllEventsWithBroadcastId();
+ for (const auto &infoTag : events)
+ m_epgEvents.erase(infoTag->UniqueBroadcastID());
+ }
+}
diff --git a/xbmc/epg/EpgContainer.h b/xbmc/epg/EpgContainer.h
index 7c0c9c4249..43dc44dc5b 100644
--- a/xbmc/epg/EpgContainer.h
+++ b/xbmc/epg/EpgContainer.h
@@ -292,6 +292,13 @@ namespace EPG
void InsertFromDatabase(int iEpgID, const std::string &strName, const std::string &strScraperName);
+ /*!
+ * @brief Update map of epg events
+ */
+ void UpdateEpgEvents();
+
+ void CleanupEpgEvents(const CEpgPtr& epg);
+
CEpgDatabase m_database; /*!< the EPG database */
/** @name Configuration */
@@ -323,5 +330,9 @@ namespace EPG
std::list<SUpdateRequest> m_updateRequests; /*!< list of update requests triggered by addon*/
CCriticalSection m_updateRequestsLock; /*!< protect update requests*/
+
+ std::map<unsigned int, CEpgInfoTagPtr> m_epgEvents; /*!< map of EPG events by unique broadcast Id*/
+ std::map<unsigned int, CDateTime> m_epgScans; /*!< map of last scan time by EPG Id*/
+ CDateTime m_lastEpgEventPurge; /*!< when the last purge has been processed*/
};
}