aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--XBMC-ATV2.xcodeproj/project.pbxproj12
-rw-r--r--XBMC-IOS.xcodeproj/project.pbxproj12
-rw-r--r--XBMC.xcodeproj/project.pbxproj12
-rw-r--r--project/VS2010Express/XBMC.vcxproj4
-rw-r--r--project/VS2010Express/XBMC.vcxproj.filters12
-rw-r--r--xbmc/GUIInfoManager.cpp3
-rw-r--r--xbmc/TextureCacheJob.cpp2
-rw-r--r--xbmc/ThumbLoader.cpp569
-rw-r--r--xbmc/ThumbLoader.h146
-rw-r--r--xbmc/interfaces/json-rpc/FileItemHandler.cpp3
-rw-r--r--xbmc/interfaces/json-rpc/FileItemHandler.h3
-rw-r--r--xbmc/music/Makefile1
-rw-r--r--xbmc/music/MusicThumbLoader.cpp159
-rw-r--r--xbmc/music/MusicThumbLoader.h62
-rw-r--r--xbmc/music/dialogs/GUIDialogMusicInfo.cpp1
-rw-r--r--xbmc/music/infoscanner/MusicInfoScanner.cpp2
-rw-r--r--xbmc/music/windows/GUIWindowMusicBase.cpp1
-rw-r--r--xbmc/music/windows/GUIWindowMusicBase.h1
-rw-r--r--xbmc/music/windows/GUIWindowMusicNav.h1
-rw-r--r--xbmc/music/windows/GUIWindowMusicPlaylistEditor.h1
-rw-r--r--xbmc/music/windows/GUIWindowMusicSongs.h1
-rw-r--r--xbmc/network/upnp/UPnPServer.cpp3
-rw-r--r--xbmc/pictures/PictureThumbLoader.cpp1
-rw-r--r--xbmc/pictures/PictureThumbLoader.h1
-rw-r--r--xbmc/pvr/recordings/PVRRecordings.h2
-rw-r--r--xbmc/utils/RecentlyAddedJob.cpp1
-rw-r--r--xbmc/utils/RecentlyAddedJob.h2
-rw-r--r--xbmc/video/Makefile1
-rw-r--r--xbmc/video/VideoInfoScanner.cpp2
-rw-r--r--xbmc/video/VideoThumbLoader.cpp459
-rw-r--r--xbmc/video/VideoThumbLoader.h125
-rw-r--r--xbmc/video/dialogs/GUIDialogVideoInfo.h2
-rw-r--r--xbmc/video/windows/GUIWindowVideoBase.h2
-rw-r--r--xbmc/video/windows/GUIWindowVideoNav.h1
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;