diff options
34 files changed, 883 insertions, 727 deletions
diff --git a/XBMC-ATV2.xcodeproj/project.pbxproj b/XBMC-ATV2.xcodeproj/project.pbxproj index 9da1d5873e..7e5862d0ed 100644 --- a/XBMC-ATV2.xcodeproj/project.pbxproj +++ b/XBMC-ATV2.xcodeproj/project.pbxproj @@ -42,6 +42,8 @@ 7C6EB708155F3B160080368A /* HTTPImageHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C6EB706155F3B160080368A /* HTTPImageHandler.cpp */; }; 7C89627013B702F3003631FE /* GUIWindowScreensaverDim.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C89626E13B702F3003631FE /* GUIWindowScreensaverDim.cpp */; }; 7C99B7AA134072CD00FC2B16 /* GUIDialogPlayEject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C99B7A8134072CD00FC2B16 /* GUIDialogPlayEject.cpp */; }; + 7CC30DF2162925BE003E7579 /* MusicThumbLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CC30DF0162925BE003E7579 /* MusicThumbLoader.cpp */; }; + 7CC30E1A16292627003E7579 /* VideoThumbLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CC30E1816292627003E7579 /* VideoThumbLoader.cpp */; }; 7CCFD9AA1514952700211D82 /* PCMCodec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CCFD9A81514952700211D82 /* PCMCodec.cpp */; }; 7CEE2E6D13D6B7A8000ABF2A /* TimeSmoother.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CEE2E6B13D6B7A8000ABF2A /* TimeSmoother.cpp */; }; C807119F135DB842002F601B /* InputOperations.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C807119D135DB842002F601B /* InputOperations.cpp */; }; @@ -1063,6 +1065,10 @@ 7C89626F13B702F3003631FE /* GUIWindowScreensaverDim.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GUIWindowScreensaverDim.h; sourceTree = "<group>"; }; 7C99B7A8134072CD00FC2B16 /* GUIDialogPlayEject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GUIDialogPlayEject.cpp; sourceTree = "<group>"; }; 7C99B7A9134072CD00FC2B16 /* GUIDialogPlayEject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GUIDialogPlayEject.h; sourceTree = "<group>"; }; + 7CC30DF0162925BE003E7579 /* MusicThumbLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MusicThumbLoader.cpp; sourceTree = "<group>"; }; + 7CC30DF1162925BE003E7579 /* MusicThumbLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MusicThumbLoader.h; sourceTree = "<group>"; }; + 7CC30E1816292627003E7579 /* VideoThumbLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VideoThumbLoader.cpp; sourceTree = "<group>"; }; + 7CC30E1916292627003E7579 /* VideoThumbLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VideoThumbLoader.h; sourceTree = "<group>"; }; 7CCFD9A81514952700211D82 /* PCMCodec.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PCMCodec.cpp; sourceTree = "<group>"; }; 7CCFD9A91514952700211D82 /* PCMCodec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PCMCodec.h; sourceTree = "<group>"; }; 7CEE2E6B13D6B7A8000ABF2A /* TimeSmoother.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TimeSmoother.cpp; sourceTree = "<group>"; }; @@ -5231,6 +5237,8 @@ 36A9468D15CF217400727135 /* MusicDbUrl.h */, F56C7643131EC153000AD0F6 /* MusicInfoLoader.cpp */, F56C7644131EC153000AD0F6 /* MusicInfoLoader.h */, + 7CC30DF0162925BE003E7579 /* MusicThumbLoader.cpp */, + 7CC30DF1162925BE003E7579 /* MusicThumbLoader.h */, F56C7645131EC153000AD0F6 /* Song.cpp */, F56C7646131EC153000AD0F6 /* Song.h */, ); @@ -5811,6 +5819,8 @@ F56C77A8131EC154000AD0F6 /* VideoInfoTag.h */, F56C77A9131EC154000AD0F6 /* VideoReferenceClock.cpp */, F56C77AA131EC154000AD0F6 /* VideoReferenceClock.h */, + 7CC30E1816292627003E7579 /* VideoThumbLoader.cpp */, + 7CC30E1916292627003E7579 /* VideoThumbLoader.h */, ); path = video; sourceTree = "<group>"; @@ -7552,6 +7562,8 @@ 36A95DB41624898700727135 /* GUIDialogMediaFilter.cpp in Sources */, F592D4BF162495B10023BCE7 /* NptPosixTime.cpp in Sources */, F592D4C2162496620023BCE7 /* NptHash.cpp in Sources */, + 7CC30DF2162925BE003E7579 /* MusicThumbLoader.cpp in Sources */, + 7CC30E1A16292627003E7579 /* VideoThumbLoader.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/XBMC-IOS.xcodeproj/project.pbxproj b/XBMC-IOS.xcodeproj/project.pbxproj index 9f1deb86f3..0b7f8706ee 100644 --- a/XBMC-IOS.xcodeproj/project.pbxproj +++ b/XBMC-IOS.xcodeproj/project.pbxproj @@ -43,6 +43,8 @@ 7C6EB71A155F3B330080368A /* HTTPImageHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C6EB718155F3B330080368A /* HTTPImageHandler.cpp */; }; 7C89628013B7031E003631FE /* GUIWindowScreensaverDim.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C89627E13B7031E003631FE /* GUIWindowScreensaverDim.cpp */; }; 7C99B7BE1340730000FC2B16 /* GUIDialogPlayEject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C99B7BC1340730000FC2B16 /* GUIDialogPlayEject.cpp */; }; + 7CC30E04162925E6003E7579 /* MusicThumbLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CC30E02162925E6003E7579 /* MusicThumbLoader.cpp */; }; + 7CC30E0716292601003E7579 /* VideoThumbLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CC30E0516292601003E7579 /* VideoThumbLoader.cpp */; }; 7CCFD9991514950700211D82 /* PCMCodec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CCFD9971514950700211D82 /* PCMCodec.cpp */; }; 7CEE2E7F13D6B7D4000ABF2A /* TimeSmoother.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CEE2E7D13D6B7D4000ABF2A /* TimeSmoother.cpp */; }; C80711AD135DB85F002F601B /* InputOperations.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C80711AB135DB85F002F601B /* InputOperations.cpp */; }; @@ -1065,6 +1067,10 @@ 7C89627F13B7031E003631FE /* GUIWindowScreensaverDim.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GUIWindowScreensaverDim.h; sourceTree = "<group>"; }; 7C99B7BC1340730000FC2B16 /* GUIDialogPlayEject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GUIDialogPlayEject.cpp; sourceTree = "<group>"; }; 7C99B7BD1340730000FC2B16 /* GUIDialogPlayEject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GUIDialogPlayEject.h; sourceTree = "<group>"; }; + 7CC30E02162925E6003E7579 /* MusicThumbLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MusicThumbLoader.cpp; sourceTree = "<group>"; }; + 7CC30E03162925E6003E7579 /* MusicThumbLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MusicThumbLoader.h; sourceTree = "<group>"; }; + 7CC30E0516292601003E7579 /* VideoThumbLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VideoThumbLoader.cpp; sourceTree = "<group>"; }; + 7CC30E0616292601003E7579 /* VideoThumbLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VideoThumbLoader.h; sourceTree = "<group>"; }; 7CCFD9971514950700211D82 /* PCMCodec.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PCMCodec.cpp; sourceTree = "<group>"; }; 7CCFD9981514950700211D82 /* PCMCodec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PCMCodec.h; sourceTree = "<group>"; }; 7CEE2E7D13D6B7D4000ABF2A /* TimeSmoother.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TimeSmoother.cpp; sourceTree = "<group>"; }; @@ -5588,6 +5594,8 @@ 36A9467315CF208B00727135 /* MusicDbUrl.h */, F56C8626131F42EA000AD0F6 /* MusicInfoLoader.cpp */, F56C8627131F42EA000AD0F6 /* MusicInfoLoader.h */, + 7CC30E02162925E6003E7579 /* MusicThumbLoader.cpp */, + 7CC30E03162925E6003E7579 /* MusicThumbLoader.h */, F56C8628131F42EA000AD0F6 /* Song.cpp */, F56C8629131F42EA000AD0F6 /* Song.h */, ); @@ -6177,6 +6185,8 @@ F56C8797131F42EC000AD0F6 /* VideoInfoTag.h */, F56C8798131F42EC000AD0F6 /* VideoReferenceClock.cpp */, F56C8799131F42EC000AD0F6 /* VideoReferenceClock.h */, + 7CC30E0516292601003E7579 /* VideoThumbLoader.cpp */, + 7CC30E0616292601003E7579 /* VideoThumbLoader.h */, ); path = video; sourceTree = "<group>"; @@ -7577,6 +7587,8 @@ 1D638120161E20F2003603ED /* PeripheralImon.cpp in Sources */, DF24EADE1621E67200034265 /* DVDDemuxBXA.cpp in Sources */, 36A95DAD1624896C00727135 /* GUIDialogMediaFilter.cpp in Sources */, + 7CC30E04162925E6003E7579 /* MusicThumbLoader.cpp in Sources */, + 7CC30E0716292601003E7579 /* VideoThumbLoader.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/XBMC.xcodeproj/project.pbxproj b/XBMC.xcodeproj/project.pbxproj index 00d62d6a84..bc7881f8b4 100644 --- a/XBMC.xcodeproj/project.pbxproj +++ b/XBMC.xcodeproj/project.pbxproj @@ -284,6 +284,8 @@ 7CAA20511079C8160096DE39 /* BaseRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CAA204F1079C8160096DE39 /* BaseRenderer.cpp */; }; 7CAA25351085963B0096DE39 /* PasswordManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CAA25331085963B0096DE39 /* PasswordManager.cpp */; }; 7CBEBB8412912BA400431822 /* fstrcmp.c in Sources */ = {isa = PBXBuildFile; fileRef = 7CBEBB8212912BA300431822 /* fstrcmp.c */; }; + 7CC30DB116291A5C003E7579 /* MusicThumbLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CC30DAF16291A5C003E7579 /* MusicThumbLoader.cpp */; }; + 7CC30DC016291C2C003E7579 /* VideoThumbLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CC30DBE16291C2C003E7579 /* VideoThumbLoader.cpp */; }; 7CCF7E721067643800992676 /* DirectoryNodeSets.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CCF7E701067643800992676 /* DirectoryNodeSets.cpp */; }; 7CCF7F1D1069F3AE00992676 /* Builtins.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CCF7F1B1069F3AE00992676 /* Builtins.cpp */; }; 7CCF7FC9106A0DF500992676 /* TimeUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CCF7FC7106A0DF500992676 /* TimeUtils.cpp */; }; @@ -1595,6 +1597,10 @@ 7CAA25371085971C0096DE39 /* MusicArtistInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MusicArtistInfo.h; sourceTree = "<group>"; }; 7CAA25381085971C0096DE39 /* ScraperUrl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScraperUrl.h; sourceTree = "<group>"; }; 7CBEBB8212912BA300431822 /* fstrcmp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = fstrcmp.c; sourceTree = "<group>"; }; + 7CC30DAF16291A5C003E7579 /* MusicThumbLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MusicThumbLoader.cpp; sourceTree = "<group>"; }; + 7CC30DB016291A5C003E7579 /* MusicThumbLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MusicThumbLoader.h; sourceTree = "<group>"; }; + 7CC30DBE16291C2C003E7579 /* VideoThumbLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VideoThumbLoader.cpp; sourceTree = "<group>"; }; + 7CC30DBF16291C2C003E7579 /* VideoThumbLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VideoThumbLoader.h; sourceTree = "<group>"; }; 7CCF7E701067643800992676 /* DirectoryNodeSets.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DirectoryNodeSets.cpp; sourceTree = "<group>"; }; 7CCF7E711067643800992676 /* DirectoryNodeSets.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DirectoryNodeSets.h; sourceTree = "<group>"; }; 7CCF7F1B1069F3AE00992676 /* Builtins.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Builtins.cpp; sourceTree = "<group>"; }; @@ -3567,6 +3573,8 @@ 36A9466615CF1FD200727135 /* MusicDbUrl.h */, E38E1D910D25F9FD00618676 /* MusicInfoLoader.cpp */, E38E1D920D25F9FD00618676 /* MusicInfoLoader.h */, + 7CC30DAF16291A5C003E7579 /* MusicThumbLoader.cpp */, + 7CC30DB016291A5C003E7579 /* MusicThumbLoader.h */, E38E1E0D0D25F9FD00618676 /* Song.cpp */, E38E1E0E0D25F9FD00618676 /* Song.h */, ); @@ -4100,6 +4108,8 @@ E38E1E980D25F9FD00618676 /* VideoInfoTag.h */, F59876BF0FBA351D008EF4FB /* VideoReferenceClock.cpp */, F59876BE0FBA351D008EF4FB /* VideoReferenceClock.h */, + 7CC30DBE16291C2C003E7579 /* VideoThumbLoader.cpp */, + 7CC30DBF16291C2C003E7579 /* VideoThumbLoader.h */, ); path = video; sourceTree = "<group>"; @@ -7610,6 +7620,8 @@ 1D638128161E211E003603ED /* PeripheralImon.cpp in Sources */, AE89ACA61621DAB800E17DBC /* DVDDemuxBXA.cpp in Sources */, 36A95DA51624894400727135 /* GUIDialogMediaFilter.cpp in Sources */, + 7CC30DB116291A5C003E7579 /* MusicThumbLoader.cpp in Sources */, + 7CC30DC016291C2C003E7579 /* VideoThumbLoader.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/project/VS2010Express/XBMC.vcxproj b/project/VS2010Express/XBMC.vcxproj index 1b12b0c46d..010cd759ce 100644 --- a/project/VS2010Express/XBMC.vcxproj +++ b/project/VS2010Express/XBMC.vcxproj @@ -1201,6 +1201,8 @@ </ClInclude> <ClInclude Include="..\..\xbmc\interfaces\json-rpc\AddonsOperations.h" /> <ClCompile Include="..\..\xbmc\ThumbLoader.cpp" /> + <ClCompile Include="..\..\xbmc\video\VideoThumbLoader.cpp" /> + <ClCompile Include="..\..\xbmc\music\MusicThumbLoader.cpp" /> <ClCompile Include="..\..\xbmc\ThumbnailCache.cpp" /> <ClCompile Include="..\..\xbmc\URL.cpp" /> <ClCompile Include="..\..\xbmc\Util.cpp" /> @@ -2350,6 +2352,8 @@ <ClInclude Include="..\..\xbmc\TextureDatabase.h" /> <ClInclude Include="..\..\xbmc\DatabaseManager.h" /> <ClInclude Include="..\..\xbmc\ThumbLoader.h" /> + <ClInclude Include="..\..\xbmc\video\VideoThumbLoader.h" /> + <ClInclude Include="..\..\xbmc\music\MusicThumbLoader.h" /> <ClInclude Include="..\..\xbmc\ThumbnailCache.h" /> <ClInclude Include="..\..\xbmc\URL.h" /> <ClInclude Include="..\..\xbmc\Util.h" /> diff --git a/project/VS2010Express/XBMC.vcxproj.filters b/project/VS2010Express/XBMC.vcxproj.filters index 36ede2fb18..357ac3ff82 100644 --- a/project/VS2010Express/XBMC.vcxproj.filters +++ b/project/VS2010Express/XBMC.vcxproj.filters @@ -2529,6 +2529,12 @@ <ClCompile Include="..\..\xbmc\pictures\PictureThumbLoader.cpp"> <Filter>pictures</Filter> </ClCompile> + <ClCompile Include="..\..\xbmc\music\MusicThumbLoader.cpp"> + <Filter>music</Filter> + </ClCompile> + <ClCompile Include="..\..\xbmc\video\VideoThumbLoader.cpp"> + <Filter>video</Filter> + </ClCompile> <ClCompile Include="..\..\xbmc\dbwrappers\Database.cpp"> <Filter>dbwrappers</Filter> </ClCompile> @@ -5475,6 +5481,12 @@ <ClInclude Include="..\..\xbmc\pictures\PictureThumbLoader.h"> <Filter>pictures</Filter> </ClInclude> + <ClInclude Include="..\..\xbmc\music\MusicThumbLoader.h"> + <Filter>music</Filter> + </ClInclude> + <ClInclude Include="..\..\xbmc\video\VideoThumbLoader.h"> + <Filter>video</Filter> + </ClInclude> <ClInclude Include="..\..\xbmc\dbwrappers\Database.h"> <Filter>dbwrappers</Filter> </ClInclude> diff --git a/xbmc/GUIInfoManager.cpp b/xbmc/GUIInfoManager.cpp index f3ad5a8fa4..fa5b6adfaf 100644 --- a/xbmc/GUIInfoManager.cpp +++ b/xbmc/GUIInfoManager.cpp @@ -75,7 +75,8 @@ #include "addons/AddonManager.h" #include "interfaces/info/InfoBool.h" -#include "ThumbLoader.h" +#include "video/VideoThumbLoader.h" +#include "music/MusicThumbLoader.h" #include "cores/AudioEngine/Utils/AEUtil.h" #define SYSHEATUPDATEINTERVAL 60000 diff --git a/xbmc/TextureCacheJob.cpp b/xbmc/TextureCacheJob.cpp index 8d024b6332..dc036f5c50 100644 --- a/xbmc/TextureCacheJob.cpp +++ b/xbmc/TextureCacheJob.cpp @@ -32,7 +32,7 @@ #include "utils/StringUtils.h" #include "URL.h" #include "FileItem.h" -#include "ThumbLoader.h" +#include "music/MusicThumbLoader.h" #include "music/tags/MusicInfoTag.h" CTextureCacheJob::CTextureCacheJob(const CStdString &url, const CStdString &oldHash) diff --git a/xbmc/ThumbLoader.cpp b/xbmc/ThumbLoader.cpp index e270c07728..c8cd1954fe 100644 --- a/xbmc/ThumbLoader.cpp +++ b/xbmc/ThumbLoader.cpp @@ -18,31 +18,13 @@ * */ -#include "filesystem/StackDirectory.h" #include "ThumbLoader.h" -#include "utils/URIUtils.h" -#include "URL.h" #include "filesystem/File.h" -#include "filesystem/DirectoryCache.h" #include "FileItem.h" -#include "settings/GUISettings.h" -#include "GUIUserMessages.h" -#include "guilib/GUIWindowManager.h" #include "TextureCache.h" -#include "utils/log.h" -#include "video/VideoInfoTag.h" -#include "video/VideoDatabase.h" -#include "cores/dvdplayer/DVDFileInfo.h" -#include "video/VideoInfoScanner.h" -#include "music/tags/MusicInfoTag.h" -#include "music/tags/MusicInfoTagLoaderFactory.h" -#include "music/infoscanner/MusicInfoScanner.h" -#include "music/Artist.h" -using namespace XFILE; using namespace std; -using namespace VIDEO; -using namespace MUSIC_INFO; +using namespace XFILE; CThumbLoader::CThumbLoader(int nThreads) : CBackgroundInfoLoader(nThreads) @@ -68,424 +50,6 @@ void CThumbLoader::SetCachedImage(const CFileItem &item, const CStdString &type, db.SetTextureForPath(item.GetPath(), type, image); } -CThumbExtractor::CThumbExtractor(const CFileItem& item, const CStdString& listpath, bool thumb, const CStdString& target) -{ - m_listpath = listpath; - m_target = target; - m_thumb = thumb; - m_item = item; - - m_path = item.GetPath(); - - if (item.IsVideoDb() && item.HasVideoInfoTag()) - m_path = item.GetVideoInfoTag()->m_strFileNameAndPath; - - if (URIUtils::IsStack(m_path)) - m_path = CStackDirectory::GetFirstStackedFile(m_path); -} - -CThumbExtractor::~CThumbExtractor() -{ -} - -bool CThumbExtractor::operator==(const CJob* job) const -{ - if (strcmp(job->GetType(),GetType()) == 0) - { - const CThumbExtractor* jobExtract = dynamic_cast<const CThumbExtractor*>(job); - if (jobExtract && jobExtract->m_listpath == m_listpath) - return true; - } - return false; -} - -bool CThumbExtractor::DoWork() -{ - if (URIUtils::IsLiveTV(m_path) - || URIUtils::IsUPnP(m_path) - || URIUtils::IsDAAP(m_path) - || m_item.IsDVD() - || m_item.IsDVDImage() - || m_item.IsDVDFile(false, true) - || m_item.IsInternetStream() - || m_item.IsDiscStub() - || m_item.IsPlayList()) - return false; - - if (URIUtils::IsRemote(m_path) && !URIUtils::IsOnLAN(m_path)) - return false; - - bool result=false; - if (m_thumb) - { - CLog::Log(LOGDEBUG,"%s - trying to extract thumb from video file %s", __FUNCTION__, m_path.c_str()); - // construct the thumb cache file - CTextureDetails details; - details.file = CTextureCache::GetCacheFile(m_target) + ".jpg"; - result = CDVDFileInfo::ExtractThumb(m_path, details, &m_item.GetVideoInfoTag()->m_streamDetails); - if(result) - { - CTextureCache::Get().AddCachedTexture(m_target, details); - m_item.SetProperty("HasAutoThumb", true); - m_item.SetProperty("AutoThumbImage", m_target); - m_item.SetArt("thumb", CTextureCache::GetCachedPath(details.file)); - } - } - else if (m_item.HasVideoInfoTag() && !m_item.GetVideoInfoTag()->HasStreamDetails()) - { - CLog::Log(LOGDEBUG,"%s - trying to extract filestream details from video file %s", __FUNCTION__, m_path.c_str()); - result = CDVDFileInfo::GetFileStreamDetails(&m_item); - } - - return result; -} - -CVideoThumbLoader::CVideoThumbLoader() : - CThumbLoader(1), CJobQueue(true), m_pStreamDetailsObs(NULL) -{ - m_database = new CVideoDatabase(); -} - -CVideoThumbLoader::~CVideoThumbLoader() -{ - StopThread(); - delete m_database; -} - -void CVideoThumbLoader::Initialize() -{ - m_database->Open(); -} - -void CVideoThumbLoader::OnLoaderStart() -{ - Initialize(); -} - -void CVideoThumbLoader::OnLoaderFinish() -{ - m_database->Close(); -} - -static void SetupRarOptions(CFileItem& item, const CStdString& path) -{ - CStdString path2(path); - if (item.IsVideoDb() && item.HasVideoInfoTag()) - path2 = item.GetVideoInfoTag()->m_strFileNameAndPath; - CURL url(path2); - CStdString opts = url.GetOptions(); - if (opts.Find("flags") > -1) - return; - if (opts.size()) - opts += "&flags=8"; - else - opts = "?flags=8"; - url.SetOptions(opts); - if (item.IsVideoDb() && item.HasVideoInfoTag()) - item.GetVideoInfoTag()->m_strFileNameAndPath = url.Get(); - else - item.SetPath(url.Get()); - g_directoryCache.ClearDirectory(url.GetWithoutFilename()); -} - -vector<string> CVideoThumbLoader::GetArtTypes(const string &type) -{ - vector<string> ret; - if (type != "episode") - { - ret.push_back("fanart"); - ret.push_back("poster"); - } - if (type == "tvshow" || type == "season" || type.empty()) - ret.push_back("banner"); - ret.push_back("thumb"); - return ret; -} - -/** - * Look for a thumbnail for pItem. If one does not exist, look for an autogenerated - * thumbnail. If that does not exist, attempt to autogenerate one. Finally, check - * for the existance of fanart and set properties accordingly. - * @return: true if pItem has been modified - */ -bool CVideoThumbLoader::LoadItem(CFileItem* pItem) -{ - if (pItem->m_bIsShareOrDrive - || pItem->IsParentFolder()) - return false; - - m_database->Open(); - - if (pItem->HasVideoInfoTag() && !pItem->GetVideoInfoTag()->HasStreamDetails() && - (pItem->GetVideoInfoTag()->m_type == "movie" || pItem->GetVideoInfoTag()->m_type == "episode" || pItem->GetVideoInfoTag()->m_type == "musicvideo")) - { - if (m_database->GetStreamDetails(*pItem->GetVideoInfoTag())) - pItem->SetInvalid(); - } - - // video db items normally have info in the database - if (pItem->HasVideoInfoTag() && pItem->GetArt().empty()) - { - FillLibraryArt(*pItem); - - if (pItem->GetVideoInfoTag()->m_type == "set" || - pItem->GetVideoInfoTag()->m_type == "actor" || - pItem->GetVideoInfoTag()->m_type == "artist" || - pItem->GetVideoInfoTag()->m_type == "director" || - pItem->GetVideoInfoTag()->m_type == "writer" || - pItem->GetVideoInfoTag()->m_type == "season" ) - { - m_database->Close(); - return true; // nothing else to be done - } - } - - // if we have no art, look for it all - map<string, string> artwork = pItem->GetArt(); - if (artwork.empty()) - { - vector<string> artTypes = GetArtTypes(pItem->HasVideoInfoTag() ? pItem->GetVideoInfoTag()->m_type : ""); - for (vector<string>::const_iterator i = artTypes.begin(); i != artTypes.end(); ++i) - { - std::string type = *i; - std::string art = GetCachedImage(*pItem, type); - if (art.empty()) - { - art = GetLocalArt(*pItem, type, type=="fanart"); - if (!art.empty()) // cache it - SetCachedImage(*pItem, type, art); - } - if (!art.empty()) - { - CTextureCache::Get().BackgroundCacheImage(art); - artwork.insert(make_pair(type, art)); - } - } - pItem->SetArt(artwork); - } - - // thumbnails are special-cased due to auto-generation - if (!pItem->HasArt("thumb") && !pItem->m_bIsFolder && pItem->IsVideo()) - { - // create unique thumb for auto generated thumbs - CStdString thumbURL = GetEmbeddedThumbURL(*pItem); - if (CTextureCache::Get().HasCachedImage(thumbURL)) - { - CTextureCache::Get().BackgroundCacheImage(thumbURL); - pItem->SetProperty("HasAutoThumb", true); - pItem->SetProperty("AutoThumbImage", thumbURL); - pItem->SetArt("thumb", thumbURL); - } - else if (g_guiSettings.GetBool("myvideos.extractthumb") && - g_guiSettings.GetBool("myvideos.extractflags")) - { - CFileItem item(*pItem); - CStdString path(item.GetPath()); - if (URIUtils::IsInRAR(item.GetPath())) - SetupRarOptions(item,path); - - CThumbExtractor* extract = new CThumbExtractor(item, path, true, thumbURL); - AddJob(extract); - - m_database->Close(); - return true; - } - } - - // flag extraction - if (!pItem->m_bIsFolder && - pItem->HasVideoInfoTag() && - g_guiSettings.GetBool("myvideos.extractflags") && - (!pItem->GetVideoInfoTag()->HasStreamDetails() || - pItem->GetVideoInfoTag()->m_streamDetails.GetVideoDuration() <= 0)) - { - CFileItem item(*pItem); - CStdString path(item.GetPath()); - if (URIUtils::IsInRAR(item.GetPath())) - SetupRarOptions(item,path); - CThumbExtractor* extract = new CThumbExtractor(item,path,false); - AddJob(extract); - } - - m_database->Close(); - return true; -} - -bool CVideoThumbLoader::FillLibraryArt(CFileItem &item) -{ - CVideoInfoTag &tag = *item.GetVideoInfoTag(); - if (tag.m_iDbId > -1 && !tag.m_type.IsEmpty()) - { - map<string, string> artwork; - m_database->Open(); - if (m_database->GetArtForItem(tag.m_iDbId, tag.m_type, artwork)) - item.SetArt(artwork); - else if (tag.m_type == "artist") - { // we retrieve music video art from the music database (no backward compat) - CMusicDatabase database; - database.Open(); - int idArtist = database.GetArtistByName(item.GetLabel()); - if (database.GetArtForItem(idArtist, "artist", artwork)) - item.SetArt(artwork); - } - else if (tag.m_type == "album") - { // we retrieve music video art from the music database (no backward compat) - CMusicDatabase database; - database.Open(); - int idAlbum = database.GetAlbumByName(item.GetLabel(), tag.m_artist); - if (database.GetArtForItem(idAlbum, "album", artwork)) - item.SetArt(artwork); - } - else - { - if (tag.m_type == "movie" || tag.m_type == "episode" || - tag.m_type == "tvshow" || tag.m_type == "musicvideo") - { // no art in the library, so find it locally and add - SScanSettings settings; - ADDON::ScraperPtr info = m_database->GetScraperForPath(tag.m_strPath, settings); - if (info) - { - CFileItem tmpItem(item); - tmpItem.SetPath(tag.GetPath()); - CVideoInfoScanner scanner; - scanner.GetArtwork(&tmpItem, info->Content(), tag.m_type != "episode" && settings.parent_name_root, true); - item.SetArt(tmpItem.GetArt()); - } - } - else if (tag.m_type == "set") - { // no art for a set -> use the first movie for this set for art - CFileItemList items; - if (m_database->GetMoviesNav("videodb://1/2/", items, -1, -1, -1, -1, -1, -1, tag.m_iDbId) && items.Size() > 0) - { - LoadItem(items[0].get()); - if (!items[0]->GetArt().empty()) - item.SetArt(items[0]->GetArt()); - } - } - else if (tag.m_type == "actor" || - tag.m_type == "writer" || tag.m_type == "director") - { - // We can't realistically get the local thumbs (as we'd need to check every movie that contains this actor) - // and most users won't have local actor thumbs that are actually different than the scraped ones. - if (g_guiSettings.GetBool("videolibrary.actorthumbs")) - { - tag.m_strPictureURL.Parse(); - CStdString thumb = CScraperUrl::GetThumbURL(tag.m_strPictureURL.GetFirstThumb()); - if (!thumb.IsEmpty()) - item.SetArt("thumb", thumb); - } - } - else if (tag.m_type == "season") - { - // season art is fetched on scan from the tvshow root path (m_strPath in the season info tag) - // or from the show m_strPictureURL member of the tvshow, so grab the tvshow to get this. - CVideoInfoTag show; - m_database->GetTvShowInfo(tag.m_strPath, show, tag.m_iIdShow); - map<int, string> seasons; - CVideoInfoScanner::GetSeasonThumbs(show, seasons, true); - map<int, string>::iterator season = seasons.find(tag.m_iSeason); - if (season != seasons.end()) - item.SetArt("thumb", season->second); - } - // add to the database for next time around - map<string, string> artwork = item.GetArt(); - if (!artwork.empty()) - { - m_database->SetArtForItem(tag.m_iDbId, tag.m_type, artwork); - for (map<string, string>::iterator i = artwork.begin(); i != artwork.end(); ++i) - CTextureCache::Get().BackgroundCacheImage(i->second); - } - else // nothing found - set an empty thumb so that next time around we don't hit here again - m_database->SetArtForItem(tag.m_iDbId, tag.m_type, "thumb", ""); - } - // For episodes and seasons, we want to set fanart for that of the show - if (!item.HasArt("fanart") && tag.m_iIdShow >= 0) - { - map<string, string> showArt; - if (m_database->GetArtForItem(tag.m_iIdShow, "tvshow", showArt)) - { - map<string, string>::iterator i = showArt.find("fanart"); - if (i != showArt.end()) - item.SetArt("fanart", i->second); - if ((i = showArt.find("thumb")) != showArt.end()) - item.SetArt("tvshowthumb", i->second); - } - } - m_database->Close(); - } - return !item.GetArt().empty(); -} - -bool CVideoThumbLoader::FillThumb(CFileItem &item) -{ - if (item.HasArt("thumb")) - return true; - CStdString thumb = GetCachedImage(item, "thumb"); - if (thumb.IsEmpty()) - { - thumb = GetLocalArt(item, "thumb"); - if (!thumb.IsEmpty()) - SetCachedImage(item, "thumb", thumb); - } - item.SetArt("thumb", thumb); - return !thumb.IsEmpty(); -} - -std::string CVideoThumbLoader::GetLocalArt(const CFileItem &item, const std::string &type, bool checkFolder) -{ - std::string art; - if (!type.empty()) - { - art = item.FindLocalArt(type + ".jpg", checkFolder); - if (art.empty()) - art = item.FindLocalArt(type + ".png", checkFolder); - } - if (art.empty() && (type.empty() || type == "thumb")) - { // backward compatibility - art = item.FindLocalArt("", false); - if (art.empty() && (checkFolder || (item.m_bIsFolder && !item.IsFileFolder()))) - { // try movie.tbn - art = item.FindLocalArt("movie.tbn", true); - if (art.empty()) // try folder.jpg - art = item.FindLocalArt("folder.jpg", true); - } - } - return art; -} - -CStdString CVideoThumbLoader::GetEmbeddedThumbURL(const CFileItem &item) -{ - CStdString path(item.GetPath()); - if (item.IsVideoDb() && item.HasVideoInfoTag()) - path = item.GetVideoInfoTag()->m_strFileNameAndPath; - if (URIUtils::IsStack(path)) - path = CStackDirectory::GetFirstStackedFile(path); - - return CTextureCache::GetWrappedImageURL(path, "video"); -} - -void CVideoThumbLoader::OnJobComplete(unsigned int jobID, bool success, CJob* job) -{ - if (success) - { - CThumbExtractor* loader = (CThumbExtractor*)job; - loader->m_item.SetPath(loader->m_listpath); - CVideoInfoTag* info = loader->m_item.GetVideoInfoTag(); - - if (loader->m_thumb && info->m_iDbId > 0 && !info->m_type.empty()) - m_database->SetArtForItem(info->m_iDbId, info->m_type, "thumb", loader->m_item.GetArt("thumb")); - - if (m_pStreamDetailsObs) - m_pStreamDetailsObs->OnStreamDetails(info->m_streamDetails, info->m_strFileNameAndPath, info->m_iFileId); - if (m_pObserver) - m_pObserver->OnItemLoaded(&loader->m_item); - CFileItemPtr pItem(new CFileItem(loader->m_item)); - CGUIMessage msg(GUI_MSG_NOTIFY_ALL, 0, 0, GUI_MSG_UPDATE_ITEM, 0, pItem); - g_windowManager.SendThreadMessage(msg); - } - CJobQueue::OnJobComplete(jobID, success, job); -} - CProgramThumbLoader::CProgramThumbLoader() { } @@ -530,7 +94,7 @@ CStdString CProgramThumbLoader::GetLocalThumb(const CFileItem &item) if (item.m_bIsFolder) { CStdString folderThumb = item.GetFolderThumb(); - if (XFILE::CFile::Exists(folderThumb)) + if (CFile::Exists(folderThumb)) return folderThumb; } else @@ -541,132 +105,3 @@ CStdString CProgramThumbLoader::GetLocalThumb(const CFileItem &item) } return ""; } - -CMusicThumbLoader::CMusicThumbLoader() : CThumbLoader(1) -{ - m_database = new CMusicDatabase; -} - -CMusicThumbLoader::~CMusicThumbLoader() -{ - delete m_database; -} - -void CMusicThumbLoader::Initialize() -{ - m_database->Open(); -} - -void CMusicThumbLoader::OnLoaderStart() -{ - Initialize(); -} - -void CMusicThumbLoader::OnLoaderFinish() -{ - m_database->Close(); -} - -bool CMusicThumbLoader::LoadItem(CFileItem* pItem) -{ - if (pItem->m_bIsShareOrDrive) - return true; - - if (pItem->HasMusicInfoTag() && pItem->GetArt().empty()) - { - if (FillLibraryArt(*pItem)) - return true; - if (pItem->GetMusicInfoTag()->GetType() == "artist") - return true; // no fallback - } - - if (!pItem->HasArt("fanart")) - { - if (pItem->HasMusicInfoTag() && !pItem->GetMusicInfoTag()->GetArtist().empty()) - { - std::string artist = pItem->GetMusicInfoTag()->GetArtist()[0]; - m_database->Open(); - int idArtist = m_database->GetArtistByName(artist); - if (idArtist >= 0) - { - string fanart = m_database->GetArtForItem(idArtist, "artist", "fanart"); - if (!fanart.empty()) - pItem->SetArt("fanart", fanart); - } - m_database->Close(); - } - } - - if (!pItem->HasArt("thumb")) - FillThumb(*pItem); - - return true; -} - -bool CMusicThumbLoader::FillThumb(CFileItem &item) -{ - if (item.HasArt("thumb")) - return true; - CStdString thumb = GetCachedImage(item, "thumb"); - if (thumb.IsEmpty()) - { - thumb = item.GetUserMusicThumb(); - if (!thumb.IsEmpty()) - SetCachedImage(item, "thumb", thumb); - } - item.SetArt("thumb", thumb); - return !thumb.IsEmpty(); -} - -bool CMusicThumbLoader::FillLibraryArt(CFileItem &item) -{ - CMusicInfoTag &tag = *item.GetMusicInfoTag(); - if (tag.GetDatabaseId() > -1 && !tag.GetType().empty()) - { - m_database->Open(); - map<string, string> artwork; - if (m_database->GetArtForItem(tag.GetDatabaseId(), tag.GetType(), artwork)) - item.SetArt(artwork); - else if (tag.GetType() == "song") - { // no art for the song, try the album - if (m_database->GetArtForItem(tag.GetAlbumId(), "album", artwork)) - item.SetArt(artwork); - } - else if (tag.GetType() == "artist") - { - { // Need the artist thumb/fanart which isn't grabbed during normal directory fetches - CArtist artist; - m_database->GetArtistInfo(tag.GetDatabaseId(), artist, false); - CMusicInfoScanner scanner; - artwork = scanner.GetArtistArtwork(tag.GetDatabaseId(), &artist); - item.SetArt(artwork); - } - // add to the database for next time around - map<string, string> artwork = item.GetArt(); - if (!artwork.empty()) - { - m_database->SetArtForItem(tag.GetDatabaseId(), tag.GetType(), artwork); - for (map<string, string>::iterator i = artwork.begin(); i != artwork.end(); ++i) - CTextureCache::Get().BackgroundCacheImage(i->second); - } - else // nothing found - set an empty thumb so that next time around we don't hit here again - m_database->SetArtForItem(tag.GetDatabaseId(), tag.GetType(), "thumb", ""); - } - if (tag.GetType() == "song" || tag.GetType() == "album") - { // fanart from the artist - item.SetArt("fanart", m_database->GetArtistArtForItem(tag.GetDatabaseId(), tag.GetType(), "fanart")); - } - m_database->Close(); - } - return !item.GetArt().empty(); -} - -bool CMusicThumbLoader::GetEmbeddedThumb(const std::string &path, EmbeddedArt &art) -{ - auto_ptr<IMusicInfoTagLoader> pLoader (CMusicInfoTagLoaderFactory::CreateLoader(path)); - CMusicInfoTag tag; - if (NULL != pLoader.get()) - pLoader->Load(path, tag, &art); - - return !art.empty(); -} diff --git a/xbmc/ThumbLoader.h b/xbmc/ThumbLoader.h index f75d384f19..13a70ea2c1 100644 --- a/xbmc/ThumbLoader.h +++ b/xbmc/ThumbLoader.h @@ -1,3 +1,4 @@ +#pragma once /* * Copyright (C) 2005-2012 Team XBMC * http://www.xbmc.org @@ -18,51 +19,8 @@ * */ -#ifndef THUMBLOADER_H -#define THUMBLOADER_H #include "BackgroundInfoLoader.h" -#include "utils/JobManager.h" -#include "FileItem.h" - -#define kJobTypeMediaFlags "mediaflags" - -class CStreamDetails; -class IStreamDetailsObserver; -class CVideoDatabase; -class CMusicDatabase; - -/*! - \ingroup thumbs,jobs - \brief Thumb extractor job class - - Used by the CVideoThumbLoader to perform asynchronous generation of thumbs - - \sa CVideoThumbLoader and CJob - */ -class CThumbExtractor : public CJob -{ -public: - CThumbExtractor(const CFileItem& item, const CStdString& listpath, bool thumb, const CStdString& strTarget=""); - virtual ~CThumbExtractor(); - - /*! - \brief Work function that extracts thumb. - */ - virtual bool DoWork(); - - virtual const char* GetType() const - { - return kJobTypeMediaFlags; - } - - virtual bool operator==(const CJob* job) const; - - CStdString m_path; ///< path of video to extract thumb from - CStdString m_target; ///< thumbpath - CStdString m_listpath; ///< path used in fileitem list - CFileItem m_item; - bool m_thumb; ///< extract thumb? -}; +#include "utils/StdString.h" class CThumbLoader : public CBackgroundInfoLoader { @@ -93,68 +51,6 @@ public: static void SetCachedImage(const CFileItem &item, const CStdString &type, const CStdString &image); }; -class CVideoThumbLoader : public CThumbLoader, public CJobQueue -{ -public: - CVideoThumbLoader(); - virtual ~CVideoThumbLoader(); - - virtual void Initialize(); - virtual bool LoadItem(CFileItem* pItem); - void SetStreamDetailsObserver(IStreamDetailsObserver *pObs) { m_pStreamDetailsObs = pObs; } - - /*! \brief Fill the thumb of a video item - First uses a cached thumb from a previous run, then checks for a local thumb - and caches it for the next run - \param item the CFileItem object to fill - \return true if we fill the thumb, false otherwise - */ - static bool FillThumb(CFileItem &item); - - /*! \brief Find a particular art type for a given item, optionally checking at the folder level - \param item the CFileItem to search. - \param type the type of art to look for. - \param checkFolder whether to also check the folder level for files. Defaults to false. - \return the art file (if found), else empty. - */ - static std::string GetLocalArt(const CFileItem &item, const std::string &type, bool checkFolder = false); - - /*! \brief return the available art types for a given media type - \param type the type of media. - \return a vector of art types. - \sa GetLocalArt - */ - static std::vector<std::string> GetArtTypes(const std::string &type); - - /*! \brief helper function to retrieve a thumb URL for embedded video thumbs - \param item a video CFileItem. - \return a URL for the embedded thumb. - */ - static CStdString GetEmbeddedThumbURL(const CFileItem &item); - - /*! \brief helper function to fill the art for a video library item - \param item a video CFileItem - \return true if we fill art, false otherwise - */ - virtual bool FillLibraryArt(CFileItem &item); - - /*! - \brief Callback from CThumbExtractor on completion of a generated image - - Performs the callbacks and updates the GUI. - - \sa CImageLoader, IJobCallback - */ - virtual void OnJobComplete(unsigned int jobID, bool success, CJob *job); - -protected: - virtual void OnLoaderStart(); - virtual void OnLoaderFinish(); - - IStreamDetailsObserver *m_pStreamDetailsObs; - CVideoDatabase *m_database; -}; - class CProgramThumbLoader : public CThumbLoader { public: @@ -179,41 +75,3 @@ public: */ static CStdString GetLocalThumb(const CFileItem &item); }; - -namespace MUSIC_INFO -{ - class EmbeddedArt; -}; - -class CMusicThumbLoader : public CThumbLoader -{ -public: - CMusicThumbLoader(); - virtual ~CMusicThumbLoader(); - - virtual void Initialize(); - virtual bool LoadItem(CFileItem* pItem); - - /*! \brief helper function to fill the art for a video library item - \param item a video CFileItem - \return true if we fill art, false otherwise - */ - virtual bool FillLibraryArt(CFileItem &item); - - /*! \brief Fill the thumb of a music file/folder item - First uses a cached thumb from a previous run, then checks for a local thumb - and caches it for the next run - \param item the CFileItem object to fill - \return true if we fill the thumb, false otherwise - */ - static bool FillThumb(CFileItem &item); - - static bool GetEmbeddedThumb(const std::string &path, MUSIC_INFO::EmbeddedArt &art); - -protected: - virtual void OnLoaderStart(); - virtual void OnLoaderFinish(); - - CMusicDatabase *m_database; -}; -#endif diff --git a/xbmc/interfaces/json-rpc/FileItemHandler.cpp b/xbmc/interfaces/json-rpc/FileItemHandler.cpp index 481aadcd2d..7745f50b3a 100644 --- a/xbmc/interfaces/json-rpc/FileItemHandler.cpp +++ b/xbmc/interfaces/json-rpc/FileItemHandler.cpp @@ -36,7 +36,8 @@ #include "filesystem/Directory.h" #include "filesystem/File.h" #include "TextureCache.h" -#include "ThumbLoader.h" +#include "video/VideoThumbLoader.h" +#include "music/MusicThumbLoader.h" #include "Util.h" using namespace MUSIC_INFO; diff --git a/xbmc/interfaces/json-rpc/FileItemHandler.h b/xbmc/interfaces/json-rpc/FileItemHandler.h index 69379b7789..a0833c35aa 100644 --- a/xbmc/interfaces/json-rpc/FileItemHandler.h +++ b/xbmc/interfaces/json-rpc/FileItemHandler.h @@ -24,9 +24,10 @@ #include "JSONRPC.h" #include "JSONUtils.h" #include "FileItem.h" -#include "ThumbLoader.h" #include "utils/StdString.h" +class CThumbLoader; + namespace JSONRPC { class CFileItemHandler : public CJSONUtils diff --git a/xbmc/music/Makefile b/xbmc/music/Makefile index 66e4a7d5a6..045a2675ca 100644 --- a/xbmc/music/Makefile +++ b/xbmc/music/Makefile @@ -5,6 +5,7 @@ SRCS=Album.cpp \ MusicDatabase.cpp \ MusicDbUrl.cpp \ MusicInfoLoader.cpp \ + MusicThumbLoader.cpp \ Song.cpp \ LIB=music.a diff --git a/xbmc/music/MusicThumbLoader.cpp b/xbmc/music/MusicThumbLoader.cpp new file mode 100644 index 0000000000..11a0128981 --- /dev/null +++ b/xbmc/music/MusicThumbLoader.cpp @@ -0,0 +1,159 @@ +/* + * Copyright (C) 2012 Team XBMC + * http://www.xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ + +#include "MusicThumbLoader.h" +#include "FileItem.h" +#include "TextureCache.h" +#include "music/tags/MusicInfoTag.h" +#include "music/tags/MusicInfoTagLoaderFactory.h" +#include "music/infoscanner/MusicInfoScanner.h" +#include "music/Artist.h" + +using namespace std; +using namespace MUSIC_INFO; + +CMusicThumbLoader::CMusicThumbLoader() : CThumbLoader(1) +{ + m_database = new CMusicDatabase; +} + +CMusicThumbLoader::~CMusicThumbLoader() +{ + delete m_database; +} + +void CMusicThumbLoader::Initialize() +{ + m_database->Open(); +} + +void CMusicThumbLoader::OnLoaderStart() +{ + Initialize(); +} + +void CMusicThumbLoader::OnLoaderFinish() +{ + m_database->Close(); +} + +bool CMusicThumbLoader::LoadItem(CFileItem* pItem) +{ + if (pItem->m_bIsShareOrDrive) + return true; + + if (pItem->HasMusicInfoTag() && pItem->GetArt().empty()) + { + if (FillLibraryArt(*pItem)) + return true; + if (pItem->GetMusicInfoTag()->GetType() == "artist") + return true; // no fallback + } + + if (!pItem->HasArt("fanart")) + { + if (pItem->HasMusicInfoTag() && !pItem->GetMusicInfoTag()->GetArtist().empty()) + { + std::string artist = pItem->GetMusicInfoTag()->GetArtist()[0]; + m_database->Open(); + int idArtist = m_database->GetArtistByName(artist); + if (idArtist >= 0) + { + string fanart = m_database->GetArtForItem(idArtist, "artist", "fanart"); + if (!fanart.empty()) + pItem->SetArt("fanart", fanart); + } + m_database->Close(); + } + } + + if (!pItem->HasArt("thumb")) + FillThumb(*pItem); + + return true; +} + +bool CMusicThumbLoader::FillThumb(CFileItem &item) +{ + if (item.HasArt("thumb")) + return true; + CStdString thumb = GetCachedImage(item, "thumb"); + if (thumb.IsEmpty()) + { + thumb = item.GetUserMusicThumb(); + if (!thumb.IsEmpty()) + SetCachedImage(item, "thumb", thumb); + } + item.SetArt("thumb", thumb); + return !thumb.IsEmpty(); +} + +bool CMusicThumbLoader::FillLibraryArt(CFileItem &item) +{ + CMusicInfoTag &tag = *item.GetMusicInfoTag(); + if (tag.GetDatabaseId() > -1 && !tag.GetType().empty()) + { + m_database->Open(); + map<string, string> artwork; + if (m_database->GetArtForItem(tag.GetDatabaseId(), tag.GetType(), artwork)) + item.SetArt(artwork); + else if (tag.GetType() == "song") + { // no art for the song, try the album + if (m_database->GetArtForItem(tag.GetAlbumId(), "album", artwork)) + item.SetArt(artwork); + } + else if (tag.GetType() == "artist") + { + { // Need the artist thumb/fanart which isn't grabbed during normal directory fetches + CArtist artist; + m_database->GetArtistInfo(tag.GetDatabaseId(), artist, false); + CMusicInfoScanner scanner; + artwork = scanner.GetArtistArtwork(tag.GetDatabaseId(), &artist); + item.SetArt(artwork); + } + // add to the database for next time around + map<string, string> artwork = item.GetArt(); + if (!artwork.empty()) + { + m_database->SetArtForItem(tag.GetDatabaseId(), tag.GetType(), artwork); + for (map<string, string>::iterator i = artwork.begin(); i != artwork.end(); ++i) + CTextureCache::Get().BackgroundCacheImage(i->second); + } + else // nothing found - set an empty thumb so that next time around we don't hit here again + m_database->SetArtForItem(tag.GetDatabaseId(), tag.GetType(), "thumb", ""); + } + if (tag.GetType() == "song" || tag.GetType() == "album") + { // fanart from the artist + item.SetArt("fanart", m_database->GetArtistArtForItem(tag.GetDatabaseId(), tag.GetType(), "fanart")); + } + m_database->Close(); + } + return !item.GetArt().empty(); +} + +bool CMusicThumbLoader::GetEmbeddedThumb(const std::string &path, EmbeddedArt &art) +{ + auto_ptr<IMusicInfoTagLoader> pLoader (CMusicInfoTagLoaderFactory::CreateLoader(path)); + CMusicInfoTag tag; + if (NULL != pLoader.get()) + pLoader->Load(path, tag, &art); + + return !art.empty(); +} diff --git a/xbmc/music/MusicThumbLoader.h b/xbmc/music/MusicThumbLoader.h new file mode 100644 index 0000000000..09358d5f32 --- /dev/null +++ b/xbmc/music/MusicThumbLoader.h @@ -0,0 +1,62 @@ +#pragma once +/* + * Copyright (C) 2012 Team XBMC + * http://www.xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ + +#include "ThumbLoader.h" + +class CFileItem; +class CMusicDatabase; + +namespace MUSIC_INFO +{ + class EmbeddedArt; +}; + +class CMusicThumbLoader : public CThumbLoader +{ +public: + CMusicThumbLoader(); + virtual ~CMusicThumbLoader(); + + virtual void Initialize(); + virtual bool LoadItem(CFileItem* pItem); + + /*! \brief helper function to fill the art for a video library item + \param item a video CFileItem + \return true if we fill art, false otherwise + */ + virtual bool FillLibraryArt(CFileItem &item); + + /*! \brief Fill the thumb of a music file/folder item + First uses a cached thumb from a previous run, then checks for a local thumb + and caches it for the next run + \param item the CFileItem object to fill + \return true if we fill the thumb, false otherwise + */ + static bool FillThumb(CFileItem &item); + + static bool GetEmbeddedThumb(const std::string &path, MUSIC_INFO::EmbeddedArt &art); + +protected: + virtual void OnLoaderStart(); + virtual void OnLoaderFinish(); + + CMusicDatabase *m_database; +}; diff --git a/xbmc/music/dialogs/GUIDialogMusicInfo.cpp b/xbmc/music/dialogs/GUIDialogMusicInfo.cpp index c26b07170c..9e885da7c0 100644 --- a/xbmc/music/dialogs/GUIDialogMusicInfo.cpp +++ b/xbmc/music/dialogs/GUIDialogMusicInfo.cpp @@ -39,6 +39,7 @@ #include "utils/URIUtils.h" #include "utils/StringUtils.h" #include "TextureCache.h" +#include "music/MusicThumbLoader.h" using namespace std; using namespace XFILE; diff --git a/xbmc/music/infoscanner/MusicInfoScanner.cpp b/xbmc/music/infoscanner/MusicInfoScanner.cpp index 8f1bc60ce2..ed6c0b04ad 100644 --- a/xbmc/music/infoscanner/MusicInfoScanner.cpp +++ b/xbmc/music/infoscanner/MusicInfoScanner.cpp @@ -48,7 +48,7 @@ #include "utils/log.h" #include "utils/URIUtils.h" #include "TextureCache.h" -#include "ThumbLoader.h" +#include "music/MusicThumbLoader.h" #include "interfaces/AnnouncementManager.h" #include "GUIUserMessages.h" diff --git a/xbmc/music/windows/GUIWindowMusicBase.cpp b/xbmc/music/windows/GUIWindowMusicBase.cpp index 2e55c07177..47a1374a96 100644 --- a/xbmc/music/windows/GUIWindowMusicBase.cpp +++ b/xbmc/music/windows/GUIWindowMusicBase.cpp @@ -63,7 +63,6 @@ #include "utils/URIUtils.h" #include "video/VideoInfoTag.h" #include "utils/StringUtils.h" -#include "ThumbLoader.h" #include "URL.h" #include "music/infoscanner/MusicInfoScanner.h" diff --git a/xbmc/music/windows/GUIWindowMusicBase.h b/xbmc/music/windows/GUIWindowMusicBase.h index 2b8fd67955..d6aa87ec08 100644 --- a/xbmc/music/windows/GUIWindowMusicBase.h +++ b/xbmc/music/windows/GUIWindowMusicBase.h @@ -31,6 +31,7 @@ #include "music/infoscanner/MusicInfoScraper.h" #include "PlayListPlayer.h" #include "music/MusicInfoLoader.h" +#include "music/MusicThumbLoader.h" /*! \ingroup windows diff --git a/xbmc/music/windows/GUIWindowMusicNav.h b/xbmc/music/windows/GUIWindowMusicNav.h index b7aff63ffa..97832467e4 100644 --- a/xbmc/music/windows/GUIWindowMusicNav.h +++ b/xbmc/music/windows/GUIWindowMusicNav.h @@ -21,7 +21,6 @@ */ #include "GUIWindowMusicBase.h" -#include "ThumbLoader.h" #include "utils/Stopwatch.h" class CFileItemList; diff --git a/xbmc/music/windows/GUIWindowMusicPlaylistEditor.h b/xbmc/music/windows/GUIWindowMusicPlaylistEditor.h index cd74aedda3..8aa9a76b73 100644 --- a/xbmc/music/windows/GUIWindowMusicPlaylistEditor.h +++ b/xbmc/music/windows/GUIWindowMusicPlaylistEditor.h @@ -21,7 +21,6 @@ */ #include "GUIWindowMusicBase.h" -#include "ThumbLoader.h" class CFileItemList; diff --git a/xbmc/music/windows/GUIWindowMusicSongs.h b/xbmc/music/windows/GUIWindowMusicSongs.h index 96156906dc..9f4a34f6a4 100644 --- a/xbmc/music/windows/GUIWindowMusicSongs.h +++ b/xbmc/music/windows/GUIWindowMusicSongs.h @@ -21,7 +21,6 @@ */ #include "GUIWindowMusicBase.h" -#include "ThumbLoader.h" class CGUIWindowMusicSongs : public CGUIWindowMusicBase, public IBackgroundLoaderObserver { diff --git a/xbmc/network/upnp/UPnPServer.cpp b/xbmc/network/upnp/UPnPServer.cpp index e225acc47e..d49028a21b 100644 --- a/xbmc/network/upnp/UPnPServer.cpp +++ b/xbmc/network/upnp/UPnPServer.cpp @@ -3,7 +3,8 @@ #include "Application.h" #include "GUIViewState.h" #include "Platinum.h" -#include "ThumbLoader.h" +#include "video/VideoThumbLoader.h" +#include "music/MusicThumbLoader.h" #include "interfaces/AnnouncementManager.h" #include "filesystem/Directory.h" #include "filesystem/MusicDatabaseDirectory.h" diff --git a/xbmc/pictures/PictureThumbLoader.cpp b/xbmc/pictures/PictureThumbLoader.cpp index c6a5a57fb0..f8a18cab76 100644 --- a/xbmc/pictures/PictureThumbLoader.cpp +++ b/xbmc/pictures/PictureThumbLoader.cpp @@ -31,6 +31,7 @@ #include "utils/URIUtils.h" #include "settings/Settings.h" #include "settings/AdvancedSettings.h" +#include "video/VideoThumbLoader.h" using namespace XFILE; using namespace std; diff --git a/xbmc/pictures/PictureThumbLoader.h b/xbmc/pictures/PictureThumbLoader.h index 7a8b5c67b3..189080e0c4 100644 --- a/xbmc/pictures/PictureThumbLoader.h +++ b/xbmc/pictures/PictureThumbLoader.h @@ -20,6 +20,7 @@ */ #include "utils/StdString.h" +#include "utils/JobManager.h" #include "ThumbLoader.h" class CPictureThumbLoader : public CThumbLoader, public CJobQueue diff --git a/xbmc/pvr/recordings/PVRRecordings.h b/xbmc/pvr/recordings/PVRRecordings.h index 50810bfc34..db0a39e1d7 100644 --- a/xbmc/pvr/recordings/PVRRecordings.h +++ b/xbmc/pvr/recordings/PVRRecordings.h @@ -23,7 +23,7 @@ #include "XBDateTime.h" #include "threads/Thread.h" #include "utils/Observer.h" -#include "ThumbLoader.h" +#include "video/VideoThumbLoader.h" #define PVR_ALL_RECORDINGS_PATH_EXTENSION "-1" diff --git a/xbmc/utils/RecentlyAddedJob.cpp b/xbmc/utils/RecentlyAddedJob.cpp index 07ed917846..c0e3d9ce7b 100644 --- a/xbmc/utils/RecentlyAddedJob.cpp +++ b/xbmc/utils/RecentlyAddedJob.cpp @@ -32,6 +32,7 @@ #include "utils/Variant.h" #include "utils/StringUtils.h" #include "settings/AdvancedSettings.h" +#include "music/MusicThumbLoader.h" #define NUM_ITEMS 10 diff --git a/xbmc/utils/RecentlyAddedJob.h b/xbmc/utils/RecentlyAddedJob.h index 13f761b446..21457f1d55 100644 --- a/xbmc/utils/RecentlyAddedJob.h +++ b/xbmc/utils/RecentlyAddedJob.h @@ -19,7 +19,7 @@ * */ -#include "ThumbLoader.h" +#include "video/VideoThumbLoader.h" #include "Job.h" enum ERecentlyAddedFlag diff --git a/xbmc/video/Makefile b/xbmc/video/Makefile index 65122a7c6a..1ebcf99307 100644 --- a/xbmc/video/Makefile +++ b/xbmc/video/Makefile @@ -7,6 +7,7 @@ SRCS=Bookmark.cpp \ VideoInfoScanner.cpp \ VideoInfoTag.cpp \ VideoReferenceClock.cpp \ + VideoThumbLoader.cpp \ LIB=video.a diff --git a/xbmc/video/VideoInfoScanner.cpp b/xbmc/video/VideoInfoScanner.cpp index 26f21b43fb..16041ca8c8 100644 --- a/xbmc/video/VideoInfoScanner.cpp +++ b/xbmc/video/VideoInfoScanner.cpp @@ -46,7 +46,7 @@ #include "utils/log.h" #include "utils/URIUtils.h" #include "utils/Variant.h" -#include "ThumbLoader.h" +#include "video/VideoThumbLoader.h" #include "TextureCache.h" #include "GUIUserMessages.h" #include "URL.h" diff --git a/xbmc/video/VideoThumbLoader.cpp b/xbmc/video/VideoThumbLoader.cpp new file mode 100644 index 0000000000..5a0a06c90b --- /dev/null +++ b/xbmc/video/VideoThumbLoader.cpp @@ -0,0 +1,459 @@ +/* + * Copyright (C) 2005-2012 Team XBMC + * http://www.xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ + +#include "VideoThumbLoader.h" +#include "filesystem/StackDirectory.h" +#include "utils/URIUtils.h" +#include "URL.h" +#include "filesystem/File.h" +#include "filesystem/DirectoryCache.h" +#include "FileItem.h" +#include "settings/GUISettings.h" +#include "GUIUserMessages.h" +#include "guilib/GUIWindowManager.h" +#include "TextureCache.h" +#include "utils/log.h" +#include "video/VideoInfoTag.h" +#include "video/VideoDatabase.h" +#include "cores/dvdplayer/DVDFileInfo.h" +#include "video/VideoInfoScanner.h" +#include "music/MusicDatabase.h" + +using namespace XFILE; +using namespace std; +using namespace VIDEO; + +CThumbExtractor::CThumbExtractor(const CFileItem& item, const CStdString& listpath, bool thumb, const CStdString& target) +{ + m_listpath = listpath; + m_target = target; + m_thumb = thumb; + m_item = item; + + m_path = item.GetPath(); + + if (item.IsVideoDb() && item.HasVideoInfoTag()) + m_path = item.GetVideoInfoTag()->m_strFileNameAndPath; + + if (URIUtils::IsStack(m_path)) + m_path = CStackDirectory::GetFirstStackedFile(m_path); +} + +CThumbExtractor::~CThumbExtractor() +{ +} + +bool CThumbExtractor::operator==(const CJob* job) const +{ + if (strcmp(job->GetType(),GetType()) == 0) + { + const CThumbExtractor* jobExtract = dynamic_cast<const CThumbExtractor*>(job); + if (jobExtract && jobExtract->m_listpath == m_listpath) + return true; + } + return false; +} + +bool CThumbExtractor::DoWork() +{ + if (URIUtils::IsLiveTV(m_path) + || URIUtils::IsUPnP(m_path) + || URIUtils::IsDAAP(m_path) + || m_item.IsDVD() + || m_item.IsDVDImage() + || m_item.IsDVDFile(false, true) + || m_item.IsInternetStream() + || m_item.IsDiscStub() + || m_item.IsPlayList()) + return false; + + if (URIUtils::IsRemote(m_path) && !URIUtils::IsOnLAN(m_path)) + return false; + + bool result=false; + if (m_thumb) + { + CLog::Log(LOGDEBUG,"%s - trying to extract thumb from video file %s", __FUNCTION__, m_path.c_str()); + // construct the thumb cache file + CTextureDetails details; + details.file = CTextureCache::GetCacheFile(m_target) + ".jpg"; + result = CDVDFileInfo::ExtractThumb(m_path, details, &m_item.GetVideoInfoTag()->m_streamDetails); + if(result) + { + CTextureCache::Get().AddCachedTexture(m_target, details); + m_item.SetProperty("HasAutoThumb", true); + m_item.SetProperty("AutoThumbImage", m_target); + m_item.SetArt("thumb", CTextureCache::GetCachedPath(details.file)); + } + } + else if (m_item.HasVideoInfoTag() && !m_item.GetVideoInfoTag()->HasStreamDetails()) + { + CLog::Log(LOGDEBUG,"%s - trying to extract filestream details from video file %s", __FUNCTION__, m_path.c_str()); + result = CDVDFileInfo::GetFileStreamDetails(&m_item); + } + + return result; +} + +CVideoThumbLoader::CVideoThumbLoader() : + CThumbLoader(1), CJobQueue(true), m_pStreamDetailsObs(NULL) +{ + m_database = new CVideoDatabase(); +} + +CVideoThumbLoader::~CVideoThumbLoader() +{ + StopThread(); + delete m_database; +} + +void CVideoThumbLoader::Initialize() +{ + m_database->Open(); +} + +void CVideoThumbLoader::OnLoaderStart() +{ + Initialize(); +} + +void CVideoThumbLoader::OnLoaderFinish() +{ + m_database->Close(); +} + +static void SetupRarOptions(CFileItem& item, const CStdString& path) +{ + CStdString path2(path); + if (item.IsVideoDb() && item.HasVideoInfoTag()) + path2 = item.GetVideoInfoTag()->m_strFileNameAndPath; + CURL url(path2); + CStdString opts = url.GetOptions(); + if (opts.Find("flags") > -1) + return; + if (opts.size()) + opts += "&flags=8"; + else + opts = "?flags=8"; + url.SetOptions(opts); + if (item.IsVideoDb() && item.HasVideoInfoTag()) + item.GetVideoInfoTag()->m_strFileNameAndPath = url.Get(); + else + item.SetPath(url.Get()); + g_directoryCache.ClearDirectory(url.GetWithoutFilename()); +} + +vector<string> CVideoThumbLoader::GetArtTypes(const string &type) +{ + vector<string> ret; + if (type != "episode") + { + ret.push_back("fanart"); + ret.push_back("poster"); + } + if (type == "tvshow" || type == "season" || type.empty()) + ret.push_back("banner"); + ret.push_back("thumb"); + return ret; +} + +/** + * Look for a thumbnail for pItem. If one does not exist, look for an autogenerated + * thumbnail. If that does not exist, attempt to autogenerate one. Finally, check + * for the existance of fanart and set properties accordingly. + * @return: true if pItem has been modified + */ +bool CVideoThumbLoader::LoadItem(CFileItem* pItem) +{ + if (pItem->m_bIsShareOrDrive + || pItem->IsParentFolder()) + return false; + + m_database->Open(); + + if (pItem->HasVideoInfoTag() && !pItem->GetVideoInfoTag()->HasStreamDetails() && + (pItem->GetVideoInfoTag()->m_type == "movie" || pItem->GetVideoInfoTag()->m_type == "episode" || pItem->GetVideoInfoTag()->m_type == "musicvideo")) + { + if (m_database->GetStreamDetails(*pItem->GetVideoInfoTag())) + pItem->SetInvalid(); + } + + // video db items normally have info in the database + if (pItem->HasVideoInfoTag() && pItem->GetArt().empty()) + { + FillLibraryArt(*pItem); + + if (pItem->GetVideoInfoTag()->m_type == "set" || + pItem->GetVideoInfoTag()->m_type == "actor" || + pItem->GetVideoInfoTag()->m_type == "artist" || + pItem->GetVideoInfoTag()->m_type == "director" || + pItem->GetVideoInfoTag()->m_type == "writer" || + pItem->GetVideoInfoTag()->m_type == "season" ) + { + m_database->Close(); + return true; // nothing else to be done + } + } + + // if we have no art, look for it all + map<string, string> artwork = pItem->GetArt(); + if (artwork.empty()) + { + vector<string> artTypes = GetArtTypes(pItem->HasVideoInfoTag() ? pItem->GetVideoInfoTag()->m_type : ""); + for (vector<string>::const_iterator i = artTypes.begin(); i != artTypes.end(); ++i) + { + std::string type = *i; + std::string art = GetCachedImage(*pItem, type); + if (art.empty()) + { + art = GetLocalArt(*pItem, type, type=="fanart"); + if (!art.empty()) // cache it + SetCachedImage(*pItem, type, art); + } + if (!art.empty()) + { + CTextureCache::Get().BackgroundCacheImage(art); + artwork.insert(make_pair(type, art)); + } + } + pItem->SetArt(artwork); + } + + // thumbnails are special-cased due to auto-generation + if (!pItem->HasArt("thumb") && !pItem->m_bIsFolder && pItem->IsVideo()) + { + // create unique thumb for auto generated thumbs + CStdString thumbURL = GetEmbeddedThumbURL(*pItem); + if (CTextureCache::Get().HasCachedImage(thumbURL)) + { + CTextureCache::Get().BackgroundCacheImage(thumbURL); + pItem->SetProperty("HasAutoThumb", true); + pItem->SetProperty("AutoThumbImage", thumbURL); + pItem->SetArt("thumb", thumbURL); + } + else if (g_guiSettings.GetBool("myvideos.extractthumb") && + g_guiSettings.GetBool("myvideos.extractflags")) + { + CFileItem item(*pItem); + CStdString path(item.GetPath()); + if (URIUtils::IsInRAR(item.GetPath())) + SetupRarOptions(item,path); + + CThumbExtractor* extract = new CThumbExtractor(item, path, true, thumbURL); + AddJob(extract); + + m_database->Close(); + return true; + } + } + + // flag extraction + if (!pItem->m_bIsFolder && + pItem->HasVideoInfoTag() && + g_guiSettings.GetBool("myvideos.extractflags") && + (!pItem->GetVideoInfoTag()->HasStreamDetails() || + pItem->GetVideoInfoTag()->m_streamDetails.GetVideoDuration() <= 0)) + { + CFileItem item(*pItem); + CStdString path(item.GetPath()); + if (URIUtils::IsInRAR(item.GetPath())) + SetupRarOptions(item,path); + CThumbExtractor* extract = new CThumbExtractor(item,path,false); + AddJob(extract); + } + + m_database->Close(); + return true; +} + +bool CVideoThumbLoader::FillLibraryArt(CFileItem &item) +{ + CVideoInfoTag &tag = *item.GetVideoInfoTag(); + if (tag.m_iDbId > -1 && !tag.m_type.IsEmpty()) + { + map<string, string> artwork; + m_database->Open(); + if (m_database->GetArtForItem(tag.m_iDbId, tag.m_type, artwork)) + item.SetArt(artwork); + else if (tag.m_type == "artist") + { // we retrieve music video art from the music database (no backward compat) + CMusicDatabase database; + database.Open(); + int idArtist = database.GetArtistByName(item.GetLabel()); + if (database.GetArtForItem(idArtist, "artist", artwork)) + item.SetArt(artwork); + } + else if (tag.m_type == "album") + { // we retrieve music video art from the music database (no backward compat) + CMusicDatabase database; + database.Open(); + int idAlbum = database.GetAlbumByName(item.GetLabel(), tag.m_artist); + if (database.GetArtForItem(idAlbum, "album", artwork)) + item.SetArt(artwork); + } + else + { + if (tag.m_type == "movie" || tag.m_type == "episode" || + tag.m_type == "tvshow" || tag.m_type == "musicvideo") + { // no art in the library, so find it locally and add + SScanSettings settings; + ADDON::ScraperPtr info = m_database->GetScraperForPath(tag.m_strPath, settings); + if (info) + { + CFileItem tmpItem(item); + tmpItem.SetPath(tag.GetPath()); + CVideoInfoScanner scanner; + scanner.GetArtwork(&tmpItem, info->Content(), tag.m_type != "episode" && settings.parent_name_root, true); + item.SetArt(tmpItem.GetArt()); + } + } + else if (tag.m_type == "set") + { // no art for a set -> use the first movie for this set for art + CFileItemList items; + if (m_database->GetMoviesNav("videodb://1/2/", items, -1, -1, -1, -1, -1, -1, tag.m_iDbId) && items.Size() > 0) + { + LoadItem(items[0].get()); + if (!items[0]->GetArt().empty()) + item.SetArt(items[0]->GetArt()); + } + } + else if (tag.m_type == "actor" || + tag.m_type == "writer" || tag.m_type == "director") + { + // We can't realistically get the local thumbs (as we'd need to check every movie that contains this actor) + // and most users won't have local actor thumbs that are actually different than the scraped ones. + if (g_guiSettings.GetBool("videolibrary.actorthumbs")) + { + tag.m_strPictureURL.Parse(); + CStdString thumb = CScraperUrl::GetThumbURL(tag.m_strPictureURL.GetFirstThumb()); + if (!thumb.IsEmpty()) + item.SetArt("thumb", thumb); + } + } + else if (tag.m_type == "season") + { + // season art is fetched on scan from the tvshow root path (m_strPath in the season info tag) + // or from the show m_strPictureURL member of the tvshow, so grab the tvshow to get this. + CVideoInfoTag show; + m_database->GetTvShowInfo(tag.m_strPath, show, tag.m_iIdShow); + map<int, string> seasons; + CVideoInfoScanner::GetSeasonThumbs(show, seasons, true); + map<int, string>::iterator season = seasons.find(tag.m_iSeason); + if (season != seasons.end()) + item.SetArt("thumb", season->second); + } + // add to the database for next time around + map<string, string> artwork = item.GetArt(); + if (!artwork.empty()) + { + m_database->SetArtForItem(tag.m_iDbId, tag.m_type, artwork); + for (map<string, string>::iterator i = artwork.begin(); i != artwork.end(); ++i) + CTextureCache::Get().BackgroundCacheImage(i->second); + } + else // nothing found - set an empty thumb so that next time around we don't hit here again + m_database->SetArtForItem(tag.m_iDbId, tag.m_type, "thumb", ""); + } + // For episodes and seasons, we want to set fanart for that of the show + if (!item.HasArt("fanart") && tag.m_iIdShow >= 0) + { + map<string, string> showArt; + if (m_database->GetArtForItem(tag.m_iIdShow, "tvshow", showArt)) + { + map<string, string>::iterator i = showArt.find("fanart"); + if (i != showArt.end()) + item.SetArt("fanart", i->second); + if ((i = showArt.find("thumb")) != showArt.end()) + item.SetArt("tvshowthumb", i->second); + } + } + m_database->Close(); + } + return !item.GetArt().empty(); +} + +bool CVideoThumbLoader::FillThumb(CFileItem &item) +{ + if (item.HasArt("thumb")) + return true; + CStdString thumb = GetCachedImage(item, "thumb"); + if (thumb.IsEmpty()) + { + thumb = GetLocalArt(item, "thumb"); + if (!thumb.IsEmpty()) + SetCachedImage(item, "thumb", thumb); + } + item.SetArt("thumb", thumb); + return !thumb.IsEmpty(); +} + +std::string CVideoThumbLoader::GetLocalArt(const CFileItem &item, const std::string &type, bool checkFolder) +{ + std::string art; + if (!type.empty()) + { + art = item.FindLocalArt(type + ".jpg", checkFolder); + if (art.empty()) + art = item.FindLocalArt(type + ".png", checkFolder); + } + if (art.empty() && (type.empty() || type == "thumb")) + { // backward compatibility + art = item.FindLocalArt("", false); + if (art.empty() && (checkFolder || (item.m_bIsFolder && !item.IsFileFolder()))) + { // try movie.tbn + art = item.FindLocalArt("movie.tbn", true); + if (art.empty()) // try folder.jpg + art = item.FindLocalArt("folder.jpg", true); + } + } + return art; +} + +CStdString CVideoThumbLoader::GetEmbeddedThumbURL(const CFileItem &item) +{ + CStdString path(item.GetPath()); + if (item.IsVideoDb() && item.HasVideoInfoTag()) + path = item.GetVideoInfoTag()->m_strFileNameAndPath; + if (URIUtils::IsStack(path)) + path = CStackDirectory::GetFirstStackedFile(path); + + return CTextureCache::GetWrappedImageURL(path, "video"); +} + +void CVideoThumbLoader::OnJobComplete(unsigned int jobID, bool success, CJob* job) +{ + if (success) + { + CThumbExtractor* loader = (CThumbExtractor*)job; + loader->m_item.SetPath(loader->m_listpath); + CVideoInfoTag* info = loader->m_item.GetVideoInfoTag(); + + if (loader->m_thumb && info->m_iDbId > 0 && !info->m_type.empty()) + m_database->SetArtForItem(info->m_iDbId, info->m_type, "thumb", loader->m_item.GetArt("thumb")); + + if (m_pStreamDetailsObs) + m_pStreamDetailsObs->OnStreamDetails(info->m_streamDetails, info->m_strFileNameAndPath, info->m_iFileId); + if (m_pObserver) + m_pObserver->OnItemLoaded(&loader->m_item); + CFileItemPtr pItem(new CFileItem(loader->m_item)); + CGUIMessage msg(GUI_MSG_NOTIFY_ALL, 0, 0, GUI_MSG_UPDATE_ITEM, 0, pItem); + g_windowManager.SendThreadMessage(msg); + } + CJobQueue::OnJobComplete(jobID, success, job); +} diff --git a/xbmc/video/VideoThumbLoader.h b/xbmc/video/VideoThumbLoader.h new file mode 100644 index 0000000000..4ed7c98b51 --- /dev/null +++ b/xbmc/video/VideoThumbLoader.h @@ -0,0 +1,125 @@ +#pragma once +/* + * Copyright (C) 2012 Team XBMC + * http://www.xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ + +#include "ThumbLoader.h" +#include "utils/JobManager.h" +#include "FileItem.h" + +#define kJobTypeMediaFlags "mediaflags" + +class CStreamDetails; +class IStreamDetailsObserver; +class CVideoDatabase; + +/*! + \ingroup thumbs,jobs + \brief Thumb extractor job class + + Used by the CVideoThumbLoader to perform asynchronous generation of thumbs + + \sa CVideoThumbLoader and CJob + */ +class CThumbExtractor : public CJob +{ +public: + CThumbExtractor(const CFileItem& item, const CStdString& listpath, bool thumb, const CStdString& strTarget=""); + virtual ~CThumbExtractor(); + + /*! + \brief Work function that extracts thumb. + */ + virtual bool DoWork(); + + virtual const char* GetType() const + { + return kJobTypeMediaFlags; + } + + virtual bool operator==(const CJob* job) const; + + CStdString m_path; ///< path of video to extract thumb from + CStdString m_target; ///< thumbpath + CStdString m_listpath; ///< path used in fileitem list + CFileItem m_item; + bool m_thumb; ///< extract thumb? +}; + +class CVideoThumbLoader : public CThumbLoader, public CJobQueue +{ +public: + CVideoThumbLoader(); + virtual ~CVideoThumbLoader(); + + virtual void Initialize(); + virtual bool LoadItem(CFileItem* pItem); + void SetStreamDetailsObserver(IStreamDetailsObserver *pObs) { m_pStreamDetailsObs = pObs; } + + /*! \brief Fill the thumb of a video item + First uses a cached thumb from a previous run, then checks for a local thumb + and caches it for the next run + \param item the CFileItem object to fill + \return true if we fill the thumb, false otherwise + */ + static bool FillThumb(CFileItem &item); + + /*! \brief Find a particular art type for a given item, optionally checking at the folder level + \param item the CFileItem to search. + \param type the type of art to look for. + \param checkFolder whether to also check the folder level for files. Defaults to false. + \return the art file (if found), else empty. + */ + static std::string GetLocalArt(const CFileItem &item, const std::string &type, bool checkFolder = false); + + /*! \brief return the available art types for a given media type + \param type the type of media. + \return a vector of art types. + \sa GetLocalArt + */ + static std::vector<std::string> GetArtTypes(const std::string &type); + + /*! \brief helper function to retrieve a thumb URL for embedded video thumbs + \param item a video CFileItem. + \return a URL for the embedded thumb. + */ + static CStdString GetEmbeddedThumbURL(const CFileItem &item); + + /*! \brief helper function to fill the art for a video library item + \param item a video CFileItem + \return true if we fill art, false otherwise + */ + virtual bool FillLibraryArt(CFileItem &item); + + /*! + \brief Callback from CThumbExtractor on completion of a generated image + + Performs the callbacks and updates the GUI. + + \sa CImageLoader, IJobCallback + */ + virtual void OnJobComplete(unsigned int jobID, bool success, CJob *job); + +protected: + virtual void OnLoaderStart(); + virtual void OnLoaderFinish(); + + IStreamDetailsObserver *m_pStreamDetailsObs; + CVideoDatabase *m_database; +}; diff --git a/xbmc/video/dialogs/GUIDialogVideoInfo.h b/xbmc/video/dialogs/GUIDialogVideoInfo.h index 7cb6601e4a..9d4afd7c35 100644 --- a/xbmc/video/dialogs/GUIDialogVideoInfo.h +++ b/xbmc/video/dialogs/GUIDialogVideoInfo.h @@ -22,7 +22,7 @@ #include "guilib/GUIDialog.h" #include "guilib/GUIListItem.h" -#include "ThumbLoader.h" +#include "video/VideoThumbLoader.h" #include "video/VideoDatabase.h" class CFileItem; diff --git a/xbmc/video/windows/GUIWindowVideoBase.h b/xbmc/video/windows/GUIWindowVideoBase.h index 78d94b5822..32eef36b85 100644 --- a/xbmc/video/windows/GUIWindowVideoBase.h +++ b/xbmc/video/windows/GUIWindowVideoBase.h @@ -23,7 +23,7 @@ #include "windows/GUIMediaWindow.h" #include "video/VideoDatabase.h" #include "PlayListPlayer.h" -#include "ThumbLoader.h" +#include "video/VideoThumbLoader.h" class CGUIWindowVideoBase : public CGUIMediaWindow, public IBackgroundLoaderObserver, public IStreamDetailsObserver { diff --git a/xbmc/video/windows/GUIWindowVideoNav.h b/xbmc/video/windows/GUIWindowVideoNav.h index 8b66c9e141..5939a1c3ae 100644 --- a/xbmc/video/windows/GUIWindowVideoNav.h +++ b/xbmc/video/windows/GUIWindowVideoNav.h @@ -21,7 +21,6 @@ */ #include "GUIWindowVideoBase.h" -#include "ThumbLoader.h" class CFileItemList; |