2 * Copyright (C) 2005-2013 Team XBMC
5 * This Program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
10 * This Program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with XBMC; see the file COPYING. If not, see
17 * <http://www.gnu.org/licenses/>.
24 #include "AdvancedSettings.h"
25 #include "Application.h"
26 #include "network/DNSNameCache.h"
27 #include "filesystem/File.h"
28 #include "utils/LangCodeExpander.h"
30 #include "profiles/ProfilesManager.h"
31 #include "settings/lib/Setting.h"
32 #include "settings/Settings.h"
33 #include "utils/StringUtils.h"
34 #include "utils/SystemInfo.h"
35 #include "utils/URIUtils.h"
36 #include "utils/XMLUtils.h"
37 #include "utils/log.h"
38 #include "filesystem/SpecialProtocol.h"
39 #include "addons/IAddon.h"
40 #include "addons/AddonManager.h"
41 #include "addons/GUIDialogAddonSettings.h"
42 #if defined(TARGET_DARWIN_IOS)
43 #include "osx/DarwinUtils.h"
46 using namespace ADDON;
47 using namespace XFILE;
50 CAdvancedSettings::CAdvancedSettings()
52 m_initialized = false;
55 void CAdvancedSettings::OnSettingsLoaded()
57 // load advanced settings
61 CLog::Log(LOGNOTICE, "Default DVD Player: %s", m_videoDefaultDVDPlayer.c_str());
62 CLog::Log(LOGNOTICE, "Default Video Player: %s", m_videoDefaultPlayer.c_str());
63 CLog::Log(LOGNOTICE, "Default Audio Player: %s", m_audioDefaultPlayer.c_str());
65 // setup any logging...
66 if (CSettings::Get().GetBool("debug.showloginfo"))
68 m_logLevel = std::max(m_logLevelHint, LOG_LEVEL_DEBUG_FREEMEM);
69 CLog::Log(LOGNOTICE, "Enabled debug logging due to GUI setting (%d)", m_logLevel);
73 m_logLevel = std::min(m_logLevelHint, LOG_LEVEL_DEBUG/*LOG_LEVEL_NORMAL*/);
74 CLog::Log(LOGNOTICE, "Disabled debug logging due to GUI setting. Level %d.", m_logLevel);
76 CLog::SetLogLevel(m_logLevel);
79 void CAdvancedSettings::OnSettingsUnloaded()
81 m_initialized = false;
84 void CAdvancedSettings::OnSettingChanged(const CSetting *setting)
89 const std::string &settingId = setting->GetId();
90 if (settingId == "debug.showloginfo")
91 SetDebugMode(((CSettingBool*)setting)->GetValue());
94 void CAdvancedSettings::OnSettingAction(const CSetting *setting)
99 const std::string settingId = setting->GetId();
100 if (settingId == "debug.setextraloglevel")
103 CAddonMgr::Get().GetAddon("xbmc.debug", addon);
104 CGUIDialogAddonSettings::ShowAndGetInput(addon, true);
105 SetExtraLogsFromAddon(addon.get());
109 void CAdvancedSettings::Initialize()
116 m_audioApplyDrc = true;
117 m_dvdplayerIgnoreDTSinWAV = false;
119 //default hold time of 25 ms, this allows a 20 hertz sine to pass undistorted
120 m_limiterHold = 0.025f;
121 m_limiterRelease = 0.1f;
123 m_omxHWAudioDecode = false;
124 m_omxDecodeStartWithValidFrame = false;
126 m_karaokeSyncDelayCDG = 0.0f;
127 m_karaokeSyncDelayLRC = 0.0f;
128 m_karaokeChangeGenreForKaraokeSongs = false;
129 m_karaokeKeepDelay = true;
130 m_karaokeStartIndex = 1;
131 m_karaokeAlwaysEmptyOnCdgs = 1;
132 m_karaokeUseSongSpecificBackground = 0;
134 m_audioDefaultPlayer = "paplayer";
135 m_audioPlayCountMinimumPercent = 90.0f;
136 m_audioHost = "default";
138 m_videoSubsDelayRange = 10;
139 m_videoAudioDelayRange = 10;
140 m_videoSmallStepBackSeconds = 7;
141 m_videoSmallStepBackTries = 3;
142 m_videoSmallStepBackDelay = 300;
143 m_videoUseTimeSeeking = true;
144 m_videoTimeSeekForward = 30;
145 m_videoTimeSeekBackward = -30;
146 m_videoTimeSeekForwardBig = 600;
147 m_videoTimeSeekBackwardBig = -600;
148 m_videoPercentSeekForward = 2;
149 m_videoPercentSeekBackward = -2;
150 m_videoPercentSeekForwardBig = 10;
151 m_videoPercentSeekBackwardBig = -10;
152 m_videoBlackBarColour = 0;
153 m_videoPPFFmpegDeint = "linblenddeint";
154 m_videoPPFFmpegPostProc = "ha:128:7,va,dr";
155 m_videoDefaultPlayer = "dvdplayer";
156 m_videoDefaultDVDPlayer = "dvdplayer";
157 m_videoIgnoreSecondsAtStart = 3*60;
158 m_videoIgnorePercentAtEnd = 8.0f;
159 m_videoPlayCountMinimumPercent = 90.0f;
160 m_videoVDPAUScaling = -1;
161 m_videoNonLinStretchRatio = 0.5f;
162 m_videoEnableHighQualityHwScalers = false;
163 m_videoAutoScaleMaxFps = 30.0f;
164 m_videoAllowMpeg4VDPAU = false;
165 m_videoAllowMpeg4VAAPI = false;
166 m_videoDisableBackgroundDeinterlace = false;
167 m_videoCaptureUseOcclusionQuery = -1; //-1 is auto detect
168 m_videoVDPAUtelecine = false;
169 m_videoVDPAUdeintSkipChromaHD = false;
170 m_DXVACheckCompatibility = false;
171 m_DXVACheckCompatibilityPresent = false;
172 m_DXVAForceProcessorRenderer = true;
173 m_DXVANoDeintProcForProgressive = false;
174 m_videoFpsDetect = 1;
175 m_videoBusyDialogDelay_ms = 500;
176 m_stagefrightConfig.useAVCcodec = -1;
177 m_stagefrightConfig.useVC1codec = -1;
178 m_stagefrightConfig.useVPXcodec = -1;
179 m_stagefrightConfig.useMP4codec = -1;
180 m_stagefrightConfig.useMPEG2codec = -1;
181 m_stagefrightConfig.useSwRenderer = false;
182 m_stagefrightConfig.useInputDTS = false;
184 m_videoDefaultLatency = 0.0;
185 m_videoDisableHi10pMultithreading = false;
187 m_musicUseTimeSeeking = true;
188 m_musicTimeSeekForward = 10;
189 m_musicTimeSeekBackward = -10;
190 m_musicTimeSeekForwardBig = 60;
191 m_musicTimeSeekBackwardBig = -60;
192 m_musicPercentSeekForward = 1;
193 m_musicPercentSeekBackward = -1;
194 m_musicPercentSeekForwardBig = 10;
195 m_musicPercentSeekBackwardBig = -10;
197 m_slideshowPanAmount = 2.5f;
198 m_slideshowZoomAmount = 5.0f;
199 m_slideshowBlackBarCompensation = 20.0f;
201 m_songInfoDuration = 10;
203 m_cddbAddress = "freedb.freedb.org";
205 m_handleMounting = g_application.IsStandAlone();
207 m_fullScreenOnMovieStart = true;
208 m_cachePath = "special://temp/";
210 m_videoCleanDateTimeRegExp = "(.*[^ _\\,\\.\\(\\)\\[\\]\\-])[ _\\.\\(\\)\\[\\]\\-]+(19[0-9][0-9]|20[0-1][0-9])([ _\\,\\.\\(\\)\\[\\]\\-]|[^0-9]$)";
212 m_videoCleanStringRegExps.clear();
213 m_videoCleanStringRegExps.push_back("[ _\\,\\.\\(\\)\\[\\]\\-](ac3|dts|custom|dc|remastered|divx|divx5|dsr|dsrip|dutch|dvd|dvd5|dvd9|dvdrip|dvdscr|dvdscreener|screener|dvdivx|cam|fragment|fs|hdtv|hdrip|hdtvrip|internal|limited|multisubs|ntsc|ogg|ogm|pal|pdtv|proper|repack|rerip|retail|r3|r5|bd5|se|svcd|swedish|german|read.nfo|nfofix|unrated|extended|ws|telesync|ts|telecine|tc|brrip|bdrip|480p|480i|576p|576i|720p|720i|1080p|1080i|3d|hrhd|hrhdtv|hddvd|bluray|x264|h264|xvid|xvidvd|xxx|www.www|cd[1-9]|\\[.*\\])([ _\\,\\.\\(\\)\\[\\]\\-]|$)");
214 m_videoCleanStringRegExps.push_back("(\\[.*\\])");
216 m_moviesExcludeFromScanRegExps.clear();
217 m_moviesExcludeFromScanRegExps.push_back("-trailer");
218 m_moviesExcludeFromScanRegExps.push_back("[!-._ \\\\/]sample[-._ \\\\/]");
219 m_tvshowExcludeFromScanRegExps.push_back("[!-._ \\\\/]sample[-._ \\\\/]");
221 m_folderStackRegExps.clear();
222 m_folderStackRegExps.push_back("((cd|dvd|dis[ck])[0-9]+)$");
224 m_videoStackRegExps.clear();
225 m_videoStackRegExps.push_back("(.*?)([ _.-]*(?:cd|dvd|p(?:(?:ar)?t)|dis[ck]|d)[ _.-]*[0-9]+)(.*?)(\\.[^.]+)$");
226 m_videoStackRegExps.push_back("(.*?)([ _.-]*(?:cd|dvd|p(?:(?:ar)?t)|dis[ck]|d)[ _.-]*[a-d])(.*?)(\\.[^.]+)$");
227 m_videoStackRegExps.push_back("(.*?)([ ._-]*[a-d])(.*?)(\\.[^.]+)$");
228 // This one is a bit too greedy to enable by default. It will stack sequels
229 // in a flat dir structure, but is perfectly safe in a dir-per-vid one.
230 //m_videoStackRegExps.push_back("(.*?)([ ._-]*[0-9])(.*?)(\\.[^.]+)$");
232 m_tvshowEnumRegExps.clear();
233 // foo.s01.e01, foo.s01_e01, S01E02 foo, S01 - E02
234 m_tvshowEnumRegExps.push_back(TVShowRegexp(false,"s([0-9]+)[ ._-]*e([0-9]+(?:(?:[a-i]|\\.[1-9])(?![0-9]))?)([^\\\\/]*)$"));
235 // foo.ep01, foo.EP_01
236 m_tvshowEnumRegExps.push_back(TVShowRegexp(false,"[\\._ -]()ep_?([0-9]+(?:(?:[a-i]|\\.[1-9])(?![0-9]))?)([^\\\\/]*)$"));
237 // foo.yyyy.mm.dd.* (byDate=true)
238 m_tvshowEnumRegExps.push_back(TVShowRegexp(true,"([0-9]{4})[\\.-]([0-9]{2})[\\.-]([0-9]{2})"));
239 // foo.mm.dd.yyyy.* (byDate=true)
240 m_tvshowEnumRegExps.push_back(TVShowRegexp(true,"([0-9]{2})[\\.-]([0-9]{2})[\\.-]([0-9]{4})"));
241 // foo.1x09* or just /1x09*
242 m_tvshowEnumRegExps.push_back(TVShowRegexp(false,"[\\\\/\\._ \\[\\(-]([0-9]+)x([0-9]+(?:(?:[a-i]|\\.[1-9])(?![0-9]))?)([^\\\\/]*)$"));
244 m_tvshowEnumRegExps.push_back(TVShowRegexp(false,"[\\\\/\\._ -]([0-9]+)([0-9][0-9](?:(?:[a-i]|\\.[1-9])(?![0-9]))?)([\\._ -][^\\\\/]*)$"));
246 m_tvshowEnumRegExps.push_back(TVShowRegexp(false,"[\\/._ -]p(?:ar)?t[_. -]()([ivx]+)([._ -][^\\/]*)$"));
248 m_tvshowMultiPartEnumRegExp = "^[-_ex]+([0-9]+(?:(?:[a-i]|\\.[1-9])(?![0-9]))?)";
251 m_controllerDeadzone = 0.2f;
253 m_playlistAsFolders = true;
254 m_detectAsUdf = false;
258 m_useDDSFanart = false;
260 m_sambaclienttimeout = 10;
261 m_sambadoscodepage = "";
262 m_sambastatfiles = true;
264 m_bHTTPDirectoryStatFilesize = false;
266 m_bFTPThumbs = false;
268 m_musicThumbs = "folder.jpg|Folder.jpg|folder.JPG|Folder.JPG|cover.jpg|Cover.jpg|cover.jpeg|thumb.jpg|Thumb.jpg|thumb.JPG|Thumb.JPG";
269 m_fanartImages = "fanart.jpg|fanart.png";
271 m_bMusicLibraryHideAllItems = false;
272 m_bMusicLibraryAllItemsOnBottom = false;
273 m_bMusicLibraryAlbumsSortByArtistThenYear = false;
274 m_bMusicLibraryCleanOnUpdate = false;
275 m_iMusicLibraryRecentlyAddedItems = 25;
276 m_strMusicLibraryAlbumFormat = "";
277 m_strMusicLibraryAlbumFormatRight = "";
278 m_prioritiseAPEv2tags = false;
279 m_musicItemSeparator = " / ";
280 m_videoItemSeparator = " / ";
282 m_bVideoLibraryHideAllItems = false;
283 m_bVideoLibraryAllItemsOnBottom = false;
284 m_iVideoLibraryRecentlyAddedItems = 25;
285 m_bVideoLibraryHideEmptySeries = false;
286 m_bVideoLibraryCleanOnUpdate = false;
287 m_bVideoLibraryExportAutoThumbs = false;
288 m_bVideoLibraryImportWatchedState = false;
289 m_bVideoLibraryImportResumePoint = false;
290 m_bVideoScannerIgnoreErrors = false;
291 m_iVideoLibraryDateAdded = 1; // prefer mtime over ctime and current time
293 m_iTuxBoxStreamtsPort = 31339;
294 m_bTuxBoxAudioChannelSelection = false;
295 m_bTuxBoxSubMenuSelection = false;
296 m_bTuxBoxPictureIcon= true;
297 m_bTuxBoxSendAllAPids= false;
298 m_iTuxBoxEpgRequestTime = 10; //seconds
299 m_iTuxBoxDefaultSubMenu = 4;
300 m_iTuxBoxDefaultRootMenu = 0; //default TV Mode
301 m_iTuxBoxZapWaitTime = 0; // Time in sec. Default 0:OFF
302 m_bTuxBoxZapstream = true;
303 m_iTuxBoxZapstreamPort = 31344;
305 m_iMythMovieLength = 0; // 0 == Off
307 m_iEpgLingerTime = 60; /* keep 1 hour by default */
308 m_iEpgUpdateCheckInterval = 300; /* check if tables need to be updated every 5 minutes */
309 m_iEpgCleanupInterval = 900; /* remove old entries from the EPG every 15 minutes */
310 m_iEpgActiveTagCheckInterval = 60; /* check for updated active tags every minute */
311 m_iEpgRetryInterruptedUpdateInterval = 30; /* retry an interrupted epg update after 30 seconds */
312 m_iEpgUpdateEmptyTagsInterval = 60; /* override user selectable EPG update interval for empty EPG tags */
313 m_bEpgDisplayUpdatePopup = true; /* display a progress popup while updating EPG data from clients */
314 m_bEpgDisplayIncrementalUpdatePopup = false; /* also display a progress popup while doing incremental EPG updates */
316 m_bEdlMergeShortCommBreaks = false; // Off by default
317 m_iEdlMaxCommBreakLength = 8 * 30 + 10; // Just over 8 * 30 second commercial break.
318 m_iEdlMinCommBreakLength = 3 * 30; // 3 * 30 second commercial breaks.
319 m_iEdlMaxCommBreakGap = 4 * 30; // 4 * 30 second commercial breaks.
320 m_iEdlMaxStartGap = 5 * 60; // 5 minutes.
321 m_iEdlCommBreakAutowait = 0; // Off by default
322 m_iEdlCommBreakAutowind = 0; // Off by default
324 m_curlconnecttimeout = 10;
325 m_curllowspeedtime = 20;
327 m_curlDisableIPV6 = false; //Certain hardware/OS combinations have trouble
330 m_fullScreen = m_startFullScreen = false;
331 m_showExitButton = true;
332 m_splashImage = true;
334 m_playlistRetries = 100;
335 m_playlistTimeout = 20; // 20 seconds timeout
336 m_GLRectangleHack = false;
337 m_iSkipLoopFilter = 0;
338 m_AllowD3D9Ex = true;
339 m_ForceD3D9Ex = false;
340 m_AllowDynamicTextures = true;
341 m_RestrictCapsMask = 0;
342 m_sleepBeforeFlip = 0;
343 m_bVirtualShares = true;
345 //caused lots of jerks
346 //#ifdef TARGET_WINDOWS
347 // m_ForcedSwapTime = 2.0;
349 m_ForcedSwapTime = 0.0;
354 #if defined(TARGET_DARWIN)
355 // default for osx is fullscreen always on top
356 m_alwaysOnTop = true;
358 // default for windows is not always on top
359 m_alwaysOnTop = false;
362 m_iPVRTimeCorrection = 0;
363 m_iPVRInfoToggleInterval = 3000;
364 m_bPVRShowEpgInfoOnEpgItemSelect = false;
365 m_iPVRMinVideoCacheLevel = 5;
366 m_iPVRMinAudioCacheLevel = 10;
367 m_bPVRCacheInDvdPlayer = true;
368 m_bPVRChannelIconsAutoScan = true;
369 m_bPVRAutoScanIconsUserSet = false;
370 m_iPVRNumericChannelSwitchTimeout = 1000;
372 m_measureRefreshrate = false;
374 m_cacheMemBufferSize = 1024 * 1024 * 20;
375 m_networkBufferMode = 0; // Default (buffer all internet streams/filesystems)
376 // the following setting determines the readRate of a player data
377 // as multiply of the default data read rate
378 m_readBufferFactor = 1.0f;
379 m_addonPackageFolderSize = 200;
381 m_jsonOutputCompact = true;
382 m_jsonTcpPort = 9090;
384 m_enableMultimediaKeys = false;
386 m_canWindowed = true;
387 m_guiVisualizeDirtyRegions = false;
388 m_guiAlgorithmDirtyRegions = 3;
389 m_guiDirtyRegionNoFlipTimeout = 0;
390 m_logEnableAirtunes = false;
391 m_airTunesPort = 36666;
392 m_airPlayPort = 36667;
394 m_databaseMusic.Reset();
395 m_databaseVideo.Reset();
397 m_pictureExtensions = ".png|.jpg|.jpeg|.bmp|.gif|.ico|.tif|.tiff|.tga|.pcx|.cbz|.zip|.cbr|.rar|.dng|.nef|.cr2|.crw|.orf|.arw|.erf|.3fr|.dcr|.x3f|.mef|.raf|.mrw|.pef|.sr2|.rss";
398 m_musicExtensions = ".nsv|.m4a|.flac|.aac|.strm|.pls|.rm|.rma|.mpa|.wav|.wma|.ogg|.mp3|.mp2|.m3u|.mod|.amf|.669|.dmf|.dsm|.far|.gdm|.imf|.it|.m15|.med|.okt|.s3m|.stm|.sfx|.ult|.uni|.xm|.sid|.ac3|.dts|.cue|.aif|.aiff|.wpl|.ape|.mac|.mpc|.mp+|.mpp|.shn|.zip|.rar|.wv|.nsf|.spc|.gym|.adx|.dsp|.adp|.ymf|.ast|.afc|.hps|.xsp|.xwav|.waa|.wvs|.wam|.gcm|.idsp|.mpdsp|.mss|.spt|.rsd|.mid|.kar|.sap|.cmc|.cmr|.dmc|.mpt|.mpd|.rmt|.tmc|.tm8|.tm2|.oga|.url|.pxml|.tta|.rss|.cm3|.cms|.dlt|.brstm|.wtv|.mka";
399 m_videoExtensions = ".m4v|.3g2|.3gp|.nsv|.tp|.ts|.ty|.strm|.pls|.rm|.rmvb|.m3u|.m3u8|.ifo|.mov|.qt|.divx|.xvid|.bivx|.vob|.nrg|.img|.iso|.pva|.wmv|.asf|.asx|.ogm|.m2v|.avi|.bin|.dat|.mpg|.mpeg|.mp4|.mkv|.avc|.vp3|.svq3|.nuv|.viv|.dv|.fli|.flv|.rar|.001|.wpl|.zip|.vdr|.dvr-ms|.xsp|.mts|.m2t|.m2ts|.evo|.ogv|.sdp|.avs|.rec|.url|.pxml|.vc1|.h264|.rcv|.rss|.mpls|.webm|.bdmv|.wtv";
400 m_subtitlesExtensions = ".utf|.utf8|.utf-8|.sub|.srt|.smi|.rt|.txt|.ssa|.text|.ssa|.aqt|.jss|.ass|.idx|.ifo|.rar|.zip";
401 m_discStubExtensions = ".disc";
402 // internal music extensions
403 m_musicExtensions += "|.sidstream|.oggstream|.nsfstream|.asapstream|.cdda";
404 // internal video extensions
405 m_videoExtensions += "|.pvr";
407 m_stereoscopicflags_sbs = "3DSBS|3D.SBS|HSBS|H.SBS|H-SBS| SBS |FULL-SBS|FULL.SBS|FULLSBS|FSBS|HALF-SBS";
408 m_stereoscopicflags_tab = "3DTAB|3D.TAB|HTAB|H.TAB|3DOU|3D.OU|3D.HOU| HOU | OU |HALF-TAB";
410 m_logLevelHint = m_logLevel = LOG_LEVEL_NORMAL;
411 m_extraLogLevels = 0;
413 #if defined(TARGET_DARWIN)
414 CStdString logDir = getenv("HOME");
415 #if defined(TARGET_DARWIN_OSX)
416 logDir += "/Library/Logs/";
418 logDir += "/" + CStdString(DarwinGetXbmcRootFolder()) + "/";
420 m_logFolder = logDir;
422 m_logFolder = "special://home/"; // log file location
425 m_userAgent = g_sysinfo.GetUserAgent();
427 m_initialized = true;
430 bool CAdvancedSettings::Load()
432 // NOTE: This routine should NOT set the default of any of these parameters
433 // it should instead use the versions of GetString/Integer/Float that
434 // don't take defaults in. Defaults are set in the constructor above
435 Initialize(); // In case of profile switch.
436 ParseSettingsFile("special://xbmc/system/advancedsettings.xml");
437 for (unsigned int i = 0; i < m_settingsFiles.size(); i++)
438 ParseSettingsFile(m_settingsFiles[i]);
439 ParseSettingsFile(CProfilesManager::Get().GetUserDataItem("advancedsettings.xml"));
441 // Add the list of disc stub extensions (if any) to the list of video extensions
442 if (!m_discStubExtensions.empty())
443 m_videoExtensions += "|" + m_discStubExtensions;
448 void CAdvancedSettings::ParseSettingsFile(const CStdString &file)
450 CXBMCTinyXML advancedXML;
451 if (!CFile::Exists(file))
453 CLog::Log(LOGNOTICE, "No settings file to load (%s)", file.c_str());
457 if (!advancedXML.LoadFile(file))
459 CLog::Log(LOGERROR, "Error loading %s, Line %d\n%s", file.c_str(), advancedXML.ErrorRow(), advancedXML.ErrorDesc());
463 TiXmlElement *pRootElement = advancedXML.RootElement();
464 if (!pRootElement || strcmpi(pRootElement->Value(),"advancedsettings") != 0)
466 CLog::Log(LOGERROR, "Error loading %s, no <advancedsettings> node", file.c_str());
470 // succeeded - tell the user it worked
471 CLog::Log(LOGNOTICE, "Loaded settings file from %s", file.c_str());
473 // Dump contents of AS.xml to debug log
474 TiXmlPrinter printer;
475 printer.SetLineBreak("\n");
476 printer.SetIndent(" ");
477 advancedXML.Accept(&printer);
478 CLog::Log(LOGNOTICE, "Contents of %s are...\n%s", file.c_str(), printer.CStr());
480 TiXmlElement *pElement = pRootElement->FirstChildElement("audio");
483 XMLUtils::GetFloat(pElement, "ac3downmixgain", m_ac3Gain, -96.0f, 96.0f);
484 XMLUtils::GetInt(pElement, "headroom", m_audioHeadRoom, 0, 12);
485 XMLUtils::GetString(pElement, "defaultplayer", m_audioDefaultPlayer);
486 // 101 on purpose - can be used to never automark as watched
487 XMLUtils::GetFloat(pElement, "playcountminimumpercent", m_audioPlayCountMinimumPercent, 0.0f, 101.0f);
489 XMLUtils::GetBoolean(pElement, "usetimeseeking", m_musicUseTimeSeeking);
490 XMLUtils::GetInt(pElement, "timeseekforward", m_musicTimeSeekForward, 0, 6000);
491 XMLUtils::GetInt(pElement, "timeseekbackward", m_musicTimeSeekBackward, -6000, 0);
492 XMLUtils::GetInt(pElement, "timeseekforwardbig", m_musicTimeSeekForwardBig, 0, 6000);
493 XMLUtils::GetInt(pElement, "timeseekbackwardbig", m_musicTimeSeekBackwardBig, -6000, 0);
495 XMLUtils::GetInt(pElement, "percentseekforward", m_musicPercentSeekForward, 0, 100);
496 XMLUtils::GetInt(pElement, "percentseekbackward", m_musicPercentSeekBackward, -100, 0);
497 XMLUtils::GetInt(pElement, "percentseekforwardbig", m_musicPercentSeekForwardBig, 0, 100);
498 XMLUtils::GetInt(pElement, "percentseekbackwardbig", m_musicPercentSeekBackwardBig, -100, 0);
500 TiXmlElement* pAudioExcludes = pElement->FirstChildElement("excludefromlisting");
502 GetCustomRegexps(pAudioExcludes, m_audioExcludeFromListingRegExps);
504 pAudioExcludes = pElement->FirstChildElement("excludefromscan");
506 GetCustomRegexps(pAudioExcludes, m_audioExcludeFromScanRegExps);
508 XMLUtils::GetString(pElement, "audiohost", m_audioHost);
509 XMLUtils::GetBoolean(pElement, "applydrc", m_audioApplyDrc);
510 XMLUtils::GetBoolean(pElement, "dvdplayerignoredtsinwav", m_dvdplayerIgnoreDTSinWAV);
512 XMLUtils::GetFloat(pElement, "limiterhold", m_limiterHold, 0.0f, 100.0f);
513 XMLUtils::GetFloat(pElement, "limiterrelease", m_limiterRelease, 0.001f, 100.0f);
516 pElement = pRootElement->FirstChildElement("omx");
519 XMLUtils::GetBoolean(pElement, "omxhwaudiodecode", m_omxHWAudioDecode);
520 XMLUtils::GetBoolean(pElement, "omxdecodestartwithvalidframe", m_omxDecodeStartWithValidFrame);
523 pElement = pRootElement->FirstChildElement("karaoke");
526 XMLUtils::GetFloat(pElement, "syncdelaycdg", m_karaokeSyncDelayCDG, -3.0f, 3.0f); // keep the old name for comp
527 XMLUtils::GetFloat(pElement, "syncdelaylrc", m_karaokeSyncDelayLRC, -3.0f, 3.0f);
528 XMLUtils::GetBoolean(pElement, "alwaysreplacegenre", m_karaokeChangeGenreForKaraokeSongs );
529 XMLUtils::GetBoolean(pElement, "storedelay", m_karaokeKeepDelay );
530 XMLUtils::GetInt(pElement, "autoassignstartfrom", m_karaokeStartIndex, 1, 2000000000);
531 XMLUtils::GetBoolean(pElement, "nocdgbackground", m_karaokeAlwaysEmptyOnCdgs );
532 XMLUtils::GetBoolean(pElement, "lookupsongbackground", m_karaokeUseSongSpecificBackground );
534 TiXmlElement* pKaraokeBackground = pElement->FirstChildElement("defaultbackground");
535 if (pKaraokeBackground)
537 const char* attr = pKaraokeBackground->Attribute("type");
539 m_karaokeDefaultBackgroundType = attr;
541 attr = pKaraokeBackground->Attribute("path");
543 m_karaokeDefaultBackgroundFilePath = attr;
547 pElement = pRootElement->FirstChildElement("video");
550 XMLUtils::GetString(pElement, "stereoscopicflagssbs", m_stereoscopicflags_sbs);
551 XMLUtils::GetString(pElement, "stereoscopicflagstab", m_stereoscopicflags_tab);
552 XMLUtils::GetFloat(pElement, "subsdelayrange", m_videoSubsDelayRange, 10, 600);
553 XMLUtils::GetFloat(pElement, "audiodelayrange", m_videoAudioDelayRange, 10, 600);
554 XMLUtils::GetInt(pElement, "blackbarcolour", m_videoBlackBarColour, 0, 255);
555 XMLUtils::GetString(pElement, "defaultplayer", m_videoDefaultPlayer);
556 XMLUtils::GetString(pElement, "defaultdvdplayer", m_videoDefaultDVDPlayer);
557 XMLUtils::GetBoolean(pElement, "fullscreenonmoviestart", m_fullScreenOnMovieStart);
558 // 101 on purpose - can be used to never automark as watched
559 XMLUtils::GetFloat(pElement, "playcountminimumpercent", m_videoPlayCountMinimumPercent, 0.0f, 101.0f);
560 XMLUtils::GetInt(pElement, "ignoresecondsatstart", m_videoIgnoreSecondsAtStart, 0, 900);
561 XMLUtils::GetFloat(pElement, "ignorepercentatend", m_videoIgnorePercentAtEnd, 0, 100.0f);
563 XMLUtils::GetInt(pElement, "smallstepbackseconds", m_videoSmallStepBackSeconds, 1, INT_MAX);
564 XMLUtils::GetInt(pElement, "smallstepbacktries", m_videoSmallStepBackTries, 1, 10);
565 XMLUtils::GetInt(pElement, "smallstepbackdelay", m_videoSmallStepBackDelay, 100, 5000); //MS
567 XMLUtils::GetBoolean(pElement, "usetimeseeking", m_videoUseTimeSeeking);
568 XMLUtils::GetInt(pElement, "timeseekforward", m_videoTimeSeekForward, 0, 6000);
569 XMLUtils::GetInt(pElement, "timeseekbackward", m_videoTimeSeekBackward, -6000, 0);
570 XMLUtils::GetInt(pElement, "timeseekforwardbig", m_videoTimeSeekForwardBig, 0, 6000);
571 XMLUtils::GetInt(pElement, "timeseekbackwardbig", m_videoTimeSeekBackwardBig, -6000, 0);
573 XMLUtils::GetInt(pElement, "percentseekforward", m_videoPercentSeekForward, 0, 100);
574 XMLUtils::GetInt(pElement, "percentseekbackward", m_videoPercentSeekBackward, -100, 0);
575 XMLUtils::GetInt(pElement, "percentseekforwardbig", m_videoPercentSeekForwardBig, 0, 100);
576 XMLUtils::GetInt(pElement, "percentseekbackwardbig", m_videoPercentSeekBackwardBig, -100, 0);
578 TiXmlElement* pVideoExcludes = pElement->FirstChildElement("excludefromlisting");
580 GetCustomRegexps(pVideoExcludes, m_videoExcludeFromListingRegExps);
582 pVideoExcludes = pElement->FirstChildElement("excludefromscan");
584 GetCustomRegexps(pVideoExcludes, m_moviesExcludeFromScanRegExps);
586 pVideoExcludes = pElement->FirstChildElement("excludetvshowsfromscan");
588 GetCustomRegexps(pVideoExcludes, m_tvshowExcludeFromScanRegExps);
590 pVideoExcludes = pElement->FirstChildElement("cleanstrings");
592 GetCustomRegexps(pVideoExcludes, m_videoCleanStringRegExps);
594 XMLUtils::GetString(pElement,"cleandatetime", m_videoCleanDateTimeRegExp);
595 XMLUtils::GetString(pElement,"ppffmpegdeinterlacing",m_videoPPFFmpegDeint);
596 XMLUtils::GetString(pElement,"ppffmpegpostprocessing",m_videoPPFFmpegPostProc);
597 XMLUtils::GetInt(pElement,"vdpauscaling",m_videoVDPAUScaling);
598 XMLUtils::GetFloat(pElement, "nonlinearstretchratio", m_videoNonLinStretchRatio, 0.01f, 1.0f);
599 XMLUtils::GetBoolean(pElement,"enablehighqualityhwscalers", m_videoEnableHighQualityHwScalers);
600 XMLUtils::GetFloat(pElement,"autoscalemaxfps",m_videoAutoScaleMaxFps, 0.0f, 1000.0f);
601 XMLUtils::GetBoolean(pElement,"allowmpeg4vdpau",m_videoAllowMpeg4VDPAU);
602 XMLUtils::GetBoolean(pElement,"disablehi10pmultithreading",m_videoDisableHi10pMultithreading);
603 XMLUtils::GetBoolean(pElement,"allowmpeg4vaapi",m_videoAllowMpeg4VAAPI);
604 XMLUtils::GetBoolean(pElement, "disablebackgrounddeinterlace", m_videoDisableBackgroundDeinterlace);
605 XMLUtils::GetInt(pElement, "useocclusionquery", m_videoCaptureUseOcclusionQuery, -1, 1);
606 XMLUtils::GetBoolean(pElement,"vdpauInvTelecine",m_videoVDPAUtelecine);
607 XMLUtils::GetBoolean(pElement,"vdpauHDdeintSkipChroma",m_videoVDPAUdeintSkipChromaHD);
609 TiXmlElement* pStagefrightElem = pElement->FirstChildElement("stagefright");
610 if (pStagefrightElem)
612 XMLUtils::GetInt(pStagefrightElem,"useavccodec",m_stagefrightConfig.useAVCcodec, -1, 1);
613 XMLUtils::GetInt(pStagefrightElem,"usevc1codec",m_stagefrightConfig.useVC1codec, -1, 1);
614 XMLUtils::GetInt(pStagefrightElem,"usevpxcodec",m_stagefrightConfig.useVPXcodec, -1, 1);
615 XMLUtils::GetInt(pStagefrightElem,"usemp4codec",m_stagefrightConfig.useMP4codec, -1, 1);
616 XMLUtils::GetInt(pStagefrightElem,"usempeg2codec",m_stagefrightConfig.useMPEG2codec, -1, 1);
617 XMLUtils::GetBoolean(pStagefrightElem,"useswrenderer",m_stagefrightConfig.useSwRenderer);
618 XMLUtils::GetBoolean(pStagefrightElem,"useinputdts",m_stagefrightConfig.useInputDTS);
621 TiXmlElement* pAdjustRefreshrate = pElement->FirstChildElement("adjustrefreshrate");
622 if (pAdjustRefreshrate)
624 TiXmlElement* pRefreshOverride = pAdjustRefreshrate->FirstChildElement("override");
625 while (pRefreshOverride)
627 RefreshOverride override = {0};
630 if (XMLUtils::GetFloat(pRefreshOverride, "fps", fps))
632 override.fpsmin = fps - 0.01f;
633 override.fpsmax = fps + 0.01f;
636 float fpsmin, fpsmax;
637 if (XMLUtils::GetFloat(pRefreshOverride, "fpsmin", fpsmin) &&
638 XMLUtils::GetFloat(pRefreshOverride, "fpsmax", fpsmax))
640 override.fpsmin = fpsmin;
641 override.fpsmax = fpsmax;
645 if (XMLUtils::GetFloat(pRefreshOverride, "refresh", refresh))
647 override.refreshmin = refresh - 0.01f;
648 override.refreshmax = refresh + 0.01f;
651 float refreshmin, refreshmax;
652 if (XMLUtils::GetFloat(pRefreshOverride, "refreshmin", refreshmin) &&
653 XMLUtils::GetFloat(pRefreshOverride, "refreshmax", refreshmax))
655 override.refreshmin = refreshmin;
656 override.refreshmax = refreshmax;
659 bool fpsCorrect = (override.fpsmin > 0.0f && override.fpsmax >= override.fpsmin);
660 bool refreshCorrect = (override.refreshmin > 0.0f && override.refreshmax >= override.refreshmin);
662 if (fpsCorrect && refreshCorrect)
663 m_videoAdjustRefreshOverrides.push_back(override);
665 CLog::Log(LOGWARNING, "Ignoring malformed refreshrate override, fpsmin:%f fpsmax:%f refreshmin:%f refreshmax:%f",
666 override.fpsmin, override.fpsmax, override.refreshmin, override.refreshmax);
668 pRefreshOverride = pRefreshOverride->NextSiblingElement("override");
671 TiXmlElement* pRefreshFallback = pAdjustRefreshrate->FirstChildElement("fallback");
672 while (pRefreshFallback)
674 RefreshOverride fallback = {0};
675 fallback.fallback = true;
678 if (XMLUtils::GetFloat(pRefreshFallback, "refresh", refresh))
680 fallback.refreshmin = refresh - 0.01f;
681 fallback.refreshmax = refresh + 0.01f;
684 float refreshmin, refreshmax;
685 if (XMLUtils::GetFloat(pRefreshFallback, "refreshmin", refreshmin) &&
686 XMLUtils::GetFloat(pRefreshFallback, "refreshmax", refreshmax))
688 fallback.refreshmin = refreshmin;
689 fallback.refreshmax = refreshmax;
692 if (fallback.refreshmin > 0.0f && fallback.refreshmax >= fallback.refreshmin)
693 m_videoAdjustRefreshOverrides.push_back(fallback);
695 CLog::Log(LOGWARNING, "Ignoring malformed refreshrate fallback, fpsmin:%f fpsmax:%f refreshmin:%f refreshmax:%f",
696 fallback.fpsmin, fallback.fpsmax, fallback.refreshmin, fallback.refreshmax);
698 pRefreshFallback = pRefreshFallback->NextSiblingElement("fallback");
702 m_DXVACheckCompatibilityPresent = XMLUtils::GetBoolean(pElement,"checkdxvacompatibility", m_DXVACheckCompatibility);
704 XMLUtils::GetBoolean(pElement,"forcedxvarenderer", m_DXVAForceProcessorRenderer);
705 XMLUtils::GetBoolean(pElement,"dxvanodeintforprogressive", m_DXVANoDeintProcForProgressive);
706 //0 = disable fps detect, 1 = only detect on timestamps with uniform spacing, 2 detect on all timestamps
707 XMLUtils::GetInt(pElement, "fpsdetect", m_videoFpsDetect, 0, 2);
709 // controls the delay, in milliseconds, until
710 // the busy dialog is shown when starting video playback.
711 XMLUtils::GetInt(pElement, "busydialogdelayms", m_videoBusyDialogDelay_ms, 0, 1000);
713 // Store global display latency settings
714 TiXmlElement* pVideoLatency = pElement->FirstChildElement("latency");
717 float refresh, refreshmin, refreshmax, delay;
718 TiXmlElement* pRefreshVideoLatency = pVideoLatency->FirstChildElement("refresh");
720 while (pRefreshVideoLatency)
722 RefreshVideoLatency videolatency = {0};
724 if (XMLUtils::GetFloat(pRefreshVideoLatency, "rate", refresh))
726 videolatency.refreshmin = refresh - 0.01f;
727 videolatency.refreshmax = refresh + 0.01f;
729 else if (XMLUtils::GetFloat(pRefreshVideoLatency, "min", refreshmin) &&
730 XMLUtils::GetFloat(pRefreshVideoLatency, "max", refreshmax))
732 videolatency.refreshmin = refreshmin;
733 videolatency.refreshmax = refreshmax;
735 if (XMLUtils::GetFloat(pRefreshVideoLatency, "delay", delay, -600.0f, 600.0f))
736 videolatency.delay = delay;
738 if (videolatency.refreshmin > 0.0f && videolatency.refreshmax >= videolatency.refreshmin)
739 m_videoRefreshLatency.push_back(videolatency);
741 CLog::Log(LOGWARNING, "Ignoring malformed display latency <refresh> entry, min:%f max:%f", videolatency.refreshmin, videolatency.refreshmax);
743 pRefreshVideoLatency = pRefreshVideoLatency->NextSiblingElement("refresh");
746 // Get default global display latency
747 XMLUtils::GetFloat(pVideoLatency, "delay", m_videoDefaultLatency, -600.0f, 600.0f);
751 pElement = pRootElement->FirstChildElement("musiclibrary");
754 XMLUtils::GetBoolean(pElement, "hideallitems", m_bMusicLibraryHideAllItems);
755 XMLUtils::GetInt(pElement, "recentlyaddeditems", m_iMusicLibraryRecentlyAddedItems, 1, INT_MAX);
756 XMLUtils::GetBoolean(pElement, "prioritiseapetags", m_prioritiseAPEv2tags);
757 XMLUtils::GetBoolean(pElement, "allitemsonbottom", m_bMusicLibraryAllItemsOnBottom);
758 XMLUtils::GetBoolean(pElement, "albumssortbyartistthenyear", m_bMusicLibraryAlbumsSortByArtistThenYear);
759 XMLUtils::GetBoolean(pElement, "cleanonupdate", m_bMusicLibraryCleanOnUpdate);
760 XMLUtils::GetString(pElement, "albumformat", m_strMusicLibraryAlbumFormat);
761 XMLUtils::GetString(pElement, "albumformatright", m_strMusicLibraryAlbumFormatRight);
762 XMLUtils::GetString(pElement, "itemseparator", m_musicItemSeparator);
765 pElement = pRootElement->FirstChildElement("videolibrary");
768 XMLUtils::GetBoolean(pElement, "hideallitems", m_bVideoLibraryHideAllItems);
769 XMLUtils::GetBoolean(pElement, "allitemsonbottom", m_bVideoLibraryAllItemsOnBottom);
770 XMLUtils::GetInt(pElement, "recentlyaddeditems", m_iVideoLibraryRecentlyAddedItems, 1, INT_MAX);
771 XMLUtils::GetBoolean(pElement, "hideemptyseries", m_bVideoLibraryHideEmptySeries);
772 XMLUtils::GetBoolean(pElement, "cleanonupdate", m_bVideoLibraryCleanOnUpdate);
773 XMLUtils::GetString(pElement, "itemseparator", m_videoItemSeparator);
774 XMLUtils::GetBoolean(pElement, "exportautothumbs", m_bVideoLibraryExportAutoThumbs);
775 XMLUtils::GetBoolean(pElement, "importwatchedstate", m_bVideoLibraryImportWatchedState);
776 XMLUtils::GetBoolean(pElement, "importresumepoint", m_bVideoLibraryImportResumePoint);
777 XMLUtils::GetInt(pElement, "dateadded", m_iVideoLibraryDateAdded);
780 pElement = pRootElement->FirstChildElement("videoscanner");
783 XMLUtils::GetBoolean(pElement, "ignoreerrors", m_bVideoScannerIgnoreErrors);
786 // Backward-compatibility of ExternalPlayer config
787 pElement = pRootElement->FirstChildElement("externalplayer");
790 CLog::Log(LOGWARNING, "External player configuration has been removed from advancedsettings.xml. It can now be configed in userdata/playercorefactory.xml");
792 pElement = pRootElement->FirstChildElement("slideshow");
795 XMLUtils::GetFloat(pElement, "panamount", m_slideshowPanAmount, 0.0f, 20.0f);
796 XMLUtils::GetFloat(pElement, "zoomamount", m_slideshowZoomAmount, 0.0f, 20.0f);
797 XMLUtils::GetFloat(pElement, "blackbarcompensation", m_slideshowBlackBarCompensation, 0.0f, 50.0f);
800 pElement = pRootElement->FirstChildElement("network");
803 XMLUtils::GetInt(pElement, "curlclienttimeout", m_curlconnecttimeout, 1, 1000);
804 XMLUtils::GetInt(pElement, "curllowspeedtime", m_curllowspeedtime, 1, 1000);
805 XMLUtils::GetInt(pElement, "curlretries", m_curlretries, 0, 10);
806 XMLUtils::GetBoolean(pElement,"disableipv6", m_curlDisableIPV6);
807 XMLUtils::GetUInt(pElement, "cachemembuffersize", m_cacheMemBufferSize);
808 XMLUtils::GetUInt(pElement, "buffermode", m_networkBufferMode, 0, 3);
809 XMLUtils::GetFloat(pElement, "readbufferfactor", m_readBufferFactor);
812 pElement = pRootElement->FirstChildElement("jsonrpc");
815 XMLUtils::GetBoolean(pElement, "compactoutput", m_jsonOutputCompact);
816 XMLUtils::GetUInt(pElement, "tcpport", m_jsonTcpPort);
819 pElement = pRootElement->FirstChildElement("samba");
822 XMLUtils::GetString(pElement, "doscodepage", m_sambadoscodepage);
823 XMLUtils::GetInt(pElement, "clienttimeout", m_sambaclienttimeout, 5, 100);
824 XMLUtils::GetBoolean(pElement, "statfiles", m_sambastatfiles);
827 pElement = pRootElement->FirstChildElement("httpdirectory");
829 XMLUtils::GetBoolean(pElement, "statfilesize", m_bHTTPDirectoryStatFilesize);
831 pElement = pRootElement->FirstChildElement("ftp");
834 XMLUtils::GetBoolean(pElement, "remotethumbs", m_bFTPThumbs);
837 pElement = pRootElement->FirstChildElement("loglevel");
839 { // read the loglevel setting, so set the setting advanced to hide it in GUI
840 // as altering it will do nothing - we don't write to advancedsettings.xml
841 XMLUtils::GetInt(pRootElement, "loglevel", m_logLevelHint, LOG_LEVEL_NONE, LOG_LEVEL_MAX);
842 CSettingBool *setting = (CSettingBool *)CSettings::Get().GetSetting("debug.showloginfo");
846 if (!((hide = pElement->Attribute("hide")) && strnicmp("false", hide, 4) == 0))
847 setting->SetVisible(false);
849 g_advancedSettings.m_logLevel = std::max(g_advancedSettings.m_logLevel, g_advancedSettings.m_logLevelHint);
850 CLog::SetLogLevel(g_advancedSettings.m_logLevel);
853 XMLUtils::GetString(pRootElement, "cddbaddress", m_cddbAddress);
856 XMLUtils::GetBoolean(pRootElement, "enableairtunesdebuglog", m_logEnableAirtunes);
857 XMLUtils::GetInt(pRootElement, "airtunesport", m_airTunesPort);
858 XMLUtils::GetInt(pRootElement, "airplayport", m_airPlayPort);
860 XMLUtils::GetBoolean(pRootElement, "handlemounting", m_handleMounting);
862 #if defined(HAS_SDL) || defined(TARGET_WINDOWS)
863 XMLUtils::GetBoolean(pRootElement, "fullscreen", m_startFullScreen);
865 XMLUtils::GetBoolean(pRootElement, "splash", m_splashImage);
866 XMLUtils::GetBoolean(pRootElement, "showexitbutton", m_showExitButton);
867 XMLUtils::GetBoolean(pRootElement, "canwindowed", m_canWindowed);
869 XMLUtils::GetInt(pRootElement, "songinfoduration", m_songInfoDuration, 0, INT_MAX);
870 XMLUtils::GetInt(pRootElement, "playlistretries", m_playlistRetries, -1, 5000);
871 XMLUtils::GetInt(pRootElement, "playlisttimeout", m_playlistTimeout, 0, 5000);
873 XMLUtils::GetBoolean(pRootElement,"glrectanglehack", m_GLRectangleHack);
874 XMLUtils::GetInt(pRootElement,"skiploopfilter", m_iSkipLoopFilter, -16, 48);
875 XMLUtils::GetFloat(pRootElement, "forcedswaptime", m_ForcedSwapTime, 0.0, 100.0);
877 XMLUtils::GetBoolean(pRootElement,"allowd3d9ex", m_AllowD3D9Ex);
878 XMLUtils::GetBoolean(pRootElement,"forced3d9ex", m_ForceD3D9Ex);
879 XMLUtils::GetBoolean(pRootElement,"allowdynamictextures", m_AllowDynamicTextures);
880 XMLUtils::GetUInt(pRootElement,"restrictcapsmask", m_RestrictCapsMask);
881 XMLUtils::GetFloat(pRootElement,"sleepbeforeflip", m_sleepBeforeFlip, 0.0f, 1.0f);
882 XMLUtils::GetBoolean(pRootElement,"virtualshares", m_bVirtualShares);
883 XMLUtils::GetUInt(pRootElement, "packagefoldersize", m_addonPackageFolderSize);
886 pElement = pRootElement->FirstChildElement("tuxbox");
889 XMLUtils::GetInt(pElement, "streamtsport", m_iTuxBoxStreamtsPort, 0, 65535);
890 XMLUtils::GetBoolean(pElement, "audiochannelselection", m_bTuxBoxAudioChannelSelection);
891 XMLUtils::GetBoolean(pElement, "submenuselection", m_bTuxBoxSubMenuSelection);
892 XMLUtils::GetBoolean(pElement, "pictureicon", m_bTuxBoxPictureIcon);
893 XMLUtils::GetBoolean(pElement, "sendallaudiopids", m_bTuxBoxSendAllAPids);
894 XMLUtils::GetInt(pElement, "epgrequesttime", m_iTuxBoxEpgRequestTime, 0, 3600);
895 XMLUtils::GetInt(pElement, "defaultsubmenu", m_iTuxBoxDefaultSubMenu, 1, 4);
896 XMLUtils::GetInt(pElement, "defaultrootmenu", m_iTuxBoxDefaultRootMenu, 0, 4);
897 XMLUtils::GetInt(pElement, "zapwaittime", m_iTuxBoxZapWaitTime, 0, 120);
898 XMLUtils::GetBoolean(pElement, "zapstream", m_bTuxBoxZapstream);
899 XMLUtils::GetInt(pElement, "zapstreamport", m_iTuxBoxZapstreamPort, 0, 65535);
903 pElement = pRootElement->FirstChildElement("myth");
906 XMLUtils::GetInt(pElement, "movielength", m_iMythMovieLength);
910 pElement = pRootElement->FirstChildElement("epg");
913 XMLUtils::GetInt(pElement, "lingertime", m_iEpgLingerTime);
914 XMLUtils::GetInt(pElement, "updatecheckinterval", m_iEpgUpdateCheckInterval);
915 XMLUtils::GetInt(pElement, "cleanupinterval", m_iEpgCleanupInterval);
916 XMLUtils::GetInt(pElement, "activetagcheckinterval", m_iEpgActiveTagCheckInterval);
917 XMLUtils::GetInt(pElement, "retryinterruptedupdateinterval", m_iEpgRetryInterruptedUpdateInterval);
918 XMLUtils::GetInt(pElement, "updateemptytagsinterval", m_iEpgUpdateEmptyTagsInterval);
919 XMLUtils::GetBoolean(pElement, "displayupdatepopup", m_bEpgDisplayUpdatePopup);
920 XMLUtils::GetBoolean(pElement, "displayincrementalupdatepopup", m_bEpgDisplayIncrementalUpdatePopup);
923 // EDL commercial break handling
924 pElement = pRootElement->FirstChildElement("edl");
927 XMLUtils::GetBoolean(pElement, "mergeshortcommbreaks", m_bEdlMergeShortCommBreaks);
928 XMLUtils::GetInt(pElement, "maxcommbreaklength", m_iEdlMaxCommBreakLength, 0, 10 * 60); // Between 0 and 10 minutes
929 XMLUtils::GetInt(pElement, "mincommbreaklength", m_iEdlMinCommBreakLength, 0, 5 * 60); // Between 0 and 5 minutes
930 XMLUtils::GetInt(pElement, "maxcommbreakgap", m_iEdlMaxCommBreakGap, 0, 5 * 60); // Between 0 and 5 minutes.
931 XMLUtils::GetInt(pElement, "maxstartgap", m_iEdlMaxStartGap, 0, 10 * 60); // Between 0 and 10 minutes
932 XMLUtils::GetInt(pElement, "commbreakautowait", m_iEdlCommBreakAutowait, 0, 10); // Between 0 and 10 seconds
933 XMLUtils::GetInt(pElement, "commbreakautowind", m_iEdlCommBreakAutowind, 0, 10); // Between 0 and 10 seconds
936 // picture exclude regexps
937 TiXmlElement* pPictureExcludes = pRootElement->FirstChildElement("pictureexcludes");
938 if (pPictureExcludes)
939 GetCustomRegexps(pPictureExcludes, m_pictureExcludeFromListingRegExps);
941 // picture extensions
942 TiXmlElement* pExts = pRootElement->FirstChildElement("pictureextensions");
944 GetCustomExtensions(pExts, m_pictureExtensions);
947 pExts = pRootElement->FirstChildElement("musicextensions");
949 GetCustomExtensions(pExts, m_musicExtensions);
952 pExts = pRootElement->FirstChildElement("videoextensions");
954 GetCustomExtensions(pExts, m_videoExtensions);
957 pExts = pRootElement->FirstChildElement("discstubextensions");
959 GetCustomExtensions(pExts, m_discStubExtensions);
962 CLangInfo::LoadTokens(pRootElement->FirstChild("sorttokens"),m_vecTokens);
964 // TODO: Should cache path be given in terms of our predefined paths??
965 // Are we even going to have predefined paths??
967 if (XMLUtils::GetPath(pRootElement, "cachepath", tmp))
969 URIUtils::AddSlashAtEnd(m_cachePath);
971 g_LangCodeExpander.LoadUserCodes(pRootElement->FirstChildElement("languagecodes"));
973 // trailer matching regexps
974 TiXmlElement* pTrailerMatching = pRootElement->FirstChildElement("trailermatching");
975 if (pTrailerMatching)
976 GetCustomRegexps(pTrailerMatching, m_trailerMatchRegExps);
978 //everything thats a trailer is not a movie
979 m_moviesExcludeFromScanRegExps.insert(m_moviesExcludeFromScanRegExps.end(),
980 m_trailerMatchRegExps.begin(),
981 m_trailerMatchRegExps.end());
983 // video stacking regexps
984 TiXmlElement* pVideoStacking = pRootElement->FirstChildElement("moviestacking");
986 GetCustomRegexps(pVideoStacking, m_videoStackRegExps);
988 // folder stacking regexps
989 TiXmlElement* pFolderStacking = pRootElement->FirstChildElement("folderstacking");
991 GetCustomRegexps(pFolderStacking, m_folderStackRegExps);
993 //tv stacking regexps
994 TiXmlElement* pTVStacking = pRootElement->FirstChildElement("tvshowmatching");
996 GetCustomTVRegexps(pTVStacking, m_tvshowEnumRegExps);
998 //tv multipart enumeration regexp
999 XMLUtils::GetString(pRootElement, "tvmultipartmatching", m_tvshowMultiPartEnumRegExp);
1001 // path substitutions
1002 TiXmlElement* pPathSubstitution = pRootElement->FirstChildElement("pathsubstitution");
1003 if (pPathSubstitution)
1005 m_pathSubstitutions.clear();
1006 CLog::Log(LOGDEBUG,"Configuring path substitutions");
1007 TiXmlNode* pSubstitute = pPathSubstitution->FirstChildElement("substitute");
1010 CStdString strFrom, strTo;
1011 TiXmlNode* pFrom = pSubstitute->FirstChild("from");
1013 strFrom = CSpecialProtocol::TranslatePath(pFrom->FirstChild()->Value()).c_str();
1014 TiXmlNode* pTo = pSubstitute->FirstChild("to");
1016 strTo = pTo->FirstChild()->Value();
1018 if (!strFrom.empty() && !strTo.empty())
1020 CLog::Log(LOGDEBUG," Registering substition pair:");
1021 CLog::Log(LOGDEBUG," From: [%s]", strFrom.c_str());
1022 CLog::Log(LOGDEBUG," To: [%s]", strTo.c_str());
1023 m_pathSubstitutions.push_back(make_pair(strFrom,strTo));
1027 // error message about missing tag
1028 if (strFrom.empty())
1029 CLog::Log(LOGERROR," Missing <from> tag");
1031 CLog::Log(LOGERROR," Missing <to> tag");
1035 pSubstitute = pSubstitute->NextSiblingElement("substitute");
1039 XMLUtils::GetInt(pRootElement, "remotedelay", m_remoteDelay, 1, 20);
1040 XMLUtils::GetFloat(pRootElement, "controllerdeadzone", m_controllerDeadzone, 0.0f, 1.0f);
1041 XMLUtils::GetUInt(pRootElement, "fanartres", m_fanartRes, 0, 1080);
1042 XMLUtils::GetUInt(pRootElement, "imageres", m_imageRes, 0, 1080);
1043 XMLUtils::GetBoolean(pRootElement, "useddsfanart", m_useDDSFanart);
1045 XMLUtils::GetBoolean(pRootElement, "playlistasfolders", m_playlistAsFolders);
1046 XMLUtils::GetBoolean(pRootElement, "detectasudf", m_detectAsUdf);
1049 TiXmlElement* pThumbs = pRootElement->FirstChildElement("musicthumbs");
1051 GetCustomExtensions(pThumbs,m_musicThumbs);
1054 TiXmlElement* pFanart = pRootElement->FirstChildElement("fanart");
1056 GetCustomExtensions(pFanart,m_fanartImages);
1058 // music filename->tag filters
1059 TiXmlElement* filters = pRootElement->FirstChildElement("musicfilenamefilters");
1062 TiXmlNode* filter = filters->FirstChild("filter");
1065 if (filter->FirstChild())
1066 m_musicTagsFromFileFilters.push_back(filter->FirstChild()->ValueStr());
1067 filter = filter->NextSibling("filter");
1071 TiXmlElement* pHostEntries = pRootElement->FirstChildElement("hosts");
1074 TiXmlElement* element = pHostEntries->FirstChildElement("entry");
1077 CStdString name = element->Attribute("name");
1079 if(element->GetText())
1080 value = element->GetText();
1082 if(name.length() > 0 && value.length() > 0)
1083 CDNSNameCache::Add(name, value);
1084 element = element->NextSiblingElement("entry");
1088 XMLUtils::GetString(pRootElement, "cputempcommand", m_cpuTempCmd);
1089 XMLUtils::GetString(pRootElement, "gputempcommand", m_gpuTempCmd);
1091 XMLUtils::GetBoolean(pRootElement, "alwaysontop", m_alwaysOnTop);
1093 TiXmlElement *pPVR = pRootElement->FirstChildElement("pvr");
1096 XMLUtils::GetInt(pPVR, "timecorrection", m_iPVRTimeCorrection, 0, 1440);
1097 XMLUtils::GetInt(pPVR, "infotoggleinterval", m_iPVRInfoToggleInterval, 0, 30000);
1098 XMLUtils::GetBoolean(pPVR, "showepginfoonselect", m_bPVRShowEpgInfoOnEpgItemSelect);
1099 XMLUtils::GetInt(pPVR, "minvideocachelevel", m_iPVRMinVideoCacheLevel, 0, 100);
1100 XMLUtils::GetInt(pPVR, "minaudiocachelevel", m_iPVRMinAudioCacheLevel, 0, 100);
1101 XMLUtils::GetBoolean(pPVR, "cacheindvdplayer", m_bPVRCacheInDvdPlayer);
1102 XMLUtils::GetBoolean(pPVR, "channeliconsautoscan", m_bPVRChannelIconsAutoScan);
1103 XMLUtils::GetBoolean(pPVR, "autoscaniconsuserset", m_bPVRAutoScanIconsUserSet);
1104 XMLUtils::GetInt(pPVR, "numericchannelswitchtimeout", m_iPVRNumericChannelSwitchTimeout, 50, 60000);
1107 XMLUtils::GetBoolean(pRootElement, "measurerefreshrate", m_measureRefreshrate);
1109 TiXmlElement* pDatabase = pRootElement->FirstChildElement("videodatabase");
1112 CLog::Log(LOGWARNING, "VIDEO database configuration is experimental.");
1113 XMLUtils::GetString(pDatabase, "type", m_databaseVideo.type);
1114 XMLUtils::GetString(pDatabase, "host", m_databaseVideo.host);
1115 XMLUtils::GetString(pDatabase, "port", m_databaseVideo.port);
1116 XMLUtils::GetString(pDatabase, "user", m_databaseVideo.user);
1117 XMLUtils::GetString(pDatabase, "pass", m_databaseVideo.pass);
1118 XMLUtils::GetString(pDatabase, "name", m_databaseVideo.name);
1119 XMLUtils::GetString(pDatabase, "key", m_databaseVideo.key);
1120 XMLUtils::GetString(pDatabase, "cert", m_databaseVideo.cert);
1121 XMLUtils::GetString(pDatabase, "ca", m_databaseVideo.ca);
1122 XMLUtils::GetString(pDatabase, "capath", m_databaseVideo.capath);
1123 XMLUtils::GetString(pDatabase, "ciphers", m_databaseVideo.ciphers);
1126 pDatabase = pRootElement->FirstChildElement("musicdatabase");
1129 XMLUtils::GetString(pDatabase, "type", m_databaseMusic.type);
1130 XMLUtils::GetString(pDatabase, "host", m_databaseMusic.host);
1131 XMLUtils::GetString(pDatabase, "port", m_databaseMusic.port);
1132 XMLUtils::GetString(pDatabase, "user", m_databaseMusic.user);
1133 XMLUtils::GetString(pDatabase, "pass", m_databaseMusic.pass);
1134 XMLUtils::GetString(pDatabase, "name", m_databaseMusic.name);
1135 XMLUtils::GetString(pDatabase, "key", m_databaseMusic.key);
1136 XMLUtils::GetString(pDatabase, "cert", m_databaseMusic.cert);
1137 XMLUtils::GetString(pDatabase, "ca", m_databaseMusic.ca);
1138 XMLUtils::GetString(pDatabase, "capath", m_databaseMusic.capath);
1139 XMLUtils::GetString(pDatabase, "ciphers", m_databaseMusic.ciphers);
1142 pDatabase = pRootElement->FirstChildElement("tvdatabase");
1145 XMLUtils::GetString(pDatabase, "type", m_databaseTV.type);
1146 XMLUtils::GetString(pDatabase, "host", m_databaseTV.host);
1147 XMLUtils::GetString(pDatabase, "port", m_databaseTV.port);
1148 XMLUtils::GetString(pDatabase, "user", m_databaseTV.user);
1149 XMLUtils::GetString(pDatabase, "pass", m_databaseTV.pass);
1150 XMLUtils::GetString(pDatabase, "name", m_databaseTV.name);
1151 XMLUtils::GetString(pDatabase, "key", m_databaseTV.key);
1152 XMLUtils::GetString(pDatabase, "cert", m_databaseTV.cert);
1153 XMLUtils::GetString(pDatabase, "ca", m_databaseTV.ca);
1154 XMLUtils::GetString(pDatabase, "capath", m_databaseTV.capath);
1155 XMLUtils::GetString(pDatabase, "ciphers", m_databaseTV.ciphers);
1158 pDatabase = pRootElement->FirstChildElement("epgdatabase");
1161 XMLUtils::GetString(pDatabase, "type", m_databaseEpg.type);
1162 XMLUtils::GetString(pDatabase, "host", m_databaseEpg.host);
1163 XMLUtils::GetString(pDatabase, "port", m_databaseEpg.port);
1164 XMLUtils::GetString(pDatabase, "user", m_databaseEpg.user);
1165 XMLUtils::GetString(pDatabase, "pass", m_databaseEpg.pass);
1166 XMLUtils::GetString(pDatabase, "name", m_databaseEpg.name);
1167 XMLUtils::GetString(pDatabase, "key", m_databaseEpg.key);
1168 XMLUtils::GetString(pDatabase, "cert", m_databaseEpg.cert);
1169 XMLUtils::GetString(pDatabase, "ca", m_databaseEpg.ca);
1170 XMLUtils::GetString(pDatabase, "capath", m_databaseEpg.capath);
1171 XMLUtils::GetString(pDatabase, "ciphers", m_databaseEpg.ciphers);
1174 pElement = pRootElement->FirstChildElement("enablemultimediakeys");
1177 XMLUtils::GetBoolean(pRootElement, "enablemultimediakeys", m_enableMultimediaKeys);
1180 pElement = pRootElement->FirstChildElement("gui");
1183 XMLUtils::GetBoolean(pElement, "visualizedirtyregions", m_guiVisualizeDirtyRegions);
1184 XMLUtils::GetInt(pElement, "algorithmdirtyregions", m_guiAlgorithmDirtyRegions);
1185 XMLUtils::GetInt(pElement, "nofliptimeout", m_guiDirtyRegionNoFlipTimeout);
1188 // load in the settings overrides
1189 CSettings::Get().Load(pRootElement, true); // true to hide the settings we read in
1192 void CAdvancedSettings::Clear()
1194 m_videoCleanStringRegExps.clear();
1195 m_moviesExcludeFromScanRegExps.clear();
1196 m_tvshowExcludeFromScanRegExps.clear();
1197 m_videoExcludeFromListingRegExps.clear();
1198 m_videoStackRegExps.clear();
1199 m_folderStackRegExps.clear();
1200 m_audioExcludeFromScanRegExps.clear();
1201 m_audioExcludeFromListingRegExps.clear();
1202 m_pictureExcludeFromListingRegExps.clear();
1204 m_pictureExtensions.clear();
1205 m_musicExtensions.clear();
1206 m_videoExtensions.clear();
1207 m_discStubExtensions.clear();
1209 m_logFolder.clear();
1210 m_userAgent.clear();
1213 void CAdvancedSettings::GetCustomTVRegexps(TiXmlElement *pRootElement, SETTINGS_TVSHOWLIST& settings)
1215 TiXmlElement *pElement = pRootElement;
1218 int iAction = 0; // overwrite
1219 // for backward compatibility
1220 const char* szAppend = pElement->Attribute("append");
1221 if ((szAppend && stricmp(szAppend, "yes") == 0))
1223 // action takes precedence if both attributes exist
1224 const char* szAction = pElement->Attribute("action");
1227 iAction = 0; // overwrite
1228 if (stricmp(szAction, "append") == 0)
1229 iAction = 1; // append
1230 else if (stricmp(szAction, "prepend") == 0)
1231 iAction = 2; // prepend
1235 TiXmlNode* pRegExp = pElement->FirstChild("regexp");
1239 if (pRegExp->FirstChild())
1241 bool bByDate = false;
1242 int iDefaultSeason = 1;
1243 if (pRegExp->ToElement())
1245 CStdString byDate = pRegExp->ToElement()->Attribute("bydate");
1246 if(byDate && stricmp(byDate, "true") == 0)
1250 CStdString defaultSeason = pRegExp->ToElement()->Attribute("defaultseason");
1251 if(!defaultSeason.empty())
1253 iDefaultSeason = atoi(defaultSeason.c_str());
1256 CStdString regExp = pRegExp->FirstChild()->Value();
1258 settings.insert(settings.begin() + i++, 1, TVShowRegexp(bByDate,regExp,iDefaultSeason));
1260 settings.push_back(TVShowRegexp(bByDate,regExp,iDefaultSeason));
1262 pRegExp = pRegExp->NextSibling("regexp");
1265 pElement = pElement->NextSiblingElement(pRootElement->Value());
1269 void CAdvancedSettings::GetCustomRegexps(TiXmlElement *pRootElement, CStdStringArray& settings)
1271 TiXmlElement *pElement = pRootElement;
1274 int iAction = 0; // overwrite
1275 // for backward compatibility
1276 const char* szAppend = pElement->Attribute("append");
1277 if ((szAppend && stricmp(szAppend, "yes") == 0))
1279 // action takes precedence if both attributes exist
1280 const char* szAction = pElement->Attribute("action");
1283 iAction = 0; // overwrite
1284 if (stricmp(szAction, "append") == 0)
1285 iAction = 1; // append
1286 else if (stricmp(szAction, "prepend") == 0)
1287 iAction = 2; // prepend
1291 TiXmlNode* pRegExp = pElement->FirstChild("regexp");
1295 if (pRegExp->FirstChild())
1297 CStdString regExp = pRegExp->FirstChild()->Value();
1299 settings.insert(settings.begin() + i++, 1, regExp);
1301 settings.push_back(regExp);
1303 pRegExp = pRegExp->NextSibling("regexp");
1306 pElement = pElement->NextSiblingElement(pRootElement->Value());
1310 void CAdvancedSettings::GetCustomExtensions(TiXmlElement *pRootElement, CStdString& extensions)
1312 CStdString extraExtensions;
1313 if (XMLUtils::GetString(pRootElement, "add", extraExtensions) && !extraExtensions.empty())
1314 extensions += "|" + extraExtensions;
1315 if (XMLUtils::GetString(pRootElement, "remove", extraExtensions) && !extraExtensions.empty())
1317 CStdStringArray exts;
1318 StringUtils::SplitString(extraExtensions,"|",exts);
1319 for (unsigned int i=0;i<exts.size();++i)
1321 int iPos = extensions.Find(exts[i]);
1324 extensions.erase(iPos,exts[i].size()+1);
1329 void CAdvancedSettings::AddSettingsFile(const CStdString &filename)
1331 m_settingsFiles.push_back(filename);
1334 float CAdvancedSettings::GetDisplayLatency(float refreshrate)
1336 float delay = m_videoDefaultLatency / 1000.0f;
1337 for (int i = 0; i < (int) m_videoRefreshLatency.size(); i++)
1339 RefreshVideoLatency& videolatency = m_videoRefreshLatency[i];
1340 if (refreshrate >= videolatency.refreshmin && refreshrate <= videolatency.refreshmax)
1341 delay = videolatency.delay / 1000.0f;
1344 return delay; // in seconds
1347 void CAdvancedSettings::SetDebugMode(bool debug)
1351 int level = std::max(m_logLevelHint, LOG_LEVEL_DEBUG_FREEMEM);
1353 CLog::SetLogLevel(level);
1354 CLog::Log(LOGNOTICE, "Enabled debug logging due to GUI setting. Level %d.", level);
1358 int level = std::min(m_logLevelHint, LOG_LEVEL_DEBUG/*LOG_LEVEL_NORMAL*/);
1359 CLog::Log(LOGNOTICE, "Disabled debug logging due to GUI setting. Level %d.", level);
1361 CLog::SetLogLevel(level);
1365 void CAdvancedSettings::SetExtraLogsFromAddon(ADDON::IAddon* addon)
1367 m_extraLogLevels = 0;
1368 for (int i=LOGMASKBIT;i<31;++i)
1370 CStdString str = StringUtils::Format("bit%i", i-LOGMASKBIT+1);
1371 if (addon->GetSetting(str) == "true")
1372 m_extraLogLevels |= (1 << i);
1374 CLog::SetExtraLogLevels(m_extraLogLevels);