[archived] GPU accelerated fanart for XBMC (Live/Ubuntu).

By Devolblog • Devolblog Archives, Tech • 26 Jan 2010

[ Information in this post is completely outdated. The best thing to do is install Dharma from source or wait for next release. ]

Update 2-12 See bottom of post for instructions on how to enabled gpu acceleration of thumbnails as well as fanart.

Replication of this tutorial for having the gpu render fanart images on xmbc live/ubuntu just in case it goes away. This is experimental at the moment and has some drawbacks for every day use, but will show an improvement in scroll speed in the gui as its handing off loading fanart images to the gpu; very handy for low power atom/ion computers.

To enable dds fanart in xbmc, create an advancedsettings.xml file in your userdata directory. If using XBMC Live, this will be ~/.xbmc/userdata. Edit advancedsettings.xml and add:

<advancedsettings>
<useddsfanart>true</useddsfanart>
</advancedsettings>

I believe you’ll need to reboot/restart xbmc for this to take effect.

Cons:

  1. The .dds images are much larger than the jpg compressed tbn files, e.g. 10MB vs 1.4MB a bit larger than the jpg. I went back and looked and most were only about 1/3 bigger than the original. So obviously this isn’t going to work so hot Might be a deal breaker if you’re running Live on a small-ish usb stick.
  2. Once useddsfanart is enabled, new fanart must be converted before it is displayed, there is no fallback to regular tbn file. (How much overhead in having cron run the conversion script every few minutes or loop the script?)
  3. Depending on the complexity of the skin, there might not be a huge performance boost. I’m using Aeon and the performance increase is noticable if you look hard, but not astounding, since Aeon is displaying a bunch of other images at the same time. I discovered, by accident, that even though I had ddsfanart enabled, xbmc was still using the tbn fanart. I had a few other entries in my advancedsettings.xml file and I think the conflicted with ddsfanart. I now have it working properly and the speed difference is amazing and totally worth the hassle if you’re using a nettop.

What you’ll need:

Install

  1. Install g++, gcc, libjpeg62 and cmake:sudo apt-get install g++ g++-4.3 gcc-4.3 libjpeg62-dev cmake

    (the cuda extension for nvcompress won’t compile on 4.4 for some reason, which is what comes with Ubuntu 9.10 Karmic. If you are running 9.04 you’re fine.)
    CUDA isn’t strictly needed, nvcompress will still work pretty quickly with the -fast option, but CUDA still seems fastest. If you don’t want to use CUDA, don’t install the cuda tools because the texture tools won’t compile without some extra work with g++ 4.3.

    *Note I went the CUDA route because I’m doing the conversion directly on my AR1600 and need all the help I can get. Compression time was typically 13-16sec per 1920×1080 jpg with cpu at 100% … which might make having the conversion script running with xbmc cause some issues.

  2. To install the CUDA tools, in terminal go to the directory where you downloaded the CUDA file I linked and run:sudo sh cudatoolkit_2.3_linux_32_ubuntu9.04.run
  3. Now you have to add the cuda libraries to your shared libraries by editing a file. I use nano for my text editor, feel free to use whatever you like.sudo nano /etc/ld.so.conf

    and add this line to the end

    include /usr/local/cuda/lib/

  4. After you save the file, run:sudo ldconfig -v

    to update the libraries.

  5. Assuming you want CUDA acceleration, after you have installed g++ and ran the CUDA tools installer, move to the nvidia-texture-tools directory (wherever you unzipped it to) and run:./configure

    You should see in the list of things that come up that JPEG is found and CUDA is found.

  6. If that works well, and you are on Ubuntu Karmic then you need to set up g++ to compile using version 4.3.sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.4 44 --slave /usr/bin/g++ g++ /usr/bin/g++-4.4 --slave /usr/bin/gcov gcov /usr/bin/gcov-4.4
    sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.3 43 --slave /usr/bin/g++ g++ /usr/bin/g++-4.3 --slave /usr/bin/gcov gcov /usr/bin/gcov-4.3
  7. You can confirm that this finished right by running:sudo update-alternatives --display gcc
  8. Now set the system to run version 4.3 instead of 4.4.make sure to change this back when you’re done

    sudo update-alternatives --config gcc

    You should see something like this:

    There are 2 choices for the alternative gcc (providing /usr/bin/gcc).

    Selection Path Priority Status
    ------------------------------------------------------------
    * 0 /usr/bin/gcc-4.4 44 auto mode
    1 /usr/bin/gcc-4.3 43 manual mode
    2 /usr/bin/gcc-4.4 44 manual mode

    Press enter to keep the current choice[*], or type selection number:

    In this case you would type 1 and hit enter. Just put whatever number you have to switch to version 4.3.

  9. After this is done, in the nvidia-texture-tools folder, type:sudo make
  10. and, assuming everything compiled ok (I got some warnings in the compile process but it did finish and everything seems to work fine) type:sudo make install

    and it should install the files properly.

  11. At this point you can change your default compiler back to version 4.4 by running the same command as above and set back to auto (option 0 in the example).
  12. Try to run nvcompress (you should be able to do this anywhere in the command line now) and if you get the typical list of options than you are good to go. Initially I had some issues with nvcompress not seeing the needed shared libraries. You’ll know if you have this same problem if, when you try to run nvcompress, you get an error saying it can’t find some shared library. If this is the case, follow the next instructions.
  13. Move to the /usr/local/bin directory and check if nvcompress is really not seeing libraries.cd /usr/local/bin
    ldd nvcompress

    You should see a list of libraries that nvcompress depends on. If you have any entries that say Not Found at the end than some libraries aren’t being seen. I was missing one (libcudart.so.2) at the end of all these steps, but I fixed this by copying the file to a library I knew was working.

    sudo cp /usr/local/cuda/lib/libcudart.so.2 /usr/local/lib/libcudart.so.2
    sudo ldconfig -v

    You only need to do something like this if nvcompress gives an error that it can’t find a shared library.

    *Note When I checked the first time, there were a bunch of libraries missing. I then followed the instructions to copy over libcudart.so.2 and re-ran the check and all of them appeared so I proceeded as planned.

