Skip to content

Commit

Permalink
[pvr] changed: instead of having a recording id set for epg tags, hav…
Browse files Browse the repository at this point in the history
…e an epg id set for recordings

epg tags are only refreshed based on a timeout, or when an update is forced
fixes playing recordings in progress from the timeline
  • Loading branch information
opdenkamp committed Mar 5, 2015
1 parent 8d9754b commit 5f76e32
Show file tree
Hide file tree
Showing 13 changed files with 97 additions and 74 deletions.
1 change: 0 additions & 1 deletion xbmc/addons/include/xbmc_epg_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,6 @@ extern "C" {
int iEpisodeNumber; /*!< @brief (optional) episode number */
int iEpisodePartNumber; /*!< @brief (optional) episode part number */
const char * strEpisodeName; /*!< @brief (optional) episode name */
const char * strRecordingId; /*!< @brief (optional) unique id of the recording on the client which represents this event */
} ATTRIBUTE_PACKED EPG_TAG;

#ifdef __cplusplus
Expand Down
5 changes: 3 additions & 2 deletions xbmc/addons/include/xbmc_pvr_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,10 @@ struct DemuxPacket;
#define PVR_STREAM_MAX_STREAMS 20

/* current PVR API version */
#define XBMC_PVR_API_VERSION "1.9.4"
#define XBMC_PVR_API_VERSION "1.9.5"

/* min. PVR API version */
#define XBMC_PVR_MIN_API_VERSION "1.9.4"
#define XBMC_PVR_MIN_API_VERSION "1.9.5"

