From 572f64b4fb2918e63c76800227eef713ab4ea8e6 Mon Sep 17 00:00:00 2001 From: Arne Morten Kvarving Date: Thu, 17 Apr 2014 00:12:29 +0200 Subject: [PATCH 01/12] added: ability to grab all chapter name and chapter positions from players --- xbmc/ApplicationPlayer.cpp | 14 +++++++-- xbmc/ApplicationPlayer.h | 3 +- xbmc/cores/IPlayer.h | 3 +- xbmc/cores/dvdplayer/DVDDemuxers/DVDDemux.h | 12 +++++-- .../dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp | 15 +++++++-- .../dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h | 3 +- xbmc/cores/dvdplayer/DVDPlayer.cpp | 31 ++++++++++++++++--- xbmc/cores/dvdplayer/DVDPlayer.h | 11 +++---- 8 files changed, 72 insertions(+), 20 deletions(-) diff --git a/xbmc/ApplicationPlayer.cpp b/xbmc/ApplicationPlayer.cpp index 15a3241713621..1f33a5e0a8a17 100644 --- a/xbmc/ApplicationPlayer.cpp +++ b/xbmc/ApplicationPlayer.cpp @@ -131,11 +131,21 @@ int CApplicationPlayer::GetChapterCount() return 0; } -void CApplicationPlayer::GetChapterName(std::string& strChapterName) +void CApplicationPlayer::GetChapterName(std::string& strChapterName, + int chapterIdx) { std::shared_ptr player = GetInternal(); if (player) - player->GetChapterName(strChapterName); + player->GetChapterName(strChapterName, chapterIdx); +} + +int64_t CApplicationPlayer::GetChapterPos(int chapterIdx) +{ + std::shared_ptr player = GetInternal(); + if (player) + return player->GetChapterPos(chapterIdx); + + return -1; } bool CApplicationPlayer::HasAudio() const diff --git a/xbmc/ApplicationPlayer.h b/xbmc/ApplicationPlayer.h index eea702ac21fa4..6242129a3c4bb 100644 --- a/xbmc/ApplicationPlayer.h +++ b/xbmc/ApplicationPlayer.h @@ -94,7 +94,8 @@ class CApplicationPlayer float GetCachePercentage() const; int GetChapterCount(); int GetChapter(); - void GetChapterName(std::string& strChapterName); + void GetChapterName(std::string& strChapterName, int chapterIdx=-1); + int64_t GetChapterPos(int chapterIdx=-1); void GetDeinterlaceMethods(std::vector &deinterlaceMethods); void GetDeinterlaceModes(std::vector &deinterlaceModes); void GetGeneralInfo(std::string& strVideoInfo); diff --git a/xbmc/cores/IPlayer.h b/xbmc/cores/IPlayer.h index 29705d951b689..1ca0b87094323 100644 --- a/xbmc/cores/IPlayer.h +++ b/xbmc/cores/IPlayer.h @@ -181,7 +181,8 @@ class IPlayer virtual int GetChapterCount() { return 0; } virtual int GetChapter() { return -1; } - virtual void GetChapterName(std::string& strChapterName) { return; } + virtual void GetChapterName(std::string& strChapterName, int chapterIdx = -1) { return; } + virtual int64_t GetChapterPos(int chapterIdx=-1) { return 0; } virtual int SeekChapter(int iChapter) { return -1; } // virtual bool GetChapterInfo(int chapter, SChapterInfo &info) { return false; } diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemux.h b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemux.h index d69991ea5b02f..fca164d60184d 100644 --- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemux.h +++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemux.h @@ -275,9 +275,17 @@ class CDVDDemux virtual int GetChapter() { return 0; } /* - * Get the name of the current chapter + * Get the name of a chapter + * \param strChapterName[out] Name of chapter + * \param chapterIdx -1 for current chapter, else a chapter index */ - virtual void GetChapterName(std::string& strChapterName) {} + virtual void GetChapterName(std::string& strChapterName, int chapterIdx=-1) {} + + /* + * Get the position of a chapter + * \param chapterIdx -1 for current chapter, else a chapter index + */ + virtual int64_t GetChapterPos(int chapterIdx=-1) { return 0; } /* * Set the playspeed, if demuxer can handle different diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp index 1315117125680..f051b4677fbbd 100644 --- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp +++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp @@ -1401,14 +1401,15 @@ int CDVDDemuxFFmpeg::GetChapter() return 0; } -void CDVDDemuxFFmpeg::GetChapterName(std::string& strChapterName) +void CDVDDemuxFFmpeg::GetChapterName(std::string& strChapterName, int chapterIdx) { + if (chapterIdx <= 0 || chapterIdx > GetChapterCount()) + chapterIdx = GetChapter(); CDVDInputStream::IChapter* ich = dynamic_cast(m_pInput); if(ich) ich->GetChapterName(strChapterName); else { - int chapterIdx = GetChapter(); if(chapterIdx <= 0) return; @@ -1419,6 +1420,16 @@ void CDVDDemuxFFmpeg::GetChapterName(std::string& strChapterName) } } +int64_t CDVDDemuxFFmpeg::GetChapterPos(int chapterIdx) +{ + if (chapterIdx <= 0 || chapterIdx > GetChapterCount()) + chapterIdx = GetChapter(); + if(chapterIdx <= 0) + return 0; + + return m_pFormatContext->chapters[chapterIdx-1]->start*av_q2d(m_pFormatContext->chapters[chapterIdx-1]->time_base); +} + bool CDVDDemuxFFmpeg::SeekChapter(int chapter, double* startpts) { if(chapter < 1) diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h index bb64a2f2bfa6d..d180e40392e75 100644 --- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h +++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h @@ -110,7 +110,8 @@ class CDVDDemuxFFmpeg : public CDVDDemux bool SeekChapter(int chapter, double* startpts = NULL); int GetChapterCount(); int GetChapter(); - void GetChapterName(std::string& strChapterName); + void GetChapterName(std::string& strChapterName, int chapterIdx=-1); + int64_t GetChapterPos(int chapterIdx=-1); virtual void GetStreamCodecName(int iStreamId, std::string &strName); bool Aborted(); diff --git a/xbmc/cores/dvdplayer/DVDPlayer.cpp b/xbmc/cores/dvdplayer/DVDPlayer.cpp index 5420da23b3f26..d620984912a13 100644 --- a/xbmc/cores/dvdplayer/DVDPlayer.cpp +++ b/xbmc/cores/dvdplayer/DVDPlayer.cpp @@ -4075,7 +4075,7 @@ bool CDVDPlayer::SetPlayerState(const std::string& state) int CDVDPlayer::GetChapterCount() { CSingleLock lock(m_StateSection); - return m_State.chapter_count; + return m_State.chapters.size(); } int CDVDPlayer::GetChapter() @@ -4084,10 +4084,13 @@ int CDVDPlayer::GetChapter() return m_State.chapter; } -void CDVDPlayer::GetChapterName(std::string& strChapterName) +void CDVDPlayer::GetChapterName(std::string& strChapterName, int chapterIdx) { CSingleLock lock(m_StateSection); - strChapterName = m_State.chapter_name; + if (chapterIdx == -1 && m_State.chapter > 0 && m_State.chapter <= (int) m_State.chapters.size()) + strChapterName = m_State.chapters[m_State.chapter - 1].first; + else if (chapterIdx > 0 && chapterIdx <= (int) m_State.chapters.size()) + strChapterName = m_State.chapters[chapterIdx - 1].first; } int CDVDPlayer::SeekChapter(int iChapter) @@ -4107,6 +4110,15 @@ int CDVDPlayer::SeekChapter(int iChapter) return 0; } +int64_t CDVDPlayer::GetChapterPos(int chapterIdx) +{ + CSingleLock lock(m_StateSection); + if (chapterIdx > 0 && chapterIdx <= (int) m_StateInput.chapters.size()) + return m_State.chapters[chapterIdx - 1].second; + + return -1; +} + int CDVDPlayer::AddSubtitle(const std::string& strSubPath) { return AddSubtitleFile(strSubPath); @@ -4279,8 +4291,17 @@ void CDVDPlayer::UpdatePlayState(double timeout) if(m_pDemuxer) { state.chapter = m_pDemuxer->GetChapter(); - state.chapter_count = m_pDemuxer->GetChapterCount(); - m_pDemuxer->GetChapterName(state.chapter_name); + + state.chapters.clear(); + if (m_pDemuxer->GetChapterCount() > 0) + { + for (int i = 0; i < m_pDemuxer->GetChapterCount(); ++i) + { + std::string name; + m_pDemuxer->GetChapterName(name, i + 1); + state.chapters.push_back(make_pair(name, m_pDemuxer->GetChapterPos(i + 1))); + } + } if(state.dts == DVD_NOPTS_VALUE) state.time = 0; diff --git a/xbmc/cores/dvdplayer/DVDPlayer.h b/xbmc/cores/dvdplayer/DVDPlayer.h index 746e0be7af7b0..f5fd125d88e43 100644 --- a/xbmc/cores/dvdplayer/DVDPlayer.h +++ b/xbmc/cores/dvdplayer/DVDPlayer.h @@ -266,7 +266,8 @@ class CDVDPlayer : public IPlayer, public CThread, public IDVDPlayer virtual int GetChapterCount(); virtual int GetChapter(); - virtual void GetChapterName(std::string& strChapterName); + virtual void GetChapterName(std::string& strChapterName, int chapterIdx=-1); + virtual int64_t GetChapterPos(int chapterIdx=-1); virtual int SeekChapter(int iChapter); virtual void SeekTime(int64_t iTime); @@ -479,8 +480,7 @@ class CDVDPlayer : public IPlayer, public CThread, public IDVDPlayer dts = DVD_NOPTS_VALUE; player_state = ""; chapter = 0; - chapter_name = ""; - chapter_count = 0; + chapters.clear(); canrecord = false; recording = false; canpause = false; @@ -505,9 +505,8 @@ class CDVDPlayer : public IPlayer, public CThread, public IDVDPlayer std::string player_state; // full player state - int chapter; // current chapter - std::string chapter_name; // name of current chapter - int chapter_count;// number of chapter + int chapter; // current chapter + std::vector> chapters; // name and position for chapters bool canrecord; // can input stream record bool recording; // are we currently recording From 1e36d5b883de65b665f4ec4954263abf24936a19 Mon Sep 17 00:00:00 2001 From: Arne Morten Kvarving Date: Thu, 17 Apr 2014 00:13:24 +0200 Subject: [PATCH 02/12] added: ability to specify position where thumb is taken from in DVDFileInfo --- xbmc/cores/dvdplayer/DVDFileInfo.cpp | 4 ++-- xbmc/cores/dvdplayer/DVDFileInfo.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/xbmc/cores/dvdplayer/DVDFileInfo.cpp b/xbmc/cores/dvdplayer/DVDFileInfo.cpp index e05b6470fd2f0..1648d605f13b8 100644 --- a/xbmc/cores/dvdplayer/DVDFileInfo.cpp +++ b/xbmc/cores/dvdplayer/DVDFileInfo.cpp @@ -97,7 +97,7 @@ int DegreeToOrientation(int degrees) bool CDVDFileInfo::ExtractThumb(const std::string &strPath, CTextureDetails &details, - CStreamDetails *pStreamDetails) + CStreamDetails *pStreamDetails, int pos) { std::string redactPath = CURL::GetRedacted(strPath); unsigned int nTime = XbmcThreads::SystemClockMillis(); @@ -216,7 +216,7 @@ bool CDVDFileInfo::ExtractThumb(const std::string &strPath, if (pVideoCodec) { int nTotalLen = pDemuxer->GetStreamLength(); - int nSeekTo = nTotalLen / 3; + int nSeekTo = (pos==-1?nTotalLen / 3:pos); CLog::Log(LOGDEBUG,"%s - seeking to pos %dms (total: %dms) in %s", __FUNCTION__, nSeekTo, nTotalLen, redactPath.c_str()); if (pDemuxer->SeekTime(nSeekTo, true)) diff --git a/xbmc/cores/dvdplayer/DVDFileInfo.h b/xbmc/cores/dvdplayer/DVDFileInfo.h index 63491ebe6a05e..1afecaf65ae46 100644 --- a/xbmc/cores/dvdplayer/DVDFileInfo.h +++ b/xbmc/cores/dvdplayer/DVDFileInfo.h @@ -36,7 +36,7 @@ class CDVDFileInfo // Extract a thumbnail immage from the media at strPath, optionally populating a streamdetails class with the data static bool ExtractThumb(const std::string &strPath, CTextureDetails &details, - CStreamDetails *pStreamDetails); + CStreamDetails *pStreamDetails, int pos=-1); // Probe the files streams and store the info in the VideoInfoTag static bool GetFileStreamDetails(CFileItem *pItem); From 1e987d235c72192336623dc206e75407724b3d98 Mon Sep 17 00:00:00 2001 From: Arne Morten Kvarving Date: Thu, 17 Apr 2014 00:14:28 +0200 Subject: [PATCH 03/12] added: ability to specify where to extract thumb from in thumb extractor job --- xbmc/video/VideoThumbLoader.cpp | 6 ++++-- xbmc/video/VideoThumbLoader.h | 3 ++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/xbmc/video/VideoThumbLoader.cpp b/xbmc/video/VideoThumbLoader.cpp index 583d9d015f6ed..e93d58bed24d2 100644 --- a/xbmc/video/VideoThumbLoader.cpp +++ b/xbmc/video/VideoThumbLoader.cpp @@ -50,12 +50,14 @@ using namespace VIDEO; CThumbExtractor::CThumbExtractor(const CFileItem& item, const std::string& listpath, bool thumb, - const std::string& target) + const std::string& target, + int64_t pos) { m_listpath = listpath; m_target = target; m_thumb = thumb; m_item = item; + m_pos = pos; if (item.IsVideoDb() && item.HasVideoInfoTag()) m_item.SetPath(item.GetVideoInfoTag()->m_strFileNameAndPath); @@ -106,7 +108,7 @@ bool CThumbExtractor::DoWork() // construct the thumb cache file CTextureDetails details; details.file = CTextureCache::GetCacheFile(m_target) + ".jpg"; - result = CDVDFileInfo::ExtractThumb(m_item.GetPath(), details, &m_item.GetVideoInfoTag()->m_streamDetails); + result = CDVDFileInfo::ExtractThumb(m_item.GetPath(), details, &m_item.GetVideoInfoTag()->m_streamDetails, (int) m_pos); if(result) { CTextureCache::Get().AddCachedTexture(m_target, details); diff --git a/xbmc/video/VideoThumbLoader.h b/xbmc/video/VideoThumbLoader.h index 55560dad4eeb9..6486c012d3d0c 100644 --- a/xbmc/video/VideoThumbLoader.h +++ b/xbmc/video/VideoThumbLoader.h @@ -38,7 +38,7 @@ class CVideoDatabase; class CThumbExtractor : public CJob { public: - CThumbExtractor(const CFileItem& item, const std::string& listpath, bool thumb, const std::string& strTarget=""); + CThumbExtractor(const CFileItem& item, const std::string& listpath, bool thumb, const std::string& strTarget="", int64_t pos = -1); virtual ~CThumbExtractor(); /*! @@ -57,6 +57,7 @@ class CThumbExtractor : public CJob std::string m_listpath; ///< path used in fileitem list CFileItem m_item; bool m_thumb; ///< extract thumb? + int64_t m_pos; ///< position to extract thumb from }; class CVideoThumbLoader : public CThumbLoader, public CJobQueue From 828b42ec8ebf8f14f9db6e5f3ccf1fdf7f94efff Mon Sep 17 00:00:00 2001 From: Arne Morten Kvarving Date: Tue, 22 Apr 2014 16:46:04 +0200 Subject: [PATCH 04/12] added: support grabbing chapter name and position from bluray/dvds --- lib/libdvd/libdvdnav/src/dvdnav.c | 5 ++++ lib/libdvd/libdvdnav/src/dvdnav/dvdnav.h | 1 + lib/libdvd/patches/libdvdnav.diff | 15 ++++++++++++ .../dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp | 6 ++++- .../DVDInputStreams/DVDInputStream.h | 3 ++- .../DVDInputStreams/DVDInputStreamBluray.cpp | 11 +++++++++ .../DVDInputStreams/DVDInputStreamBluray.h | 3 ++- .../DVDInputStreamNavigator.cpp | 23 +++++++++++++++++++ .../DVDInputStreams/DVDInputStreamNavigator.h | 3 ++- .../dvdplayer/DVDInputStreams/DllDvdNav.h | 10 ++++++++ 10 files changed, 76 insertions(+), 4 deletions(-) diff --git a/lib/libdvd/libdvdnav/src/dvdnav.c b/lib/libdvd/libdvdnav/src/dvdnav.c index 7b2ff892a4b67..b261b3e3590e8 100644 --- a/lib/libdvd/libdvdnav/src/dvdnav.c +++ b/lib/libdvd/libdvdnav/src/dvdnav.c @@ -1230,6 +1230,11 @@ int dvdnav_get_button_info(dvdnav_t* this, int alpha[2][4], int color[2][4]) return 0; } +void dvdnav_free(void* pdata) +{ + free(pdata); +} + #undef printerr #define printerr(str) strncpy(self->err_str, str, MAX_ERR_LEN); diff --git a/lib/libdvd/libdvdnav/src/dvdnav/dvdnav.h b/lib/libdvd/libdvdnav/src/dvdnav/dvdnav.h index bf6aae9d2a3ea..8b9d75ea2bdf7 100644 --- a/lib/libdvd/libdvdnav/src/dvdnav/dvdnav.h +++ b/lib/libdvd/libdvdnav/src/dvdnav/dvdnav.h @@ -697,6 +697,7 @@ int8_t dvdnav_is_domain_vtsm(dvdnav_t *self); */ int8_t dvdnav_is_domain_vts(dvdnav_t *self); +void dvdnav_free(void* pdata); #ifdef __cplusplus } diff --git a/lib/libdvd/patches/libdvdnav.diff b/lib/libdvd/patches/libdvdnav.diff index cb702a4b38de2..42bad876b0fb7 100644 --- a/lib/libdvd/patches/libdvdnav.diff +++ b/lib/libdvd/patches/libdvdnav.diff @@ -149,6 +149,16 @@ diff -uwr ../libdvdnav-4.2.1/src/dvdnav/dvdnav.h lib/libdvd/libdvdnav/src/dvdnav /* * Stop playing the current position and start playback of the title + * from the specified timecode. + * +@@ -695,6 +697,7 @@ + */ + int8_t dvdnav_is_domain_vts(dvdnav_t *self); + ++void dvdnav_free(void* pdata); + + #ifdef __cplusplus + } diff -uwr ../libdvdnav-4.2.1/src/dvdnav.c lib/libdvd/libdvdnav/src/dvdnav.c --- ../libdvdnav-4.2.1/src/dvdnav.c Thu Oct 3 23:39:38 2013 +++ lib/libdvd/libdvdnav/src/dvdnav.c Fri Feb 7 19:24:42 2014 @@ -284,6 +294,11 @@ diff -uwr ../libdvdnav-4.2.1/src/dvdnav.c lib/libdvd/libdvdnav/src/dvdnav.c + return 0; +} + ++void dvdnav_free(void* pdata) ++{ ++ free(pdata); ++} ++ +#undef printerr +#define printerr(str) strncpy(self->err_str, str, MAX_ERR_LEN); + diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp index f051b4677fbbd..66a4a244a4040 100644 --- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp +++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp @@ -1407,7 +1407,7 @@ void CDVDDemuxFFmpeg::GetChapterName(std::string& strChapterName, int chapterIdx chapterIdx = GetChapter(); CDVDInputStream::IChapter* ich = dynamic_cast(m_pInput); if(ich) - ich->GetChapterName(strChapterName); + ich->GetChapterName(strChapterName, chapterIdx); else { if(chapterIdx <= 0) @@ -1427,6 +1427,10 @@ int64_t CDVDDemuxFFmpeg::GetChapterPos(int chapterIdx) if(chapterIdx <= 0) return 0; + CDVDInputStream::IChapter* ich = dynamic_cast(m_pInput); + if(ich) + return ich->GetChapterPos(chapterIdx); + return m_pFormatContext->chapters[chapterIdx-1]->start*av_q2d(m_pFormatContext->chapters[chapterIdx-1]->time_base); } diff --git a/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStream.h b/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStream.h index 72af2ddeaf8f5..e8bae5ecf5ba2 100644 --- a/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStream.h +++ b/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStream.h @@ -101,7 +101,8 @@ class CDVDInputStream virtual ~IChapter() {}; virtual int GetChapter() = 0; virtual int GetChapterCount() = 0; - virtual void GetChapterName(std::string& name) = 0; + virtual void GetChapterName(std::string& name, int ch=-1) = 0; + virtual int64_t GetChapterPos(int ch=-1) = 0; virtual bool SeekChapter(int ch) = 0; }; diff --git a/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamBluray.cpp b/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamBluray.cpp index 2ef5f95d7fa87..61667bd7ee7f1 100644 --- a/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamBluray.cpp +++ b/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamBluray.cpp @@ -935,6 +935,17 @@ bool CDVDInputStreamBluray::SeekChapter(int ch) return true; } +int64_t CDVDInputStreamBluray::GetChapterPos(int ch) +{ + if (ch == -1 || ch > GetChapterCount()) + ch = GetChapter(); + + if (m_title && m_title->chapters) + return m_title->chapters[ch - 1].start / 90000; + else + return 0; +} + int64_t CDVDInputStreamBluray::Seek(int64_t offset, int whence) { #if LIBBLURAY_BYTESEEK diff --git a/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamBluray.h b/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamBluray.h index 1f5f9266520f2..1107ed2282db7 100644 --- a/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamBluray.h +++ b/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamBluray.h @@ -96,7 +96,8 @@ class CDVDInputStreamBluray int GetChapter(); int GetChapterCount(); - void GetChapterName(std::string& name) {}; + void GetChapterName(std::string& name, int ch=-1) {}; + int64_t GetChapterPos(int ch); bool SeekChapter(int ch); int GetTotalTime(); diff --git a/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamNavigator.cpp b/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamNavigator.cpp index 3fd9a0745816a..c7a6e4c159ff8 100644 --- a/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamNavigator.cpp +++ b/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamNavigator.cpp @@ -1455,3 +1455,26 @@ bool CDVDInputStreamNavigator::GetDVDSerialString(std::string& serialStr) serialStr.assign(str); return true; } + +int64_t CDVDInputStreamNavigator::GetChapterPos(int ch) +{ + if (ch == -1 || ch > GetChapterCount()) + ch = GetChapter(); + + if (ch <= 1) + return 0; + + uint64_t* times = NULL; + uint64_t duration; + + m_dll.dvdnav_describe_title_chapters(m_dvdnav, m_iTitle, ×, &duration); + + int64_t result = 0; + + if (times) + { + result = times[ch - 2] / 90000; + m_dll.dvdnav_free(times); + } + return result; +} diff --git a/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamNavigator.h b/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamNavigator.h index f9a6d0f6ee84e..d7e967cf21907 100644 --- a/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamNavigator.h +++ b/xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamNavigator.h @@ -127,7 +127,8 @@ class CDVDInputStreamNavigator int GetChapter() { return m_iPart; } // the current part in the current title int GetChapterCount() { return m_iPartCount; } // the number of parts in the current title - void GetChapterName(std::string& name) {}; + void GetChapterName(std::string& name, int idx=-1) {}; + int64_t GetChapterPos(int ch=-1); bool SeekChapter(int iChapter); int GetTotalTime(); // the total time in milli seconds diff --git a/xbmc/cores/dvdplayer/DVDInputStreams/DllDvdNav.h b/xbmc/cores/dvdplayer/DVDInputStreams/DllDvdNav.h index ecacd978f344a..dcbf829cd840a 100644 --- a/xbmc/cores/dvdplayer/DVDInputStreams/DllDvdNav.h +++ b/xbmc/cores/dvdplayer/DVDInputStreams/DllDvdNav.h @@ -106,6 +106,8 @@ class DllDvdNavInterface virtual dvdnav_status_t dvdnav_mouse_select(dvdnav_t *self, pci_t *pci, int32_t x, int32_t y)=0; virtual dvdnav_status_t dvdnav_get_title_string(dvdnav_t *self, const char **title_str)=0; virtual dvdnav_status_t dvdnav_get_serial_string(dvdnav_t *self, const char **serial_str)=0; + virtual uint32_t dvdnav_describe_title_chapters(dvdnav_t* self, uint32_t title, uint64_t** times, uint64_t* duration)=0; + virtual void dvdnav_free(void* pdata) = 0; }; #if (defined USE_STATIC_LIBDVDNAV) @@ -231,6 +233,10 @@ class DllDvdNav : public DllDynamic, DllDvdNavInterface { return ::dvdnav_get_title_string(self, title_str); } virtual dvdnav_status_t dvdnav_get_serial_string(dvdnav_t *self, const char **serial_str) { return ::dvdnav_get_serial_string(self, serial_str); } + virtual uint32_t dvdnav_describe_title_chapters(dvdnav_t* self, uint32_t title, uint64_t** times, uint64_t* duration) + { return ::dvdnav_describe_title_chapters(self, title, times, duration); } + virtual void dvdnav_free(void* data) + { return ::dvdnav_free(data); } // DLL faking. virtual bool ResolveExports() { return true; } @@ -303,6 +309,8 @@ class DllDvdNav : public DllDynamic, DllDvdNavInterface DEFINE_METHOD4(dvdnav_status_t, dvdnav_mouse_select, (dvdnav_t *p1, pci_t *p2, int32_t p3, int32_t p4)) DEFINE_METHOD2(dvdnav_status_t, dvdnav_get_title_string, (dvdnav_t *p1, const char **p2)) DEFINE_METHOD2(dvdnav_status_t, dvdnav_get_serial_string, (dvdnav_t *p1, const char **p2)) + DEFINE_METHOD4(uint32_t, dvdnav_describe_title_chapters, (dvdnav_t* p1, uint32_t p2, uint64_t** p3, uint64_t* p4)) + DEFINE_METHOD1(void, dvdnav_free, (void *p1)) BEGIN_METHOD_RESOLVE() RESOLVE_METHOD(dvdnav_open) RESOLVE_METHOD(dvdnav_close) @@ -363,6 +371,8 @@ class DllDvdNav : public DllDynamic, DllDvdNavInterface RESOLVE_METHOD(dvdnav_mouse_select) RESOLVE_METHOD(dvdnav_get_title_string) RESOLVE_METHOD(dvdnav_get_serial_string) + RESOLVE_METHOD(dvdnav_describe_title_chapters) + RESOLVE_METHOD(dvdnav_free) END_METHOD_RESOLVE() }; From c77af5dc2fc6cb26f7b837c7627038d245bbb20f Mon Sep 17 00:00:00 2001 From: ace20022 Date: Fri, 13 Feb 2015 17:23:39 +0100 Subject: [PATCH 05/12] [dvdplayer] Fix wrong chapter numbers in dvd menus. --- xbmc/cores/dvdplayer/DVDPlayer.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/xbmc/cores/dvdplayer/DVDPlayer.cpp b/xbmc/cores/dvdplayer/DVDPlayer.cpp index d620984912a13..ba18f74a865c4 100644 --- a/xbmc/cores/dvdplayer/DVDPlayer.cpp +++ b/xbmc/cores/dvdplayer/DVDPlayer.cpp @@ -4290,7 +4290,10 @@ void CDVDPlayer::UpdatePlayState(double timeout) if(m_pDemuxer) { - state.chapter = m_pDemuxer->GetChapter(); + if (IsInMenu()) + state.chapter = 0; + else + state.chapter = m_pDemuxer->GetChapter(); state.chapters.clear(); if (m_pDemuxer->GetChapterCount() > 0) From 269513ed7a5192d3aa7c5173711ebedfafbe9cb4 Mon Sep 17 00:00:00 2001 From: ace20022 Date: Sat, 14 Feb 2015 13:47:53 +0100 Subject: [PATCH 06/12] [demuxer] set correct startpts when seeking chapters of discs. --- xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp index 66a4a244a4040..f58472f6b87a1 100644 --- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp +++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp @@ -1447,7 +1447,9 @@ bool CDVDDemuxFFmpeg::SeekChapter(int chapter, double* startpts) return false; if(startpts) - *startpts = DVD_NOPTS_VALUE; + { + *startpts = DVD_SEC_TO_TIME(ich->GetChapterPos(chapter)); + } Flush(); return true; From 3f80a3d11f853fd1284acc2343a02936ed61ea65 Mon Sep 17 00:00:00 2001 From: ace20022 Date: Sun, 15 Feb 2015 23:03:32 +0100 Subject: [PATCH 07/12] [VideoThumbLoader] Add parameter to skip querying/storing stream details when extracting thumbs. This is useful for chapter thumbs extraction for example. --- xbmc/video/VideoThumbLoader.cpp | 6 ++++-- xbmc/video/VideoThumbLoader.h | 3 ++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/xbmc/video/VideoThumbLoader.cpp b/xbmc/video/VideoThumbLoader.cpp index e93d58bed24d2..6738dedb6c86e 100644 --- a/xbmc/video/VideoThumbLoader.cpp +++ b/xbmc/video/VideoThumbLoader.cpp @@ -51,13 +51,15 @@ CThumbExtractor::CThumbExtractor(const CFileItem& item, const std::string& listpath, bool thumb, const std::string& target, - int64_t pos) + int64_t pos, + bool fillStreamDetails) { m_listpath = listpath; m_target = target; m_thumb = thumb; m_item = item; m_pos = pos; + m_fillStreamDetails = fillStreamDetails; if (item.IsVideoDb() && item.HasVideoInfoTag()) m_item.SetPath(item.GetVideoInfoTag()->m_strFileNameAndPath); @@ -108,7 +110,7 @@ bool CThumbExtractor::DoWork() // construct the thumb cache file CTextureDetails details; details.file = CTextureCache::GetCacheFile(m_target) + ".jpg"; - result = CDVDFileInfo::ExtractThumb(m_item.GetPath(), details, &m_item.GetVideoInfoTag()->m_streamDetails, (int) m_pos); + result = CDVDFileInfo::ExtractThumb(m_item.GetPath(), details, m_fillStreamDetails ? &m_item.GetVideoInfoTag()->m_streamDetails : NULL, (int) m_pos); if(result) { CTextureCache::Get().AddCachedTexture(m_target, details); diff --git a/xbmc/video/VideoThumbLoader.h b/xbmc/video/VideoThumbLoader.h index 6486c012d3d0c..1ad97adfbd847 100644 --- a/xbmc/video/VideoThumbLoader.h +++ b/xbmc/video/VideoThumbLoader.h @@ -38,7 +38,7 @@ class CVideoDatabase; class CThumbExtractor : public CJob { public: - CThumbExtractor(const CFileItem& item, const std::string& listpath, bool thumb, const std::string& strTarget="", int64_t pos = -1); + CThumbExtractor(const CFileItem& item, const std::string& listpath, bool thumb, const std::string& strTarget="", int64_t pos = -1, bool fillStreamDetails = true); virtual ~CThumbExtractor(); /*! @@ -58,6 +58,7 @@ class CThumbExtractor : public CJob CFileItem m_item; bool m_thumb; ///< extract thumb? int64_t m_pos; ///< position to extract thumb from + bool m_fillStreamDetails; ///< fill in stream details? }; class CVideoThumbLoader : public CThumbLoader, public CJobQueue From 2e7b2679c6c7405c708e666d15bf0274d16295aa Mon Sep 17 00:00:00 2001 From: ace20022 Date: Tue, 24 Feb 2015 15:43:25 +0100 Subject: [PATCH 08/12] [VideoThumbLoader] Make == operator more strict. --- xbmc/video/VideoThumbLoader.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/xbmc/video/VideoThumbLoader.cpp b/xbmc/video/VideoThumbLoader.cpp index 6738dedb6c86e..7ba93fa8d8950 100644 --- a/xbmc/video/VideoThumbLoader.cpp +++ b/xbmc/video/VideoThumbLoader.cpp @@ -77,7 +77,8 @@ bool CThumbExtractor::operator==(const CJob* job) const if (strcmp(job->GetType(),GetType()) == 0) { const CThumbExtractor* jobExtract = dynamic_cast(job); - if (jobExtract && jobExtract->m_listpath == m_listpath) + if (jobExtract && jobExtract->m_listpath == m_listpath + && jobExtract->m_target == m_target) return true; } return false; From 39fe834df562950ae44f185740d7e9ebb85962c3 Mon Sep 17 00:00:00 2001 From: ace20022 Date: Thu, 17 Apr 2014 00:15:03 +0200 Subject: [PATCH 09/12] added: show chapters in bookmark dialog (with thumbs) Original version by Arne Morten Kvarving (notspiff). --- .../video/dialogs/GUIDialogVideoBookmarks.cpp | 111 ++++++++++++++++-- xbmc/video/dialogs/GUIDialogVideoBookmarks.h | 16 ++- 2 files changed, 113 insertions(+), 14 deletions(-) diff --git a/xbmc/video/dialogs/GUIDialogVideoBookmarks.cpp b/xbmc/video/dialogs/GUIDialogVideoBookmarks.cpp index 00139c834b60a..a3e8e729c0cc9 100644 --- a/xbmc/video/dialogs/GUIDialogVideoBookmarks.cpp +++ b/xbmc/video/dialogs/GUIDialogVideoBookmarks.cpp @@ -48,6 +48,10 @@ #include "utils/Variant.h" #include "Util.h" #include "cores/IPlayer.h" +#include "video/VideoThumbLoader.h" +#include "filesystem/File.h" +#include "TextureCache.h" +#include "ApplicationMessenger.h" using namespace std; @@ -61,10 +65,12 @@ using namespace std; #define CONTROL_THUMBS 11 CGUIDialogVideoBookmarks::CGUIDialogVideoBookmarks() - : CGUIDialog(WINDOW_DIALOG_VIDEO_BOOKMARKS, "VideoOSDBookmarks.xml") + : CGUIDialog(WINDOW_DIALOG_VIDEO_BOOKMARKS, "VideoOSDBookmarks.xml"), + CJobQueue(false, 1, CJob::PRIORITY_NORMAL) { m_vecItems = new CFileItemList; - m_loadType = KEEP_IN_MEMORY; + m_loadType = LOAD_EVERY_TIME; + m_jobsStarted = 0; } CGUIDialogVideoBookmarks::~CGUIDialogVideoBookmarks() @@ -134,7 +140,17 @@ bool CGUIDialogVideoBookmarks::OnMessage(CGUIMessage& message) break; case GUI_MSG_REFRESH_LIST: { - OnRefreshList(); + switch (message.GetParam1()) + { + case 0: + OnRefreshList(); + break; + case 1: + UpdateItem(message.GetParam2()); + break; + default: + break; + } } break; } @@ -159,7 +175,7 @@ bool CGUIDialogVideoBookmarks::OnAction(const CAction &action) void CGUIDialogVideoBookmarks::OnPopupMenu(int item) { - if (item < 0 || item >= m_vecItems->Size()) + if (item < 0 || item >= (int) m_bookmarks.size()) return; // highlight the item @@ -199,25 +215,41 @@ void CGUIDialogVideoBookmarks::Delete(int item) Update(); } +void CGUIDialogVideoBookmarks::UpdateItem(unsigned int chapterIdx) +{ + CSingleLock lock(m_refreshSection); + int itemPos = ((chapterIdx - 1) + m_chapterOffset); + if (itemPos < m_vecItems->Size()) + { + std::string time = StringUtils::Format("chapter://%s/%i", m_filePath.c_str(), chapterIdx); + std::string cachefile = CTextureCache::Get().GetCachedPath(CTextureCache::Get().GetCacheFile(time) + ".jpg"); + if (XFILE::CFile::Exists(cachefile)) + { + (*m_vecItems)[itemPos]->SetArt("thumb", cachefile); + } + } +} + void CGUIDialogVideoBookmarks::OnRefreshList() { m_bookmarks.clear(); CBookmark resumemark; // open the d/b and retrieve the bookmarks for the current movie - std::string path = g_application.CurrentFile(); + m_filePath = g_application.CurrentFile(); if (g_application.CurrentFileItem().HasProperty("original_listitem_url") && !URIUtils::IsVideoDb(g_application.CurrentFileItem().GetProperty("original_listitem_url").asString())) - path = g_application.CurrentFileItem().GetProperty("original_listitem_url").asString(); + m_filePath = g_application.CurrentFileItem().GetProperty("original_listitem_url").asString(); CVideoDatabase videoDatabase; videoDatabase.Open(); - videoDatabase.GetBookMarksForFile(path, m_bookmarks); - videoDatabase.GetBookMarksForFile(path, m_bookmarks, CBookmark::EPISODE, true); + videoDatabase.GetBookMarksForFile(m_filePath, m_bookmarks); + videoDatabase.GetBookMarksForFile(m_filePath, m_bookmarks, CBookmark::EPISODE, true); /* push in the resume mark first */ - if( videoDatabase.GetResumeBookMark(path, resumemark) ) + if (videoDatabase.GetResumeBookMark(m_filePath, resumemark)) m_bookmarks.push_back(resumemark); videoDatabase.Close(); + CSingleLock lock(m_refreshSection); m_vecItems->Clear(); // cycle through each stored bookmark and add it to our list control for (unsigned int i = 0; i < m_bookmarks.size(); ++i) @@ -235,6 +267,32 @@ void CGUIDialogVideoBookmarks::OnRefreshList() item->SetArt("thumb", m_bookmarks[i].thumbNailImage); m_vecItems->Add(item); } + // add chapters if around + m_chapterOffset = m_vecItems->Size(); + for (int i=1;i<=g_application.m_pPlayer->GetChapterCount();++i) + { + std::string chapterName; + g_application.m_pPlayer->GetChapterName(chapterName, i); + int64_t pos = g_application.m_pPlayer->GetChapterPos(i); + std::string time = + StringUtils::SecondsToTimeString((long) pos, TIME_FORMAT_HH_MM_SS); + std::string name = StringUtils::Format("%s (%s)", + chapterName.c_str(), time.c_str()); + CFileItemPtr item(new CFileItem(name)); + time = StringUtils::Format("chapter://%s/%i", m_filePath.c_str(), i); + std::string cachefile = CTextureCache::Get().GetCachedPath(CTextureCache::Get().GetCacheFile(time)+".jpg"); + if (XFILE::CFile::Exists(cachefile)) + item->SetArt("thumb", cachefile); + else if (i > m_jobsStarted) + { + CFileItem item(m_filePath, false); + CJob* job = new CThumbExtractor(item, m_filePath, true, time, pos * 1000, false); + AddJob(job); + m_mapJobsChapter[job] = i; + m_jobsStarted++; + } + m_vecItems->Add(item); + } m_viewControl.SetItems(*m_vecItems); } @@ -284,11 +342,16 @@ void CGUIDialogVideoBookmarks::Clear() void CGUIDialogVideoBookmarks::GotoBookmark(int item) { - if (item < 0 || item >= (int)m_bookmarks.size()) return; + if (item < 0 || item >= (int)m_bookmarks.size()+g_application.m_pPlayer->GetChapterCount()) return; if (g_application.m_pPlayer->HasPlayer()) { - g_application.m_pPlayer->SetPlayerState(m_bookmarks[item].playerState); - g_application.SeekTime((double)m_bookmarks[item].timeInSeconds); + if (item < (int) m_bookmarks.size()) + { + g_application.m_pPlayer->SetPlayerState(m_bookmarks[item].playerState); + g_application.SeekTime((double)m_bookmarks[item].timeInSeconds); + } + else + g_application.m_pPlayer->SeekChapter(item-m_bookmarks.size()+1); } } @@ -387,10 +450,17 @@ void CGUIDialogVideoBookmarks::OnWindowLoaded() m_viewControl.Reset(); m_viewControl.SetParentWindow(GetID()); m_viewControl.AddView(GetControl(CONTROL_THUMBS)); + m_jobsStarted = 0; + m_mapJobsChapter.clear(); + m_vecItems->Clear(); } void CGUIDialogVideoBookmarks::OnWindowUnload() { + //stop running thumb extraction jobs + CancelJobs(); + m_mapJobsChapter.clear(); + m_vecItems->Clear(); CGUIDialog::OnWindowUnload(); m_viewControl.Reset(); } @@ -474,4 +544,19 @@ bool CGUIDialogVideoBookmarks::OnAddEpisodeBookmark() return bReturn; } - +void CGUIDialogVideoBookmarks::OnJobComplete(unsigned int jobID, + bool success, CJob* job) +{ + if (success && IsActive()) + { + MAPJOBSCHAPS::iterator iter = m_mapJobsChapter.find(job); + if (iter != m_mapJobsChapter.end()) + { + unsigned int chapterIdx = (*iter).second; + CGUIMessage m(GUI_MSG_REFRESH_LIST, GetID(), 0, 1, chapterIdx); + CApplicationMessenger::Get().SendGUIMessage(m); + m_mapJobsChapter.erase(iter); + } + } + CJobQueue::OnJobComplete(jobID, success, job); +} diff --git a/xbmc/video/dialogs/GUIDialogVideoBookmarks.h b/xbmc/video/dialogs/GUIDialogVideoBookmarks.h index 8d0e6213f2147..9bac80ff913ec 100644 --- a/xbmc/video/dialogs/GUIDialogVideoBookmarks.h +++ b/xbmc/video/dialogs/GUIDialogVideoBookmarks.h @@ -23,11 +23,14 @@ #include "guilib/GUIDialog.h" #include "view/GUIViewControl.h" #include "video/VideoDatabase.h" +#include "utils/JobManager.h" class CFileItemList; -class CGUIDialogVideoBookmarks : public CGUIDialog +class CGUIDialogVideoBookmarks : public CGUIDialog, public CJobQueue { + typedef std::map MAPJOBSCHAPS; + public: CGUIDialogVideoBookmarks(void); virtual ~CGUIDialogVideoBookmarks(void); @@ -69,7 +72,18 @@ class CGUIDialogVideoBookmarks : public CGUIDialog void OnPopupMenu(int item); CGUIControl *GetFirstFocusableControl(int id); + void OnJobComplete(unsigned int jobID, bool success, CJob* job); + CFileItemList* m_vecItems; CGUIViewControl m_viewControl; VECBOOKMARKS m_bookmarks; + +private: + void UpdateItem(unsigned int chapterIdx); + + int m_chapterOffset; + int m_jobsStarted; + std::string m_filePath; + CCriticalSection m_refreshSection; + MAPJOBSCHAPS m_mapJobsChapter; }; From 498747bbe8ae1bdc99ab92f6f204c474b1da092d Mon Sep 17 00:00:00 2001 From: Arne Morten Kvarving Date: Tue, 22 Apr 2014 16:45:20 +0200 Subject: [PATCH 10/12] added: if chapter is nameless, use a generic 'Chapter %u' string --- language/English/strings.po | 7 ++++++- xbmc/video/dialogs/GUIDialogVideoBookmarks.cpp | 2 ++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/language/English/strings.po b/language/English/strings.po index 9acbf50b562a5..307325bce3348 100644 --- a/language/English/strings.po +++ b/language/English/strings.po @@ -12830,7 +12830,12 @@ msgctxt "#25009" msgid "The menu of this Blu-ray is not supported" msgstr "" -#empty strings from id 25010 to 29799 +#: xbmc/video/dialogs/GUIDialogVideoBookmarks.cpp +msgctxt "#25010" +msgid "Chapter %u" +msgstr "" + +#empty strings from id 25011 to 29799 #strings 29800 thru 29998 reserved strings used only in the default Project Mayhem III skin and not c++ code #: skin.confluence diff --git a/xbmc/video/dialogs/GUIDialogVideoBookmarks.cpp b/xbmc/video/dialogs/GUIDialogVideoBookmarks.cpp index a3e8e729c0cc9..294a1cf03d0f7 100644 --- a/xbmc/video/dialogs/GUIDialogVideoBookmarks.cpp +++ b/xbmc/video/dialogs/GUIDialogVideoBookmarks.cpp @@ -273,6 +273,8 @@ void CGUIDialogVideoBookmarks::OnRefreshList() { std::string chapterName; g_application.m_pPlayer->GetChapterName(chapterName, i); + if (chapterName.empty()) + chapterName = StringUtils::Format(g_localizeStrings.Get(25010).c_str(), i); int64_t pos = g_application.m_pPlayer->GetChapterPos(i); std::string time = StringUtils::SecondsToTimeString((long) pos, TIME_FORMAT_HH_MM_SS); From 5dbae9f3e27913347edd9c53174a25f429ab34da Mon Sep 17 00:00:00 2001 From: ace20022 Date: Mon, 2 Mar 2015 00:23:15 +0100 Subject: [PATCH 11/12] [VideoBookmarks] Add a setting for chapter thumbnail extraction. --- language/English/strings.po | 14 +++++++++++++- system/settings/settings.xml | 5 +++++ xbmc/video/dialogs/GUIDialogVideoBookmarks.cpp | 3 ++- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/language/English/strings.po b/language/English/strings.po index 307325bce3348..c0c13832ef719 100644 --- a/language/English/strings.po +++ b/language/English/strings.po @@ -16253,7 +16253,19 @@ msgctxt "#37043" msgid "Defines the time to wait for subsequent key presses before performing the skip. Only applies when using smart skipping (when using more than one skip step for a direction)." msgstr "" -#empty strings from id 37044 to 38009 +#. Setting #37044 Settings -> Video -> File lists -> Extract chapter thumbnails +#: system/settings/settings.xml +msgctxt "#37044" +msgid "Extract chapter thumbnails" +msgstr "" + +#. Description of setting #37044 "Video -> File lists -> Extract chapter thumbnails" +#: system/settings/settings.xml +msgctxt "#37045" +msgid "Extract chapter thumbnails for presentation in the chapters/bookmarks dialog. This might increase CPU load." +msgstr "" + +#empty strings from id 37046 to 38009 #: system/settings/rbp.xml msgctxt "#38010" diff --git a/system/settings/settings.xml b/system/settings/settings.xml index ecd2e9010f9ba..52d1fb7cce5d4 100644 --- a/system/settings/settings.xml +++ b/system/settings/settings.xml @@ -780,6 +780,11 @@ true + + 1 + true + + 1 true diff --git a/xbmc/video/dialogs/GUIDialogVideoBookmarks.cpp b/xbmc/video/dialogs/GUIDialogVideoBookmarks.cpp index 294a1cf03d0f7..328974bcbcf0f 100644 --- a/xbmc/video/dialogs/GUIDialogVideoBookmarks.cpp +++ b/xbmc/video/dialogs/GUIDialogVideoBookmarks.cpp @@ -52,6 +52,7 @@ #include "filesystem/File.h" #include "TextureCache.h" #include "ApplicationMessenger.h" +#include "settings/Settings.h" using namespace std; @@ -285,7 +286,7 @@ void CGUIDialogVideoBookmarks::OnRefreshList() std::string cachefile = CTextureCache::Get().GetCachedPath(CTextureCache::Get().GetCacheFile(time)+".jpg"); if (XFILE::CFile::Exists(cachefile)) item->SetArt("thumb", cachefile); - else if (i > m_jobsStarted) + else if (i > m_jobsStarted && CSettings::Get().GetBool("myvideos.extractchapterthumbs")) { CFileItem item(m_filePath, false); CJob* job = new CThumbExtractor(item, m_filePath, true, time, pos * 1000, false); From 45e003e34f83adbf7352dbfdfe5d2dd58cd22612 Mon Sep 17 00:00:00 2001 From: ace20022 Date: Mon, 2 Mar 2015 00:31:48 +0100 Subject: [PATCH 12/12] [Settings/rpi] Disable chapter thumbnail extraction by default for the rpi. --- system/settings/rbp.xml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/system/settings/rbp.xml b/system/settings/rbp.xml index f572eedbfae23..bd3e2ad51f283 100644 --- a/system/settings/rbp.xml +++ b/system/settings/rbp.xml @@ -16,6 +16,13 @@ + + + + false + + +