diff options
-rw-r--r-- | xbmc/Application.cpp | 6 | ||||
-rw-r--r-- | xbmc/FileItem.cpp | 23 | ||||
-rw-r--r-- | xbmc/FileItem.h | 12 | ||||
-rw-r--r-- | xbmc/interfaces/AnnouncementManager.cpp | 6 | ||||
-rw-r--r-- | xbmc/interfaces/AnnouncementManager.h | 2 | ||||
-rw-r--r-- | xbmc/network/AirPlayServer.cpp | 15 | ||||
-rw-r--r-- | xbmc/network/AirPlayServer.h | 1 | ||||
-rw-r--r-- | xbmc/network/upnp/UPnPServer.cpp | 3 | ||||
-rw-r--r-- | xbmc/pvr/windows/GUIWindowPVRRecordings.cpp | 17 |
9 files changed, 65 insertions, 20 deletions
diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp index b7eaca31ec..9242d5363f 100644 --- a/xbmc/Application.cpp +++ b/xbmc/Application.cpp @@ -3555,6 +3555,8 @@ void CApplication::Stop(int exitCode) CLog::Log(LOGNOTICE, "stop player"); m_pPlayer->ClosePlayer(); + CAnnouncementManager::Deinitialize(); + StopPVRManager(); StopServices(); //Sleep(5000); @@ -4004,8 +4006,8 @@ PlayBackRet CApplication::PlayFile(const CFileItem& item, bool bRestart) should the playerState be required, it is fetched from the database. See the note in CGUIWindowVideoBase::ShowResumeMenu. */ - if (item.HasVideoInfoTag() && item.GetVideoInfoTag()->m_resumePoint.IsSet()) - options.starttime = item.GetVideoInfoTag()->m_resumePoint.timeInSeconds; + if (item.IsResumePointSet()) + options.starttime = item.GetCurrentResumeTime(); } else if (item.HasVideoInfoTag()) { diff --git a/xbmc/FileItem.cpp b/xbmc/FileItem.cpp index eb0e4a5cc4..75f70b81f9 100644 --- a/xbmc/FileItem.cpp +++ b/xbmc/FileItem.cpp @@ -3320,3 +3320,26 @@ int CFileItem::GetVideoContentType() const return type; } +bool CFileItem::IsResumePointSet() const +{ + return (HasVideoInfoTag() && GetVideoInfoTag()->m_resumePoint.IsSet()) || + (HasPVRRecordingInfoTag() && GetPVRRecordingInfoTag()->GetLastPlayedPosition() > 0); +} + +double CFileItem::GetCurrentResumeTime() const +{ + if (HasPVRRecordingInfoTag()) + { + // This will retrieve 'fresh' resume information from the PVR server + int rc = GetPVRRecordingInfoTag()->GetLastPlayedPosition(); + if (rc > 0) + return rc; + // Fall through to default value + } + if (HasVideoInfoTag() && GetVideoInfoTag()->m_resumePoint.IsSet()) + { + return GetVideoInfoTag()->m_resumePoint.timeInSeconds; + } + // Resume from start when resume points are invalid or the PVR server returns an error + return 0; +} diff --git a/xbmc/FileItem.h b/xbmc/FileItem.h index 286bd349b2..56df810036 100644 --- a/xbmc/FileItem.h +++ b/xbmc/FileItem.h @@ -295,6 +295,18 @@ public: return m_pvrTimerInfoTag; } + /*! + \brief Test if this item has a valid resume point set. + \return True if this item has a resume point and it is set, false otherwise. + */ + bool IsResumePointSet() const; + + /*! + \brief Return the current resume time. + \return The time in seconds from the start to resume playing from. + */ + double GetCurrentResumeTime() const; + inline bool HasPictureInfoTag() const { return m_pictureInfoTag != NULL; diff --git a/xbmc/interfaces/AnnouncementManager.cpp b/xbmc/interfaces/AnnouncementManager.cpp index 287f5a4715..2932e59aba 100644 --- a/xbmc/interfaces/AnnouncementManager.cpp +++ b/xbmc/interfaces/AnnouncementManager.cpp @@ -39,6 +39,12 @@ using namespace ANNOUNCEMENT; #define m_announcers XBMC_GLOBAL_USE(ANNOUNCEMENT::CAnnouncementManager::Globals).m_announcers #define m_critSection XBMC_GLOBAL_USE(ANNOUNCEMENT::CAnnouncementManager::Globals).m_critSection +void CAnnouncementManager::Deinitialize() +{ + CSingleLock lock (m_critSection); + m_announcers.clear(); +} + void CAnnouncementManager::AddAnnouncer(IAnnouncer *listener) { if (!listener) diff --git a/xbmc/interfaces/AnnouncementManager.h b/xbmc/interfaces/AnnouncementManager.h index b8f1a7b37d..6f4208d97c 100644 --- a/xbmc/interfaces/AnnouncementManager.h +++ b/xbmc/interfaces/AnnouncementManager.h @@ -38,6 +38,8 @@ namespace ANNOUNCEMENT std::vector<IAnnouncer *> m_announcers; }; + static void Deinitialize(); + static void AddAnnouncer(IAnnouncer *listener); static void RemoveAnnouncer(IAnnouncer *listener); static void Announce(AnnouncementFlag flag, const char *sender, const char *message); diff --git a/xbmc/network/AirPlayServer.cpp b/xbmc/network/AirPlayServer.cpp index 127a765985..8040d9b0d1 100644 --- a/xbmc/network/AirPlayServer.cpp +++ b/xbmc/network/AirPlayServer.cpp @@ -63,6 +63,7 @@ using namespace ANNOUNCEMENT; #define AIRPLAY_STATUS_NOT_IMPLEMENTED 501 #define AIRPLAY_STATUS_NO_RESPONSE_NEEDED 1000 +CCriticalSection CAirPlayServer::ServerInstanceLock; CAirPlayServer *CAirPlayServer::ServerInstance = NULL; int CAirPlayServer::m_isPlaying = 0; @@ -156,6 +157,8 @@ const char *eventStrings[] = {"playing", "paused", "loading", "stopped"}; void CAirPlayServer::Announce(AnnouncementFlag flag, const char *sender, const char *message, const CVariant &data) { + CSingleLock lock(ServerInstanceLock); + if ( (flag & Player) && strcmp(sender, "xbmc") == 0 && ServerInstance) { if (strcmp(message, "OnStop") == 0) @@ -184,6 +187,8 @@ bool CAirPlayServer::StartServer(int port, bool nonlocal) { StopServer(true); + CSingleLock lock(ServerInstanceLock); + ServerInstance = new CAirPlayServer(port, nonlocal); if (ServerInstance->Initialize()) { @@ -196,6 +201,7 @@ bool CAirPlayServer::StartServer(int port, bool nonlocal) bool CAirPlayServer::SetCredentials(bool usePassword, const CStdString& password) { + CSingleLock lock(ServerInstanceLock); bool ret = false; if (ServerInstance) @@ -214,6 +220,7 @@ bool CAirPlayServer::SetInternalCredentials(bool usePassword, const CStdString& void CAirPlayServer::StopServer(bool bWait) { + CSingleLock lock(ServerInstanceLock); if (ServerInstance) { ServerInstance->StopThread(bWait); @@ -694,13 +701,17 @@ bool CAirPlayServer::CTCPClient::checkAuthorization(const CStdString& authStr, void CAirPlayServer::backupVolume() { - if (ServerInstance->m_origVolume == -1) + CSingleLock lock(ServerInstanceLock); + + if (ServerInstance && ServerInstance->m_origVolume == -1) ServerInstance->m_origVolume = (int)g_application.GetVolume(); } void CAirPlayServer::restoreVolume() { - if (ServerInstance->m_origVolume != -1 && CSettings::Get().GetBool("services.airplayvolumecontrol")) + CSingleLock lock(ServerInstanceLock); + + if (ServerInstance && ServerInstance->m_origVolume != -1 && CSettings::Get().GetBool("services.airplayvolumecontrol")) { g_application.SetVolume((float)ServerInstance->m_origVolume); ServerInstance->m_origVolume = -1; diff --git a/xbmc/network/AirPlayServer.h b/xbmc/network/AirPlayServer.h index 4c486fbff8..27c7f40b2d 100644 --- a/xbmc/network/AirPlayServer.h +++ b/xbmc/network/AirPlayServer.h @@ -112,6 +112,7 @@ private: CStdString m_password; int m_origVolume; + static CCriticalSection ServerInstanceLock; static CAirPlayServer *ServerInstance; }; diff --git a/xbmc/network/upnp/UPnPServer.cpp b/xbmc/network/upnp/UPnPServer.cpp index 49a21c4fa1..4fd42af4fc 100644 --- a/xbmc/network/upnp/UPnPServer.cpp +++ b/xbmc/network/upnp/UPnPServer.cpp @@ -755,7 +755,8 @@ CUPnPServer::BuildResponse(PLT_ActionReference& action, // this isn't pretty but needed to properly hide the addons node from clients if (StringUtils::StartsWith(items.GetPath(), "library")) { for (int i=0; i<items.Size(); i++) { - if (StringUtils::StartsWith(items[i]->GetPath(), "addons")) + if (StringUtils::StartsWith(items[i]->GetPath(), "addons") || + StringUtils::EndsWith(items[i]->GetPath(), "/addons.xml/")) items.Remove(i); } } diff --git a/xbmc/pvr/windows/GUIWindowPVRRecordings.cpp b/xbmc/pvr/windows/GUIWindowPVRRecordings.cpp index feb39008de..573b46493f 100644 --- a/xbmc/pvr/windows/GUIWindowPVRRecordings.cpp +++ b/xbmc/pvr/windows/GUIWindowPVRRecordings.cpp @@ -70,21 +70,8 @@ CStdString CGUIWindowPVRRecordings::GetResumeString(const CFileItem& item) // First try to find the resume position on the back-end, if that fails use video database int positionInSeconds = item.GetPVRRecordingInfoTag()->GetLastPlayedPosition(); - // If the back-end does report a saved position then make sure there is a corresponding resume bookmark - if (positionInSeconds > 0) - { - CBookmark bookmark; - bookmark.timeInSeconds = positionInSeconds; - bookmark.totalTimeInSeconds = (double)item.GetPVRRecordingInfoTag()->GetDuration(); - CVideoDatabase db; - if (db.Open()) - { - CStdString itemPath(item.GetPVRRecordingInfoTag()->m_strFileNameAndPath); - db.AddBookMarkToFile(itemPath, bookmark, CBookmark::RESUME); - db.Close(); - } - } - else if (positionInSeconds < 0) + // If the back-end does report a saved position it will be picked up by FileItem + if (positionInSeconds < 0) { CVideoDatabase db; if (db.Open()) |