[Windows] Fix driver version detection of AMD RDNA+ GPU on Windows 10
[xbmc.git] / xbmc / settings / MediaSettings.cpp
blob097a9c11f0cbe5af9007e58651f2b893be80c531
1 /*
2 * Copyright (C) 2013-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
9 #include "MediaSettings.h"
11 #include "PlayListPlayer.h"
12 #include "ServiceBroker.h"
13 #include "cores/RetroPlayer/RetroPlayerUtils.h"
14 #include "dialogs/GUIDialogFileBrowser.h"
15 #include "guilib/LocalizeStrings.h"
16 #include "interfaces/AnnouncementManager.h"
17 #include "interfaces/builtins/Builtins.h"
18 #include "messaging/helpers/DialogHelper.h"
19 #include "messaging/helpers/DialogOKHelper.h"
20 #include "music/MusicLibraryQueue.h"
21 #include "settings/Settings.h"
22 #include "settings/dialogs/GUIDialogLibExportSettings.h"
23 #include "settings/lib/Setting.h"
24 #include "storage/MediaManager.h"
25 #include "utils/StringUtils.h"
26 #include "utils/Variant.h"
27 #include "utils/XBMCTinyXML.h"
28 #include "utils/XMLUtils.h"
29 #include "utils/log.h"
30 #include "video/VideoDatabase.h"
31 #include "video/VideoLibraryQueue.h"
33 #include <limits.h>
34 #include <mutex>
35 #include <string>
37 using namespace KODI;
38 using namespace KODI::MESSAGING;
40 using KODI::MESSAGING::HELPERS::DialogResponse;
42 CMediaSettings::CMediaSettings()
44 m_watchedModes["files"] = WatchedModeAll;
45 m_watchedModes["movies"] = WatchedModeAll;
46 m_watchedModes["tvshows"] = WatchedModeAll;
47 m_watchedModes["musicvideos"] = WatchedModeAll;
48 m_watchedModes["recordings"] = WatchedModeAll;
50 m_musicPlaylistRepeat = false;
51 m_musicPlaylistShuffle = false;
52 m_videoPlaylistRepeat = false;
53 m_videoPlaylistShuffle = false;
55 m_mediaStartWindowed = false;
56 m_additionalSubtitleDirectoryChecked = 0;
58 m_musicNeedsUpdate = 0;
59 m_videoNeedsUpdate = 0;
62 CMediaSettings::~CMediaSettings() = default;
64 CMediaSettings& CMediaSettings::GetInstance()
66 static CMediaSettings sMediaSettings;
67 return sMediaSettings;
70 bool CMediaSettings::Load(const TiXmlNode *settings)
72 if (settings == NULL)
73 return false;
75 std::unique_lock<CCriticalSection> lock(m_critical);
76 const TiXmlElement *pElement = settings->FirstChildElement("defaultvideosettings");
77 if (pElement != NULL)
79 int interlaceMethod;
80 XMLUtils::GetInt(pElement, "interlacemethod", interlaceMethod, VS_INTERLACEMETHOD_NONE, VS_INTERLACEMETHOD_MAX);
82 m_defaultVideoSettings.m_InterlaceMethod = (EINTERLACEMETHOD)interlaceMethod;
83 int scalingMethod;
84 if (!XMLUtils::GetInt(pElement, "scalingmethod", scalingMethod, VS_SCALINGMETHOD_NEAREST, VS_SCALINGMETHOD_MAX))
85 scalingMethod = (int)VS_SCALINGMETHOD_LINEAR;
86 m_defaultVideoSettings.m_ScalingMethod = (ESCALINGMETHOD)scalingMethod;
88 XMLUtils::GetInt(pElement, "viewmode", m_defaultVideoSettings.m_ViewMode, ViewModeNormal, ViewModeZoom110Width);
89 if (!XMLUtils::GetFloat(pElement, "zoomamount", m_defaultVideoSettings.m_CustomZoomAmount, 0.5f, 2.0f))
90 m_defaultVideoSettings.m_CustomZoomAmount = 1.0f;
91 if (!XMLUtils::GetFloat(pElement, "pixelratio", m_defaultVideoSettings.m_CustomPixelRatio, 0.5f, 2.0f))
92 m_defaultVideoSettings.m_CustomPixelRatio = 1.0f;
93 if (!XMLUtils::GetFloat(pElement, "verticalshift", m_defaultVideoSettings.m_CustomVerticalShift, -2.0f, 2.0f))
94 m_defaultVideoSettings.m_CustomVerticalShift = 0.0f;
95 if (!XMLUtils::GetFloat(pElement, "volumeamplification", m_defaultVideoSettings.m_VolumeAmplification, VOLUME_DRC_MINIMUM * 0.01f, VOLUME_DRC_MAXIMUM * 0.01f))
96 m_defaultVideoSettings.m_VolumeAmplification = VOLUME_DRC_MINIMUM * 0.01f;
97 if (!XMLUtils::GetFloat(pElement, "noisereduction", m_defaultVideoSettings.m_NoiseReduction, 0.0f, 1.0f))
98 m_defaultVideoSettings.m_NoiseReduction = 0.0f;
99 XMLUtils::GetBoolean(pElement, "postprocess", m_defaultVideoSettings.m_PostProcess);
100 if (!XMLUtils::GetFloat(pElement, "sharpness", m_defaultVideoSettings.m_Sharpness, -1.0f, 1.0f))
101 m_defaultVideoSettings.m_Sharpness = 0.0f;
102 XMLUtils::GetBoolean(pElement, "showsubtitles", m_defaultVideoSettings.m_SubtitleOn);
103 if (!XMLUtils::GetFloat(pElement, "brightness", m_defaultVideoSettings.m_Brightness, 0, 100))
104 m_defaultVideoSettings.m_Brightness = 50;
105 if (!XMLUtils::GetFloat(pElement, "contrast", m_defaultVideoSettings.m_Contrast, 0, 100))
106 m_defaultVideoSettings.m_Contrast = 50;
107 if (!XMLUtils::GetFloat(pElement, "gamma", m_defaultVideoSettings.m_Gamma, 0, 100))
108 m_defaultVideoSettings.m_Gamma = 20;
109 if (!XMLUtils::GetFloat(pElement, "audiodelay", m_defaultVideoSettings.m_AudioDelay, -10.0f, 10.0f))
110 m_defaultVideoSettings.m_AudioDelay = 0.0f;
111 if (!XMLUtils::GetFloat(pElement, "subtitledelay", m_defaultVideoSettings.m_SubtitleDelay, -10.0f, 10.0f))
112 m_defaultVideoSettings.m_SubtitleDelay = 0.0f;
113 XMLUtils::GetBoolean(pElement, "nonlinstretch", m_defaultVideoSettings.m_CustomNonLinStretch);
114 if (!XMLUtils::GetInt(pElement, "stereomode", m_defaultVideoSettings.m_StereoMode))
115 m_defaultVideoSettings.m_StereoMode = 0;
116 if (!XMLUtils::GetInt(pElement, "centermixlevel", m_defaultVideoSettings.m_CenterMixLevel))
117 m_defaultVideoSettings.m_CenterMixLevel = 0;
119 int toneMapMethod;
120 if (!XMLUtils::GetInt(pElement, "tonemapmethod", toneMapMethod, VS_TONEMAPMETHOD_OFF,
121 VS_TONEMAPMETHOD_MAX))
122 toneMapMethod = VS_TONEMAPMETHOD_HABLE;
123 m_defaultVideoSettings.m_ToneMapMethod = static_cast<ETONEMAPMETHOD>(toneMapMethod);
125 if (!XMLUtils::GetFloat(pElement, "tonemapparam", m_defaultVideoSettings.m_ToneMapParam, 0.1f, 5.0f))
126 m_defaultVideoSettings.m_ToneMapParam = 1.0f;
129 m_defaultGameSettings.Reset();
130 pElement = settings->FirstChildElement("defaultgamesettings");
131 if (pElement != nullptr)
133 std::string videoFilter;
134 if (XMLUtils::GetString(pElement, "videofilter", videoFilter))
135 m_defaultGameSettings.SetVideoFilter(videoFilter);
137 std::string stretchMode;
138 if (XMLUtils::GetString(pElement, "stretchmode", stretchMode))
140 RETRO::STRETCHMODE sm = RETRO::CRetroPlayerUtils::IdentifierToStretchMode(stretchMode);
141 m_defaultGameSettings.SetStretchMode(sm);
144 int rotation;
145 if (XMLUtils::GetInt(pElement, "rotation", rotation, 0, 270) && rotation >= 0)
146 m_defaultGameSettings.SetRotationDegCCW(static_cast<unsigned int>(rotation));
149 // mymusic settings
150 pElement = settings->FirstChildElement("mymusic");
151 if (pElement != NULL)
153 const TiXmlElement *pChild = pElement->FirstChildElement("playlist");
154 if (pChild != NULL)
156 XMLUtils::GetBoolean(pChild, "repeat", m_musicPlaylistRepeat);
157 XMLUtils::GetBoolean(pChild, "shuffle", m_musicPlaylistShuffle);
159 if (!XMLUtils::GetInt(pElement, "needsupdate", m_musicNeedsUpdate, 0, INT_MAX))
160 m_musicNeedsUpdate = 0;
163 // Set music playlist player repeat and shuffle from loaded settings
164 if (m_musicPlaylistRepeat)
165 CServiceBroker::GetPlaylistPlayer().SetRepeat(PLAYLIST::Id::TYPE_MUSIC,
166 PLAYLIST::RepeatState::ALL);
167 else
168 CServiceBroker::GetPlaylistPlayer().SetRepeat(PLAYLIST::Id::TYPE_MUSIC,
169 PLAYLIST::RepeatState::NONE);
170 CServiceBroker::GetPlaylistPlayer().SetShuffle(PLAYLIST::Id::TYPE_MUSIC, m_musicPlaylistShuffle);
172 // Read the watchmode settings for the various media views
173 pElement = settings->FirstChildElement("myvideos");
174 if (pElement != NULL)
176 int tmp;
177 if (XMLUtils::GetInt(pElement, "watchmodemovies", tmp, (int)WatchedModeAll, (int)WatchedModeWatched))
178 m_watchedModes["movies"] = (WatchedMode)tmp;
179 if (XMLUtils::GetInt(pElement, "watchmodetvshows", tmp, (int)WatchedModeAll, (int)WatchedModeWatched))
180 m_watchedModes["tvshows"] = (WatchedMode)tmp;
181 if (XMLUtils::GetInt(pElement, "watchmodemusicvideos", tmp, (int)WatchedModeAll, (int)WatchedModeWatched))
182 m_watchedModes["musicvideos"] = (WatchedMode)tmp;
183 if (XMLUtils::GetInt(pElement, "watchmoderecordings", tmp, static_cast<int>(WatchedModeAll), static_cast<int>(WatchedModeWatched)))
184 m_watchedModes["recordings"] = static_cast<WatchedMode>(tmp);
186 const TiXmlElement *pChild = pElement->FirstChildElement("playlist");
187 if (pChild != NULL)
189 XMLUtils::GetBoolean(pChild, "repeat", m_videoPlaylistRepeat);
190 XMLUtils::GetBoolean(pChild, "shuffle", m_videoPlaylistShuffle);
192 if (!XMLUtils::GetInt(pElement, "needsupdate", m_videoNeedsUpdate, 0, INT_MAX))
193 m_videoNeedsUpdate = 0;
196 // Set video playlist player repeat and shuffle from loaded settings
197 if (m_videoPlaylistRepeat)
198 CServiceBroker::GetPlaylistPlayer().SetRepeat(PLAYLIST::Id::TYPE_VIDEO,
199 PLAYLIST::RepeatState::ALL);
200 else
201 CServiceBroker::GetPlaylistPlayer().SetRepeat(PLAYLIST::Id::TYPE_VIDEO,
202 PLAYLIST::RepeatState::NONE);
203 CServiceBroker::GetPlaylistPlayer().SetShuffle(PLAYLIST::Id::TYPE_VIDEO, m_videoPlaylistShuffle);
205 return true;
208 bool CMediaSettings::Save(TiXmlNode *settings) const
210 if (settings == NULL)
211 return false;
213 std::unique_lock<CCriticalSection> lock(m_critical);
214 // default video settings
215 TiXmlElement videoSettingsNode("defaultvideosettings");
216 TiXmlNode *pNode = settings->InsertEndChild(videoSettingsNode);
217 if (pNode == NULL)
218 return false;
220 XMLUtils::SetInt(pNode, "interlacemethod", m_defaultVideoSettings.m_InterlaceMethod);
221 XMLUtils::SetInt(pNode, "scalingmethod", m_defaultVideoSettings.m_ScalingMethod);
222 XMLUtils::SetFloat(pNode, "noisereduction", m_defaultVideoSettings.m_NoiseReduction);
223 XMLUtils::SetBoolean(pNode, "postprocess", m_defaultVideoSettings.m_PostProcess);
224 XMLUtils::SetFloat(pNode, "sharpness", m_defaultVideoSettings.m_Sharpness);
225 XMLUtils::SetInt(pNode, "viewmode", m_defaultVideoSettings.m_ViewMode);
226 XMLUtils::SetFloat(pNode, "zoomamount", m_defaultVideoSettings.m_CustomZoomAmount);
227 XMLUtils::SetFloat(pNode, "pixelratio", m_defaultVideoSettings.m_CustomPixelRatio);
228 XMLUtils::SetFloat(pNode, "verticalshift", m_defaultVideoSettings.m_CustomVerticalShift);
229 XMLUtils::SetFloat(pNode, "volumeamplification", m_defaultVideoSettings.m_VolumeAmplification);
230 XMLUtils::SetBoolean(pNode, "showsubtitles", m_defaultVideoSettings.m_SubtitleOn);
231 XMLUtils::SetFloat(pNode, "brightness", m_defaultVideoSettings.m_Brightness);
232 XMLUtils::SetFloat(pNode, "contrast", m_defaultVideoSettings.m_Contrast);
233 XMLUtils::SetFloat(pNode, "gamma", m_defaultVideoSettings.m_Gamma);
234 XMLUtils::SetFloat(pNode, "audiodelay", m_defaultVideoSettings.m_AudioDelay);
235 XMLUtils::SetFloat(pNode, "subtitledelay", m_defaultVideoSettings.m_SubtitleDelay);
236 XMLUtils::SetBoolean(pNode, "nonlinstretch", m_defaultVideoSettings.m_CustomNonLinStretch);
237 XMLUtils::SetInt(pNode, "stereomode", m_defaultVideoSettings.m_StereoMode);
238 XMLUtils::SetInt(pNode, "centermixlevel", m_defaultVideoSettings.m_CenterMixLevel);
239 XMLUtils::SetInt(pNode, "tonemapmethod", m_defaultVideoSettings.m_ToneMapMethod);
240 XMLUtils::SetFloat(pNode, "tonemapparam", m_defaultVideoSettings.m_ToneMapParam);
242 // default audio settings for dsp addons
243 TiXmlElement audioSettingsNode("defaultaudiosettings");
244 pNode = settings->InsertEndChild(audioSettingsNode);
245 if (pNode == NULL)
246 return false;
248 // Default game settings
249 TiXmlElement gameSettingsNode("defaultgamesettings");
250 pNode = settings->InsertEndChild(gameSettingsNode);
251 if (pNode == nullptr)
252 return false;
254 XMLUtils::SetString(pNode, "videofilter", m_defaultGameSettings.VideoFilter());
255 std::string sm = RETRO::CRetroPlayerUtils::StretchModeToIdentifier(m_defaultGameSettings.StretchMode());
256 XMLUtils::SetString(pNode, "stretchmode", sm);
257 XMLUtils::SetInt(pNode, "rotation", m_defaultGameSettings.RotationDegCCW());
259 // mymusic
260 pNode = settings->FirstChild("mymusic");
261 if (pNode == NULL)
263 TiXmlElement videosNode("mymusic");
264 pNode = settings->InsertEndChild(videosNode);
265 if (pNode == NULL)
266 return false;
269 TiXmlElement musicPlaylistNode("playlist");
270 TiXmlNode *playlistNode = pNode->InsertEndChild(musicPlaylistNode);
271 if (playlistNode == NULL)
272 return false;
273 XMLUtils::SetBoolean(playlistNode, "repeat", m_musicPlaylistRepeat);
274 XMLUtils::SetBoolean(playlistNode, "shuffle", m_musicPlaylistShuffle);
276 XMLUtils::SetInt(pNode, "needsupdate", m_musicNeedsUpdate);
278 // myvideos
279 pNode = settings->FirstChild("myvideos");
280 if (pNode == NULL)
282 TiXmlElement videosNode("myvideos");
283 pNode = settings->InsertEndChild(videosNode);
284 if (pNode == NULL)
285 return false;
288 XMLUtils::SetInt(pNode, "watchmodemovies", m_watchedModes.find("movies")->second);
289 XMLUtils::SetInt(pNode, "watchmodetvshows", m_watchedModes.find("tvshows")->second);
290 XMLUtils::SetInt(pNode, "watchmodemusicvideos", m_watchedModes.find("musicvideos")->second);
291 XMLUtils::SetInt(pNode, "watchmoderecordings", m_watchedModes.find("recordings")->second);
293 TiXmlElement videoPlaylistNode("playlist");
294 playlistNode = pNode->InsertEndChild(videoPlaylistNode);
295 if (playlistNode == NULL)
296 return false;
297 XMLUtils::SetBoolean(playlistNode, "repeat", m_videoPlaylistRepeat);
298 XMLUtils::SetBoolean(playlistNode, "shuffle", m_videoPlaylistShuffle);
300 XMLUtils::SetInt(pNode, "needsupdate", m_videoNeedsUpdate);
302 return true;
305 void CMediaSettings::OnSettingAction(const std::shared_ptr<const CSetting>& setting)
307 if (setting == NULL)
308 return;
310 const std::string &settingId = setting->GetId();
311 if (settingId == CSettings::SETTING_MUSICLIBRARY_CLEANUP)
313 if (HELPERS::ShowYesNoDialogText(CVariant{313}, CVariant{333}) == DialogResponse::CHOICE_YES)
315 if (CMusicLibraryQueue::GetInstance().IsRunning())
316 HELPERS::ShowOKDialogText(CVariant{700}, CVariant{703});
317 else
318 CMusicLibraryQueue::GetInstance().CleanLibrary(true);
321 else if (settingId == CSettings::SETTING_MUSICLIBRARY_EXPORT)
323 CLibExportSettings m_musicExportSettings;
324 if (CGUIDialogLibExportSettings::Show(m_musicExportSettings))
326 // Export music library showing progress dialog
327 CMusicLibraryQueue::GetInstance().ExportLibrary(m_musicExportSettings, true);
330 else if (settingId == CSettings::SETTING_MUSICLIBRARY_IMPORT)
332 std::string path;
333 VECSOURCES shares;
334 CServiceBroker::GetMediaManager().GetLocalDrives(shares);
335 CServiceBroker::GetMediaManager().GetNetworkLocations(shares);
336 CServiceBroker::GetMediaManager().GetRemovableDrives(shares);
338 if (CGUIDialogFileBrowser::ShowAndGetFile(shares, "musicdb.xml", g_localizeStrings.Get(651) , path))
340 // Import data to music library showing progress dialog
341 CMusicLibraryQueue::GetInstance().ImportLibrary(path, true);
344 else if (settingId == CSettings::SETTING_VIDEOLIBRARY_CLEANUP)
346 if (HELPERS::ShowYesNoDialogText(CVariant{313}, CVariant{333}) == DialogResponse::CHOICE_YES)
348 if (!CVideoLibraryQueue::GetInstance().CleanLibraryModal())
349 HELPERS::ShowOKDialogText(CVariant{700}, CVariant{703});
352 else if (settingId == CSettings::SETTING_VIDEOLIBRARY_EXPORT)
353 CBuiltins::GetInstance().Execute("exportlibrary(video)");
354 else if (settingId == CSettings::SETTING_VIDEOLIBRARY_IMPORT)
356 std::string path;
357 VECSOURCES shares;
358 CServiceBroker::GetMediaManager().GetLocalDrives(shares);
359 CServiceBroker::GetMediaManager().GetNetworkLocations(shares);
360 CServiceBroker::GetMediaManager().GetRemovableDrives(shares);
362 if (CGUIDialogFileBrowser::ShowAndGetDirectory(shares, g_localizeStrings.Get(651) , path))
364 CVideoDatabase videodatabase;
365 videodatabase.Open();
366 videodatabase.ImportFromXML(path);
367 videodatabase.Close();
372 void CMediaSettings::OnSettingChanged(const std::shared_ptr<const CSetting>& setting)
374 if (setting == nullptr)
375 return;
377 if (setting->GetId() == CSettings::SETTING_VIDEOLIBRARY_SHOWUNWATCHEDPLOTS)
378 CServiceBroker::GetAnnouncementManager()->Announce(ANNOUNCEMENT::VideoLibrary, "OnRefresh");
381 int CMediaSettings::GetWatchedMode(const std::string &content) const
383 std::unique_lock<CCriticalSection> lock(m_critical);
384 WatchedModes::const_iterator it = m_watchedModes.find(GetWatchedContent(content));
385 if (it != m_watchedModes.end())
386 return it->second;
388 return WatchedModeAll;
391 void CMediaSettings::SetWatchedMode(const std::string &content, WatchedMode mode)
393 std::unique_lock<CCriticalSection> lock(m_critical);
394 WatchedModes::iterator it = m_watchedModes.find(GetWatchedContent(content));
395 if (it != m_watchedModes.end())
396 it->second = mode;
399 void CMediaSettings::CycleWatchedMode(const std::string &content)
401 std::unique_lock<CCriticalSection> lock(m_critical);
402 WatchedModes::iterator it = m_watchedModes.find(GetWatchedContent(content));
403 if (it != m_watchedModes.end())
405 it->second = (WatchedMode)((int)it->second + 1);
406 if (it->second > WatchedModeWatched)
407 it->second = WatchedModeAll;
411 std::string CMediaSettings::GetWatchedContent(const std::string &content)
413 if (content == "seasons" || content == "episodes")
414 return "tvshows";
416 return content;