Thumbnails/Cache

XBMC maintains a local texture cache for thumbs and fanart, to allow fast loading of these images so that skins can show off your media in the best way possible.

All textures that XBMC loads, with the exception of textures that are provided directly by the skin, are cached to the userdata/Thumbnails folder.

Art for library items
As of XBMC v12:

The art URL's associated with library items are stored in the art table inside the video or music databases. These store the original URL to the art (e.g. from http://themoviedb.org, http://thetvdb.com, or http://theaudiodb.org). This means that central databases store where the art is obtained from, and multiple clients then just keep a local thumbnail cache as described below.

The caching procedure
The caching procedure utilizes both copies (possibly scaled down) of the original texture, saved in .jpg or .png format, an (optional) fast loading .dds version of those images, and an SQL database that maintains the local cache.

The cache operates primarily on an "as and when needed" basis. i.e. textures are cached when they're first requested to be loaded. In addition, however, in some places textures may be cached before they're immediately needed, such as in the scanning routines. In either case, the main caching procedure starts with an image URL. We cache as follows:

1. We generate a CRC (hash) of the URL. (see Code Samples on how to calculate CRC values)

2. We cache the image, reducing it in size if required, to a local file with the given CRC. It's cached as a PNG or JPG based on whether transparency is required.

3. We generate a hash of the image, based on size and modified date, that we can use to check whether the original image has changed or not.

4. We store these details, along with information on when the image was cached in the SQL database Textures.db.

Loading textures
When loading a texture, XBMC basically just has a URL to the image. Given a particular URL, we load the texture as follows:

1. We first check to see whether the image is provided by the skin. If so, we load it directly.

2. We then check to see whether the URL is from our thumbnail cache. If it is, we skip to step 5.

3. If not, we look up to see whether this image is in our texture cache by querying the SQL database. If it is, we swap the URL to the cached version and skip to step 5.

4. If it's not in the cache, we cache the image as outlined above.

5. We then additionally check if a "fast loading" version (.dds) of the texture exists. If it does, we swap the URL to the fast loading version.

6. We load the image.

7. We (optionally) generate a "fast loading" version (.dds) of the texture, if it doesn't already exist.

8. We update the texture database with access times to the texture (allowing us to clear the texture cache out of images that are rarely used).

9. If it's been at least 24 hours since the texture was last loaded, we check whether or not the cached version needs to be refreshed from the original image. If so, we cache the image as outlined above.

DDS artwork
XBMC uses the compressed format DXT1 or DXT5 in the form of a .dds file. These are GPU-friendly compressed formats which allow for very fast loading of textures. It comes at the disadvantage of a loss in quality - DXT compression can in some cases be very bad quality. XBMC uses libsquish which is reasonably optimal at compressing the images. In the future XBMC may use DXT5 in the YCoCg colour space which is the same size as DXT5 (i.e. 8bits/pixel) but is visually close to being lossless. For now, if XBMC deems the quality isn't quite good enough to use DXT1 or DXT5, we use ARGB (i.e. 32bits/pixel) which can result in some very large images on disk. On systems with slow disk access, these may take longer to load than .jpg or .png versions.

The generation of .dds versions of the artwork is automatic if you have set the advancedsetting. DDS versions are generated in step 7 above. Even if you haven't set the advanced setting, XBMC will still load .dds versions of the textures if they're available, so on slower systems you may wish to generate .dds versions offline and place them in the texture cache directly.

The future
The texture cache in the future will be auto-cleaning, i.e. textures that are stale will automatically be cleaned out to save disk space. Also, the music and video artwork will be moved to the new system. This will allow the cached versions of these images to be updated whenever the original image changes (eg you replace the fanart with a different version).

In addition, the texture cache will be updated to automatically tell the image control that it needs to refresh itself. Currently if the texturecache detects that a new version of an image is available (whether it be a .dds version or an updated copy of the original image that has since changed) then all that happens is the new version gets re-cached. Thus, you only see the new version of an image once you view it a second time after any change (this allows the image to be free'd from memory and reloaded from the freshly updated version).

How to refresh the cached image of an icon
There is an image like /home/x/.xbmc/addons/my.lovely.addon/icon.png. After changing that file, the old image is still visible in XBMC. To solve this we need to remove the actual thumbnail file from the filesystem and its reference in the DB:

$ sqlite3 .xbmc/userdata/Database/Textures13.db "SELECT cachedurl FROM texture WHERE url = '/home/x/.xbmc/addons/my.lovely.addon/icon.png';" 6/6a643bff.png
 * 1) Get the thumbnail path to remove the file from the filesystem

This 6/6a643bff.png is the cached image under /home/x/.xbmc/userdata/Thumbnails. So: you need to remove from your filesystem ''/home/x/.xbmc/userdata/Thumbnails/6/6a43bff.png"

$ sqlite3 .xbmc/userdata/Database/Textures13.db "DELETE FROM texture WHERE url = '/home/x/.xbmc/addons/my.lovely.addon/icon.png';"
 * 1) Remove the image->cached image link in the DB

Next time XBMC needs the image, it will recreate the thumbnail.



Cache manipulation tools

 * Texture Cache Maintenance utility