#ifdef __cplusplus
extern "C" {
Expand Down Expand Up @@ -299,6 +299,7 @@ extern "C" {
int iPlayCount; /*!< @brief (optional) play count of this recording on the client */
int iLastPlayedPosition; /*!< @brief (optional) last played position of this recording on the client */
bool bIsDeleted; /*!< @brief (optional) shows this recording is deleted and can be undelete */
unsigned int iEpgEventId; /*!< @brief (optional) EPG event id associated with this recording */
} ATTRIBUTE_PACKED PVR_RECORDING;

/*!
Expand Down
31 changes: 11 additions & 20 deletions xbmc/epg/Epg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,17 @@ CEpgInfoTagPtr CEpg::GetTag(const CDateTime &StartTime) const
return CEpgInfoTagPtr();
}

CEpgInfoTagPtr CEpg::GetTag(int uniqueID) const
{
CEpgInfoTagPtr retval;
CSingleLock lock(m_critSection);
for (map<CDateTime, CEpgInfoTagPtr>::const_iterator it = m_tags.begin(); !retval && it != m_tags.end(); ++it)
if (it->second->UniqueBroadcastID() == uniqueID)
retval = it->second;

return retval;
}

CEpgInfoTagPtr CEpg::GetTagBetween(const CDateTime &beginTime, const CDateTime &endTime) const
{
CSingleLock lock(m_critSection);
Expand Down Expand Up @@ -303,7 +314,6 @@ void CEpg::AddEntry(const CEpgInfoTag &tag)
newTag->Update(tag);
newTag->SetPVRChannel(m_pvrChannel);
newTag->SetEpg(this);
UpdateRecording(newTag);
}
}

Expand All @@ -329,32 +339,13 @@ bool CEpg::UpdateEntry(const CEpgInfoTag &tag, bool bUpdateDatabase /* = false *
infoTag->Update(tag, bNewTag);
infoTag->SetEpg(this);
infoTag->SetPVRChannel(m_pvrChannel);
UpdateRecording(infoTag);

if (bUpdateDatabase)
m_changedTags.insert(make_pair(infoTag->UniqueBroadcastID(), infoTag));

return true;
}

void CEpg::UpdateRecording(CEpgInfoTagPtr &tag)
{
if (!tag)
return;

if (tag->HasPVRChannel() && tag->HasRecordingId())
{
CPVRRecordingPtr recording = g_PVRRecordings->GetById(tag->ChannelTag()->ClientID(), tag->RecordingId());
if (recording)
{
tag->SetRecording(recording);
return;
}
}

tag->ClearRecording();
}

bool CEpg::Load(void)
{
bool bReturn(false);
Expand Down
17 changes: 12 additions & 5 deletions xbmc/epg/Epg.h
Original file line number Diff line number Diff line change
Expand Up @@ -191,16 +191,25 @@ namespace EPG
CEpgInfoTagPtr GetTagBetween(const CDateTime &beginTime, const CDateTime &endTime) const;

/*!
* @brief Get the infotag with the given ID.
* @brief Get the infotag with the given begin time.
*
* Get the infotag with the given ID.
* If it wasn't found, try finding the event with the given start time
*
* @param uniqueID The unique ID of the event to find.
* @param beginTime The start time in UTC of the event to find if it wasn't found by it's unique ID.
* @return The found tag or NULL if it wasn't found.
* @return The found tag or an empty tag if it wasn't found.
*/
CEpgInfoTagPtr GetTag(const CDateTime &beginTime) const;
/*!
* @brief Get the infotag with the given ID.
*
* Get the infotag with the given ID.
* If it wasn't found, try finding the event with the given start time
*
* @param uniqueID The unique ID of the event to find.
* @return The found tag or an empty tag if it wasn't found.
*/
CEpgInfoTagPtr GetTag(int uniqueID) const;

/*!
* @brief Update an entry in this EPG.
Expand Down Expand Up @@ -339,8 +348,6 @@ namespace EPG

bool IsRemovableTag(const EPG::CEpgInfoTag &tag) const;

void UpdateRecording(CEpgInfoTagPtr &tag);

std::map<CDateTime, CEpgInfoTagPtr> m_tags;
std::map<int, CEpgInfoTagPtr> m_changedTags;
std::map<int, CEpgInfoTagPtr> m_deletedTags;
Expand Down
22 changes: 19 additions & 3 deletions xbmc/epg/EpgContainer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include "utils/log.h"
#include "pvr/PVRManager.h"
#include "pvr/channels/PVRChannelGroupsContainer.h"
#include "pvr/recordings/PVRRecordings.h"
#include "pvr/timers/PVRTimers.h"

#include "EpgContainer.h"
Expand Down Expand Up @@ -146,6 +147,8 @@ void CEpgContainer::Start(void)
}

LoadFromDB();
if (g_PVRManager.IsStarted())
g_PVRManager.Recordings()->UpdateEpgTags();

CSingleLock lock(m_critSection);
if (!m_bStop)
Expand Down Expand Up @@ -339,6 +342,15 @@ CEpg *CEpgContainer::GetById(int iEpgId) const
return it != m_epgs.end() ? it->second : NULL;
}

CEpgInfoTagPtr CEpgContainer::GetTagById(int iBroadcastId) const
{
CEpgInfoTagPtr retval;
CSingleLock lock(m_critSection);
for (map<unsigned int, CEpg *>::const_iterator it = m_epgs.begin(); !retval && it != m_epgs.end(); ++it)
retval = it->second->GetTag(iBroadcastId);
return retval;
}

CEpg *CEpgContainer::GetByChannel(const CPVRChannel &channel) const
{
CSingleLock lock(m_critSection);
Expand Down Expand Up @@ -550,9 +562,13 @@ bool CEpgContainer::UpdateEPG(bool bOnlyPending /* = false */)
{
CLog::Log(LOGERROR, "EpgContainer - %s - could not open the database", __FUNCTION__);

CSingleLock lock(m_critSection);
m_bIsUpdating = false;
m_updateEvent.Set();
{
CSingleLock lock(m_critSection);
m_bIsUpdating = false;
m_updateEvent.Set();
}

g_PVRManager.Recordings()->UpdateEpgTags();

if (bShowProgress && !bOnlyPending)
CloseProgressDialog();
Expand Down
7 changes: 7 additions & 0 deletions xbmc/epg/EpgContainer.h
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,13 @@ namespace EPG
*/
virtual CEpg *GetById(int iEpgId) const;

/*!
* @brief Get the EPG event with the given event id
* @param iBroadcastId The event id to get
* @return The requested event, or an empty tag when not found
*/
virtual CEpgInfoTagPtr GetTagById(int iBroadcastId) const;

/*!
* @brief Get an EPG table given a PVR channel.
* @param channel The channel to get the EPG table for.
Expand Down
19 changes: 7 additions & 12 deletions xbmc/epg/EpgDatabase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,7 @@ void CEpgDatabase::CreateTables(void)
"iSeriesId integer, "
"iEpisodeId integer, "
"iEpisodePart integer, "
"sEpisodeName varchar(128), "
"sRecordingId varchar(128)"
"sEpisodeName varchar(128)"
")"
);
CLog::Log(LOGDEBUG, "EpgDB - %s - creating table 'lastepgscan'", __FUNCTION__);
Expand All @@ -98,9 +97,6 @@ void CEpgDatabase::UpdateTables(int iVersion)
if (iVersion < 5)
m_pDS->exec("ALTER TABLE epgtags ADD sGenre varchar(128);");

if (iVersion < 8)
m_pDS->exec("ALTER TABLE epgtags ADD sRecordingId varchar(128);");

if (iVersion < 9)
m_pDS->exec("ALTER TABLE epgtags ADD sIconPath varchar(255);");
}
Expand Down Expand Up @@ -231,7 +227,6 @@ int CEpgDatabase::Get(CEpg &epg)
newTag->m_iEpisodePart = m_pDS->fv("iEpisodePart").get_asInt();
newTag->m_strEpisodeName = m_pDS->fv("sEpisodeName").get_asString().c_str();
newTag->m_iSeriesNumber = m_pDS->fv("iSeriesId").get_asInt();
newTag->m_strRecordingId = m_pDS->fv("sRecordingId").get_asString().c_str();
newTag->m_strIconPath = m_pDS->fv("sIconPath").get_asString().c_str();

epg.AddEntry(*newTag);
Expand Down Expand Up @@ -340,26 +335,26 @@ int CEpgDatabase::Persist(const CEpgInfoTag &tag, bool bSingleUpdate /* = true *
strQuery = PrepareSQL("REPLACE INTO epgtags (idEpg, iStartTime, "
"iEndTime, sTitle, sPlotOutline, sPlot, sIconPath, iGenreType, iGenreSubType, sGenre, "
"iFirstAired, iParentalRating, iStarRating, bNotify, iSeriesId, "
"iEpisodeId, iEpisodePart, sEpisodeName, iBroadcastUid, sRecordingId) "
"VALUES (%u, %u, %u, '%s', '%s', '%s', '%s', %i, %i, '%s', %u, %i, %i, %i, %i, %i, %i, '%s', %i, '%s');",
"iEpisodeId, iEpisodePart, sEpisodeName, iBroadcastUid) "
"VALUES (%u, %u, %u, '%s', '%s', '%s', '%s', %i, %i, '%s', %u, %i, %i, %i, %i, %i, %i, '%s', %i);",
tag.EpgID(), iStartTime, iEndTime,
tag.Title(true).c_str(), tag.PlotOutline(true).c_str(), tag.Plot(true).c_str(), tag.Icon().c_str(), tag.GenreType(), tag.GenreSubType(), strGenre.c_str(),
iFirstAired, tag.ParentalRating(), tag.StarRating(), tag.Notify(),
tag.SeriesNumber(), tag.EpisodeNumber(), tag.EpisodePart(), tag.EpisodeName().c_str(),
tag.UniqueBroadcastID(), tag.RecordingId().c_str());
tag.UniqueBroadcastID());
}
else
{
strQuery = PrepareSQL("REPLACE INTO epgtags (idEpg, iStartTime, "
"iEndTime, sTitle, sPlotOutline, sPlot, sIconPath, iGenreType, iGenreSubType, sGenre, "
"iFirstAired, iParentalRating, iStarRating, bNotify, iSeriesId, "
"iEpisodeId, iEpisodePart, sEpisodeName, iBroadcastUid, idBroadcast, sRecordingId) "
"VALUES (%u, %u, %u, '%s', '%s', '%s', '%s', %i, %i, '%s', %u, %i, %i, %i, %i, %i, %i, '%s', %i, %i, '%s');",
"iEpisodeId, iEpisodePart, sEpisodeName, iBroadcastUid, idBroadcast) "
"VALUES (%u, %u, %u, '%s', '%s', '%s', '%s', %i, %i, '%s', %u, %i, %i, %i, %i, %i, %i, '%s', %i, %i);",
tag.EpgID(), iStartTime, iEndTime,
tag.Title(true).c_str(), tag.PlotOutline(true).c_str(), tag.Plot(true).c_str(), tag.Icon().c_str(), tag.GenreType(), tag.GenreSubType(), strGenre.c_str(),
iFirstAired, tag.ParentalRating(), tag.StarRating(), tag.Notify(),
tag.SeriesNumber(), tag.EpisodeNumber(), tag.EpisodePart(), tag.EpisodeName().c_str(),
tag.UniqueBroadcastID(), iBroadcastId, tag.RecordingId().c_str());
tag.UniqueBroadcastID(), iBroadcastId);
}

if (bSingleUpdate)
Expand Down
18 changes: 1 addition & 17 deletions xbmc/epg/EpgInfoTag.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,6 @@ CEpgInfoTag::CEpgInfoTag(const EPG_TAG &data) :
m_strEpisodeName = data.strEpisodeName;
if (data.strIconPath)
m_strIconPath = data.strIconPath;
if (data.strRecordingId)
m_strRecordingId = data.strRecordingId;

UpdatePath();
}
Expand Down Expand Up @@ -149,8 +147,7 @@ bool CEpgInfoTag::operator ==(const CEpgInfoTag& right) const
m_strFileNameAndPath == right.m_strFileNameAndPath &&
m_startTime == right.m_startTime &&
m_endTime == right.m_endTime &&
m_pvrChannel == right.m_pvrChannel &&
m_strRecordingId == right.m_strRecordingId);
m_pvrChannel == right.m_pvrChannel);
}

bool CEpgInfoTag::operator !=(const CEpgInfoTag& right) const
Expand Down Expand Up @@ -180,7 +177,6 @@ void CEpgInfoTag::Serialize(CVariant &value) const
value["episodenum"] = m_iEpisodeNumber;
value["episodepart"] = m_iEpisodePart;
value["hastimer"] = HasTimer();
value["recordingid"] = m_strRecordingId;
value["hasrecording"] = HasRecording();
value["isactive"] = IsActive();
value["wasactive"] = WasActive();
Expand Down Expand Up @@ -442,16 +438,6 @@ std::string CEpgInfoTag::Path(void) const
return m_strFileNameAndPath;
}

const std::string& CEpgInfoTag::RecordingId(void) const
{
return m_strRecordingId;
}

bool CEpgInfoTag::HasRecordingId(void) const
{
return !m_strRecordingId.empty();
}

bool CEpgInfoTag::HasTimer(void) const
{
return m_timer != NULL;
Expand Down Expand Up @@ -514,7 +500,6 @@ bool CEpgInfoTag::Update(const CEpgInfoTag &tag, bool bUpdateBroadcastId /* = tr
EpgID() != tag.EpgID() ||
m_pvrChannel != tag.m_pvrChannel ||
m_genre != tag.m_genre ||
m_strRecordingId != tag.m_strRecordingId ||
m_strIconPath != tag.m_strIconPath
);
if (bUpdateBroadcastId)
Expand Down Expand Up @@ -553,7 +538,6 @@ bool CEpgInfoTag::Update(const CEpgInfoTag &tag, bool bUpdateBroadcastId /* = tr
m_iSeriesNumber = tag.m_iSeriesNumber;
m_strEpisodeName = tag.m_strEpisodeName;
m_iUniqueBroadcastID = tag.m_iUniqueBroadcastID;
m_strRecordingId = tag.m_strRecordingId;
m_strIconPath = tag.m_strIconPath;
}
}
Expand Down
13 changes: 0 additions & 13 deletions xbmc/epg/EpgInfoTag.h
Original file line number Diff line number Diff line change
Expand Up @@ -284,18 +284,6 @@ namespace EPG
*/
std::string Path(void) const;

/*!
* @brief The recording ID to this event.
* @return The recording ID.
*/
const std::string& RecordingId(void) const;

/*!
* @brief Check whether this event has a recording ID.
* @return True if it has a recording ID, false if not.
*/
bool HasRecordingId(void) const;

/*!
* @brief Set a timer for this event or NULL to clear it.
* @param newTimer The new timer value.
Expand Down Expand Up @@ -414,7 +402,6 @@ namespace EPG
CDateTime m_startTime; /*!< event start time */
CDateTime m_endTime; /*!< event end time */
CDateTime m_firstAired; /*!< first airdate */
std::string m_strRecordingId; /*!< linked recording ID */

PVR::CPVRTimerInfoTagPtr m_timer;
PVR::CPVRRecordingPtr m_recording;
Expand Down
7 changes: 6 additions & 1 deletion xbmc/pvr/recordings/PVRRecording.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ CPVRRecording::CPVRRecording(const PVR_RECORDING &recording, unsigned int iClien
m_strThumbnailPath = recording.strThumbnailPath;
m_strFanartPath = recording.strFanartPath;
m_bIsDeleted = recording.bIsDeleted;
m_iEpgEventId = recording.iEpgEventId;
}

bool CPVRRecording::operator ==(const CPVRRecording& right) const
Expand All @@ -127,7 +128,8 @@ bool CPVRRecording::operator ==(const CPVRRecording& right) const
m_strThumbnailPath == right.m_strThumbnailPath &&
m_strFanartPath == right.m_strFanartPath &&
m_iRecordingId == right.m_iRecordingId &&
m_bIsDeleted == right.m_bIsDeleted);
m_bIsDeleted == right.m_bIsDeleted &&
m_iEpgEventId == right.m_iEpgEventId);
}