Compress Scripts
The post currently has two different scripts for automatically converting the fanart directories. Both only address the video fanart directory and will need to have the music fanart directory added to also convert those.

  • Script #1
    #!/bin/sh

    rename 's/tbn$/jpg/' ~/.xbmc/userdata/Thumbnails/Video/Fanart/*.tbn
    find ~/.xbmc/userdata/Thumbnails/Video/Fanart -type f -name '*.jpg' -printf '%fn' | sed 's/.jpg$/n/' > ~/.xbmc/userdata/Thumbnails/Video/Fanart/found.txt
    find ~/.xbmc/userdata/Thumbnails/Video/Fanart -type f -name '*.dds' -printf '%fn' | sed 's/.dds$/n/' >> ~/.xbmc/userdata/Thumbnails/Video/Fanart/found.txt
    cat ~/.xbmc/userdata/Thumbnails/Video/Fanart/found.txt | sort | uniq -u > ~/.xbmc/userdata/Thumbnails/Video/Fanart/new.txt
    cat ~/.xbmc/userdata/Thumbnails/Video/Fanart/new.txt | xargs -I {} nvcompress -bc1 ~/.xbmc/userdata/Thumbnails/Video/Fanart/{}.jpg
    rename 's/jpg$/tbn/' ~/.xbmc/userdata/Thumbnails/Video/Fanart/*.jpg
    rm ~/.xbmc/userdata/Thumbnails/Video/Fanart/found.txt
    rm ~/.xbmc/userdata/Thumbnails/Video/Fanart/new.txt

  • Script #2
    #!/bin/sh
    cd ~/.xbmc/userdata/Thumbnails/Video/Fanart/ || exit
    find . -name '*.tbn' -or -name '*.dds' | cut -c-10 | sort | uniq -u |
    while read n; do
    mv $n.tbn $n.jpg
    nvcompress -bc1 $n.jpg | awk '/taken:/{printf $3}'
    mv $n.jpg $n.tbn
    echo "s $(ls *.dds | wc -l)/$(ls *.tbn | wc -l)"
    done

Instead of using crontab I would prefer to figure out how to loop the script so that it could remain running and loop every xx seconds. Will investigate tonight.

Update 1-27 I’ve modified script #2 by wrapping it in a while -d ; do and controlling the frequency with sleep. I’m totally not a bash scripter, but the idea is to keep the script running conditional to the directory existing. I’ve also nested a loop through the music fanart directory wrapped in an if statement that checks for the music directory’s existence; I’ll post the script tonight. I still need to test to see if it will actually pick up new files though. If anybody is reading this and has any bash scripting experience feel free to post a comment with any tips/suggestions.

Update 2-12 Still need to post my hacked up script for converting tbn to dds and have it watch for new additions (still doesn’t pick up changed tbn).

Currently, the switch in advancedsettings only enables gpu acceleration of dds compressed fanart. With a small change to source you can also enable dds thumbnails which makes an epic difference in scroll speed on my AR1600.

(copy and paste directly from this forum post)
--- xbmc/GUILargeTextureManager.cpp~
+++ xbmc/GUILargeTextureManager.cpp
@@ -64,8 +64,10 @@ bool CImageLoader::DoWork()
{
CStdString baseFolder1 = g_settings.GetMusicFanartFolder();
CStdString baseFolder2 = g_settings.GetVideoFanartFolder();
+ CStdString baseFolder3 = g_settings.GetVideoThumbFolder();
if (baseFolder1.Equals(m_path.Left(baseFolder1.GetLength())) ||
- baseFolder2.Equals(m_path.Left(baseFolder2.GetLength())))
+ baseFolder2.Equals(m_path.Left(baseFolder2.GetLength())) ||
+ baseFolder3.Equals(m_path.Left(baseFolder3.GetLength())))
{ // switch to dds
CUtil::ReplaceExtension(m_path, ".dds", loadPath);
}

  1. nano xmbc/GUILargeTextureManager.cpp
  2. add the new CStdString baseFolder 3 line
  3. remove the trailing ) for the existing baseFolder2.Equals line and add || to the end
  4. add new baseFolder3.Equals line
  5. compile and install
    Need to add compile and install from source instructions to my other post because I keep forgetting, when I do it, to make sure I’ve got lib-vdpau and end up having to compile twice.
  6. make sure to convert tbn to dds for your root /Thumbnails/Video folder and not just /Fanart

From my limited testing, it also appears that my music album cover thumbnails are accelerated?! Which is baffling, I’m hoping I’m just imaging things; I was expecting to need the addition of another baseFolder line.

  • My Script
  • /etc/rc.local add either /etc/init.d/xbmc-dds-compress start if using an init script or, /home/xbmc/dds-convert.sh & so that the script starts at boot.
  • Really cheap init script. Save to /etc/init.d and chmod +x.
    #!/bin/sh
    #
    # Script to start DDS-Compress
    #
    set -e
    . /lib/lsb/init-functions
    case "$1" in
    start)
    /home/xbmc/dds-convert.sh &
    ;;
    stop)
    pkill dds-convert.sh
    ;;
    esac
    exit 0
  • Script that I’m using. It’s a modification of #2 above. It’s monitoring the root Thumbnails/Video directory to convert all thumbnails and fanart; goes along with the source code change above.
    #!/bin/sh
    PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/
    video='/home/xbmc/.xbmc/userdata/Thumbnails/Video'
    music='/home/xbmc/.xbmc/userdata/Thumbnails/Music'
    private='/home/xbmc/.xbmc/userdata/profiles/Private/Thumbnails/Video'

    # limit cpu usage for nvcompress so it doesn't kill xbmc gui
    cpulimit -e nvcompress -l 50 &

    while [ -d $video ]; do

    cd $video || exit

    find . -name '*.tbn' -or -name '*.dds' | cut -d'.' -f2 | sort | uniq -u |

    while read n; do

    mv $video$n.tbn $video$n.jpg
    nvcompress -bc1 $video$n.jpg | awk '/taken:/{printf $3}'
    mv $video$n.jpg $video$n.tbn

    done

    #music is secondary and only done if video exists
    if [ -d $music ]; then

    cd $music || exit

    find . -name '*.tbn' -or -name '*.dds' | cut -d'.' -f2 | sort | uniq -u |

    while read n; do

    mv $music$n.tbn $music$n.jpg
    nvcompress -bc1 $music$n.jpg | awk '/taken:/{printf $3}'
    mv $music$n.jpg $music$n.tbn

    done

    fi

    #doing Private profile Thumbnails here
    if [ -d $private ]; then

    cd $private || exit

    find . -name '*.tbn' -or -name '*.dds' | cut -d'.' -f2 | sort | uniq -u |

    while read n; do

    mv $private$n.tbn $private$n.jpg
    nvcompress -bc1 $private$n.jpg | awk '/taken:/{printf $3}'
    mv $private$n.jpg $private$n.tbn

    done

    fi

    sleep 1

    done
    My scripting skills aren’t the best, but I’m at least checking to make sure the directories exist. I don’t really remember why I decided that Music should be nested under the main Video wrap, but I guess it works. I also put in a section labelled ‘Private’ for profiles; if you’re using different profiles just replace Private with your profile’s name. Without the sleep command this script will use about 10-15% CPU on the AR1600. With, you never see it in TOP.

    Also, I’m using cpulimit (sudo apt-get install cpulimit) on nvcompress so that XBMC doesn’t choke when new content is added.

  • This script fails to convert changed posters or fanart for an existing library item. I need to take a closer look at the find command to see if I can also watch for file changes.

Tags:

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>