Ejemplo n.º 1
0
MythImage *MythUIHelper::LoadCacheImage(QString srcfile, QString label,
                                        MythPainter *painter,
                                        ImageCacheMode cacheMode)
{
    LOG(VB_GUI | VB_FILE, LOG_INFO, LOC +
        QString("LoadCacheImage(%1,%2)").arg(srcfile).arg(label));

    if (srcfile.isEmpty() || label.isEmpty())
        return NULL;

    if (!(kCacheForceStat & cacheMode))
    {
        // Some screens include certain images dozens or even hundreds of
        // times.  Even if the image is in the cache, there is still a
        // stat system call on the original file to see if it has changed.
        // This code relaxes the original-file check so that the check
        // isn't repeated if it was already done within kImageCacheTimeout
        // seconds.

        // This only applies to the MEMORY cache
        const uint kImageCacheTimeout = 60;
        uint now = MythDate::current().toTime_t();

        QMutexLocker locker(d->m_cacheLock);

        if (d->imageCache.contains(label) &&
            d->CacheTrack[label] + kImageCacheTimeout > now)
        {
            d->imageCache[label]->IncrRef();
            return d->imageCache[label];
        }
    }

    MythImage *ret = NULL;

    // Check Memory Cache
    ret = GetImageFromCache(label);

    // If the image is in the memory or we are not ignoring the disk cache
    // then proceed to check whether the source file is newer than our cached
    // copy
    if (ret || !(cacheMode & kCacheIgnoreDisk))
    {
        // Create url to image in disk cache
        QString cachefilepath = GetThemeCacheDir() + '/' + label;
        QFileInfo cacheFileInfo(cachefilepath);

        // If the file isn't in the disk cache, then we don't want to bother
        // checking the last modified times of the original
        if (!cacheFileInfo.exists())
            return NULL;

        // Now compare the time on the source versus our cached copy
        QDateTime srcLastModified;

        // For internet images this involves querying the headers of the remote
        // image. This is slow even without redownloading the whole image
        if ((srcfile.startsWith("http://")) ||
            (srcfile.startsWith("https://")) ||
            (srcfile.startsWith("ftp://")))
        {
            // If the image is in the memory cache then skip the last modified
            // check, since memory cached images are loaded in the foreground
            // this can cause an intolerable delay. The images won't stay in
            // the cache forever and so eventually they will be checked.
            if (ret)
                srcLastModified = cacheFileInfo.lastModified();
            else
            {
                srcLastModified =
                    GetMythDownloadManager()->GetLastModified(srcfile);
            }
        }
        else if (srcfile.startsWith("myth://"))
            srcLastModified = RemoteFile::LastModified(srcfile);
        else
        {
            if (!FindThemeFile(srcfile))
                return NULL;

            QFileInfo original(srcfile);

            if (original.exists())
                srcLastModified = original.lastModified();
        }

        // Now compare the timestamps, if the cached image is newer than the
        // source image we can use it, otherwise we want to remove it from the
        // cache
        if (cacheFileInfo.lastModified() >= srcLastModified)
        {
            // If we haven't already loaded the image from the memory cache
            // and we're not ignoring the disk cache, then it's time to load
            // it from there instead
            if (!ret && (cacheMode == kCacheNormal))
            {

                if (painter)
                    ret = painter->GetFormatImage();

                // Load file from disk cache to memory cache
                if (ret->Load(cachefilepath))
                {
                    // Add to ram cache, and skip saving to disk since that is
                    // where we found this in the first place.
                    CacheImage(label, ret, true);
                }
                else
                {
                    LOG(VB_GUI | VB_FILE, LOG_WARNING, LOC +
                        QString("LoadCacheImage: Could not load :%1")
                        .arg(cachefilepath));

                    ret->SetIsInCache(false);
                    ret->DecrRef();
                    ret = NULL;
                }
            }
        }
        else
        {
            ret = NULL;
            // If file has changed on disk, then remove it from the memory
            // and disk cache
            RemoveFromCacheByURL(label);
        }
    }

    return ret;
}
Ejemplo n.º 2
0
MythImage *MythUIHelper::LoadCacheImage(QString srcfile, QString label,
                                        MythPainter *painter,
                                        ImageCacheMode cacheMode)
{
    LOG(VB_GUI | VB_FILE, LOG_INFO, LOC +
        QString("LoadCacheImage(%1,%2)").arg(srcfile).arg(label));

    if (srcfile.isEmpty() || label.isEmpty())
        return NULL;

    if (!(kCacheForceStat & cacheMode))
    {
        // Some screens include certain images dozens or even hundreds of
        // times.  Even if the image is in the cache, there is still a
        // stat system call on the original file to see if it has changed.
        // This code relaxes the original-file check so that the check
        // isn't repeated if it was already done within kImageCacheTimeout
        // seconds.
        const uint kImageCacheTimeout = 5;
        uint now = MythDate::current().toTime_t();

        QMutexLocker locker(d->m_cacheLock);

        if (d->imageCache.contains(label) &&
            d->CacheTrack[label] + kImageCacheTimeout > now)
        {
            d->imageCache[label]->IncrRef();
            return d->imageCache[label];
        }
    }

    QString cachefilepath = GetThemeCacheDir() + '/' + label;
    QFileInfo fi(cachefilepath);

    MythImage *ret = NULL;

    if (!!(cacheMode & kCacheIgnoreDisk) || fi.exists())
    {
        // Now compare the time on the source versus our cached copy
        if (!(cacheMode & kCacheIgnoreDisk))
            FindThemeFile(srcfile);

        QDateTime srcLastModified;
        QFileInfo original(srcfile);

        if ((srcfile.startsWith("http://")) ||
            (srcfile.startsWith("https://")) ||
            (srcfile.startsWith("ftp://")))
        {
            srcLastModified =
                GetMythDownloadManager()->GetLastModified(srcfile);
        }
        else if (srcfile.startsWith("myth://"))
            srcLastModified = RemoteFile::LastModified(srcfile);
        else if (original.exists())
            srcLastModified = original.lastModified();

        if (!!(cacheMode & kCacheIgnoreDisk) ||
            (fi.lastModified() > srcLastModified))
        {
            // Check Memory Cache
            ret = GetImageFromCache(label);

            if (!ret && (cacheMode == kCacheNormal) && painter)
            {
                // Load file from disk cache to memory cache
                ret = painter->GetFormatImage();

                if (!ret->Load(cachefilepath, false))
                {
                    LOG(VB_GUI | VB_FILE, LOG_WARNING, LOC +
                        QString("LoadCacheImage: Could not load :%1")
                        .arg(cachefilepath));

                    ret->SetIsInCache(false);
                    ret->DecrRef();
                    ret = NULL;
                }
                else
                {
                    // Add to ram cache, and skip saving to disk since that is
                    // where we found this in the first place.
                    CacheImage(label, ret, true);
                }
            }
        }
        else
        {
            // If file has changed on disk, then remove it from the memory
            // and disk cache
            RemoveFromCacheByURL(label);
        }
    }

    return ret;
}