1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
|
/*
* Copyright (C) 2005-2018 Team Kodi
* This file is part of Kodi - https://kodi.tv
*
* SPDX-License-Identifier: GPL-2.0-or-later
* See LICENSES/README.md for more information.
*/
#include "PVRThumbLoader.h"
#include "FileItem.h"
#include "ServiceBroker.h"
#include "TextureCache.h"
#include "TextureCacheJob.h"
#include "pictures/Picture.h"
#include "pvr/PVRCachedImages.h"
#include "pvr/PVRManager.h"
#include "pvr/filesystem/PVRGUIDirectory.h"
#include "settings/AdvancedSettings.h"
#include "settings/Settings.h"
#include "settings/SettingsComponent.h"
#include "utils/StringUtils.h"
#include "utils/log.h"
#include <ctime>
using namespace PVR;
bool CPVRThumbLoader::LoadItem(CFileItem* item)
{
bool result = LoadItemCached(item);
result |= LoadItemLookup(item);
return result;
}
bool CPVRThumbLoader::LoadItemCached(CFileItem* item)
{
return FillThumb(*item);
}
bool CPVRThumbLoader::LoadItemLookup(CFileItem* item)
{
return false;
}
void CPVRThumbLoader::OnLoaderFinish()
{
if (m_bInvalidated)
{
m_bInvalidated = false;
CServiceBroker::GetPVRManager().PublishEvent(PVREvent::ChannelGroupsInvalidated);
}
CThumbLoader::OnLoaderFinish();
}
void CPVRThumbLoader::ClearCachedImage(CFileItem& item)
{
const std::string thumb = item.GetArt("thumb");
if (!thumb.empty())
{
CServiceBroker::GetTextureCache()->ClearCachedImage(thumb);
if (m_textureDatabase->Open())
{
m_textureDatabase->ClearTextureForPath(item.GetPath(), "thumb");
m_textureDatabase->Close();
}
item.SetArt("thumb", "");
m_bInvalidated = true;
}
}
void CPVRThumbLoader::ClearCachedImages(const CFileItemList& items)
{
for (auto& item : items)
ClearCachedImage(*item);
}
bool CPVRThumbLoader::FillThumb(CFileItem& item)
{
// see whether we have a cached image for this item
std::string thumb = GetCachedImage(item, "thumb");
if (thumb.empty())
{
if (item.IsPVRChannelGroup())
thumb = CreateChannelGroupThumb(item);
else
CLog::LogF(LOGERROR, "Unsupported PVR item '{}'", item.GetPath());
if (!thumb.empty())
{
SetCachedImage(item, "thumb", thumb);
m_bInvalidated = true;
}
}
if (thumb.empty())
return false;
item.SetArt("thumb", thumb);
return true;
}
std::string CPVRThumbLoader::CreateChannelGroupThumb(const CFileItem& channelGroupItem)
{
const CPVRGUIDirectory channelGroupDir(channelGroupItem.GetPath());
CFileItemList channels;
if (channelGroupDir.GetChannelsDirectory(channels))
{
std::vector<std::string> channelIcons;
for (const auto& channel : channels)
{
const std::string& icon = channel->GetArt("icon");
if (!icon.empty())
channelIcons.emplace_back(CPVRCachedImages::UnwrapImageURL(icon));
if (channelIcons.size() == 9) // limit number of tiles
break;
}
std::string thumb = StringUtils::Format(
"{}?ts={}", // append timestamp to Thumb URL to enforce texture refresh
CTextureUtils::GetWrappedImageURL(channelGroupItem.GetPath(), "pvr"), std::time(nullptr));
const std::string relativeCacheFile = CTextureCache::GetCacheFile(thumb) + ".png";
if (CPicture::CreateTiledThumb(channelIcons, CTextureCache::GetCachedPath(relativeCacheFile)))
{
CTextureDetails details;
details.file = relativeCacheFile;
details.width = CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_imageRes;
details.height = details.width;
CServiceBroker::GetTextureCache()->AddCachedTexture(thumb, details);
return thumb;
}
}
return {};
}
|