strip added smb:// shares of their user/pass when adding, and instead store that...
[vuplus_xbmc] / xbmc / settings / AdvancedSettings.cpp
1 /*
2  *      Copyright (C) 2005-2008 Team XBMC
3  *      http://www.xbmc.org
4  *
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)
8  *  any later version.
9  *
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.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with XBMC; see the file COPYING.  If not, write to
17  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
18  *  http://www.gnu.org/copyleft/gpl.html
19  *
20  */
21
22 #include <limits.h>
23
24 #include "system.h"
25 #include "AdvancedSettings.h"
26 #include "Application.h"
27 #include "network/DNSNameCache.h"
28 #include "filesystem/File.h"
29 #include "utils/LangCodeExpander.h"
30 #include "LangInfo.h"
31 #include "settings/GUISettings.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
40 using namespace XFILE;
41
42 CAdvancedSettings::CAdvancedSettings()
43 {
44   m_initialized = false;
45 }
46
47 void CAdvancedSettings::Initialize()
48 {
49   m_audioHeadRoom = 0;
50   m_ac3Gain = 12.0f;
51   m_audioApplyDrc = true;
52   m_dvdplayerIgnoreDTSinWAV = false;
53   m_audioResample = 0;
54   m_allowTranscode44100 = false;
55   m_audioForceDirectSound = false;
56   m_audioAudiophile = false;
57   m_allChannelStereo = false;
58   m_audioSinkBufferDurationMsec = 50;
59
60   //default hold time of 25 ms, this allows a 20 hertz sine to pass undistorted
61   m_limiterHold = 0.025f;
62   m_limiterRelease = 0.1f;
63
64   m_karaokeSyncDelayCDG = 0.0f;
65   m_karaokeSyncDelayLRC = 0.0f;
66   m_karaokeChangeGenreForKaraokeSongs = false;
67   m_karaokeKeepDelay = true;
68   m_karaokeStartIndex = 1;
69   m_karaokeAlwaysEmptyOnCdgs = 1;
70   m_karaokeUseSongSpecificBackground = 0;
71
72   m_audioDefaultPlayer = "paplayer";
73   m_audioPlayCountMinimumPercent = 90.0f;
74   m_audioHost = "default";
75
76   m_videoSubsDelayRange = 10;
77   m_videoAudioDelayRange = 10;
78   m_videoSmallStepBackSeconds = 7;
79   m_videoSmallStepBackTries = 3;
80   m_videoSmallStepBackDelay = 300;
81   m_videoUseTimeSeeking = true;
82   m_videoTimeSeekForward = 30;
83   m_videoTimeSeekBackward = -30;
84   m_videoTimeSeekForwardBig = 600;
85   m_videoTimeSeekBackwardBig = -600;
86   m_videoPercentSeekForward = 2;
87   m_videoPercentSeekBackward = -2;
88   m_videoPercentSeekForwardBig = 10;
89   m_videoPercentSeekBackwardBig = -10;
90   m_videoBlackBarColour = 0;
91   m_videoPPFFmpegDeint = "linblenddeint";
92   m_videoPPFFmpegPostProc = "ha:128:7,va,dr";
93   m_videoDefaultPlayer = "dvdplayer";
94   m_videoDefaultDVDPlayer = "dvdplayer";
95   m_videoIgnoreSecondsAtStart = 3*60;
96   m_videoIgnorePercentAtEnd   = 8.0f;
97   m_videoPlayCountMinimumPercent = 90.0f;
98   m_videoVDPAUScaling = false;
99   m_videoNonLinStretchRatio = 0.5f;
100   m_videoEnableHighQualityHwScalers = false;
101   m_videoAutoScaleMaxFps = 30.0f;
102   m_videoAllowMpeg4VDPAU = false;
103   m_videoAllowMpeg4VAAPI = false;  
104   m_videoDisableBackgroundDeinterlace = false;
105   m_videoCaptureUseOcclusionQuery = -1; //-1 is auto detect
106   m_DXVACheckCompatibility = false;
107   m_DXVACheckCompatibilityPresent = false;
108   m_DXVAForceProcessorRenderer = true;
109   m_DXVANoDeintProcForProgressive = false;
110   m_videoFpsDetect = 1;
111   m_videoDefaultLatency = 0.0;
112
113   m_musicUseTimeSeeking = true;
114   m_musicTimeSeekForward = 10;
115   m_musicTimeSeekBackward = -10;
116   m_musicTimeSeekForwardBig = 60;
117   m_musicTimeSeekBackwardBig = -60;
118   m_musicPercentSeekForward = 1;
119   m_musicPercentSeekBackward = -1;
120   m_musicPercentSeekForwardBig = 10;
121   m_musicPercentSeekBackwardBig = -10;
122
123   m_slideshowPanAmount = 2.5f;
124   m_slideshowZoomAmount = 5.0f;
125   m_slideshowBlackBarCompensation = 20.0f;
126
127   m_lcdHeartbeat = false;
128   m_lcdDimOnScreenSave = false;
129   m_lcdScrolldelay = 1;
130   m_lcdHostName = "localhost";
131
132   m_autoDetectPingTime = 30;
133
134   m_songInfoDuration = 10;
135   m_busyDialogDelay = 2000;
136
137   m_cddbAddress = "freedb.freedb.org";
138
139   m_handleMounting = g_application.IsStandAlone();
140
141   m_fullScreenOnMovieStart = true;
142   m_cachePath = "special://temp/";
143
144   m_videoCleanDateTimeRegExp = "(.*[^ _\\,\\.\\(\\)\\[\\]\\-])[ _\\.\\(\\)\\[\\]\\-]+(19[0-9][0-9]|20[0-1][0-9])([ _\\,\\.\\(\\)\\[\\]\\-]|[^0-9]$)";
145
146   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]|\\[.*\\])([ _\\,\\.\\(\\)\\[\\]\\-]|$)");
147   m_videoCleanStringRegExps.push_back("(\\[.*\\])");
148
149   m_moviesExcludeFromScanRegExps.push_back("-trailer");
150   m_moviesExcludeFromScanRegExps.push_back("[!-._ \\\\/]sample[-._ \\\\/]");
151   m_tvshowExcludeFromScanRegExps.push_back("[!-._ \\\\/]sample[-._ \\\\/]");
152
153   m_folderStackRegExps.push_back("((cd|dvd|dis[ck])[0-9]+)$");
154
155   m_videoStackRegExps.push_back("(.*?)([ _.-]*(?:cd|dvd|p(?:(?:ar)?t)|dis[ck]|d)[ _.-]*[0-9]+)(.*?)(\\.[^.]+)$");
156   m_videoStackRegExps.push_back("(.*?)([ _.-]*(?:cd|dvd|p(?:(?:ar)?t)|dis[ck]|d)[ _.-]*[a-d])(.*?)(\\.[^.]+)$");
157   m_videoStackRegExps.push_back("(.*?)([ ._-]*[a-d])(.*?)(\\.[^.]+)$");
158   // This one is a bit too greedy to enable by default.  It will stack sequels
159   // in a flat dir structure, but is perfectly safe in a dir-per-vid one.
160   //m_videoStackRegExps.push_back("(.*?)([ ._-]*[0-9])(.*?)(\\.[^.]+)$");
161
162   // foo.s01.e01, foo.s01_e01, S01E02 foo, S01 - E02
163   m_tvshowEnumRegExps.push_back(TVShowRegexp(false,"[Ss]([0-9]+)[][ ._-]*[Ee]([0-9]+)([^\\\\/]*)$"));
164   // foo.ep01, foo.EP_01
165   m_tvshowEnumRegExps.push_back(TVShowRegexp(false,"[\\._ -]()[Ee][Pp]_?([0-9]+)([^\\\\/]*)$"));
166   // foo.yyyy.mm.dd.* (byDate=true)
167   m_tvshowEnumRegExps.push_back(TVShowRegexp(true,"([0-9]{4})[\\.-]([0-9]{2})[\\.-]([0-9]{2})"));
168   // foo.mm.dd.yyyy.* (byDate=true)
169   m_tvshowEnumRegExps.push_back(TVShowRegexp(true,"([0-9]{2})[\\.-]([0-9]{2})[\\.-]([0-9]{4})"));
170   // foo.1x09* or just /1x09*
171   m_tvshowEnumRegExps.push_back(TVShowRegexp(false,"[\\\\/\\._ \\[\\(-]([0-9]+)x([0-9]+)([^\\\\/]*)$"));
172   // foo.103*, 103 foo
173   m_tvshowEnumRegExps.push_back(TVShowRegexp(false,"[\\\\/\\._ -]([0-9]+)([0-9][0-9])([\\._ -][^\\\\/]*)$"));
174   // Part I, Pt.VI
175   m_tvshowEnumRegExps.push_back(TVShowRegexp(false,"[\\/._ -]p(?:ar)?t[_. -]()([ivx]+)([._ -][^\\/]*)$"));
176
177   m_tvshowMultiPartEnumRegExp = "^[-_EeXx]+([0-9]+)";
178
179   m_remoteDelay = 3;
180   m_controllerDeadzone = 0.2f;
181
182   m_playlistAsFolders = true;
183   m_detectAsUdf = false;
184
185   m_fanartRes = 1080;
186   m_imageRes = 720;
187   m_useDDSFanart = false;
188
189   m_sambaclienttimeout = 10;
190   m_sambadoscodepage = "";
191   m_sambastatfiles = true;
192
193   m_bHTTPDirectoryStatFilesize = false;
194
195   m_bFTPThumbs = false;
196
197   m_musicThumbs = "folder.jpg|Folder.jpg|folder.JPG|Folder.JPG|cover.jpg|Cover.jpg|cover.jpeg|thumb.jpg|Thumb.jpg|thumb.JPG|Thumb.JPG";
198   m_dvdThumbs = "folder.jpg|Folder.jpg|folder.JPG|Folder.JPG";
199   m_fanartImages = "fanart.jpg|fanart.png";
200
201   m_bMusicLibraryHideAllItems = false;
202   m_bMusicLibraryAllItemsOnBottom = false;
203   m_bMusicLibraryAlbumsSortByArtistThenYear = false;
204   m_iMusicLibraryRecentlyAddedItems = 25;
205   m_strMusicLibraryAlbumFormat = "";
206   m_strMusicLibraryAlbumFormatRight = "";
207   m_prioritiseAPEv2tags = false;
208   m_musicItemSeparator = " / ";
209   m_videoItemSeparator = " / ";
210
211   m_bVideoLibraryHideAllItems = false;
212   m_bVideoLibraryAllItemsOnBottom = false;
213   m_iVideoLibraryRecentlyAddedItems = 25;
214   m_bVideoLibraryHideRecentlyAddedItems = false;
215   m_bVideoLibraryHideEmptySeries = false;
216   m_bVideoLibraryCleanOnUpdate = false;
217   m_bVideoLibraryExportAutoThumbs = false;
218   m_bVideoLibraryImportWatchedState = false;
219   m_bVideoLibraryImportResumePoint = false;
220   m_bVideoScannerIgnoreErrors = false;
221   m_iVideoLibraryDateAdded = 1; // prefer mtime over ctime and current time
222
223   m_iTuxBoxStreamtsPort = 31339;
224   m_bTuxBoxAudioChannelSelection = false;
225   m_bTuxBoxSubMenuSelection = false;
226   m_bTuxBoxPictureIcon= true;
227   m_bTuxBoxSendAllAPids= false;
228   m_iTuxBoxEpgRequestTime = 10; //seconds
229   m_iTuxBoxDefaultSubMenu = 4;
230   m_iTuxBoxDefaultRootMenu = 0; //default TV Mode
231   m_iTuxBoxZapWaitTime = 0; // Time in sec. Default 0:OFF
232   m_bTuxBoxZapstream = true;
233   m_iTuxBoxZapstreamPort = 31344;
234
235   m_iMythMovieLength = 0; // 0 == Off
236
237   m_bEdlMergeShortCommBreaks = false;      // Off by default
238   m_iEdlMaxCommBreakLength = 8 * 30 + 10;  // Just over 8 * 30 second commercial break.
239   m_iEdlMinCommBreakLength = 3 * 30;       // 3 * 30 second commercial breaks.
240   m_iEdlMaxCommBreakGap = 4 * 30;          // 4 * 30 second commercial breaks.
241   m_iEdlMaxStartGap = 5 * 60;              // 5 minutes.
242   m_iEdlCommBreakAutowait = 0;             // Off by default
243   m_iEdlCommBreakAutowind = 0;             // Off by default
244
245   m_curlconnecttimeout = 10;
246   m_curllowspeedtime = 20;
247   m_curlretries = 2;
248   m_curlDisableIPV6 = false;      //Certain hardware/OS combinations have trouble
249                                   //with ipv6.
250
251   m_fullScreen = m_startFullScreen = false;
252   m_showExitButton = true;
253   m_splashImage = true;
254
255   m_playlistRetries = 100;
256   m_playlistTimeout = 20; // 20 seconds timeout
257   m_GLRectangleHack = false;
258   m_iSkipLoopFilter = 0;
259   m_AllowD3D9Ex = true;
260   m_ForceD3D9Ex = false;
261   m_AllowDynamicTextures = true;
262   m_RestrictCapsMask = 0;
263   m_sleepBeforeFlip = 0;
264   m_bVirtualShares = true;
265
266 //caused lots of jerks
267 //#ifdef _WIN32
268 //  m_ForcedSwapTime = 2.0;
269 //#else
270   m_ForcedSwapTime = 0.0;
271 //#endif
272
273   m_cpuTempCmd = "";
274   m_gpuTempCmd = "";
275 #if defined(TARGET_DARWIN)
276   // default for osx is fullscreen always on top
277   m_alwaysOnTop = true;
278 #else
279   // default for windows is not always on top
280   m_alwaysOnTop = false;
281 #endif
282
283   m_bgInfoLoaderMaxThreads = 5;
284
285   m_measureRefreshrate = false;
286
287   m_cacheMemBufferSize = 1024 * 1024 * 20;
288
289   m_jsonOutputCompact = true;
290   m_jsonTcpPort = 9090;
291
292   m_enableMultimediaKeys = false;
293
294   m_canWindowed = true;
295   m_guiVisualizeDirtyRegions = false;
296   m_guiAlgorithmDirtyRegions = 0;
297   m_guiDirtyRegionNoFlipTimeout = -1;
298   m_logEnableAirtunes = false;
299   m_airTunesPort = 36666;
300   m_airPlayPort = 36667;
301   m_initialized = true;
302 }
303
304 bool CAdvancedSettings::Load()
305 {
306   // NOTE: This routine should NOT set the default of any of these parameters
307   //       it should instead use the versions of GetString/Integer/Float that
308   //       don't take defaults in.  Defaults are set in the constructor above
309   Initialize(); // In case of profile switch.
310   ParseSettingsFile("special://xbmc/system/advancedsettings.xml");
311   for (unsigned int i = 0; i < m_settingsFiles.size(); i++)
312     ParseSettingsFile(m_settingsFiles[i]);
313   ParseSettingsFile(g_settings.GetUserDataItem("advancedsettings.xml"));
314   return true;
315 }
316
317 void CAdvancedSettings::ParseSettingsFile(const CStdString &file)
318 {
319   CXBMCTinyXML advancedXML;
320   if (!CFile::Exists(file))
321   {
322     CLog::Log(LOGNOTICE, "No settings file to load (%s)", file.c_str());
323     return;
324   }
325
326   if (!advancedXML.LoadFile(file))
327   {
328     CLog::Log(LOGERROR, "Error loading %s, Line %d\n%s", file.c_str(), advancedXML.ErrorRow(), advancedXML.ErrorDesc());
329     return;
330   }
331
332   TiXmlElement *pRootElement = advancedXML.RootElement();
333   if (!pRootElement || strcmpi(pRootElement->Value(),"advancedsettings") != 0)
334   {
335     CLog::Log(LOGERROR, "Error loading %s, no <advancedsettings> node", file.c_str());
336     return;
337   }
338
339   // succeeded - tell the user it worked
340   CLog::Log(LOGNOTICE, "Loaded settings file from %s", file.c_str());
341
342   // Dump contents of AS.xml to debug log
343   TiXmlPrinter printer;
344   printer.SetLineBreak("\n");
345   printer.SetIndent("  ");
346   advancedXML.Accept(&printer);
347   CLog::Log(LOGNOTICE, "Contents of %s are...\n%s", file.c_str(), printer.CStr());
348
349   TiXmlElement *pElement = pRootElement->FirstChildElement("audio");
350   if (pElement)
351   {
352     XMLUtils::GetFloat(pElement, "ac3downmixgain", m_ac3Gain, -96.0f, 96.0f);
353     XMLUtils::GetInt(pElement, "headroom", m_audioHeadRoom, 0, 12);
354     XMLUtils::GetString(pElement, "defaultplayer", m_audioDefaultPlayer);
355     // 101 on purpose - can be used to never automark as watched
356     XMLUtils::GetFloat(pElement, "playcountminimumpercent", m_audioPlayCountMinimumPercent, 0.0f, 101.0f);
357
358     XMLUtils::GetBoolean(pElement, "usetimeseeking", m_musicUseTimeSeeking);
359     XMLUtils::GetInt(pElement, "timeseekforward", m_musicTimeSeekForward, 0, 6000);
360     XMLUtils::GetInt(pElement, "timeseekbackward", m_musicTimeSeekBackward, -6000, 0);
361     XMLUtils::GetInt(pElement, "timeseekforwardbig", m_musicTimeSeekForwardBig, 0, 6000);
362     XMLUtils::GetInt(pElement, "timeseekbackwardbig", m_musicTimeSeekBackwardBig, -6000, 0);
363
364     XMLUtils::GetInt(pElement, "percentseekforward", m_musicPercentSeekForward, 0, 100);
365     XMLUtils::GetInt(pElement, "percentseekbackward", m_musicPercentSeekBackward, -100, 0);
366     XMLUtils::GetInt(pElement, "percentseekforwardbig", m_musicPercentSeekForwardBig, 0, 100);
367     XMLUtils::GetInt(pElement, "percentseekbackwardbig", m_musicPercentSeekBackwardBig, -100, 0);
368
369     XMLUtils::GetInt(pElement, "resample", m_audioResample, 0, 192000);
370     XMLUtils::GetBoolean(pElement, "allowtranscode44100", m_allowTranscode44100);
371     XMLUtils::GetBoolean(pElement, "forceDirectSound", m_audioForceDirectSound);
372     XMLUtils::GetBoolean(pElement, "audiophile", m_audioAudiophile);
373     XMLUtils::GetBoolean(pElement, "allchannelstereo", m_allChannelStereo);
374     XMLUtils::GetString(pElement, "transcodeto", m_audioTranscodeTo);
375     XMLUtils::GetInt(pElement, "audiosinkbufferdurationmsec", m_audioSinkBufferDurationMsec);
376
377     TiXmlElement* pAudioExcludes = pElement->FirstChildElement("excludefromlisting");
378     if (pAudioExcludes)
379       GetCustomRegexps(pAudioExcludes, m_audioExcludeFromListingRegExps);
380
381     pAudioExcludes = pElement->FirstChildElement("excludefromscan");
382     if (pAudioExcludes)
383       GetCustomRegexps(pAudioExcludes, m_audioExcludeFromScanRegExps);
384
385     XMLUtils::GetString(pElement, "audiohost", m_audioHost);
386     XMLUtils::GetBoolean(pElement, "applydrc", m_audioApplyDrc);
387     XMLUtils::GetBoolean(pElement, "dvdplayerignoredtsinwav", m_dvdplayerIgnoreDTSinWAV);
388
389     XMLUtils::GetFloat(pElement, "limiterhold", m_limiterHold, 0.0f, 100.0f);
390     XMLUtils::GetFloat(pElement, "limiterrelease", m_limiterRelease, 0.001f, 100.0f);
391   }
392
393   pElement = pRootElement->FirstChildElement("karaoke");
394   if (pElement)
395   {
396     XMLUtils::GetFloat(pElement, "syncdelaycdg", m_karaokeSyncDelayCDG, -3.0f, 3.0f); // keep the old name for comp
397     XMLUtils::GetFloat(pElement, "syncdelaylrc", m_karaokeSyncDelayLRC, -3.0f, 3.0f);
398     XMLUtils::GetBoolean(pElement, "alwaysreplacegenre", m_karaokeChangeGenreForKaraokeSongs );
399     XMLUtils::GetBoolean(pElement, "storedelay", m_karaokeKeepDelay );
400     XMLUtils::GetInt(pElement, "autoassignstartfrom", m_karaokeStartIndex, 1, 2000000000);
401     XMLUtils::GetBoolean(pElement, "nocdgbackground", m_karaokeAlwaysEmptyOnCdgs );
402     XMLUtils::GetBoolean(pElement, "lookupsongbackground", m_karaokeUseSongSpecificBackground );
403
404     TiXmlElement* pKaraokeBackground = pElement->FirstChildElement("defaultbackground");
405     if (pKaraokeBackground)
406     {
407       const char* attr = pKaraokeBackground->Attribute("type");
408       if ( attr )
409         m_karaokeDefaultBackgroundType = attr;
410
411       attr = pKaraokeBackground->Attribute("path");
412       if ( attr )
413         m_karaokeDefaultBackgroundFilePath = attr;
414     }
415   }
416
417   pElement = pRootElement->FirstChildElement("video");
418   if (pElement)
419   {
420     XMLUtils::GetFloat(pElement, "subsdelayrange", m_videoSubsDelayRange, 10, 600);
421     XMLUtils::GetFloat(pElement, "audiodelayrange", m_videoAudioDelayRange, 10, 600);
422     XMLUtils::GetInt(pElement, "blackbarcolour", m_videoBlackBarColour, 0, 255);
423     XMLUtils::GetString(pElement, "defaultplayer", m_videoDefaultPlayer);
424     XMLUtils::GetString(pElement, "defaultdvdplayer", m_videoDefaultDVDPlayer);
425     XMLUtils::GetBoolean(pElement, "fullscreenonmoviestart", m_fullScreenOnMovieStart);
426     // 101 on purpose - can be used to never automark as watched
427     XMLUtils::GetFloat(pElement, "playcountminimumpercent", m_videoPlayCountMinimumPercent, 0.0f, 101.0f);
428     XMLUtils::GetInt(pElement, "ignoresecondsatstart", m_videoIgnoreSecondsAtStart, 0, 900);
429     XMLUtils::GetFloat(pElement, "ignorepercentatend", m_videoIgnorePercentAtEnd, 0, 100.0f);
430
431     XMLUtils::GetInt(pElement, "smallstepbackseconds", m_videoSmallStepBackSeconds, 1, INT_MAX);
432     XMLUtils::GetInt(pElement, "smallstepbacktries", m_videoSmallStepBackTries, 1, 10);
433     XMLUtils::GetInt(pElement, "smallstepbackdelay", m_videoSmallStepBackDelay, 100, 5000); //MS
434
435     XMLUtils::GetBoolean(pElement, "usetimeseeking", m_videoUseTimeSeeking);
436     XMLUtils::GetInt(pElement, "timeseekforward", m_videoTimeSeekForward, 0, 6000);
437     XMLUtils::GetInt(pElement, "timeseekbackward", m_videoTimeSeekBackward, -6000, 0);
438     XMLUtils::GetInt(pElement, "timeseekforwardbig", m_videoTimeSeekForwardBig, 0, 6000);
439     XMLUtils::GetInt(pElement, "timeseekbackwardbig", m_videoTimeSeekBackwardBig, -6000, 0);
440
441     XMLUtils::GetInt(pElement, "percentseekforward", m_videoPercentSeekForward, 0, 100);
442     XMLUtils::GetInt(pElement, "percentseekbackward", m_videoPercentSeekBackward, -100, 0);
443     XMLUtils::GetInt(pElement, "percentseekforwardbig", m_videoPercentSeekForwardBig, 0, 100);
444     XMLUtils::GetInt(pElement, "percentseekbackwardbig", m_videoPercentSeekBackwardBig, -100, 0);
445
446     TiXmlElement* pVideoExcludes = pElement->FirstChildElement("excludefromlisting");
447     if (pVideoExcludes)
448       GetCustomRegexps(pVideoExcludes, m_videoExcludeFromListingRegExps);
449
450     pVideoExcludes = pElement->FirstChildElement("excludefromscan");
451     if (pVideoExcludes)
452       GetCustomRegexps(pVideoExcludes, m_moviesExcludeFromScanRegExps);
453
454     pVideoExcludes = pElement->FirstChildElement("excludetvshowsfromscan");
455     if (pVideoExcludes)
456       GetCustomRegexps(pVideoExcludes, m_tvshowExcludeFromScanRegExps);
457
458     pVideoExcludes = pElement->FirstChildElement("cleanstrings");
459     if (pVideoExcludes)
460       GetCustomRegexps(pVideoExcludes, m_videoCleanStringRegExps);
461
462     XMLUtils::GetString(pElement,"cleandatetime", m_videoCleanDateTimeRegExp);
463     XMLUtils::GetString(pElement,"ppffmpegdeinterlacing",m_videoPPFFmpegDeint);
464     XMLUtils::GetString(pElement,"ppffmpegpostprocessing",m_videoPPFFmpegPostProc);
465     XMLUtils::GetBoolean(pElement,"vdpauscaling",m_videoVDPAUScaling);
466     XMLUtils::GetFloat(pElement, "nonlinearstretchratio", m_videoNonLinStretchRatio, 0.01f, 1.0f);
467     XMLUtils::GetBoolean(pElement,"enablehighqualityhwscalers", m_videoEnableHighQualityHwScalers);
468     XMLUtils::GetFloat(pElement,"autoscalemaxfps",m_videoAutoScaleMaxFps, 0.0f, 1000.0f);
469     XMLUtils::GetBoolean(pElement,"allowmpeg4vdpau",m_videoAllowMpeg4VDPAU);
470     XMLUtils::GetBoolean(pElement,"allowmpeg4vaapi",m_videoAllowMpeg4VAAPI);    
471     XMLUtils::GetBoolean(pElement, "disablebackgrounddeinterlace", m_videoDisableBackgroundDeinterlace);
472     XMLUtils::GetInt(pElement, "useocclusionquery", m_videoCaptureUseOcclusionQuery, -1, 1);
473
474     TiXmlElement* pAdjustRefreshrate = pElement->FirstChildElement("adjustrefreshrate");
475     if (pAdjustRefreshrate)
476     {
477       TiXmlElement* pRefreshOverride = pAdjustRefreshrate->FirstChildElement("override");
478       while (pRefreshOverride)
479       {
480         RefreshOverride override = {0};
481
482         float fps;
483         if (XMLUtils::GetFloat(pRefreshOverride, "fps", fps))
484         {
485           override.fpsmin = fps - 0.01f;
486           override.fpsmax = fps + 0.01f;
487         }
488
489         float fpsmin, fpsmax;
490         if (XMLUtils::GetFloat(pRefreshOverride, "fpsmin", fpsmin) &&
491             XMLUtils::GetFloat(pRefreshOverride, "fpsmax", fpsmax))
492         {
493           override.fpsmin = fpsmin;
494           override.fpsmax = fpsmax;
495         }
496
497         float refresh;
498         if (XMLUtils::GetFloat(pRefreshOverride, "refresh", refresh))
499         {
500           override.refreshmin = refresh - 0.01f;
501           override.refreshmax = refresh + 0.01f;
502         }
503
504         float refreshmin, refreshmax;
505         if (XMLUtils::GetFloat(pRefreshOverride, "refreshmin", refreshmin) &&
506             XMLUtils::GetFloat(pRefreshOverride, "refreshmax", refreshmax))
507         {
508           override.refreshmin = refreshmin;
509           override.refreshmax = refreshmax;
510         }
511
512         bool fpsCorrect     = (override.fpsmin > 0.0f && override.fpsmax >= override.fpsmin);
513         bool refreshCorrect = (override.refreshmin > 0.0f && override.refreshmax >= override.refreshmin);
514
515         if (fpsCorrect && refreshCorrect)
516           m_videoAdjustRefreshOverrides.push_back(override);
517         else
518           CLog::Log(LOGWARNING, "Ignoring malformed refreshrate override, fpsmin:%f fpsmax:%f refreshmin:%f refreshmax:%f",
519               override.fpsmin, override.fpsmax, override.refreshmin, override.refreshmax);
520
521         pRefreshOverride = pRefreshOverride->NextSiblingElement("override");
522       }
523
524       TiXmlElement* pRefreshFallback = pAdjustRefreshrate->FirstChildElement("fallback");
525       while (pRefreshFallback)
526       {
527         RefreshOverride fallback = {0};
528         fallback.fallback = true;
529
530         float refresh;
531         if (XMLUtils::GetFloat(pRefreshFallback, "refresh", refresh))
532         {
533           fallback.refreshmin = refresh - 0.01f;
534           fallback.refreshmax = refresh + 0.01f;
535         }
536
537         float refreshmin, refreshmax;
538         if (XMLUtils::GetFloat(pRefreshFallback, "refreshmin", refreshmin) &&
539             XMLUtils::GetFloat(pRefreshFallback, "refreshmax", refreshmax))
540         {
541           fallback.refreshmin = refreshmin;
542           fallback.refreshmax = refreshmax;
543         }
544
545         if (fallback.refreshmin > 0.0f && fallback.refreshmax >= fallback.refreshmin)
546           m_videoAdjustRefreshOverrides.push_back(fallback);
547         else
548           CLog::Log(LOGWARNING, "Ignoring malformed refreshrate fallback, fpsmin:%f fpsmax:%f refreshmin:%f refreshmax:%f",
549               fallback.fpsmin, fallback.fpsmax, fallback.refreshmin, fallback.refreshmax);
550
551         pRefreshFallback = pRefreshFallback->NextSiblingElement("fallback");
552       }
553     }
554
555     m_DXVACheckCompatibilityPresent = XMLUtils::GetBoolean(pElement,"checkdxvacompatibility", m_DXVACheckCompatibility);
556
557     XMLUtils::GetBoolean(pElement,"forcedxvarenderer", m_DXVAForceProcessorRenderer);
558     XMLUtils::GetBoolean(pElement,"dxvanodeintforprogressive", m_DXVANoDeintProcForProgressive);
559     //0 = disable fps detect, 1 = only detect on timestamps with uniform spacing, 2 detect on all timestamps
560     XMLUtils::GetInt(pElement, "fpsdetect", m_videoFpsDetect, 0, 2);
561
562     // Store global display latency settings
563     TiXmlElement* pVideoLatency = pElement->FirstChildElement("latency");
564     if (pVideoLatency)
565     {
566       float refresh, refreshmin, refreshmax, delay;
567       TiXmlElement* pRefreshVideoLatency = pVideoLatency->FirstChildElement("refresh");
568
569       while (pRefreshVideoLatency)
570       {
571         RefreshVideoLatency videolatency = {0};
572
573         if (XMLUtils::GetFloat(pRefreshVideoLatency, "rate", refresh))
574         {
575           videolatency.refreshmin = refresh - 0.01f;
576           videolatency.refreshmax = refresh + 0.01f;
577         }
578         else if (XMLUtils::GetFloat(pRefreshVideoLatency, "min", refreshmin) &&
579                  XMLUtils::GetFloat(pRefreshVideoLatency, "max", refreshmax))
580         {
581           videolatency.refreshmin = refreshmin;
582           videolatency.refreshmax = refreshmax;
583         }
584         if (XMLUtils::GetFloat(pRefreshVideoLatency, "delay", delay, -600.0f, 600.0f))
585           videolatency.delay = delay;
586
587         if (videolatency.refreshmin > 0.0f && videolatency.refreshmax >= videolatency.refreshmin)
588           m_videoRefreshLatency.push_back(videolatency);
589         else
590           CLog::Log(LOGWARNING, "Ignoring malformed display latency <refresh> entry, min:%f max:%f", videolatency.refreshmin, videolatency.refreshmax);
591
592         pRefreshVideoLatency = pRefreshVideoLatency->NextSiblingElement("refresh");
593       }
594
595       // Get default global display latency
596       XMLUtils::GetFloat(pVideoLatency, "delay", m_videoDefaultLatency, -600.0f, 600.0f);
597     }
598   }
599
600   pElement = pRootElement->FirstChildElement("musiclibrary");
601   if (pElement)
602   {
603     XMLUtils::GetBoolean(pElement, "hideallitems", m_bMusicLibraryHideAllItems);
604     XMLUtils::GetInt(pElement, "recentlyaddeditems", m_iMusicLibraryRecentlyAddedItems, 1, INT_MAX);
605     XMLUtils::GetBoolean(pElement, "prioritiseapetags", m_prioritiseAPEv2tags);
606     XMLUtils::GetBoolean(pElement, "allitemsonbottom", m_bMusicLibraryAllItemsOnBottom);
607     XMLUtils::GetBoolean(pElement, "albumssortbyartistthenyear", m_bMusicLibraryAlbumsSortByArtistThenYear);
608     XMLUtils::GetString(pElement, "albumformat", m_strMusicLibraryAlbumFormat);
609     XMLUtils::GetString(pElement, "albumformatright", m_strMusicLibraryAlbumFormatRight);
610     XMLUtils::GetString(pElement, "itemseparator", m_musicItemSeparator);
611   }
612
613   pElement = pRootElement->FirstChildElement("videolibrary");
614   if (pElement)
615   {
616     XMLUtils::GetBoolean(pElement, "hideallitems", m_bVideoLibraryHideAllItems);
617     XMLUtils::GetBoolean(pElement, "allitemsonbottom", m_bVideoLibraryAllItemsOnBottom);
618     XMLUtils::GetInt(pElement, "recentlyaddeditems", m_iVideoLibraryRecentlyAddedItems, 1, INT_MAX);
619     XMLUtils::GetBoolean(pElement, "hiderecentlyaddeditems", m_bVideoLibraryHideRecentlyAddedItems);
620     XMLUtils::GetBoolean(pElement, "hideemptyseries", m_bVideoLibraryHideEmptySeries);
621     XMLUtils::GetBoolean(pElement, "cleanonupdate", m_bVideoLibraryCleanOnUpdate);
622     XMLUtils::GetString(pElement, "itemseparator", m_videoItemSeparator);
623     XMLUtils::GetBoolean(pElement, "exportautothumbs", m_bVideoLibraryExportAutoThumbs);
624     XMLUtils::GetBoolean(pElement, "importwatchedstate", m_bVideoLibraryImportWatchedState);
625     XMLUtils::GetBoolean(pElement, "importresumepoint", m_bVideoLibraryImportResumePoint);
626     XMLUtils::GetInt(pElement, "dateadded", m_iVideoLibraryDateAdded);
627   }
628
629   pElement = pRootElement->FirstChildElement("videoscanner");
630   if (pElement)
631   {
632     XMLUtils::GetBoolean(pElement, "ignoreerrors", m_bVideoScannerIgnoreErrors);
633   }
634
635   // Backward-compatibility of ExternalPlayer config
636   pElement = pRootElement->FirstChildElement("externalplayer");
637   if (pElement)
638   {
639     CLog::Log(LOGWARNING, "External player configuration has been removed from advancedsettings.xml.  It can now be configed in userdata/playercorefactory.xml");
640   }
641   pElement = pRootElement->FirstChildElement("slideshow");
642   if (pElement)
643   {
644     XMLUtils::GetFloat(pElement, "panamount", m_slideshowPanAmount, 0.0f, 20.0f);
645     XMLUtils::GetFloat(pElement, "zoomamount", m_slideshowZoomAmount, 0.0f, 20.0f);
646     XMLUtils::GetFloat(pElement, "blackbarcompensation", m_slideshowBlackBarCompensation, 0.0f, 50.0f);
647   }
648
649   pElement = pRootElement->FirstChildElement("lcd");
650   if (pElement)
651   {
652     XMLUtils::GetBoolean(pElement, "heartbeat", m_lcdHeartbeat);
653     XMLUtils::GetBoolean(pElement, "dimonscreensave", m_lcdDimOnScreenSave);
654     XMLUtils::GetInt(pElement, "scrolldelay", m_lcdScrolldelay, -8, 8);
655     XMLUtils::GetString(pElement, "hostname", m_lcdHostName);
656   }
657   pElement = pRootElement->FirstChildElement("network");
658   if (pElement)
659   {
660     XMLUtils::GetInt(pElement, "autodetectpingtime", m_autoDetectPingTime, 1, 240);
661     XMLUtils::GetInt(pElement, "curlclienttimeout", m_curlconnecttimeout, 1, 1000);
662     XMLUtils::GetInt(pElement, "curllowspeedtime", m_curllowspeedtime, 1, 1000);
663     XMLUtils::GetInt(pElement, "curlretries", m_curlretries, 0, 10);
664     XMLUtils::GetBoolean(pElement,"disableipv6", m_curlDisableIPV6);
665     XMLUtils::GetUInt(pElement, "cachemembuffersize", m_cacheMemBufferSize);
666   }
667
668   pElement = pRootElement->FirstChildElement("jsonrpc");
669   if (pElement)
670   {
671     XMLUtils::GetBoolean(pElement, "compactoutput", m_jsonOutputCompact);
672     XMLUtils::GetUInt(pElement, "tcpport", m_jsonTcpPort);
673   }
674
675   pElement = pRootElement->FirstChildElement("samba");
676   if (pElement)
677   {
678     XMLUtils::GetString(pElement,  "doscodepage",   m_sambadoscodepage);
679     XMLUtils::GetInt(pElement, "clienttimeout", m_sambaclienttimeout, 5, 100);
680     XMLUtils::GetBoolean(pElement, "statfiles", m_sambastatfiles);
681   }
682
683   pElement = pRootElement->FirstChildElement("httpdirectory");
684   if (pElement)
685     XMLUtils::GetBoolean(pElement, "statfilesize", m_bHTTPDirectoryStatFilesize);
686
687   pElement = pRootElement->FirstChildElement("ftp");
688   if (pElement)
689   {
690     XMLUtils::GetBoolean(pElement, "remotethumbs", m_bFTPThumbs);
691   }
692
693   pElement = pRootElement->FirstChildElement("loglevel");
694   if (pElement)
695   { // read the loglevel setting, so set the setting advanced to hide it in GUI
696     // as altering it will do nothing - we don't write to advancedsettings.xml
697     XMLUtils::GetInt(pRootElement, "loglevel", m_logLevelHint, LOG_LEVEL_NONE, LOG_LEVEL_MAX);
698     CSettingBool *setting = (CSettingBool *)g_guiSettings.GetSetting("debug.showloginfo");
699     if (setting)
700     {
701       const char* hide;
702       if (!((hide = pElement->Attribute("hide")) && strnicmp("false", hide, 4) == 0))
703         setting->SetAdvanced();
704     }
705     g_advancedSettings.m_logLevel = std::max(g_advancedSettings.m_logLevel, g_advancedSettings.m_logLevelHint);
706     CLog::SetLogLevel(g_advancedSettings.m_logLevel);
707   }
708      
709   XMLUtils::GetString(pRootElement, "cddbaddress", m_cddbAddress);
710
711   //airtunes + airplay
712   XMLUtils::GetBoolean(pRootElement, "enableairtunesdebuglog", m_logEnableAirtunes);
713   XMLUtils::GetInt(pRootElement,     "airtunesport", m_airTunesPort);
714   XMLUtils::GetInt(pRootElement,     "airplayport", m_airPlayPort);  
715   
716
717   XMLUtils::GetBoolean(pRootElement, "handlemounting", m_handleMounting);
718
719 #if defined(HAS_SDL) || defined(TARGET_WINDOWS)
720   XMLUtils::GetBoolean(pRootElement, "fullscreen", m_startFullScreen);
721 #endif
722   XMLUtils::GetBoolean(pRootElement, "splash", m_splashImage);
723   XMLUtils::GetBoolean(pRootElement, "showexitbutton", m_showExitButton);
724   XMLUtils::GetBoolean(pRootElement, "canwindowed", m_canWindowed);
725
726   XMLUtils::GetInt(pRootElement, "songinfoduration", m_songInfoDuration, 0, INT_MAX);
727   XMLUtils::GetInt(pRootElement, "busydialogdelay", m_busyDialogDelay, 0, 5000);
728   XMLUtils::GetInt(pRootElement, "playlistretries", m_playlistRetries, -1, 5000);
729   XMLUtils::GetInt(pRootElement, "playlisttimeout", m_playlistTimeout, 0, 5000);
730
731   XMLUtils::GetBoolean(pRootElement,"glrectanglehack", m_GLRectangleHack);
732   XMLUtils::GetInt(pRootElement,"skiploopfilter", m_iSkipLoopFilter, -16, 48);
733   XMLUtils::GetFloat(pRootElement, "forcedswaptime", m_ForcedSwapTime, 0.0, 100.0);
734
735   XMLUtils::GetBoolean(pRootElement,"allowd3d9ex", m_AllowD3D9Ex);
736   XMLUtils::GetBoolean(pRootElement,"forced3d9ex", m_ForceD3D9Ex);
737   XMLUtils::GetBoolean(pRootElement,"allowdynamictextures", m_AllowDynamicTextures);
738   XMLUtils::GetUInt(pRootElement,"restrictcapsmask", m_RestrictCapsMask);
739   XMLUtils::GetFloat(pRootElement,"sleepbeforeflip", m_sleepBeforeFlip, 0.0f, 1.0f);
740   XMLUtils::GetBoolean(pRootElement,"virtualshares", m_bVirtualShares);
741
742   //Tuxbox
743   pElement = pRootElement->FirstChildElement("tuxbox");
744   if (pElement)
745   {
746     XMLUtils::GetInt(pElement, "streamtsport", m_iTuxBoxStreamtsPort, 0, 65535);
747     XMLUtils::GetBoolean(pElement, "audiochannelselection", m_bTuxBoxAudioChannelSelection);
748     XMLUtils::GetBoolean(pElement, "submenuselection", m_bTuxBoxSubMenuSelection);
749     XMLUtils::GetBoolean(pElement, "pictureicon", m_bTuxBoxPictureIcon);
750     XMLUtils::GetBoolean(pElement, "sendallaudiopids", m_bTuxBoxSendAllAPids);
751     XMLUtils::GetInt(pElement, "epgrequesttime", m_iTuxBoxEpgRequestTime, 0, 3600);
752     XMLUtils::GetInt(pElement, "defaultsubmenu", m_iTuxBoxDefaultSubMenu, 1, 4);
753     XMLUtils::GetInt(pElement, "defaultrootmenu", m_iTuxBoxDefaultRootMenu, 0, 4);
754     XMLUtils::GetInt(pElement, "zapwaittime", m_iTuxBoxZapWaitTime, 0, 120);
755     XMLUtils::GetBoolean(pElement, "zapstream", m_bTuxBoxZapstream);
756     XMLUtils::GetInt(pElement, "zapstreamport", m_iTuxBoxZapstreamPort, 0, 65535);
757   }
758
759   // Myth TV
760   pElement = pRootElement->FirstChildElement("myth");
761   if (pElement)
762   {
763     XMLUtils::GetInt(pElement, "movielength", m_iMythMovieLength);
764   }
765
766   // EDL commercial break handling
767   pElement = pRootElement->FirstChildElement("edl");
768   if (pElement)
769   {
770     XMLUtils::GetBoolean(pElement, "mergeshortcommbreaks", m_bEdlMergeShortCommBreaks);
771     XMLUtils::GetInt(pElement, "maxcommbreaklength", m_iEdlMaxCommBreakLength, 0, 10 * 60); // Between 0 and 10 minutes
772     XMLUtils::GetInt(pElement, "mincommbreaklength", m_iEdlMinCommBreakLength, 0, 5 * 60);  // Between 0 and 5 minutes
773     XMLUtils::GetInt(pElement, "maxcommbreakgap", m_iEdlMaxCommBreakGap, 0, 5 * 60);        // Between 0 and 5 minutes.
774     XMLUtils::GetInt(pElement, "maxstartgap", m_iEdlMaxStartGap, 0, 10 * 60);               // Between 0 and 10 minutes
775     XMLUtils::GetInt(pElement, "commbreakautowait", m_iEdlCommBreakAutowait, 0, 10);        // Between 0 and 10 seconds
776     XMLUtils::GetInt(pElement, "commbreakautowind", m_iEdlCommBreakAutowind, 0, 10);        // Between 0 and 10 seconds
777   }
778
779   // picture exclude regexps
780   TiXmlElement* pPictureExcludes = pRootElement->FirstChildElement("pictureexcludes");
781   if (pPictureExcludes)
782     GetCustomRegexps(pPictureExcludes, m_pictureExcludeFromListingRegExps);
783
784   // picture extensions
785   TiXmlElement* pExts = pRootElement->FirstChildElement("pictureextensions");
786   if (pExts)
787     GetCustomExtensions(pExts,g_settings.m_pictureExtensions);
788
789   // music extensions
790   pExts = pRootElement->FirstChildElement("musicextensions");
791   if (pExts)
792     GetCustomExtensions(pExts,g_settings.m_musicExtensions);
793
794   // video extensions
795   pExts = pRootElement->FirstChildElement("videoextensions");
796   if (pExts)
797     GetCustomExtensions(pExts,g_settings.m_videoExtensions);
798
799   // stub extensions
800   pExts = pRootElement->FirstChildElement("discstubextensions");
801   if (pExts)
802     GetCustomExtensions(pExts,g_settings.m_discStubExtensions);
803
804   m_vecTokens.clear();
805   CLangInfo::LoadTokens(pRootElement->FirstChild("sorttokens"),m_vecTokens);
806
807   // TODO: Should cache path be given in terms of our predefined paths??
808   //       Are we even going to have predefined paths??
809   CSettings::GetPath(pRootElement, "cachepath", m_cachePath);
810   URIUtils::AddSlashAtEnd(m_cachePath);
811
812   g_LangCodeExpander.LoadUserCodes(pRootElement->FirstChildElement("languagecodes"));
813
814   // trailer matching regexps
815   TiXmlElement* pTrailerMatching = pRootElement->FirstChildElement("trailermatching");
816   if (pTrailerMatching)
817     GetCustomRegexps(pTrailerMatching, m_trailerMatchRegExps);
818
819   //everything thats a trailer is not a movie
820   m_moviesExcludeFromScanRegExps.insert(m_moviesExcludeFromScanRegExps.end(),
821                                         m_trailerMatchRegExps.begin(),
822                                         m_trailerMatchRegExps.end());
823
824   // video stacking regexps
825   TiXmlElement* pVideoStacking = pRootElement->FirstChildElement("moviestacking");
826   if (pVideoStacking)
827     GetCustomRegexps(pVideoStacking, m_videoStackRegExps);
828
829   // folder stacking regexps
830   TiXmlElement* pFolderStacking = pRootElement->FirstChildElement("folderstacking");
831   if (pFolderStacking)
832     GetCustomRegexps(pFolderStacking, m_folderStackRegExps);
833
834   //tv stacking regexps
835   TiXmlElement* pTVStacking = pRootElement->FirstChildElement("tvshowmatching");
836   if (pTVStacking)
837     GetCustomTVRegexps(pTVStacking, m_tvshowEnumRegExps);
838
839   //tv multipart enumeration regexp
840   XMLUtils::GetString(pRootElement, "tvmultipartmatching", m_tvshowMultiPartEnumRegExp);
841
842   // path substitutions
843   TiXmlElement* pPathSubstitution = pRootElement->FirstChildElement("pathsubstitution");
844   if (pPathSubstitution)
845   {
846     m_pathSubstitutions.clear();
847     CLog::Log(LOGDEBUG,"Configuring path substitutions");
848     TiXmlNode* pSubstitute = pPathSubstitution->FirstChildElement("substitute");
849     while (pSubstitute)
850     {
851       CStdString strFrom, strTo;
852       TiXmlNode* pFrom = pSubstitute->FirstChild("from");
853       if (pFrom)
854         strFrom = CSpecialProtocol::TranslatePath(pFrom->FirstChild()->Value()).c_str();
855       TiXmlNode* pTo = pSubstitute->FirstChild("to");
856       if (pTo)
857         strTo = pTo->FirstChild()->Value();
858
859       if (!strFrom.IsEmpty() && !strTo.IsEmpty())
860       {
861         CLog::Log(LOGDEBUG,"  Registering substition pair:");
862         CLog::Log(LOGDEBUG,"    From: [%s]", strFrom.c_str());
863         CLog::Log(LOGDEBUG,"    To:   [%s]", strTo.c_str());
864         m_pathSubstitutions.push_back(make_pair(strFrom,strTo));
865       }
866       else
867       {
868         // error message about missing tag
869         if (strFrom.IsEmpty())
870           CLog::Log(LOGERROR,"  Missing <from> tag");
871         else
872           CLog::Log(LOGERROR,"  Missing <to> tag");
873       }
874
875       // get next one
876       pSubstitute = pSubstitute->NextSiblingElement("substitute");
877     }
878   }
879
880   XMLUtils::GetInt(pRootElement, "remotedelay", m_remoteDelay, 1, 20);
881   XMLUtils::GetFloat(pRootElement, "controllerdeadzone", m_controllerDeadzone, 0.0f, 1.0f);
882   XMLUtils::GetInt(pRootElement, "fanartres", m_fanartRes, 0, 1080);
883   XMLUtils::GetInt(pRootElement, "imageres", m_imageRes, 0, 1080);
884   XMLUtils::GetBoolean(pRootElement, "useddsfanart", m_useDDSFanart);
885
886   XMLUtils::GetBoolean(pRootElement, "playlistasfolders", m_playlistAsFolders);
887   XMLUtils::GetBoolean(pRootElement, "detectasudf", m_detectAsUdf);
888
889   // music thumbs
890   TiXmlElement* pThumbs = pRootElement->FirstChildElement("musicthumbs");
891   if (pThumbs)
892     GetCustomExtensions(pThumbs,m_musicThumbs);
893
894   // dvd thumbs
895   pThumbs = pRootElement->FirstChildElement("dvdthumbs");
896   if (pThumbs)
897     GetCustomExtensions(pThumbs,m_dvdThumbs);
898
899   // movie fanarts
900   TiXmlElement* pFanart = pRootElement->FirstChildElement("fanart");
901   if (pFanart)
902     GetCustomExtensions(pFanart,m_fanartImages);
903
904   // music filename->tag filters
905   TiXmlElement* filters = pRootElement->FirstChildElement("musicfilenamefilters");
906   if (filters)
907   {
908     TiXmlNode* filter = filters->FirstChild("filter");
909     while (filter)
910     {
911       if (filter->FirstChild())
912         m_musicTagsFromFileFilters.push_back(filter->FirstChild()->ValueStr());
913       filter = filter->NextSibling("filter");
914     }
915   }
916
917   TiXmlElement* pHostEntries = pRootElement->FirstChildElement("hosts");
918   if (pHostEntries)
919   {
920     TiXmlElement* element = pHostEntries->FirstChildElement("entry");
921     while(element)
922     {
923       CStdString name  = element->Attribute("name");
924       CStdString value;
925       if(element->GetText())
926         value = element->GetText();
927
928       if(name.length() > 0 && value.length() > 0)
929         CDNSNameCache::Add(name, value);
930       element = element->NextSiblingElement("entry");
931     }
932   }
933
934   XMLUtils::GetString(pRootElement, "cputempcommand", m_cpuTempCmd);
935   XMLUtils::GetString(pRootElement, "gputempcommand", m_gpuTempCmd);
936
937   XMLUtils::GetBoolean(pRootElement, "alwaysontop", m_alwaysOnTop);
938
939   XMLUtils::GetInt(pRootElement, "bginfoloadermaxthreads", m_bgInfoLoaderMaxThreads);
940   m_bgInfoLoaderMaxThreads = std::max(1, m_bgInfoLoaderMaxThreads);
941
942   XMLUtils::GetBoolean(pRootElement, "measurerefreshrate", m_measureRefreshrate);
943
944   TiXmlElement* pDatabase = pRootElement->FirstChildElement("videodatabase");
945   if (pDatabase)
946   {
947     CLog::Log(LOGWARNING, "VIDEO database configuration is experimental.");
948     XMLUtils::GetString(pDatabase, "type", m_databaseVideo.type);
949     XMLUtils::GetString(pDatabase, "host", m_databaseVideo.host);
950     XMLUtils::GetString(pDatabase, "port", m_databaseVideo.port);
951     XMLUtils::GetString(pDatabase, "user", m_databaseVideo.user);
952     XMLUtils::GetString(pDatabase, "pass", m_databaseVideo.pass);
953     XMLUtils::GetString(pDatabase, "name", m_databaseVideo.name);
954   }
955
956   pDatabase = pRootElement->FirstChildElement("musicdatabase");
957   if (pDatabase)
958   {
959     XMLUtils::GetString(pDatabase, "type", m_databaseMusic.type);
960     XMLUtils::GetString(pDatabase, "host", m_databaseMusic.host);
961     XMLUtils::GetString(pDatabase, "port", m_databaseMusic.port);
962     XMLUtils::GetString(pDatabase, "user", m_databaseMusic.user);
963     XMLUtils::GetString(pDatabase, "pass", m_databaseMusic.pass);
964     XMLUtils::GetString(pDatabase, "name", m_databaseMusic.name);
965   }
966
967   pElement = pRootElement->FirstChildElement("enablemultimediakeys");
968   if (pElement)
969   {
970     XMLUtils::GetBoolean(pRootElement, "enablemultimediakeys", m_enableMultimediaKeys);
971   }
972   
973   pElement = pRootElement->FirstChildElement("gui");
974   if (pElement)
975   {
976     XMLUtils::GetBoolean(pElement, "visualizedirtyregions", m_guiVisualizeDirtyRegions);
977     XMLUtils::GetInt(pElement, "algorithmdirtyregions",     m_guiAlgorithmDirtyRegions);
978     XMLUtils::GetInt(pElement, "nofliptimeout",             m_guiDirtyRegionNoFlipTimeout);
979   }
980
981   // load in the GUISettings overrides:
982   g_guiSettings.LoadXML(pRootElement, true);  // true to hide the settings we read in
983 }
984
985 void CAdvancedSettings::Clear()
986 {
987   m_videoCleanStringRegExps.clear();
988   m_moviesExcludeFromScanRegExps.clear();
989   m_tvshowExcludeFromScanRegExps.clear();
990   m_videoExcludeFromListingRegExps.clear();
991   m_videoStackRegExps.clear();
992   m_folderStackRegExps.clear();
993   m_audioExcludeFromScanRegExps.clear();
994   m_audioExcludeFromListingRegExps.clear();
995   m_pictureExcludeFromListingRegExps.clear();
996 }
997
998 void CAdvancedSettings::GetCustomTVRegexps(TiXmlElement *pRootElement, SETTINGS_TVSHOWLIST& settings)
999 {
1000   int iAction = 0; // overwrite
1001   // for backward compatibility
1002   const char* szAppend = pRootElement->Attribute("append");
1003   if ((szAppend && stricmp(szAppend, "yes") == 0))
1004     iAction = 1;
1005   // action takes precedence if both attributes exist
1006   const char* szAction = pRootElement->Attribute("action");
1007   if (szAction)
1008   {
1009     iAction = 0; // overwrite
1010     if (stricmp(szAction, "append") == 0)
1011       iAction = 1; // append
1012     else if (stricmp(szAction, "prepend") == 0)
1013       iAction = 2; // prepend
1014   }
1015   if (iAction == 0)
1016     settings.clear();
1017   TiXmlNode* pRegExp = pRootElement->FirstChild("regexp");
1018   int i = 0;
1019   while (pRegExp)
1020   {
1021     if (pRegExp->FirstChild())
1022     {
1023       bool bByDate = false;
1024       int iDefaultSeason = 1;
1025       if (pRegExp->ToElement())
1026       {
1027         CStdString byDate = pRegExp->ToElement()->Attribute("bydate");
1028         if(byDate && stricmp(byDate, "true") == 0)
1029         {
1030           bByDate = true;
1031         }
1032         CStdString defaultSeason = pRegExp->ToElement()->Attribute("defaultseason");
1033         if(!defaultSeason.empty())
1034         {
1035           iDefaultSeason = atoi(defaultSeason.c_str());
1036         }
1037       }
1038       CStdString regExp = pRegExp->FirstChild()->Value();
1039       regExp.MakeLower();
1040       if (iAction == 2)
1041         settings.insert(settings.begin() + i++, 1, TVShowRegexp(bByDate,regExp,iDefaultSeason));
1042       else
1043         settings.push_back(TVShowRegexp(bByDate,regExp,iDefaultSeason));
1044     }
1045     pRegExp = pRegExp->NextSibling("regexp");
1046   }
1047 }
1048
1049 void CAdvancedSettings::GetCustomRegexps(TiXmlElement *pRootElement, CStdStringArray& settings)
1050 {
1051   TiXmlElement *pElement = pRootElement;
1052   while (pElement)
1053   {
1054     int iAction = 0; // overwrite
1055     // for backward compatibility
1056     const char* szAppend = pElement->Attribute("append");
1057     if ((szAppend && stricmp(szAppend, "yes") == 0))
1058       iAction = 1;
1059     // action takes precedence if both attributes exist
1060     const char* szAction = pElement->Attribute("action");
1061     if (szAction)
1062     {
1063       iAction = 0; // overwrite
1064       if (stricmp(szAction, "append") == 0)
1065         iAction = 1; // append
1066       else if (stricmp(szAction, "prepend") == 0)
1067         iAction = 2; // prepend
1068     }
1069     if (iAction == 0)
1070       settings.clear();
1071     TiXmlNode* pRegExp = pElement->FirstChild("regexp");
1072     int i = 0;
1073     while (pRegExp)
1074     {
1075       if (pRegExp->FirstChild())
1076       {
1077         CStdString regExp = pRegExp->FirstChild()->Value();
1078         if (iAction == 2)
1079           settings.insert(settings.begin() + i++, 1, regExp);
1080         else
1081           settings.push_back(regExp);
1082       }
1083       pRegExp = pRegExp->NextSibling("regexp");
1084     }
1085
1086     pElement = pElement->NextSiblingElement(pRootElement->Value());
1087   }
1088 }
1089
1090 void CAdvancedSettings::GetCustomExtensions(TiXmlElement *pRootElement, CStdString& extensions)
1091 {
1092   CStdString extraExtensions;
1093   CSettings::GetString(pRootElement,"add",extraExtensions,"");
1094   if (extraExtensions != "")
1095     extensions += "|" + extraExtensions;
1096   CSettings::GetString(pRootElement,"remove",extraExtensions,"");
1097   if (extraExtensions != "")
1098   {
1099     CStdStringArray exts;
1100     StringUtils::SplitString(extraExtensions,"|",exts);
1101     for (unsigned int i=0;i<exts.size();++i)
1102     {
1103       int iPos = extensions.Find(exts[i]);
1104       if (iPos == -1)
1105         continue;
1106       extensions.erase(iPos,exts[i].size()+1);
1107     }
1108   }
1109 }
1110
1111 void CAdvancedSettings::AddSettingsFile(const CStdString &filename)
1112 {
1113   m_settingsFiles.push_back(filename);
1114 }
1115
1116 float CAdvancedSettings::GetDisplayLatency(float refreshrate)
1117 {
1118   float delay = m_videoDefaultLatency / 1000.0f;
1119   for (int i = 0; i < (int) m_videoRefreshLatency.size(); i++)
1120   {
1121     RefreshVideoLatency& videolatency = m_videoRefreshLatency[i];
1122     if (refreshrate >= videolatency.refreshmin && refreshrate <= videolatency.refreshmax)
1123       delay = videolatency.delay / 1000.0f;
1124   }
1125
1126   return delay; // in seconds
1127 }