bool CPVRRecording::operator !=(const CPVRRecording& right) const
Expand All @@ -149,6 +151,7 @@ void CPVRRecording::Serialize(CVariant& value) const
value["endtime"] = m_recordingTime.IsValid() ? (m_recordingTime + m_duration).GetAsDBDateTime() : "";
value["recordingid"] = m_iRecordingId;
value["deleted"] = m_bIsDeleted;
value["epgevent"] = m_iEpgEventId;

if (!value.isMember("art"))
value["art"] = CVariant(CVariant::VariantTypeObject);
Expand All @@ -174,6 +177,7 @@ void CPVRRecording::Reset(void)
m_bGotMetaData = false;
m_iRecordingId = 0;
m_bIsDeleted = false;
m_iEpgEventId = -1;

m_recordingTime.Reset();
CVideoInfoTag::Reset();
Expand Down Expand Up @@ -333,6 +337,7 @@ void CPVRRecording::Update(const CPVRRecording &tag)
m_strThumbnailPath = tag.m_strThumbnailPath;
m_strFanartPath = tag.m_strFanartPath;
m_bIsDeleted = tag.m_bIsDeleted;
m_iEpgEventId = tag.m_iEpgEventId;

if (g_PVRClients->SupportsRecordingPlayCount(m_iClientId))
m_playCount = tag.m_playCount;
Expand Down
6 changes: 6 additions & 0 deletions xbmc/pvr/recordings/PVRRecording.h
Original file line number Diff line number Diff line change
Expand Up @@ -198,10 +198,16 @@ namespace PVR
*/
bool IsDeleted() const { return m_bIsDeleted; }

/*!
* @return Broadcast id of the EPG event associated with this recording
*/
int EpgEvent(void) const { return m_iEpgEventId; }

private:
CDateTime m_recordingTime; /*!< start time of the recording */
bool m_bGotMetaData;
bool m_bIsDeleted; /*!< set if entry is a deleted recording which can be undelete */
int m_iEpgEventId; /*!< epg broadcast id associated with this recording */

void UpdatePath(void);
void DisplayError(PVR_ERROR err) const;
Expand Down
Loading

0 comments on commit 5f76e32

Please sign in to comment.