Merge pull request #3475 from Karlson2k/http_charset_01a
authorjmarshallnz <jcmarsha@gmail.com>
Tue, 5 Nov 2013 02:10:57 +0000 (18:10 -0800)
committerjmarshallnz <jcmarsha@gmail.com>
Tue, 5 Nov 2013 02:10:57 +0000 (18:10 -0800)
Right encoding support - part 01

72 files changed:
addons/skin.confluence/720p/script-XBMC_Lyrics-main.xml
addons/xbmc.json/addon.xml
language/English/strings.po
system/settings/settings.xml
xbmc/Application.cpp
xbmc/FileItem.cpp
xbmc/GUIInfoManager.cpp
xbmc/URL.cpp
xbmc/URL.h
xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp
xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.h
xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEBuffer.cpp
xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEBuffer.h
xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResample.cpp
xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResample.h
xbmc/cores/AudioEngine/Utils/AERemap.cpp
xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp
xbmc/cores/dvdplayer/DVDFileInfo.cpp
xbmc/cores/dvdplayer/DVDPlayer.cpp
xbmc/cores/omxplayer/OMXAudio.cpp
xbmc/cores/omxplayer/OMXImage.cpp
xbmc/cores/omxplayer/OMXImage.h
xbmc/cores/omxplayer/OMXPlayer.cpp
xbmc/cores/omxplayer/OMXPlayerVideo.cpp
xbmc/cores/omxplayer/OMXPlayerVideo.h
xbmc/cores/omxplayer/PCMRemap.cpp
xbmc/cores/playercorefactory/PlayerCoreFactory.cpp
xbmc/dialogs/GUIDialogFileBrowser.cpp
xbmc/filesystem/CurlFile.cpp
xbmc/filesystem/DAVDirectory.cpp
xbmc/filesystem/Directory.cpp
xbmc/filesystem/File.cpp
xbmc/filesystem/FileCache.cpp
xbmc/filesystem/LibraryDirectory.cpp
xbmc/filesystem/SMBDirectory.cpp
xbmc/filesystem/SmbFile.cpp
xbmc/filesystem/StackDirectory.cpp
xbmc/filesystem/StackDirectory.h
xbmc/guilib/GUIIncludes.cpp
xbmc/guilib/GUIWindow.cpp
xbmc/guilib/Makefile.in
xbmc/guilib/StereoscopicsManager.cpp
xbmc/guilib/Texture.cpp
xbmc/guilib/Texture.h
xbmc/guilib/TextureGL.cpp
xbmc/guilib/TextureGL.h
xbmc/guilib/TexturePi.cpp [new file with mode: 0644]
xbmc/guilib/TexturePi.h [new file with mode: 0644]
xbmc/interfaces/json-rpc/JSONServiceDescription.cpp
xbmc/interfaces/json-rpc/ServiceDescription.h
xbmc/interfaces/json-rpc/VideoLibrary.cpp
xbmc/interfaces/json-rpc/VideoLibrary.h
xbmc/interfaces/json-rpc/methods.json
xbmc/linux/OMXCore.cpp
xbmc/linux/RBP.cpp
xbmc/linux/RBP.h
xbmc/profiles/ProfilesManager.cpp
xbmc/profiles/ProfilesManager.h
xbmc/settings/Settings.cpp
xbmc/settings/SettingsManager.cpp
xbmc/test/Makefile
xbmc/test/TestURL.cpp [new file with mode: 0644]
xbmc/utils/SaveFileStateJob.h
xbmc/utils/URIUtils.cpp
xbmc/utils/URIUtils.h
xbmc/video/VideoDatabase.cpp
xbmc/video/VideoDatabase.h
xbmc/video/VideoInfoScanner.cpp
xbmc/video/VideoThumbLoader.cpp
xbmc/video/windows/GUIWindowVideoBase.cpp
xbmc/windowing/egl/WinSystemEGL.h
xbmc/windows/GUIMediaWindow.cpp

index 6c53011..a5ea18a 100644 (file)
@@ -1,7 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <window>
        <allowoverlay>no</allowoverlay>
-       <defaultcontrol always="false">101</defaultcontrol>
        <coordinates>
                <system>1</system>
                <left>680</left>
                                <onclick>PreviousMenu</onclick>
                                <texturefocus>DialogCloseButton-focus.png</texturefocus>
                                <texturenofocus>DialogCloseButton.png</texturenofocus>
-                               <onleft>101</onleft>
-                               <onright>101</onright>
-                               <onup>101</onup>
-                               <ondown>101</ondown>
                                <visible>system.getbool(input.enablemouse)</visible>
                        </control>
                        <control type="label">
                                <height>4</height>
                                <texture>separator.png</texture>
                        </control>
-                       <!-- ** Required ** Do not change <id> or <type> (Text box for lyrics) -->
-                       <control type="textbox" id="100">
-                               <description>textarea</description>
-                               <left>30</left>
-                               <top>130</top>
-                               <width>550</width>
-                               <height>500</height>
-                               <align>center</align>
-                               <font>font13</font>
-                               <textcolor>white</textcolor>
-                               <shadowcolor>black</shadowcolor>
-                               <pagecontrol>101</pagecontrol>
-                       </control>
-                       <control type="spincontrol" id="101">
-                               <description>Next page button</description>
-                               <left>520</left>
-                               <top>650</top>
-                               <subtype>page</subtype>
-                               <font>font12</font>
-                               <onleft>101</onleft>
-                               <onright>101</onright>
-                               <ondown>101</ondown>
-                               <onup>101</onup>
-                               <textcolor>blue</textcolor>
-                               <showonepage>true</showonepage>
-                               <visible>Control.IsVisible(100)</visible>
-                       </control>
                        <!-- ** Required ** Do not change <id> or <type> (Smooth scrolling list for lyrics) -->
                        <control type="list" id="110">
                                <left>30</left>
                                <font>font13_title</font>
                                <label>31203</label>
                                <textcolor>white</textcolor>
-                               <visible>Control.IsVisible(120) + ![Control.IsVisible(100) | Control.IsVisible(110)]</visible>
+                               <visible>Control.IsVisible(120) + !Control.IsVisible(110)</visible>
                        </control>
                        <!-- ** Required ** Do not change <id> or <type> (Song Chooser if it gets it wrong) -->
                        <control type="list" id="120">
index acf3214..6886782 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<addon id="xbmc.json" version="6.11.0" provider-name="Team XBMC">
+<addon id="xbmc.json" version="6.12.0" provider-name="Team XBMC">
   <backwards-compatibility abi="6.0.0"/>
   <requires>
     <import addon="xbmc.core" version="0.1.0"/>
index bd391fc..5096061 100755 (executable)
@@ -1434,7 +1434,7 @@ msgstr ""
 
 #: system/settings/settings.xml
 msgctxt "#346"
-msgid "Boost volume level on downmix"
+msgid "Normalize levels on downmix"
 msgstr ""
 
 #: system/settings/settings.xml
@@ -14660,7 +14660,12 @@ msgctxt "#36532"
 msgid "Same as movie"
 msgstr ""
 
-#empty strings from id 36533 to 36534
+#: settings/DisplaySettings.cpp
+msgctxt "#36533"
+msgid "Select how audio is downmixed, for example from 5.1 to 2.0: [Enabled] maintains the dynamic range of the original audio source when downmixed however volume will be lower [Disabled] maintains volume level of the original audio source however the dynamic range is compressed. Note - Dynamic range is the difference between the quietest and loudest sounds in a audio source."
+msgstr ""
+
+#empty strings from id 36534 to 36534
 
 #: guilib/StereoscopicsManager.cpp
 #: xbmc/video/dialogs/GUIDialogVideoSettings.cpp
index f998480..00dce05 100644 (file)
           </dependencies>
           <control type="toggle" />
         </setting>
+        <setting id="audiooutput.normalizelevels" type="boolean" label="346" help="36533">
+          <level>2</level>
+          <default>true</default>
+        </setting>
         <setting id="audiooutput.processquality" type="integer" label="13505" help="36169">
           <requirement>HAS_AE_QUALITY_LEVELS</requirement>
           <level>2</level>
index 955df80..c78b847 100644 (file)
@@ -4895,10 +4895,13 @@ bool CApplication::OnMessage(CGUIMessage& message)
 bool CApplication::ExecuteXBMCAction(std::string actionStr)
 {
   // see if it is a user set string
-  CLog::Log(LOGDEBUG,"%s : Translating %s", __FUNCTION__, actionStr.c_str());
+
+  //We don't know if there is unsecure information in this yet, so we
+  //postpone any logging
+  const std::string in_actionStr(actionStr);
+  CLog::Log(LOGDEBUG,"%s : Translating action string", __FUNCTION__);
   CGUIInfoLabel info(actionStr, "");
   actionStr = info.GetLabel(0);
-  CLog::Log(LOGDEBUG,"%s : To %s", __FUNCTION__, actionStr.c_str());
 
   // user has asked for something to be executed
   if (CBuiltins::HasCommand(actionStr))
@@ -4925,7 +4928,12 @@ bool CApplication::ExecuteXBMCAction(std::string actionStr)
       PlayFile(item);
     }
     else
+    {
+      //At this point we have given up to translate, so even though
+      //there may be insecure information, we log it.
+      CLog::Log(LOGDEBUG,"%s : Tried translating, but failed to understand %s", __FUNCTION__, in_actionStr.c_str());
       return false;
+    }
   }
   return true;
 }
index a30c705..352c754 100644 (file)
@@ -2586,10 +2586,9 @@ bool CFileItemList::Load(int windowID)
   CFile file;
   if (file.Open(GetDiscFileCache(windowID)))
   {
-    CLog::Log(LOGDEBUG,"Loading fileitems [%s]",GetPath().c_str());
     CArchive ar(&file, CArchive::load);
     ar >> *this;
-    CLog::Log(LOGDEBUG,"  -- items: %i, directory: %s sort method: %i, ascending: %s", Size(), GetPath().c_str(), m_sortDescription.sortBy,
+    CLog::Log(LOGDEBUG,"Loading items: %i, directory: %s sort method: %i, ascending: %s", Size(), CURL::GetRedacted(GetPath()).c_str(), m_sortDescription.sortBy,
       m_sortDescription.sortOrder == SortOrderAscending ? "true" : "false");
     ar.Close();
     file.Close();
@@ -2605,7 +2604,7 @@ bool CFileItemList::Save(int windowID)
   if (iSize <= 0)
     return false;
 
-  CLog::Log(LOGDEBUG,"Saving fileitems [%s]",GetPath().c_str());
+  CLog::Log(LOGDEBUG,"Saving fileitems [%s]", CURL::GetRedacted(GetPath()).c_str());
 
   CFile file;
   if (file.OpenForWrite(GetDiscFileCache(windowID), true)) // overwrite always
index 2bdddb2..72bbd87 100644 (file)
@@ -3992,7 +3992,7 @@ void CGUIInfoManager::SetCurrentSong(CFileItem &item)
 
 void CGUIInfoManager::SetCurrentMovie(CFileItem &item)
 {
-  CLog::Log(LOGDEBUG,"CGUIInfoManager::SetCurrentMovie(%s)",item.GetPath().c_str());
+  CLog::Log(LOGDEBUG,"CGUIInfoManager::SetCurrentMovie(%s)", CURL::GetRedacted(item.GetPath()).c_str());
   *m_currentFile = item;
 
   /* also call GetMovieInfo() when a VideoInfoTag is already present or additional info won't be present in the tag */
index 20c4372..86afbc0 100644 (file)
@@ -531,33 +531,33 @@ CStdString CURL::Get() const
   strURL = GetWithoutFilename();
   strURL += m_strFileName;
 
-  if( m_strOptions.length() > 0 )
+  if( !m_strOptions.empty() )
     strURL += m_strOptions;
-  if (m_strProtocolOptions.length() > 0)
+  if (!m_strProtocolOptions.empty())
     strURL += "|"+m_strProtocolOptions;
 
   return strURL;
 }
 
-CStdString CURL::GetWithoutUserDetails() const
+std::string CURL::GetWithoutUserDetails(bool redact) const
 {
-  CStdString strURL;
+  std::string strURL;
 
   if (m_strProtocol.Equals("stack"))
   {
     CFileItemList items;
-    CStdString strURL2;
+    std::string strURL2;
     strURL2 = Get();
     XFILE::CStackDirectory dir;
     dir.GetDirectory(strURL2,items);
-    vector<CStdString> newItems;
+    vector<std::string> newItems;
     for (int i=0;i<items.Size();++i)
     {
       CURL url(items[i]->GetPath());
-      items[i]->SetPath(url.GetWithoutUserDetails());
+      items[i]->SetPath(url.GetWithoutUserDetails(redact));
       newItems.push_back(items[i]->GetPath());
     }
-    dir.ConstructStackPath(newItems,strURL);
+    dir.ConstructStackPath(newItems, strURL);
     return strURL;
   }
 
@@ -569,6 +569,9 @@ CStdString CURL::GetWithoutUserDetails() const
                         + m_strProtocolOptions.length()
                         + 10;
 
+  if (redact)
+    sizeneed += sizeof("USERNAME:PASSWORD@");
+
   strURL.reserve(sizeneed);
 
   if (m_strProtocol == "")
@@ -577,9 +580,19 @@ CStdString CURL::GetWithoutUserDetails() const
   strURL = m_strProtocol;
   strURL += "://";
 
-  if (m_strHostName != "")
+  if (redact && !m_strUserName.empty())
+  {
+    strURL += "USERNAME";
+    if (!m_strPassword.empty())
+    {
+      strURL += ":PASSWORD";
+    }
+    strURL += "@";
+  }
+
+  if (!m_strHostName.empty())
   {
-    CStdString strHostName;
+    std::string strHostName;
 
     if (URIUtils::ProtocolHasParentInHostname(m_strProtocol))
       strHostName = CURL(m_strHostName).GetWithoutUserDetails();
@@ -593,10 +606,7 @@ CStdString CURL::GetWithoutUserDetails() const
 
     if ( HasPort() )
     {
-      CStdString strPort;
-      strPort.Format("%i", m_iPort);
-      strURL += ":";
-      strURL += strPort;
+      strURL += StringUtils::Format(":%i", m_iPort);
     }
     strURL += "/";
   }
@@ -665,6 +675,16 @@ CStdString CURL::GetWithoutFilename() const
   return strURL;
 }
 
+std::string CURL::GetRedacted() const
+{
+  return GetWithoutUserDetails(true);
+}
+
+std::string CURL::GetRedacted(const std::string& path)
+{
+  return CURL(path).GetRedacted();
+}
+
 bool CURL::IsLocal() const
 {
   return (IsLocalHost() || m_strProtocol.IsEmpty());
index 30bf590..1b510b1 100644 (file)
@@ -63,8 +63,10 @@ public:
   char GetDirectorySeparator() const;
 
   CStdString Get() const;
-  CStdString GetWithoutUserDetails() const;
+  std::string GetWithoutUserDetails(bool redact = false) const;
   CStdString GetWithoutFilename() const;
+  std::string GetRedacted() const;
+  static std::string GetRedacted(const std::string& path);
   bool IsLocal() const;
   bool IsLocalHost() const;
   static bool IsFileOnly(const CStdString &url); ///< return true if there are no directories in the url.
index 6494fab..7194945 100644 (file)
@@ -1004,7 +1004,7 @@ void CActiveAE::Configure(AEAudioFormat *desiredFmt)
       {
         (*it)->m_resampleBuffers = new CActiveAEBufferPoolResample((*it)->m_inputBuffers->m_format, outputFormat, m_settings.resampleQuality);
         (*it)->m_resampleBuffers->m_changeResampler = (*it)->m_forceResampler;
-        (*it)->m_resampleBuffers->Create(MAX_CACHE_LEVEL*1000, false, m_settings.stereoupmix);
+        (*it)->m_resampleBuffers->Create(MAX_CACHE_LEVEL*1000, false, m_settings.stereoupmix, m_settings.normalizelevels);
       }
       if (m_mode == MODE_TRANSCODE || m_streams.size() > 1)
         (*it)->m_resampleBuffers->m_fillPackets = true;
@@ -1240,14 +1240,22 @@ void CActiveAE::ChangeResamplers()
   std::list<CActiveAEStream*>::iterator it;
   for(it=m_streams.begin(); it!=m_streams.end(); ++it)
   {
+    bool normalize = true;
+    if (((*it)->m_resampleBuffers->m_format.m_channelLayout.Count() <
+         (*it)->m_resampleBuffers->m_inputFormat.m_channelLayout.Count()) &&
+         !m_settings.normalizelevels)
+      normalize = false;
+
     if ((*it)->m_resampleBuffers && (*it)->m_resampleBuffers->m_resampler &&
         (((*it)->m_resampleBuffers->m_resampleQuality != m_settings.resampleQuality) ||
-        ((*it)->m_resampleBuffers->m_stereoUpmix != m_settings.stereoupmix)))
+        (((*it)->m_resampleBuffers->m_stereoUpmix != m_settings.stereoupmix)) ||
+        ((*it)->m_resampleBuffers->m_normalize != normalize)))
     {
       (*it)->m_resampleBuffers->m_changeResampler = true;
     }
     (*it)->m_resampleBuffers->m_resampleQuality = m_settings.resampleQuality;
     (*it)->m_resampleBuffers->m_stereoUpmix = m_settings.stereoupmix;
+    (*it)->m_resampleBuffers->m_normalize = normalize;
   }
 }
 
@@ -1634,8 +1642,9 @@ bool CActiveAE::RunStages()
               fadingStep = delta / samples;
             }
 
-            // for stream amplification we need to run on a per sample basis
-            if ((*it)->m_amplify != 1.0)
+            // for streams amplification of turned off downmix normalization
+            // we need to run on a per sample basis
+            if ((*it)->m_amplify != 1.0 || !(*it)->m_resampleBuffers->m_normalize)
             {
               nb_floats = out->pkt->config.channels / out->pkt->planes;
               nb_loops = out->pkt->nb_samples;
@@ -1700,8 +1709,9 @@ bool CActiveAE::RunStages()
               fadingStep = delta / samples;
             }
 
-            // for stream amplification we need to run on a per sample basis
-            if ((*it)->m_amplify != 1.0)
+            // for streams amplification of turned off downmix normalization
+            // we need to run on a per sample basis
+            if ((*it)->m_amplify != 1.0 || !(*it)->m_resampleBuffers->m_normalize)
             {
               nb_floats = out->pkt->config.channels / out->pkt->planes;
               nb_loops = out->pkt->nb_samples;
@@ -1981,6 +1991,7 @@ void CActiveAE::LoadSettings()
   m_settings.samplerate = CSettings::Get().GetInt("audiooutput.samplerate");
 
   m_settings.stereoupmix = CSettings::Get().GetBool("audiooutput.stereoupmix");
+  m_settings.normalizelevels = CSettings::Get().GetBool("audiooutput.normalizelevels");
 
   m_settings.passthrough = m_settings.config == AE_CONFIG_FIXED ? false : CSettings::Get().GetBool("audiooutput.passthrough");
   m_settings.ac3passthrough = CSettings::Get().GetBool("audiooutput.ac3passthrough");
@@ -2057,7 +2068,8 @@ void CActiveAE::OnSettingsChange(const std::string& setting)
       setting == "audiooutput.streamsilence"     ||
       setting == "audiooutput.processquality"    ||
       setting == "audiooutput.passthrough"       ||
-      setting == "audiooutput.samplerate")
+      setting == "audiooutput.samplerate"        ||
+      setting == "audiooutput.normalizelevels")
   {
     m_controlPort.SendOutMessage(CActiveAEControlProtocol::RECONFIGURE);
   }
@@ -2438,6 +2450,7 @@ bool CActiveAE::ResampleSound(CActiveAESound *sound)
                   orig_config.fmt,
                   orig_config.bits_per_sample,
                   false,
+                  true,
                   NULL,
                   AE_QUALITY_MID);
 
index 0156593..2955bb8 100644 (file)
@@ -55,6 +55,7 @@ struct AudioSettings
   bool truehdpassthrough;
   bool dtshdpassthrough;
   bool stereoupmix;
+  bool normalizelevels;
   bool passthrough;
   int config;
   unsigned int samplerate;
index e64b248..b5daee6 100644 (file)
@@ -146,6 +146,7 @@ CActiveAEBufferPoolResample::CActiveAEBufferPoolResample(AEAudioFormat inputForm
   m_resampleQuality = quality;
   m_changeResampler = false;
   m_stereoUpmix = false;
+  m_normalize = true;
 }
 
 CActiveAEBufferPoolResample::~CActiveAEBufferPoolResample()
@@ -153,10 +154,15 @@ CActiveAEBufferPoolResample::~CActiveAEBufferPoolResample()
   delete m_resampler;
 }
 
-bool CActiveAEBufferPoolResample::Create(unsigned int totaltime, bool remap, bool upmix)
+bool CActiveAEBufferPoolResample::Create(unsigned int totaltime, bool remap, bool upmix, bool normalize)
 {
   CActiveAEBufferPool::Create(totaltime);
 
+  m_stereoUpmix = upmix;
+  m_normalize = true;
+  if ((m_format.m_channelLayout.Count() < m_inputFormat.m_channelLayout.Count() && !normalize))
+    m_normalize = false;
+
   if (m_inputFormat.m_channelLayout != m_format.m_channelLayout ||
       m_inputFormat.m_sampleRate != m_format.m_sampleRate ||
       m_inputFormat.m_dataFormat != m_format.m_dataFormat ||
@@ -174,11 +180,11 @@ bool CActiveAEBufferPoolResample::Create(unsigned int totaltime, bool remap, boo
                                 CActiveAEResample::GetAVSampleFormat(m_inputFormat.m_dataFormat),
                                 CAEUtil::DataFormatToUsedBits(m_inputFormat.m_dataFormat),
                                 upmix,
+                                m_normalize,
                                 remap ? &m_format.m_channelLayout : NULL,
                                 m_resampleQuality);
   }
 
-  m_stereoUpmix = upmix;
   m_changeResampler = false;
 
   return true;
@@ -200,6 +206,7 @@ void CActiveAEBufferPoolResample::ChangeResampler()
                                 CActiveAEResample::GetAVSampleFormat(m_inputFormat.m_dataFormat),
                                 CAEUtil::DataFormatToUsedBits(m_inputFormat.m_dataFormat),
                                 m_stereoUpmix,
+                                m_normalize,
                                 NULL,
                                 m_resampleQuality);
 
index fb1b197..8475918 100644 (file)
@@ -90,7 +90,7 @@ class CActiveAEBufferPoolResample : public CActiveAEBufferPool
 public:
   CActiveAEBufferPoolResample(AEAudioFormat inputFormat, AEAudioFormat outputFormat, AEQuality quality);
   virtual ~CActiveAEBufferPoolResample();
-  virtual bool Create(unsigned int totaltime, bool remap, bool upmix);
+  virtual bool Create(unsigned int totaltime, bool remap, bool upmix, bool normalize = true);
   void ChangeResampler();
   bool ResampleBuffers(unsigned int timestamp = 0);
   float GetDelay();
@@ -108,6 +108,7 @@ public:
   double m_resampleRatio;
   AEQuality m_resampleQuality;
   bool m_stereoUpmix;
+  bool m_normalize;
 };
 
 }
index 2c5f41b..e2e4aa5 100644 (file)
@@ -36,7 +36,7 @@ CActiveAEResample::~CActiveAEResample()
   m_dllSwResample.Unload();
 }
 
-bool CActiveAEResample::Init(uint64_t dst_chan_layout, int dst_channels, int dst_rate, AVSampleFormat dst_fmt, int dst_bits, uint64_t src_chan_layout, int src_channels, int src_rate, AVSampleFormat src_fmt, int src_bits, bool upmix, CAEChannelInfo *remapLayout, AEQuality quality)
+bool CActiveAEResample::Init(uint64_t dst_chan_layout, int dst_channels, int dst_rate, AVSampleFormat dst_fmt, int dst_bits, uint64_t src_chan_layout, int src_channels, int src_rate, AVSampleFormat src_fmt, int src_bits, bool upmix, bool normalize, CAEChannelInfo *remapLayout, AEQuality quality)
 {
   if (!m_dllAvUtil.Load() || !m_dllSwResample.Load())
     return false;
@@ -86,7 +86,7 @@ bool CActiveAEResample::Init(uint64_t dst_chan_layout, int dst_channels, int dst
   // not required for sink stage (remapLayout == true)
   if ((m_dst_fmt == AV_SAMPLE_FMT_FLT || m_dst_fmt == AV_SAMPLE_FMT_FLTP) &&
       (m_src_fmt == AV_SAMPLE_FMT_FLT || m_src_fmt == AV_SAMPLE_FMT_FLTP) &&
-      !remapLayout)
+      !remapLayout && normalize)
   {
      m_dllAvUtil.av_opt_set_double(m_pContext, "rematrix_maxval", 1.0, 0);
   }
index 6fb39eb..792ff12 100644 (file)
@@ -34,7 +34,7 @@ class CActiveAEResample
 public:
   CActiveAEResample();
   virtual ~CActiveAEResample();
-  bool Init(uint64_t dst_chan_layout, int dst_channels, int dst_rate, AVSampleFormat dst_fmt, int dst_bits, uint64_t src_chan_layout, int src_channels, int src_rate, AVSampleFormat src_fmt, int src_bits, bool upmix, CAEChannelInfo *remapLayout, AEQuality quality);
+  bool Init(uint64_t dst_chan_layout, int dst_channels, int dst_rate, AVSampleFormat dst_fmt, int dst_bits, uint64_t src_chan_layout, int src_channels, int src_rate, AVSampleFormat src_fmt, int src_bits, bool upmix, bool normalize, CAEChannelInfo *remapLayout, AEQuality quality);
   int Resample(uint8_t **dst_buffer, int dst_samples, uint8_t **src_buffer, int src_samples, double ratio);
   int64_t GetDelay(int64_t base);
   int GetBufferedSamples();
index f99d52e..0f68c8d 100644 (file)
@@ -206,8 +206,7 @@ bool CAERemap::Initialize(CAEChannelInfo input, CAEChannelInfo output, bool fina
     normalize = true;
   else
   {
-    //FIXME: guisetting is reversed, change the setting name after frodo
-    normalize = !CSettings::Get().GetBool("audiooutput.normalizelevels");
+    normalize = CSettings::Get().GetBool("audiooutput.normalizelevels");
     CLog::Log(LOGDEBUG, "AERemap: Downmix normalization is %s", (normalize ? "enabled" : "disabled"));
   }
 
index fde4322..af05077 100644 (file)
@@ -308,7 +308,7 @@ bool CDVDDemuxFFmpeg::Open(CDVDInputStream* pInput)
     }
     if (result < 0 && m_dllAvFormat.avformat_open_input(&m_pFormatContext, strFile.c_str(), iformat, &options) < 0 )
     {
-      CLog::Log(LOGDEBUG, "Error, could not open file %s", strFile.c_str());
+      CLog::Log(LOGDEBUG, "Error, could not open file %s", CURL::GetRedacted(strFile).c_str());
       Dispose();
       m_dllAvUtil.av_dict_free(&options);
       return false;
@@ -353,7 +353,7 @@ bool CDVDDemuxFFmpeg::Open(CDVDInputStream* pInput)
         pd.buf_size = m_dllAvFormat.avio_read(m_ioContext, pd.buf, m_ioContext->max_packet_size ? m_ioContext->max_packet_size : m_ioContext->buffer_size);
         if (pd.buf_size <= 0)
         {
-          CLog::Log(LOGERROR, "%s - error reading from input stream, %s", __FUNCTION__, strFile.c_str());
+          CLog::Log(LOGERROR, "%s - error reading from input stream, %s", __FUNCTION__, CURL::GetRedacted(strFile).c_str());
           return false;
         }
         memset(pd.buf+pd.buf_size, 0, AVPROBE_PADDING_SIZE);
@@ -416,7 +416,7 @@ bool CDVDDemuxFFmpeg::Open(CDVDInputStream* pInput)
 
       if (!iformat)
       {
-        CLog::Log(LOGERROR, "%s - error probing input format, %s", __FUNCTION__, strFile.c_str());
+        CLog::Log(LOGERROR, "%s - error probing input format, %s", __FUNCTION__, CURL::GetRedacted(strFile).c_str());
         return false;
       }
       else
@@ -433,7 +433,7 @@ bool CDVDDemuxFFmpeg::Open(CDVDInputStream* pInput)
 
     if (m_dllAvFormat.avformat_open_input(&m_pFormatContext, strFile.c_str(), iformat, NULL) < 0)
     {
-      CLog::Log(LOGERROR, "%s - Error, could not open file %s", __FUNCTION__, strFile.c_str());
+      CLog::Log(LOGERROR, "%s - Error, could not open file %s", __FUNCTION__, CURL::GetRedacted(strFile).c_str());
       Dispose();
       return false;
     }
@@ -462,7 +462,7 @@ bool CDVDDemuxFFmpeg::Open(CDVDInputStream* pInput)
     int iErr = m_dllAvFormat.avformat_find_stream_info(m_pFormatContext, NULL);
     if (iErr < 0)
     {
-      CLog::Log(LOGWARNING,"could not find codec parameters for %s", strFile.c_str());
+      CLog::Log(LOGWARNING,"could not find codec parameters for %s", CURL::GetRedacted(strFile).c_str());
       if (m_pInput->IsStreamType(DVDSTREAM_TYPE_DVD)
       ||  m_pInput->IsStreamType(DVDSTREAM_TYPE_BLURAY)
       || (m_pFormatContext->nb_streams == 1 && m_pFormatContext->streams[0]->codec->codec_id == AV_CODEC_ID_AC3))
index c73ea36..43e5506 100644 (file)
@@ -94,24 +94,25 @@ int DegreeToOrientation(int degrees)
 
 bool CDVDFileInfo::ExtractThumb(const CStdString &strPath, CTextureDetails &details, CStreamDetails *pStreamDetails)
 {
+  std::string redactPath = CURL::GetRedacted(strPath);
   unsigned int nTime = XbmcThreads::SystemClockMillis();
   CDVDInputStream *pInputStream = CDVDFactoryInputStream::CreateInputStream(NULL, strPath, "");
   if (!pInputStream)
   {
-    CLog::Log(LOGERROR, "InputStream: Error creating stream for %s", strPath.c_str());
+    CLog::Log(LOGERROR, "InputStream: Error creating stream for %s", redactPath.c_str());
     return false;
   }
 
   if (pInputStream->IsStreamType(DVDSTREAM_TYPE_DVD))
   {
-    CLog::Log(LOGERROR, "InputStream: dvd streams not supported for thumb extraction, file: %s", strPath.c_str());
+    CLog::Log(LOGERROR, "InputStream: dvd streams not supported for thumb extraction, file: %s", redactPath.c_str());
     delete pInputStream;
     return false;
   }
 
   if (!pInputStream->Open(strPath.c_str(), ""))
   {
-    CLog::Log(LOGERROR, "InputStream: Error opening, %s", strPath.c_str());
+    CLog::Log(LOGERROR, "InputStream: Error opening, %s", redactPath.c_str());
     if (pInputStream)
       delete pInputStream;
     return false;
@@ -210,7 +211,7 @@ bool CDVDFileInfo::ExtractThumb(const CStdString &strPath, CTextureDetails &deta
       int nTotalLen = pDemuxer->GetStreamLength();
       int nSeekTo = nTotalLen / 3;
 
-      CLog::Log(LOGDEBUG,"%s - seeking to pos %dms (total: %dms) in %s", __FUNCTION__, nSeekTo, nTotalLen, strPath.c_str());
+      CLog::Log(LOGDEBUG,"%s - seeking to pos %dms (total: %dms) in %s", __FUNCTION__, nSeekTo, nTotalLen, redactPath.c_str());
       if (pDemuxer->SeekTime(nSeekTo, true))
       {
         int iDecoderState = VC_ERROR;
@@ -290,7 +291,7 @@ bool CDVDFileInfo::ExtractThumb(const CStdString &strPath, CTextureDetails &deta
         }
         else
         {
-          CLog::Log(LOGDEBUG,"%s - decode failed in %s after %d packets.", __FUNCTION__, strPath.c_str(), packetsTried);
+          CLog::Log(LOGDEBUG,"%s - decode failed in %s after %d packets.", __FUNCTION__, redactPath.c_str(), packetsTried);
         }
       }
       delete pVideoCodec;
@@ -310,7 +311,7 @@ bool CDVDFileInfo::ExtractThumb(const CStdString &strPath, CTextureDetails &deta
   }
 
   unsigned int nTotalTime = XbmcThreads::SystemClockMillis() - nTime;
-  CLog::Log(LOGDEBUG,"%s - measured %u ms to extract thumb from file <%s> in %d packets. ", __FUNCTION__, nTotalTime, strPath.c_str(), packetsTried);
+  CLog::Log(LOGDEBUG,"%s - measured %u ms to extract thumb from file <%s> in %d packets. ", __FUNCTION__, nTotalTime, redactPath.c_str(), packetsTried);
   return bOk;
 }
 
index b3205c1..ed11151 100644 (file)
@@ -445,7 +445,7 @@ bool CDVDPlayer::OpenFile(const CFileItem& file, const CPlayerOptions &options)
 {
   try
   {
-    CLog::Log(LOGNOTICE, "DVDPlayer: Opening: %s", file.GetPath().c_str());
+    CLog::Log(LOGNOTICE, "DVDPlayer: Opening: %s", CURL::GetRedacted(file.GetPath()).c_str());
 
     // if playing a file close it first
     // this has to be changed so we won't have to close it.
index a03d53b..e4d725d 100644 (file)
@@ -1087,6 +1087,10 @@ unsigned int COMXAudio::AddPackets(const void* data, unsigned int len, double dt
 
 void COMXAudio::UpdateAttenuation()
 {
+  // always called with m_critSection lock held
+  if (!m_Initialized || m_Passthrough)
+    return;
+
   if (m_amplification == 1.0)
   {
     ApplyVolume();
index 380d2cc..89e82d8 100644 (file)
 #include "settings/Settings.h"
 #include "linux/RBP.h"
 #include "utils/URIUtils.h"
+#include "windowing/WindowingFactory.h"
+#include "Application.h"
+
+#ifdef _DEBUG
+#define CheckError() m_result = eglGetError(); if (m_result != EGL_SUCCESS) CLog::Log(LOGERROR, "EGL error in %s: %x",__FUNCTION__, m_result);
+#else
+#define CheckError()
+#endif
 
 #define EXIF_TAG_ORIENTATION    0x0112
 
 #endif
 #define CLASSNAME "COMXImage"
 
+COMXImage::COMXImage()
+: CThread("CRBPWorker")
+{
+}
+
+COMXImage::~COMXImage()
+{
+  Deinitialize();
+}
+
+void COMXImage::Initialize()
+{
+  Create();
+}
+
+void COMXImage::Deinitialize()
+{
+  // wake up thread so it can quit
+  {
+    CSingleLock lock(m_texqueue_lock);
+    m_bStop = true;
+    m_texqueue_cond.notifyAll();
+  }
+  if (IsRunning())
+    StopThread();
+}
+
 bool COMXImage::CreateThumbnailFromSurface(unsigned char* buffer, unsigned int width, unsigned int height,
       unsigned int format, unsigned int pitch, const CStdString& destFile)
 {
@@ -163,6 +198,241 @@ bool COMXImage::CreateThumb(const CStdString& srcFile, unsigned int maxHeight, u
   return okay;
 }
 
+void COMXImage::AllocTextureInternal(struct textureinfo *tex)
+{
+  glGenTextures(1, (GLuint*) &tex->texture);
+  glBindTexture(GL_TEXTURE_2D, tex->texture);
+  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tex->width, tex->height, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 0);
+  tex->egl_image = eglCreateImageKHR(m_egl_display, m_egl_context, EGL_GL_TEXTURE_2D_KHR, (EGLClientBuffer)tex->texture, NULL);
+  tex->sync.Set();
+  GLint m_result;
+  CheckError();
+}
+
+void COMXImage::GetTexture(void *userdata, GLuint *texture)
+{
+  struct textureinfo *tex = static_cast<struct textureinfo *>(userdata);
+  *texture = tex->texture;
+}
+
+void COMXImage::DestroyTextureInternal(struct textureinfo *tex)
+{
+  bool s = true;
+  if (!tex->egl_image || !tex->texture)
+  {
+    CLog::Log(LOGNOTICE, "%s: Invalid image/texture %p:%d", __func__, tex->egl_image, tex->texture);
+    return;
+  }
+  s = eglDestroyImageKHR(m_egl_display, tex->egl_image);
+  if (!s)
+    CLog::Log(LOGNOTICE, "%s: failed to destroy texture", __func__);
+  glDeleteTextures(1, (GLuint*) &tex->texture);
+  tex->sync.Set();
+}
+
+void COMXImage::DestroyTexture(void *userdata)
+{
+  struct textureinfo *tex = static_cast<struct textureinfo *>(userdata);
+  // we can only call gl functions from the application thread
+
+  tex->action = TEXTURE_DELETE;
+  tex->sync.Reset();
+  if ( g_application.IsCurrentThread() )
+  {
+     DestroyTextureInternal(tex);
+  }
+  else
+  {
+    CSingleLock lock(m_texqueue_lock);
+    m_texqueue.push(tex);
+    m_texqueue_cond.notifyAll();
+  }
+  // wait for function to have finished (in texture thread)
+  tex->sync.Wait();
+  delete tex;
+}
+
+bool COMXImage::DecodeJpegToTexture(COMXImageFile *file, unsigned int width, unsigned int height, void **userdata)
+{
+  bool ret = false;
+  COMXTexture omx_image;
+
+  struct textureinfo *tex = new struct textureinfo;
+  if (!tex)
+    return NULL;
+
+  tex->parent = (void *)this;
+  tex->width = width;
+  tex->height = height;
+  tex->texture = 0;
+  tex->egl_image = NULL;
+  tex->filename = file->GetFilename();
+  tex->action = TEXTURE_ALLOC;
+  tex->sync.Reset();
+
+  {
+    CSingleLock lock(m_texqueue_lock);
+    m_texqueue.push(tex);
+    m_texqueue_cond.notifyAll();
+  }
+
+  // wait for function to have finished (in texture thread)
+  tex->sync.Wait();
+
+  if (tex->egl_image && tex->texture && omx_image.Decode(file->GetImageBuffer(), file->GetImageSize(), width, height, tex->egl_image, m_egl_display))
+  {
+    ret = true;
+    *userdata = tex;
+  }
+  else
+  {
+    CLog::Log(LOGNOTICE, "%s: unable to decode to texture %s %dx%d", __func__, file->GetFilename(), width, height);
+    DestroyTexture(tex);
+  }
+  return ret;
+}
+
+static bool ChooseConfig(EGLDisplay display, const EGLint *configAttrs, EGLConfig *config)
+{
+  EGLBoolean eglStatus = true;
+  EGLint     configCount = 0;
+  EGLConfig* configList = NULL;
+  GLint m_result;
+  // Find out how many configurations suit our needs
+  eglStatus = eglChooseConfig(display, configAttrs, NULL, 0, &configCount);
+  CheckError();
+
+  if (!eglStatus || !configCount)
+  {
+    CLog::Log(LOGERROR, "EGL failed to return any matching configurations: %i", configCount);
+    return false;
+  }
+
+  // Allocate room for the list of matching configurations
+  configList = (EGLConfig*)malloc(configCount * sizeof(EGLConfig));
+  if (!configList)
+  {
+    CLog::Log(LOGERROR, "EGL failure obtaining configuration list");
+    return false;
+  }
+
+  // Obtain the configuration list from EGL
+  eglStatus = eglChooseConfig(display, configAttrs, configList, configCount, &configCount);
+  CheckError();
+  if (!eglStatus || !configCount)
+  {
+    CLog::Log(LOGERROR, "EGL failed to populate configuration list: %d", eglStatus);
+    return false;
+  }
+
+  // Select an EGL configuration that matches the native window
+  *config = configList[0];
+
+  free(configList);
+  return true;
+}
+
+void COMXImage::CreateContext()
+{
+  EGLConfig egl_config;
+  GLint m_result;
+
+  m_egl_display = g_Windowing.GetEGLDisplay();
+  eglInitialize(m_egl_display, NULL, NULL);
+  CheckError();
+  eglBindAPI(EGL_OPENGL_ES_API);
+  CheckError();
+  static const EGLint contextAttrs [] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
+  static const EGLint configAttrs [] = {
+        EGL_RED_SIZE,        8,
+        EGL_GREEN_SIZE,      8,
+        EGL_BLUE_SIZE,       8,
+        EGL_ALPHA_SIZE,      8,
+        EGL_DEPTH_SIZE,     16,
+        EGL_STENCIL_SIZE,    0,
+        EGL_SAMPLE_BUFFERS,  0,
+        EGL_SAMPLES,         0,
+        EGL_SURFACE_TYPE,    EGL_WINDOW_BIT,
+        EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+        EGL_NONE
+  };
+  bool s = ChooseConfig(m_egl_display, configAttrs, &egl_config);
+  CheckError();
+  if (!s)
+  {
+    CLog::Log(LOGERROR, "%s: Could not find a compatible configuration",__FUNCTION__);
+    return;
+  }
+  m_egl_context = eglCreateContext(m_egl_display, egl_config, g_Windowing.GetEGLContext(), contextAttrs);
+  CheckError();
+  if (m_egl_context == EGL_NO_CONTEXT)
+  {
+    CLog::Log(LOGERROR, "%s: Could not create a context",__FUNCTION__);
+    return;
+  }
+  EGLSurface egl_surface = eglCreatePbufferSurface(m_egl_display, egl_config, NULL);
+  CheckError();
+  if (egl_surface == EGL_NO_SURFACE)
+  {
+    CLog::Log(LOGERROR, "%s: Could not create a surface",__FUNCTION__);
+    return;
+  }
+  s = eglMakeCurrent(m_egl_display, egl_surface, egl_surface, m_egl_context);
+  CheckError();
+  if (!s)
+  {
+    CLog::Log(LOGERROR, "%s: Could not make current",__FUNCTION__);
+    return;
+  }
+}
+
+void COMXImage::Process()
+{
+  bool firsttime = true;
+
+  while(!m_bStop)
+  {
+    struct textureinfo *tex = NULL;
+    while (!m_bStop)
+    {
+      CSingleLock lock(m_texqueue_lock);
+      if (!m_texqueue.empty())
+      {
+        tex = m_texqueue.front();
+        m_texqueue.pop();
+        break;
+      }
+      m_texqueue_cond.wait(lock);
+    }
+
+    if (m_bStop)
+      return;
+
+    if (firsttime)
+      CreateContext();
+    firsttime = false;
+
+    if (tex && tex->action == TEXTURE_ALLOC)
+      AllocTextureInternal(tex);
+    else if (tex && tex->action == TEXTURE_DELETE)
+      DestroyTextureInternal(tex);
+    else
+      CLog::Log(LOGERROR, "%s: Unexpected texture job: %p:%d", __func__, tex, tex ? tex->action : 0);
+  }
+}
+
+void COMXImage::OnStartup()
+{
+}
+
+void COMXImage::OnExit()
+{
+}
+
 #ifdef CLASSNAME
 #undef CLASSNAME
 #endif
@@ -1528,3 +1798,311 @@ bool COMXImageReEnc::ReEncode(COMXImageFile &srcFile, unsigned int maxWidth, uns
 
   return true;
 }
+
+
+#ifdef CLASSNAME
+#undef CLASSNAME
+#endif
+#define CLASSNAME "COMXTexture"
+
+COMXTexture::COMXTexture()
+{
+}
+
+COMXTexture::~COMXTexture()
+{
+  Close();
+}
+
+void COMXTexture::Close()
+{
+  CSingleLock lock(m_OMXSection);
+
+  if (m_omx_tunnel_decode.IsInitialized())
+    m_omx_tunnel_decode.Deestablish();
+  if (m_omx_tunnel_egl.IsInitialized())
+    m_omx_tunnel_egl.Deestablish();
+  // delete components
+  if (m_omx_decoder.IsInitialized())
+    m_omx_decoder.Deinitialize(true);
+  if (m_omx_resize.IsInitialized())
+    m_omx_resize.Deinitialize(true);
+  if (m_omx_egl_render.IsInitialized())
+    m_omx_egl_render.Deinitialize(true);
+}
+
+bool COMXTexture::HandlePortSettingChange(unsigned int resize_width, unsigned int resize_height, void *egl_image, void *egl_display, bool port_settings_changed)
+{
+  OMX_ERRORTYPE omx_err;
+
+  if (port_settings_changed)
+    CLog::Log(LOGERROR, "%s::%s Unexpected second port_settings_changed call\n", CLASSNAME, __func__);
+
+  OMX_PARAM_PORTDEFINITIONTYPE port_def;
+  OMX_INIT_STRUCTURE(port_def);
+
+  port_def.nPortIndex = m_omx_decoder.GetOutputPort();
+  omx_err = m_omx_decoder.GetParameter(OMX_IndexParamPortDefinition, &port_def);
+  if (omx_err != OMX_ErrorNone)
+  {
+    CLog::Log(LOGERROR, "%s::%s m_omx_decoder.GetParameter result(0x%x)\n", CLASSNAME, __func__, omx_err);
+    return false;
+  }
+
+  // TODO: jpeg decoder can decimate by factors of 2
+  port_def.format.image.eColorFormat = OMX_COLOR_FormatYUV420PackedPlanar;
+  port_def.format.image.nSliceHeight = 16;
+  port_def.format.image.nStride = 0;
+
+  omx_err = m_omx_decoder.SetParameter(OMX_IndexParamPortDefinition, &port_def);
+  if (omx_err != OMX_ErrorNone)
+  {
+    CLog::Log(LOGERROR, "%s::%s m_omx_decoder.SetParameter result(0x%x)\n", CLASSNAME, __func__, omx_err);
+    return false;
+  }
+
+  if (!m_omx_resize.Initialize("OMX.broadcom.resize", OMX_IndexParamImageInit))
+  {
+    CLog::Log(LOGERROR, "%s::%s error m_omx_resize.Initialize", CLASSNAME, __func__);
+    return false;
+  }
+
+  port_def.nPortIndex = m_omx_resize.GetInputPort();
+
+  omx_err = m_omx_resize.SetParameter(OMX_IndexParamPortDefinition, &port_def);
+  if (omx_err != OMX_ErrorNone)
+  {
+    CLog::Log(LOGERROR, "%s::%s m_omx_resize.SetParameter result(0x%x)\n", CLASSNAME, __func__, omx_err);
+    return false;
+  }
+
+  port_def.nPortIndex = m_omx_resize.GetOutputPort();
+  omx_err = m_omx_resize.GetParameter(OMX_IndexParamPortDefinition, &port_def);
+  if (omx_err != OMX_ErrorNone)
+  {
+    CLog::Log(LOGERROR, "%s::%s m_omx_resize.GetParameter result(0x%x)\n", CLASSNAME, __func__, omx_err);
+    return false;
+  }
+
+  port_def.format.image.eColorFormat = OMX_COLOR_FormatYUV420PackedPlanar;
+  port_def.format.image.nFrameWidth = resize_width;
+  port_def.format.image.nFrameHeight = resize_height;
+  port_def.format.image.nSliceHeight = 16;
+  port_def.format.image.nStride = 0;
+  omx_err = m_omx_resize.SetParameter(OMX_IndexParamPortDefinition, &port_def);
+  if (omx_err != OMX_ErrorNone)
+  {
+    CLog::Log(LOGERROR, "%s::%s m_omx_resize.SetParameter result(0x%x)\n", CLASSNAME, __func__, omx_err);
+    return false;
+  }
+
+  if (!m_omx_egl_render.Initialize("OMX.broadcom.egl_render", OMX_IndexParamVideoInit))
+  {
+    CLog::Log(LOGERROR, "%s::%s error m_omx_egl_render.Initialize", CLASSNAME, __func__);
+    return false;
+  }
+
+  port_def.nPortIndex = m_omx_egl_render.GetOutputPort();
+  omx_err = m_omx_egl_render.GetParameter(OMX_IndexParamPortDefinition, &port_def);
+  if (omx_err != OMX_ErrorNone)
+  {
+    CLog::Log(LOGERROR, "%s::%s m_omx_egl_render.SetParameter result(0x%x)\n", CLASSNAME, __func__, omx_err);
+    return false;
+  }
+  port_def.nBufferCountActual = 1;
+  port_def.format.video.pNativeWindow = egl_display;
+
+  omx_err = m_omx_egl_render.SetParameter(OMX_IndexParamPortDefinition, &port_def);
+  if (omx_err != OMX_ErrorNone)
+  {
+    CLog::Log(LOGERROR, "%s::%s m_omx_egl_render.SetParameter result(0x%x)\n", CLASSNAME, __func__, omx_err);
+    return false;
+  }
+
+  omx_err = m_omx_egl_render.UseEGLImage(&m_egl_buffer, m_omx_egl_render.GetOutputPort(), NULL, egl_image);
+  if (omx_err != OMX_ErrorNone)
+  {
+    CLog::Log(LOGERROR, "%s::%s error m_omx_egl_render.UseEGLImage (%x)", CLASSNAME, __func__, omx_err);
+    return false;
+  }
+
+  m_omx_tunnel_decode.Initialize(&m_omx_decoder, m_omx_decoder.GetOutputPort(), &m_omx_resize, m_omx_resize.GetInputPort());
+
+  omx_err = m_omx_tunnel_decode.Establish(false);
+  if (omx_err != OMX_ErrorNone)
+  {
+    CLog::Log(LOGERROR, "%s::%s m_omx_tunnel_decode.Establish (%x)", CLASSNAME, __func__, omx_err);
+    return false;
+  }
+
+  m_omx_tunnel_egl.Initialize(&m_omx_resize, m_omx_resize.GetOutputPort(), &m_omx_egl_render, m_omx_egl_render.GetInputPort());
+
+  omx_err = m_omx_tunnel_egl.Establish(false);
+  if (omx_err != OMX_ErrorNone)
+  {
+    CLog::Log(LOGERROR, "%s::%s m_omx_tunnel_egl.Establish (%x)", CLASSNAME, __func__, omx_err);
+    return false;
+  }
+
+  omx_err = m_omx_resize.SetStateForComponent(OMX_StateExecuting);
+  if (omx_err != OMX_ErrorNone)
+  {
+    CLog::Log(LOGERROR, "%s::%s error m_omx_egl_render.GetParameter (%x)", CLASSNAME, __func__, omx_err);
+    return false;
+  }
+
+  omx_err = m_omx_egl_render.SetStateForComponent(OMX_StateExecuting);
+  if (omx_err != OMX_ErrorNone)
+  {
+    CLog::Log(LOGERROR, "%s::%s error m_omx_egl_render.SetStateForComponent (%x)", CLASSNAME, __func__, omx_err);
+    return false;
+  }
+
+  return true;
+}
+
+bool COMXTexture::Decode(const uint8_t *demuxer_content, unsigned demuxer_bytes, unsigned int width, unsigned int height, void *egl_image, void *egl_display)
+{
+  CSingleLock lock(m_OMXSection);
+  OMX_ERRORTYPE omx_err = OMX_ErrorNone;
+
+  if (!demuxer_content || !demuxer_bytes)
+  {
+    CLog::Log(LOGERROR, "%s::%s no input buffer\n", CLASSNAME, __func__);
+    return false;
+  }
+
+  if (!m_omx_decoder.Initialize("OMX.broadcom.image_decode", OMX_IndexParamImageInit))
+  {
+    CLog::Log(LOGERROR, "%s::%s error m_omx_decoder.Initialize", CLASSNAME, __func__);
+    return false;
+  }
+
+  // set input format
+  OMX_PARAM_PORTDEFINITIONTYPE portParam;
+  OMX_INIT_STRUCTURE(portParam);
+  portParam.nPortIndex = m_omx_decoder.GetInputPort();
+
+  omx_err = m_omx_decoder.GetParameter(OMX_IndexParamPortDefinition, &portParam);
+  if (omx_err != OMX_ErrorNone)
+  {
+    CLog::Log(LOGERROR, "%s::%s error GetParameter:OMX_IndexParamPortDefinition omx_err(0x%08x)\n", CLASSNAME, __func__, omx_err);
+    return false;
+  }
+
+  portParam.nBufferCountActual = portParam.nBufferCountMin;
+  portParam.nBufferSize = std::max(portParam.nBufferSize, ALIGN_UP(demuxer_bytes, portParam.nBufferAlignment));
+  portParam.format.image.eCompressionFormat = OMX_IMAGE_CodingJPEG;
+
+  omx_err = m_omx_decoder.SetParameter(OMX_IndexParamPortDefinition, &portParam);
+  if (omx_err != OMX_ErrorNone)
+  {
+    CLog::Log(LOGERROR, "%s::%s error SetParameter:OMX_IndexParamPortDefinition omx_err(0x%08x)\n", CLASSNAME, __func__, omx_err);
+    return false;
+  }
+
+  omx_err = m_omx_decoder.AllocInputBuffers();
+  if (omx_err != OMX_ErrorNone)
+  {
+    CLog::Log(LOGERROR, "%s::%s - Error alloc buffers  (%x)", CLASSNAME, __func__, omx_err);
+    return false;
+  }
+
+  omx_err = m_omx_decoder.SetStateForComponent(OMX_StateExecuting);
+  if (omx_err != OMX_ErrorNone)
+  {
+    CLog::Log(LOGERROR, "%s::%s error m_omx_sched.SetStateForComponent (%x)", CLASSNAME, __func__, omx_err);
+    return false;
+  }
+
+  bool port_settings_changed = false;
+  bool eos = false;
+  while(demuxer_bytes > 0 || !port_settings_changed || !eos)
+  {
+    long timeout = 0;
+    if (demuxer_bytes)
+    {
+      OMX_BUFFERHEADERTYPE *omx_buffer = m_omx_decoder.GetInputBuffer(1000);
+      if (omx_buffer)
+      {
+        omx_buffer->nOffset = omx_buffer->nFlags  = 0;
+
+        omx_buffer->nFilledLen = (demuxer_bytes > omx_buffer->nAllocLen) ? omx_buffer->nAllocLen : demuxer_bytes;
+        memcpy(omx_buffer->pBuffer, demuxer_content, omx_buffer->nFilledLen);
+
+        demuxer_content += omx_buffer->nFilledLen;
+        demuxer_bytes -= omx_buffer->nFilledLen;
+
+        if (demuxer_bytes == 0)
+          omx_buffer->nFlags |= OMX_BUFFERFLAG_EOS;
+
+        omx_err = m_omx_decoder.EmptyThisBuffer(omx_buffer);
+        if (omx_err != OMX_ErrorNone)
+        {
+          CLog::Log(LOGERROR, "%s::%s - m_omx_decoder.OMX_EmptyThisBuffer (%x)", CLASSNAME, __func__, omx_err);
+          return false;
+         }
+      }
+    }
+    if (!demuxer_bytes)
+    {
+       // we've submitted all buffers so can wait now
+       timeout = 1000;
+    }
+
+    omx_err = m_omx_decoder.WaitForEvent(OMX_EventPortSettingsChanged, timeout);
+    if (omx_err == OMX_ErrorNone)
+    {
+      if (!HandlePortSettingChange(width, height, egl_image, egl_display, port_settings_changed))
+      {
+        CLog::Log(LOGERROR, "%s::%s - HandlePortSettingChange failed (%x)", CLASSNAME, __func__, omx_err);
+        return false;
+      }
+      port_settings_changed = true;
+    }
+    else if (omx_err == OMX_ErrorStreamCorrupt)
+    {
+      CLog::Log(LOGERROR, "%s::%s - image not supported", CLASSNAME, __func__);
+      return false;
+    }
+    else if (timeout || omx_err != OMX_ErrorTimeout)
+    {
+      CLog::Log(LOGERROR, "%s::%s WaitForEvent:OMX_EventPortSettingsChanged failed (%x)\n", CLASSNAME, __func__, omx_err);
+      return false;
+    }
+
+    if (port_settings_changed && m_egl_buffer && demuxer_bytes == 0 && !eos)
+    {
+      OMX_BUFFERHEADERTYPE *omx_buffer = m_omx_egl_render.GetOutputBuffer();
+      if (!omx_buffer)
+      {
+        CLog::Log(LOGERROR, "%s::%s GetOutputBuffer failed\n", CLASSNAME, __func__);
+        return false;
+      }
+      if (omx_buffer != m_egl_buffer)
+      {
+        CLog::Log(LOGERROR, "%s::%s error m_omx_egl_render.GetOutputBuffer (%p,%p)", CLASSNAME, __func__, omx_buffer, m_egl_buffer);
+        return false;
+      }
+
+      omx_err = m_omx_egl_render.FillThisBuffer(m_egl_buffer);
+      if (omx_err != OMX_ErrorNone)
+      {
+        CLog::Log(LOGERROR, "%s::%s error m_omx_egl_render.FillThisBuffer (%x)", CLASSNAME, __func__, omx_err);
+        return false;
+      }
+
+      omx_err = m_omx_egl_render.WaitForOutputDone(1000);
+      if (omx_err != OMX_ErrorNone)
+      {
+        CLog::Log(LOGERROR, "%s::%s m_omx_egl_render.WaitForOutputDone result(0x%x)\n", CLASSNAME, __func__, omx_err);
+        return false;
+      }
+      eos = true;
+    }
+  }
+  Close();
+  return true;
+}
+
+COMXImage g_OMXImage;
index 11422b1..843d8e3 100644 (file)
 #include "guilib/XBTF.h"
 #endif
 
+#include "system_gl.h"
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include "threads/Thread.h"
+
 using namespace XFILE;
 using namespace std;
 
 class COMXImageFile;
 
-class COMXImage
+class COMXImage : public CThread
 {
+enum TextureAction {TEXTURE_ALLOC, TEXTURE_DELETE };
+
+struct textureinfo {
+  TextureAction action;
+  int width, height;
+  GLuint texture;
+  EGLImageKHR egl_image;
+  void *parent;
+  const char *filename;
+  CEvent sync;
+};
+
+protected:
+  virtual void OnStartup();
+  virtual void OnExit();
+  virtual void Process();
 public:
+  COMXImage();
+  virtual ~COMXImage();
+  void Initialize();
+  void Deinitialize();
   static COMXImageFile *LoadJpeg(const CStdString& texturePath);
   static void CloseJpeg(COMXImageFile *file);
 
@@ -50,6 +75,19 @@ public:
       unsigned int format, unsigned int pitch, const CStdString& destFile);
   static bool ClampLimits(unsigned int &width, unsigned int &height, unsigned int m_width, unsigned int m_height, bool transposed = false);
   static bool CreateThumb(const CStdString& srcFile, unsigned int width, unsigned int height, std::string &additional_info, const CStdString& destFile);
+  bool DecodeJpegToTexture(COMXImageFile *file, unsigned int width, unsigned int height, void **userdata);
+  void DestroyTexture(void *userdata);
+  void GetTexture(void *userdata, GLuint *texture);
+private:
+  EGLDisplay m_egl_display;
+  EGLContext m_egl_context;
+
+  void CreateContext();
+  CCriticalSection               m_texqueue_lock;
+  XbmcThreads::ConditionVariable m_texqueue_cond;
+  std::queue <struct textureinfo *> m_texqueue;
+  void AllocTextureInternal(struct textureinfo *tex);
+  void DestroyTextureInternal(struct textureinfo *tex);
 };
 
 class COMXImageFile
@@ -138,4 +176,29 @@ protected:
   unsigned int                  m_nDestAllocSize;
 };
 
+class COMXTexture
+{
+public:
+  COMXTexture();
+  virtual ~COMXTexture();
+
+  // Required overrides
+  void Close(void);
+  bool Decode(const uint8_t *data, unsigned size, unsigned int width, unsigned int height, void *egl_image, void *egl_display);
+protected:
+  bool HandlePortSettingChange(unsigned int resize_width, unsigned int resize_height, void *egl_image, void *egl_display, bool port_settings_changed);
+
+  // Components
+  COMXCoreComponent m_omx_decoder;
+  COMXCoreComponent m_omx_resize;
+  COMXCoreComponent m_omx_egl_render;
+
+  COMXCoreTunel     m_omx_tunnel_decode;
+  COMXCoreTunel     m_omx_tunnel_egl;
+
+  OMX_BUFFERHEADERTYPE *m_egl_buffer;
+  CCriticalSection              m_OMXSection;
+};
+
+extern COMXImage g_OMXImage;
 #endif
index 56099fe..a149070 100644 (file)
@@ -517,7 +517,7 @@ bool COMXPlayer::OpenFile(const CFileItem &file, const CPlayerOptions &options)
 #endif
 
     Create();
-    if(!m_ready.WaitMSec(100))
+    if(!m_ready.WaitMSec(g_advancedSettings.m_videoBusyDialogDelay_ms))
     {
       CGUIDialogBusy* dialog = (CGUIDialogBusy*)g_windowManager.GetWindow(WINDOW_DIALOG_BUSY);
       if(dialog)
@@ -546,9 +546,6 @@ bool COMXPlayer::CloseFile()
 {
   CLog::Log(LOGDEBUG, "COMXPlayer::CloseFile");
 
-  // unpause the player
-  SetPlaySpeed(DVD_PLAYSPEED_NORMAL);
-
   // set the abort request so that other threads can finish up
   m_bAbortRequest = true;
 
@@ -814,10 +811,9 @@ bool COMXPlayer::ReadPacket(DemuxPacket*& packet, CDemuxStream*& stream)
 {
 
   // check if we should read from subtitle demuxer
-  if(m_dvdPlayerSubtitle.AcceptsData() &&  m_pSubtitleDemuxer)
+  if( m_pSubtitleDemuxer && m_dvdPlayerSubtitle.AcceptsData() )
   {
-    if(m_pSubtitleDemuxer)
-      packet = m_pSubtitleDemuxer->Read();
+    packet = m_pSubtitleDemuxer->Read();
 
     if(packet)
     {
@@ -2970,6 +2966,7 @@ void COMXPlayer::GetSubtitleStreamInfo(int index, SPlayerSubtitleStreamInfo &inf
 
 void COMXPlayer::SetSubtitle(int iStream)
 {
+  CMediaSettings::Get().GetCurrentVideoSettings().m_SubtitleStream = iStream;
   m_messenger.Put(new CDVDMsgPlayerSetSubtitleStream(iStream));
 }
 
@@ -3007,6 +3004,7 @@ int COMXPlayer::GetAudioStream()
 
 void COMXPlayer::SetAudioStream(int iStream)
 {
+  CMediaSettings::Get().GetCurrentVideoSettings().m_AudioStream = iStream;
   m_messenger.Put(new CDVDMsgPlayerSetAudioStream(iStream));
   SynchronizeDemuxer(100);
 }
@@ -3135,7 +3133,7 @@ bool COMXPlayer::OpenAudioStream(int iStream, int source, bool reset)
 
   /* software decoding normaly consumes full cpu time so prio it */
   m_omxPlayerAudio.SetPriority(GetPriority()+1);
-
+  CMediaSettings::Get().GetCurrentVideoSettings().m_AudioStream =  m_SelectionStreams.IndexOf(STREAM_AUDIO, source, iStream);
   return true;
 }
 
@@ -3324,6 +3322,7 @@ bool COMXPlayer::OpenSubtitleStream(int iStream, int source)
   m_CurrentSubtitle.stream = (void*)pStream;
   m_CurrentSubtitle.started = false;
 
+  CMediaSettings::Get().GetCurrentVideoSettings().m_SubtitleStream = m_SelectionStreams.IndexOf(STREAM_SUBTITLE, source, iStream);
   return true;
 }
 
@@ -3591,10 +3590,10 @@ int COMXPlayer::OnDVDNavResult(void* pData, int iMessage)
           m_dvd.iDVDStillStartTime = XbmcThreads::SystemClockMillis();
 
           /* adjust for the output delay in the video queue */
-          DWORD time = 0;
+          unsigned int time = 0;
           if( m_CurrentVideo.stream && m_dvd.iDVDStillTime > 0 )
           {
-            time = (DWORD)(m_omxPlayerVideo.GetOutputDelay() / ( DVD_TIME_BASE / 1000 ));
+            time = (unsigned int)(m_omxPlayerVideo.GetOutputDelay() / ( DVD_TIME_BASE / 1000 ));
             if( time < 10000 && time > 0 )
               m_dvd.iDVDStillTime += time;
           }
@@ -3608,7 +3607,7 @@ int COMXPlayer::OnDVDNavResult(void* pData, int iMessage)
       break;
     case DVDNAV_SPU_CLUT_CHANGE:
       {
-        m_dvdPlayerSubtitle.SendMessage(new CDVDMsgSubtitleClutChange((BYTE*)pData));
+        m_dvdPlayerSubtitle.SendMessage(new CDVDMsgSubtitleClutChange((uint8_t*)pData));
       }
       break;
     case DVDNAV_SPU_STREAM_CHANGE:
@@ -3797,6 +3796,11 @@ bool COMXPlayer::OnAction(const CAction &action)
         THREAD_ACTION(action);
         CLog::Log(LOGDEBUG, " - go to menu");
         pMenus->OnMenu();
+        if (m_playSpeed == DVD_PLAYSPEED_PAUSE)
+        {
+          SetPlaySpeed(DVD_PLAYSPEED_NORMAL);
+          m_callback.OnPlayBackResumed();
+        }
         // send a message to everyone that we've gone to the menu
         CGUIMessage msg(GUI_MSG_VIDEO_MENU_STARTED, 0, 0);
         g_windowManager.SendThreadMessage(msg);
@@ -3999,9 +4003,9 @@ bool COMXPlayer::HasMenu()
 
 bool COMXPlayer::GetCurrentSubtitle(CStdString& strSubtitle)
 {
-  double pts = m_clock.GetClock();
+  double pts = m_clock.GetClock() + m_State.time_offset;
 
-  if (m_pInputStream && m_pInputStream->IsStreamType(DVDSTREAM_TYPE_DVD))
+  if (m_pInputStream && m_pInputStream->IsStreamType(DVDSTREAM_TYPE_DVD) && m_CurrentSubtitle.source != STREAM_SOURCE_TEXT && m_CurrentSubtitle.source != STREAM_SOURCE_DEMUX_SUB)
     return false;
 
   m_dvdPlayerSubtitle.GetCurrentSubtitle(strSubtitle, pts - m_omxPlayerVideo.GetSubtitleDelay());
@@ -4075,8 +4079,8 @@ int COMXPlayer::GetCacheLevel() const
 
 double COMXPlayer::GetQueueTime()
 {
-  int a = m_omxPlayerVideo.GetLevel();
-  int v = m_omxPlayerAudio.GetLevel();
+  int a = m_omxPlayerAudio.GetLevel();
+  int v = m_omxPlayerVideo.GetLevel();
   return max(a, v) * 8000.0 / 100;
 }
 
@@ -4090,10 +4094,9 @@ void COMXPlayer::GetVideoStreamInfo(SPlayerVideoStreamInfo &info)
   info.videoCodecName = retVal;
   info.videoAspectRatio = g_renderManager.GetAspectRatio();
   g_renderManager.GetVideoRect(info.SrcRect, info.DestRect);
-  if (m_CurrentVideo.hint.stereo_mode == "mono")
+  info.stereoMode = m_omxPlayerVideo.GetStereoMode();
+  if (info.stereoMode == "mono")
     info.stereoMode = "";
-  else
-    info.stereoMode = m_CurrentVideo.hint.stereo_mode;
 }
 
 int COMXPlayer::GetSourceBitrate()
@@ -4153,6 +4156,17 @@ int COMXPlayer::AddSubtitleFile(const std::string& filename, const std::string&
     int index = m_SelectionStreams.IndexOf(STREAM_SUBTITLE, m_SelectionStreams.Source(STREAM_SOURCE_DEMUX_SUB, filename), 0);
     m_SelectionStreams.Get(STREAM_SUBTITLE, index).flags = flags;
     m_SelectionStreams.Get(STREAM_SUBTITLE, index).filename2 = vobsubfile;
+    ExternalStreamInfo info;
+    CUtil::GetExternalStreamDetailsFromFilename(m_filename, vobsubfile, info);
+    m_SelectionStreams.Get(STREAM_SUBTITLE, index).name = info.name;
+    if (m_SelectionStreams.Get(STREAM_SUBTITLE, index).language.empty())
+      m_SelectionStreams.Get(STREAM_SUBTITLE, index).language = info.language;
+
+    if (static_cast<CDemuxStream::EFlags>(info.flag) == CDemuxStream::FLAG_NONE)
+      m_SelectionStreams.Get(STREAM_SUBTITLE, index).flags = flags;
+    else
+      m_SelectionStreams.Get(STREAM_SUBTITLE, index).flags = static_cast<CDemuxStream::EFlags>(info.flag);
+
     return index;
   }
   if(ext == ".sub")
@@ -4166,8 +4180,15 @@ int COMXPlayer::AddSubtitleFile(const std::string& filename, const std::string&
   s.type     = STREAM_SUBTITLE;
   s.id       = 0;
   s.filename = filename;
-  s.name     = URIUtils::GetFileName(filename);
-  s.flags    = flags;
+  ExternalStreamInfo info;
+  CUtil::GetExternalStreamDetailsFromFilename(m_filename, filename, info);
+  s.name = info.name;
+  s.language = info.language;
+  if (static_cast<CDemuxStream::EFlags>(info.flag) == CDemuxStream::FLAG_NONE)
+    s .flags = flags;
+  else
+    s.flags = static_cast<CDemuxStream::EFlags>(info.flag);
+
   m_SelectionStreams.Update(s);
   return m_SelectionStreams.IndexOf(STREAM_SUBTITLE, s.source, s.id);
 }
@@ -4371,7 +4392,19 @@ bool COMXPlayer::GetStreamDetails(CStreamDetails &details)
 {
   if (m_pDemuxer)
   {
-    bool result = CDVDFileInfo::DemuxerToStreamDetails(m_pInputStream, m_pDemuxer, details);
+    std::vector<OMXSelectionStream> subs = m_SelectionStreams.Get(STREAM_SUBTITLE);
+    std::vector<CStreamDetailSubtitle> extSubDetails;
+    for (unsigned int i = 0; i < subs.size(); i++)
+    {
+      if (subs[i].filename == m_filename)
+        continue;
+
+      CStreamDetailSubtitle p;
+      p.m_strLanguage = subs[i].language;
+      extSubDetails.push_back(p);
+    }
+
+    bool result = CDVDFileInfo::DemuxerToStreamDetails(m_pInputStream, m_pDemuxer, extSubDetails, details);
     if (result && details.GetStreamCount(CStreamDetail::VIDEO) > 0) // this is more correct (dvds in particular)
     {
       /* 
index 7601bc7..4421e04 100644 (file)
@@ -259,6 +259,22 @@ void OMXPlayerVideo::ProcessOverlays(double pts)
   }
 }
 
+std::string OMXPlayerVideo::GetStereoMode()
+{
+  std::string  stereo_mode;
+
+  switch(CMediaSettings::Get().GetCurrentVideoSettings().m_StereoMode)
+  {
+    case RENDER_STEREO_MODE_SPLIT_VERTICAL:   stereo_mode = "left_right"; break;
+    case RENDER_STEREO_MODE_SPLIT_HORIZONTAL: stereo_mode = "top_bottom"; break;
+    default:                                  stereo_mode = m_hints.stereo_mode; break;
+  }
+
+  if(CMediaSettings::Get().GetCurrentVideoSettings().m_StereoInvert)
+    stereo_mode = GetStereoModeInvert(stereo_mode);
+  return stereo_mode;
+}
+
 void OMXPlayerVideo::Output(double pts, bool bDropPacket)
 {
   if (!g_renderManager.IsStarted()) {
index fafc258..2b3c831 100644 (file)
@@ -113,6 +113,7 @@ public:
   void SetSpeed(int iSpeed);
   std::string GetPlayerInfo();
   int GetVideoBitrate();
+  std::string GetStereoMode();
   double GetOutputDelay();
   double GetSubtitleDelay()                         { return m_iSubtitleDelay; }
   void SetSubtitleDelay(double delay)               { m_iSubtitleDelay = delay; }
index c0733c6..c643175 100644 (file)
@@ -364,7 +364,7 @@ void CPCMRemap::BuildMap()
   m_outStride = m_inSampleSize * m_outChannels;
 
   /* see if we need to normalize the levels */
-  bool dontnormalize = CSettings::Get().GetBool("audiooutput.normalizelevels");
+  bool dontnormalize = !CSettings::Get().GetBool("audiooutput.normalizelevels");
   CLog::Log(LOGDEBUG, "CPCMRemap: Downmix normalization is %s", (dontnormalize ? "disabled" : "enabled"));
 
   ResolveChannels();
index 16319b9..61a4b3e 100644 (file)
@@ -163,7 +163,7 @@ void CPlayerCoreFactory::GetPlayers( const CFileItem& item, VECPLAYERCORES &vecC
 {
   CURL url(item.GetPath());
 
-  CLog::Log(LOGDEBUG, "CPlayerCoreFactory::GetPlayers(%s)", item.GetPath().c_str());
+  CLog::Log(LOGDEBUG, "CPlayerCoreFactory::GetPlayers(%s)", CURL::GetRedacted(item.GetPath()).c_str());
 
   // Process rules
   for(unsigned int i = 0; i < m_vecCoreSelectionRules.size(); i++)
index fc45250..7ee0bed 100644 (file)
@@ -362,7 +362,7 @@ void CGUIDialogFileBrowser::Update(const CStdString &strDirectory)
 
     if (!m_rootDir.GetDirectory(strDirectory, items,m_useFileDirectories))
     {
-      CLog::Log(LOGERROR,"CGUIDialogFileBrowser::GetDirectory(%s) failed", strDirectory.c_str());
+      CLog::Log(LOGERROR,"CGUIDialogFileBrowser::GetDirectory(%s) failed", CURL::GetRedacted(strDirectory).c_str());
 
       // We assume, we can get the parent
       // directory again
index b7f1a34..500b54c 100644 (file)
@@ -662,7 +662,7 @@ void CCurlFile::ParseAndCorrectUrl(CURL &url2)
     // we was using url optons for urls, keep the old code work and warning
     if (!url2.GetOptions().IsEmpty())
     {
-      CLog::Log(LOGWARNING, "%s: ftp url option is deprecated, please switch to use protocol option (change '?' to '|'), url: [%s]", __FUNCTION__, url2.Get().c_str());
+      CLog::Log(LOGWARNING, "%s: ftp url option is deprecated, please switch to use protocol option (change '?' to '|'), url: [%s]", __FUNCTION__, url2.GetRedacted().c_str());
       url2.SetProtocolOptions(url2.GetOptions().Mid(1));
       /* ftp has no options */
       url2.SetOptions("");
@@ -888,7 +888,8 @@ bool CCurlFile::Open(const CURL& url)
   CURL url2(url);
   ParseAndCorrectUrl(url2);
 
-  CLog::Log(LOGDEBUG, "CurlFile::Open(%p) %s", (void*)this, m_url.c_str());
+  std::string redactPath = CURL::GetRedacted(m_url);
+  CLog::Log(LOGDEBUG, "CurlFile::Open(%p) %s", (void*)this, redactPath.c_str());
 
   ASSERT(!(!m_state->m_easyHandle ^ !m_state->m_multiHandle));
   if( m_state->m_easyHandle == NULL )
@@ -917,7 +918,7 @@ bool CCurlFile::Open(const CURL& url)
      || !m_state->m_httpheader.GetValue("icy-name").empty()
      || !m_state->m_httpheader.GetValue("icy-br").empty()) && !m_skipshout)
   {
-    CLog::Log(LOGDEBUG,"CCurlFile::Open - File <%s> is a shoutcast stream. Re-opening", m_url.c_str());
+    CLog::Log(LOGDEBUG,"CCurlFile::Open - File <%s> is a shoutcast stream. Re-opening", redactPath.c_str());
     throw new CRedirectException(new CShoutcastFile);
   }
 
@@ -966,7 +967,7 @@ bool CCurlFile::OpenForWrite(const CURL& url, bool bOverWrite)
   CURL url2(url);
   ParseAndCorrectUrl(url2);
 
-  CLog::Log(LOGDEBUG, "CCurlFile::OpenForWrite(%p) %s", (void*)this, m_url.c_str());
+  CLog::Log(LOGDEBUG, "CCurlFile::OpenForWrite(%p) %s", (void*)this, CURL::GetRedacted(m_url).c_str());
 
   ASSERT(m_state->m_easyHandle == NULL);
   g_curlInterface.easy_aquire(url2.GetProtocol(), url2.GetHostName(), &m_state->m_easyHandle, &m_state->m_multiHandle);
@@ -1021,7 +1022,7 @@ int CCurlFile::Write(const void* lpBuf, int64_t uiBufSize)
     {
       long code;
       if(g_curlInterface.easy_getinfo(m_state->m_easyHandle, CURLINFO_RESPONSE_CODE, &code) == CURLE_OK )
-        CLog::Log(LOGERROR, "%s - Unable to write curl resource (%s) - %ld", __FUNCTION__, m_url.c_str(), code);
+        CLog::Log(LOGERROR, "%s - Unable to write curl resource (%s) - %ld", __FUNCTION__, CURL::GetRedacted(m_url).c_str(), code);
       m_inError = true;
       return -1;
     }
@@ -1068,7 +1069,7 @@ bool CCurlFile::Exists(const CURL& url)
   // if file is already running, get info from it
   if( m_opened )
   {
-    CLog::Log(LOGWARNING, "CCurlFile::Exists - Exist called on open file %s", url.Get().c_str());
+    CLog::Log(LOGWARNING, "CCurlFile::Exists - Exist called on open file %s", url.GetRedacted().c_str());
     return true;
   }
 
@@ -1104,11 +1105,11 @@ bool CCurlFile::Exists(const CURL& url)
   {
     long code;
     if(g_curlInterface.easy_getinfo(m_state->m_easyHandle, CURLINFO_RESPONSE_CODE, &code) == CURLE_OK && code != 404 )
-      CLog::Log(LOGERROR, "CCurlFile::Exists - Failed: HTTP returned error %ld for %s", code, url.Get().c_str());
+      CLog::Log(LOGERROR, "CCurlFile::Exists - Failed: HTTP returned error %ld for %s", code, url.GetRedacted().c_str());
   }
   else if (result != CURLE_REMOTE_FILE_NOT_FOUND && result != CURLE_FTP_COULDNT_RETR_FILE)
   {
-    CLog::Log(LOGERROR, "CCurlFile::Exists - Failed: %s(%d) for %s", g_curlInterface.easy_strerror(result), result, url.Get().c_str());
+    CLog::Log(LOGERROR, "CCurlFile::Exists - Failed: %s(%d) for %s", g_curlInterface.easy_strerror(result), result, url.GetRedacted().c_str());
   }
 
   errno = ENOENT;
@@ -1213,7 +1214,7 @@ int CCurlFile::Stat(const CURL& url, struct __stat64* buffer)
   // if file is already running, get info from it
   if( m_opened )
   {
-    CLog::Log(LOGWARNING, "CCurlFile::Stat - Stat called on open file %s", url.Get().c_str());
+    CLog::Log(LOGWARNING, "CCurlFile::Stat - Stat called on open file %s", url.GetRedacted().c_str());
     if (buffer)
     {
       memset(buffer, 0, sizeof(struct __stat64));
@@ -1281,7 +1282,7 @@ int CCurlFile::Stat(const CURL& url, struct __stat64* buffer)
   {
     g_curlInterface.easy_release(&m_state->m_easyHandle, NULL);
     errno = ENOENT;
-    CLog::Log(LOGERROR, "CCurlFile::Stat - Failed: %s(%d) for %s", g_curlInterface.easy_strerror(result), result, url.Get().c_str());
+    CLog::Log(LOGERROR, "CCurlFile::Stat - Failed: %s(%d) for %s", g_curlInterface.easy_strerror(result), result, url.GetRedacted().c_str());
     return -1;
   }
 
@@ -1292,7 +1293,7 @@ int CCurlFile::Stat(const CURL& url, struct __stat64* buffer)
     if (url.GetProtocol() == "ftp")
     {
       g_curlInterface.easy_release(&m_state->m_easyHandle, NULL);
-      CLog::Log(LOGNOTICE, "CCurlFile::Stat - Content length failed: %s(%d) for %s", g_curlInterface.easy_strerror(result), result, url.Get().c_str());
+      CLog::Log(LOGNOTICE, "CCurlFile::Stat - Content length failed: %s(%d) for %s", g_curlInterface.easy_strerror(result), result, url.GetRedacted().c_str());
       errno = ENOENT;
       return -1;
     }
@@ -1308,7 +1309,7 @@ int CCurlFile::Stat(const CURL& url, struct __stat64* buffer)
     result = g_curlInterface.easy_getinfo(m_state->m_easyHandle, CURLINFO_CONTENT_TYPE, &content);
     if (result != CURLE_OK)
     {
-      CLog::Log(LOGNOTICE, "CCurlFile::Stat - Content type failed: %s(%d) for %s", g_curlInterface.easy_strerror(result), result, url.Get().c_str());
+      CLog::Log(LOGNOTICE, "CCurlFile::Stat - Content type failed: %s(%d) for %s", g_curlInterface.easy_strerror(result), result, url.GetRedacted().c_str());
       g_curlInterface.easy_release(&m_state->m_easyHandle, NULL);
       errno = ENOENT;
       return -1;
@@ -1326,7 +1327,7 @@ int CCurlFile::Stat(const CURL& url, struct __stat64* buffer)
     result = g_curlInterface.easy_getinfo(m_state->m_easyHandle, CURLINFO_FILETIME, &filetime);
     if (result != CURLE_OK)
     {
-      CLog::Log(LOGNOTICE, "CCurlFile::Stat - Filetime failed: %s(%d) for %s", g_curlInterface.easy_strerror(result), result, url.Get().c_str());
+      CLog::Log(LOGNOTICE, "CCurlFile::Stat - Filetime failed: %s(%d) for %s", g_curlInterface.easy_strerror(result), result, url.GetRedacted().c_str());
     }
     else
     {
@@ -1573,7 +1574,7 @@ bool CCurlFile::GetHttpHeader(const CURL &url, CHttpHeader &headers)
   }
   catch(...)
   {
-    CLog::Log(LOGERROR, "%s - Exception thrown while trying to retrieve header url: %s", __FUNCTION__, url.Get().c_str());
+    CLog::Log(LOGERROR, "%s - Exception thrown while trying to retrieve header url: %s", __FUNCTION__, url.GetRedacted().c_str());
     return false;
   }
 }
@@ -1585,16 +1586,17 @@ bool CCurlFile::GetMimeType(const CURL &url, CStdString &content, CStdString use
     file.SetUserAgent(useragent);
 
   struct __stat64 buffer;
+  std::string redactUrl = url.GetRedacted();
   if( file.Stat(url, &buffer) == 0 )
   {
     if (buffer.st_mode == _S_IFDIR)
       content = "x-directory/normal";
     else
       content = file.GetMimeType();
-    CLog::Log(LOGDEBUG, "CCurlFile::GetMimeType - %s -> %s", url.Get().c_str(), content.c_str());
+    CLog::Log(LOGDEBUG, "CCurlFile::GetMimeType - %s -> %s", redactUrl.c_str(), content.c_str());
     return true;
   }
-  CLog::Log(LOGDEBUG, "CCurlFile::GetMimeType - %s -> failed", url.Get().c_str());
+  CLog::Log(LOGDEBUG, "CCurlFile::GetMimeType - %s -> failed", redactUrl.c_str());
   content = "";
   return false;
 }
index 9165a1c..07917dc 100644 (file)
@@ -132,7 +132,7 @@ bool CDAVDirectory::GetDirectory(const CStdString& strPath, CFileItemList &items
 
   if (!dav.Open(url))
   {
-    CLog::Log(LOGERROR, "%s - Unable to get dav directory (%s)", __FUNCTION__, strPath.c_str());
+    CLog::Log(LOGERROR, "%s - Unable to get dav directory (%s)", __FUNCTION__, CURL::GetRedacted(strPath).c_str());
     return false;
   }
 
@@ -144,7 +144,7 @@ bool CDAVDirectory::GetDirectory(const CStdString& strPath, CFileItemList &items
 
   if (!davResponse.Parse(strResponse))
   {
-    CLog::Log(LOGERROR, "%s - Unable to process dav directory (%s)", __FUNCTION__, strPath.c_str());
+    CLog::Log(LOGERROR, "%s - Unable to process dav directory (%s)", __FUNCTION__, CURL::GetRedacted(strPath).c_str());
     dav.Close();
     return false;
   }
@@ -201,7 +201,7 @@ bool CDAVDirectory::Create(const char* strPath)
  
   if (!dav.Execute(url))
   {
-    CLog::Log(LOGERROR, "%s - Unable to create dav directory (%s) - %d", __FUNCTION__, url.Get().c_str(), dav.GetLastResponseCode());
+    CLog::Log(LOGERROR, "%s - Unable to create dav directory (%s) - %d", __FUNCTION__, url.GetRedacted().c_str(), dav.GetLastResponseCode());
     return false;
   }
 
@@ -234,7 +234,7 @@ bool CDAVDirectory::Remove(const char* strPath)
  
   if (!dav.Execute(url))
   {
-    CLog::Log(LOGERROR, "%s - Unable to delete dav directory (%s) - %d", __FUNCTION__, url.Get().c_str(), dav.GetLastResponseCode());
+    CLog::Log(LOGERROR, "%s - Unable to delete dav directory (%s) - %d", __FUNCTION__, url.GetRedacted().c_str(), dav.GetLastResponseCode());
     return false;
   }
 
index af7074d..3a2b5c7 100644 (file)
@@ -33,6 +33,7 @@
 #include "dialogs/GUIDialogBusy.h"
 #include "threads/SingleLock.h"
 #include "utils/URIUtils.h"
+#include "URL.h"
 
 using namespace std;
 using namespace XFILE;
@@ -191,7 +192,7 @@ bool CDirectory::GetDirectory(const CStdString& strPath, CFileItemList &items, c
         {
           if (!cancel && g_application.IsCurrentThread() && pDirectory->ProcessRequirements())
             continue;
-          CLog::Log(LOGERROR, "%s - Error getting %s", __FUNCTION__, strPath.c_str());
+          CLog::Log(LOGERROR, "%s - Error getting %s", __FUNCTION__, CURL::GetRedacted(strPath).c_str());
           return false;
         }
       }
@@ -228,7 +229,7 @@ bool CDirectory::GetDirectory(const CStdString& strPath, CFileItemList &items, c
   {
     CLog::Log(LOGERROR, "%s - Unhandled exception", __FUNCTION__);
   }
-  CLog::Log(LOGERROR, "%s - Error getting %s", __FUNCTION__, strPath.c_str());
+  CLog::Log(LOGERROR, "%s - Error getting %s", __FUNCTION__, CURL::GetRedacted(strPath).c_str());
   return false;
 }
 
@@ -247,7 +248,7 @@ bool CDirectory::Create(const CStdString& strPath)
   {
     CLog::Log(LOGERROR, "%s - Unhandled exception", __FUNCTION__);
   }
-  CLog::Log(LOGERROR, "%s - Error creating %s", __FUNCTION__, strPath.c_str());
+  CLog::Log(LOGERROR, "%s - Error creating %s", __FUNCTION__, CURL::GetRedacted(strPath).c_str());
   return false;
 }
 
@@ -274,7 +275,7 @@ bool CDirectory::Exists(const CStdString& strPath, bool bUseCache /* = true */)
   {
     CLog::Log(LOGERROR, "%s - Unhandled exception", __FUNCTION__);
   }
-  CLog::Log(LOGERROR, "%s - Error checking for %s", __FUNCTION__, strPath.c_str());
+  CLog::Log(LOGERROR, "%s - Error checking for %s", __FUNCTION__, CURL::GetRedacted(strPath).c_str());
   return false;
 }
 
@@ -296,7 +297,7 @@ bool CDirectory::Remove(const CStdString& strPath)
   {
     CLog::Log(LOGERROR, "%s - Unhandled exception", __FUNCTION__);
   }
-  CLog::Log(LOGERROR, "%s - Error removing %s", __FUNCTION__, strPath.c_str());
+  CLog::Log(LOGERROR, "%s - Error removing %s", __FUNCTION__, CURL::GetRedacted(strPath).c_str());
   return false;
 }
 
index 357b8db..0973657 100644 (file)
@@ -402,6 +402,16 @@ bool CFile::Exists(const CStdString& strFileName, bool bUseCache /* = true */)
 
 int CFile::Stat(struct __stat64 *buffer)
 {
+  if (!buffer)
+    return -1;
+
+  if (!m_pFile)
+  {
+    memset(buffer, 0, sizeof(struct __stat64));
+    errno = ENOENT;
+    return -1;
+  }
+
   return m_pFile->Stat(buffer);
 }
 
@@ -414,6 +424,9 @@ bool CFile::SkipNext()
 
 int CFile::Stat(const CStdString& strFileName, struct __stat64* buffer)
 {
+  if (!buffer)
+    return -1;
+
   CURL url;
   
   try
@@ -463,7 +476,7 @@ int CFile::Stat(const CStdString& strFileName, struct __stat64* buffer)
 
 unsigned int CFile::Read(void *lpBuf, int64_t uiBufSize)
 {
-  if (!m_pFile)
+  if (!m_pFile || !lpBuf)
     return 0;
 
   if(m_pBuffer)
@@ -641,7 +654,7 @@ int64_t CFile::GetPosition() const
 //*********************************************************************************************
 bool CFile::ReadString(char *szLine, int iLineLength)
 {
-  if (!m_pFile)
+  if (!m_pFile || !szLine)
     return false;
 
   if (m_pBuffer)
@@ -701,6 +714,9 @@ bool CFile::ReadString(char *szLine, int iLineLength)
 
 int CFile::Write(const void* lpBuf, int64_t uiBufSize)
 {
+  if (!m_pFile || !lpBuf)
+    return -1;
+
   try
   {
     return m_pFile->Write(lpBuf, uiBufSize);
index f4c7d22..5aa3faf 100644 (file)
@@ -168,7 +168,7 @@ bool CFileCache::Open(const CURL& url)
   // opening the source file.
   if (!m_source.Open(m_sourcePath, READ_NO_CACHE | READ_TRUNCATED | READ_CHUNKED))
   {
-    CLog::Log(LOGERROR,"%s - failed to open source <%s>", __FUNCTION__, m_sourcePath.c_str());
+    CLog::Log(LOGERROR,"%s - failed to open source <%s>", __FUNCTION__, url.GetRedacted().c_str());
     Close();
     return false;
   }
index 79ee3a4..d3adb35 100644 (file)
@@ -84,7 +84,10 @@ bool CLibraryDirectory::GetDirectory(const CStdString& strPath, CFileItemList &i
         CStdString path;
         XMLUtils::GetPath(node, "path", path);
         if (!path.IsEmpty())
+        {
+          URIUtils::AddSlashAtEnd(path);
           return CDirectory::GetDirectory(path, items, m_strFileMask, m_flags);
+        }
       }
     }
     return false;
index 105c08b..1b7f4c7 100644 (file)
@@ -1,4 +1,3 @@
-
 /*
  *      Copyright (C) 2005-2013 Team XBMC
  *      http://xbmc.org
@@ -151,7 +150,7 @@ bool CSMBDirectory::GetDirectory(const CStdString& strPath, CFileItemList &items
         if ((m_flags & DIR_FLAG_NO_FILE_INFO)==0 && g_advancedSettings.m_sambastatfiles)
         {
           // make sure we use the authenticated path wich contains any default username
-          CStdString strFullName = strAuth + smb.URLEncode(strFile);
+          const CStdString strFullName = strAuth + smb.URLEncode(strFile);
 
           lock.Enter();
 
@@ -172,7 +171,7 @@ bool CSMBDirectory::GetDirectory(const CStdString& strPath, CFileItemList &items
                 hidden = true;
             }
             else
-              CLog::Log(LOGERROR, "Getting extended attributes for the share: '%s'\nunix_err:'%x' error: '%s'", strFullName.c_str(), errno, strerror(errno));
+              CLog::Log(LOGERROR, "Getting extended attributes for the share: '%s'\nunix_err:'%x' error: '%s'", CURL::GetRedacted(strFullName).c_str(), errno, strerror(errno));
 #endif
 
             bIsDir = (info.st_mode & S_IFDIR) ? true : false;
@@ -182,7 +181,7 @@ bool CSMBDirectory::GetDirectory(const CStdString& strPath, CFileItemList &items
             iSize = info.st_size;
           }
           else
-            CLog::Log(LOGERROR, "%s - Failed to stat file %s", __FUNCTION__, strFullName.c_str());
+            CLog::Log(LOGERROR, "%s - Failed to stat file %s", __FUNCTION__, CURL::GetRedacted(strFullName).c_str());
 
           lock.Leave();
         }
@@ -260,7 +259,7 @@ int CSMBDirectory::OpenDir(const CURL& url, CStdString& strAuth)
 
   // remove the / or \ at the end. the samba library does not strip them off
   // don't do this for smb:// !!
-  CStdString s = strAuth;
+  std::string s = strAuth;
   int len = s.length();
   if (len > 1 && s.at(len - 2) != '/' &&
       (s.at(len - 1) == '/' || s.at(len - 1) == '\\'))
@@ -268,7 +267,7 @@ int CSMBDirectory::OpenDir(const CURL& url, CStdString& strAuth)
     s.erase(len - 1, 1);
   }
 
-  CLog::Log(LOGDEBUG, "%s - Using authentication url %s", __FUNCTION__, s.c_str());
+  CLog::Log(LOGDEBUG, "%s - Using authentication url %s", __FUNCTION__, CURL::GetRedacted(s).c_str());
   { CSingleLock lock(smb);
     fd = smbc_opendir(s.c_str());
   }
@@ -323,9 +322,9 @@ int CSMBDirectory::OpenDir(const CURL& url, CStdString& strAuth)
   {
     // write error to logfile
 #ifdef TARGET_WINDOWS
-    CLog::Log(LOGERROR, "SMBDirectory->GetDirectory: Unable to open directory : '%s'\nunix_err:'%x' nt_err : '%x' error : '%s'", strAuth.c_str(), errno, nt_error, get_friendly_nt_error_msg(nt_error));
+    CLog::Log(LOGERROR, "SMBDirectory->GetDirectory: Unable to open directory : '%s'\nunix_err:'%x' nt_err : '%x' error : '%s'", CURL::GetRedacted(strAuth).c_str(), errno, nt_error, get_friendly_nt_error_msg(nt_error));
 #else
-    CLog::Log(LOGERROR, "SMBDirectory->GetDirectory: Unable to open directory : '%s'\nunix_err:'%x' error : '%s'", strAuth.c_str(), errno, strerror(errno));
+    CLog::Log(LOGERROR, "SMBDirectory->GetDirectory: Unable to open directory : '%s'\nunix_err:'%x' error : '%s'", CURL::GetRedacted(strAuth).c_str(), errno, strerror(errno));
 #endif
   }
 
index 8437968..cc9aa0d 100644 (file)
@@ -407,9 +407,9 @@ bool CSmbFile::Open(const CURL& url)
     // write error to logfile
 #ifdef TARGET_WINDOWS
     int nt_error = smb.ConvertUnixToNT(errno);
-    CLog::Log(LOGINFO, "FileSmb->Open: Unable to open file : '%s'\nunix_err:'%x' nt_err : '%x' error : '%s'", strFileName.c_str(), errno, nt_error, get_friendly_nt_error_msg(nt_error));
+    CLog::Log(LOGINFO, "FileSmb->Open: Unable to open file : '%s'\nunix_err:'%x' nt_err : '%x' error : '%s'", CURL::GetRedacted(strFileName).c_str(), errno, nt_error, get_friendly_nt_error_msg(nt_error));
 #else
-    CLog::Log(LOGINFO, "FileSmb->Open: Unable to open file : '%s'\nunix_err:'%x' error : '%s'", strFileName.c_str(), errno, strerror(errno));
+    CLog::Log(LOGINFO, "FileSmb->Open: Unable to open file : '%s'\nunix_err:'%x' error : '%s'", CURL::GetRedacted(strFileName).c_str(), errno, strerror(errno));
 #endif
     return false;
   }
index 7cc8a66..7fa3384 100644 (file)
@@ -219,14 +219,29 @@ namespace XFILE
 
   bool CStackDirectory::ConstructStackPath(const vector<CStdString> &paths, CStdString& stackedPath)
   {
+    vector<string> pathsT;
+    pathsT.reserve(paths.size());
+    for (vector<CStdString>::const_iterator path = paths.begin();
+         path != paths.end(); ++path)
+    {
+      pathsT.push_back(*path);
+    }
+    std::string stackedPathT = stackedPath;
+    bool retVal = ConstructStackPath(pathsT, stackedPathT);
+    stackedPath = stackedPathT;
+    return retVal;
+  }
+
+  bool CStackDirectory::ConstructStackPath(const vector<std::string> &paths, std::string& stackedPath)
+  {
     if (paths.size() < 2)
       return false;
     stackedPath = "stack://";
-    CStdString folder, file;
+    std::string folder, file;
     URIUtils::Split(paths[0], folder, file);
     stackedPath += folder;
     // double escape any occurence of commas
-    file.Replace(",", ",,");
+    StringUtils::Replace(file, ",", ",,");
     stackedPath += file;
     for (unsigned int i = 1; i < paths.size(); ++i)
     {
@@ -234,7 +249,7 @@ namespace XFILE
       file = paths[i];
 
       // double escape any occurence of commas
-      file.Replace(",", ",,");
+      StringUtils::Replace(file, ",", ",,");
       stackedPath += file;
     }
     return true;
index 396e86b..a2335e6 100644 (file)
@@ -37,5 +37,6 @@ namespace XFILE
     static bool GetPaths(const CStdString& strPath, std::vector<CStdString>& vecPaths);
     static CStdString ConstructStackPath(const CFileItemList& items, const std::vector<int> &stack);
     static bool ConstructStackPath(const std::vector<CStdString> &paths, CStdString &stackedPath);
+    static bool ConstructStackPath(const std::vector<std::string> &paths, std::string &stackedPath);
   };
 }
index 9240f50..0bab179 100644 (file)
@@ -49,6 +49,12 @@ CGUIIncludes::CGUIIncludes()
   
   m_constantNodes.insert("posx");
   m_constantNodes.insert("posy");
+  m_constantNodes.insert("left");
+  m_constantNodes.insert("right");
+  m_constantNodes.insert("centerx");
+  m_constantNodes.insert("top");
+  m_constantNodes.insert("bottom");
+  m_constantNodes.insert("centery");
   m_constantNodes.insert("width");
   m_constantNodes.insert("height");
   m_constantNodes.insert("offsetx");
index a1f894b..8306c79 100644 (file)
@@ -219,6 +219,8 @@ bool CGUIWindow::Load(TiXmlElement* pRootElement)
     {
       XMLUtils::GetFloat(pChild, "posx", m_posX);
       XMLUtils::GetFloat(pChild, "posy", m_posY);
+      XMLUtils::GetFloat(pChild, "left", m_posX);
+      XMLUtils::GetFloat(pChild, "top", m_posY);
 
       TiXmlElement *originElement = pChild->FirstChildElement("origin");
       while (originElement)
index 74260ab..086fb0d 100644 (file)
@@ -86,6 +86,7 @@ endif
 
 ifeq (@USE_OPENGLES@,1)
 SRCS += TextureGL.cpp
+SRCS += TexturePi.cpp
 SRCS += GUIFontTTFGL.cpp
 SRCS += GUITextureGLES.cpp
 SRCS += MatrixGLES.cpp
index f5acd79..3ece247 100644 (file)
@@ -43,6 +43,7 @@
 #include "rendering/RenderSystem.h"
 #include "utils/log.h"
 #include "utils/StringUtils.h"
+#include "URL.h"
 #include "windowing/WindowingFactory.h"
 
 
@@ -170,7 +171,7 @@ std::string CStereoscopicsManager::DetectStereoModeByString(const std::string &n
   if (stereoMode.empty())
     stereoMode = "mono";
 
-  CLog::Log(LOGDEBUG, "StereoscopicsManager: Detected stereo mode in string '%s' is '%s'", needle.c_str(), stereoMode.c_str());
+  CLog::Log(LOGDEBUG, "StereoscopicsManager: Detected stereo mode in string '%s' is '%s'", CURL::GetRedacted(needle).c_str(), stereoMode.c_str());
   return stereoMode;
 }
 
index 36b5fe5..0dc2561 100644 (file)
 #include "filesystem/AndroidAppFile.h"
 #endif
 
-#if defined(HAS_OMXPLAYER)
-#include "xbmc/cores/omxplayer/OMXImage.h"
-#endif
-
 /************************************************************************/
 /*                                                                      */
 /************************************************************************/
@@ -101,8 +97,13 @@ void CBaseTexture::Allocate(unsigned int width, unsigned int height, unsigned in
   CLAMP(m_textureHeight, g_Windowing.GetMaxTextureSize());
   CLAMP(m_imageWidth, m_textureWidth);
   CLAMP(m_imageHeight, m_textureHeight);
+
   delete[] m_pixels;
-  m_pixels = new unsigned char[GetPitch() * GetRows()];
+  m_pixels = NULL;
+  if (GetPitch() * GetRows() > 0)
+  {
+    m_pixels = new unsigned char[GetPitch() * GetRows()];
+  }
 }
 
 void CBaseTexture::Update(unsigned int width, unsigned int height, unsigned int pitch, unsigned int format, const unsigned char *pixels, bool loadToGPU)
@@ -219,31 +220,6 @@ CBaseTexture *CBaseTexture::LoadFromFileInMemory(unsigned char *buffer, size_t b
 
 bool CBaseTexture::LoadFromFileInternal(const CStdString& texturePath, unsigned int maxWidth, unsigned int maxHeight, bool autoRotate)
 {
-#if defined(HAS_OMXPLAYER)
-  if (URIUtils::HasExtension(texturePath, ".jpg|.tbn")
-      /*|| URIUtils::HasExtension(texturePath, ".png")*/)
-  {
-    COMXImageFile *file = COMXImage::LoadJpeg(texturePath);
-    if (file)
-    {
-      bool okay = false;
-      int orientation = file->GetOrientation();
-      // limit the sizes of jpegs (even if we fail to decode)
-      COMXImage::ClampLimits(maxWidth, maxHeight, file->GetWidth(), file->GetHeight(), orientation & 4);
-      Allocate(maxWidth, maxHeight, XB_FMT_A8R8G8B8);
-      if (m_pixels && COMXImage::DecodeJpeg(file, maxWidth, GetRows(), GetPitch(), (void *)m_pixels))
-      {
-        m_hasAlpha = false;
-        if (autoRotate && orientation)
-          m_orientation = orientation - 1;
-        okay = true;
-      }
-      COMXImage::CloseJpeg(file);
-      if (okay)
-        return true;
-    }
-  }
-#endif
   if (URIUtils::HasExtension(texturePath, ".dds"))
   { // special case for DDS images
     CDDSImage image;
index 01ae547..aaec96f 100644 (file)
@@ -32,6 +32,7 @@ struct COLOR {unsigned char b,g,r,x;};        // Windows GDI expects 4bytes per color
 
 class CTexture;
 class CGLTexture;
+class CPiTexture;
 class CDXTexture;
 
 /*!
@@ -131,7 +132,10 @@ protected:
   bool m_hasAlpha;
 };
 
-#if defined(HAS_GL) || defined(HAS_GLES)
+#if defined(HAS_OMXPLAYER)
+#include "TexturePi.h"
+#define CTexture CPiTexture
+#elif defined(HAS_GL) || defined(HAS_GLES)
 #include "TextureGL.h"
 #define CTexture CGLTexture
 #elif defined(HAS_DX)
index 97da5e2..565b770 100644 (file)
@@ -19,7 +19,7 @@
  */
 
 #include "system.h"
-#include "TextureGL.h"
+#include "Texture.h"
 #include "windowing/WindowingFactory.h"
 #include "utils/log.h"
 #include "utils/GLUtils.h"
index b0ae1fd..7d149ed 100644 (file)
@@ -40,7 +40,7 @@ public:
   void LoadToGPU();
   void BindToUnit(unsigned int unit);
 
-private:
+protected:
   GLuint m_texture;
 };
 
diff --git a/xbmc/guilib/TexturePi.cpp b/xbmc/guilib/TexturePi.cpp
new file mode 100644 (file)
index 0000000..156f3d0
--- /dev/null
@@ -0,0 +1,142 @@
+/*
+ *      Copyright (C) 2013 Team XBMC
+ *      http://xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, see
+ *  <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "system.h"
+#include "Texture.h"
+#include "windowing/WindowingFactory.h"
+#include "utils/log.h"
+#include "utils/GLUtils.h"
+#include "guilib/TextureManager.h"
+#include "utils/URIUtils.h"
+
+#if defined(HAS_OMXPLAYER)
+#include "cores/omxplayer/OMXImage.h"
+
+using namespace std;
+
+/************************************************************************/
+/*    CPiTexture                                                       */
+/************************************************************************/
+
+CPiTexture::CPiTexture(unsigned int width, unsigned int height, unsigned int format)
+: CGLTexture(width, height, format)
+{
+  m_egl_image = NULL;
+}
+
+CPiTexture::~CPiTexture()
+{
+  if (m_egl_image)
+  {
+    g_OMXImage.DestroyTexture(m_egl_image);
+    m_egl_image = NULL;
+  }
+}
+
+void CPiTexture::Allocate(unsigned int width, unsigned int height, unsigned int format)
+{
+  if (m_egl_image)
+  {
+    m_imageWidth = m_originalWidth = width;
+    m_imageHeight = m_originalHeight = height;
+    m_format = format;
+    m_orientation = 0;
+
+    m_textureWidth = m_imageWidth;
+    m_textureHeight = m_imageHeight;
+    return;
+  }
+  return CGLTexture::Allocate(width, height, format);
+}
+
+void CPiTexture::CreateTextureObject()
+{
+  if (m_egl_image && !m_texture)
+  {
+    g_OMXImage.GetTexture(m_egl_image, &m_texture);
+    return;
+  }
+  CGLTexture::CreateTextureObject();
+}
+
+void CPiTexture::LoadToGPU()
+{
+  if (m_egl_image)
+  {
+    if (m_loadedToGPU)
+    {
+      // nothing to load - probably same image (no change)
+      return;
+    }
+    if (m_texture == 0)
+    {
+      // Have OpenGL generate a texture object handle for us
+      // this happens only one time - the first time the texture is loaded
+      CreateTextureObject();
+    }
+
+    // Bind the texture object
+    glBindTexture(GL_TEXTURE_2D, m_texture);
+
+    m_loadedToGPU = true;
+    return;
+  }
+  CGLTexture::LoadToGPU();
+}
+
+void CPiTexture::Update(unsigned int width, unsigned int height, unsigned int pitch, unsigned int format, const unsigned char *pixels, bool loadToGPU)
+{
+  if (m_egl_image)
+  {
+    if (loadToGPU)
+      LoadToGPU();
+    return;
+  }
+  CGLTexture::Update(width, height, pitch, format, pixels, loadToGPU);
+}
+
+bool CPiTexture::LoadFromFileInternal(const CStdString& texturePath, unsigned int maxWidth, unsigned int maxHeight, bool autoRotate)
+{
+  if (URIUtils::HasExtension(texturePath, ".jpg|.tbn"))
+  {
+    COMXImageFile *file = g_OMXImage.LoadJpeg(texturePath);
+    if (file)
+    {
+      bool okay = false;
+      int orientation = file->GetOrientation();
+      // limit the sizes of jpegs (even if we fail to decode)
+      g_OMXImage.ClampLimits(maxWidth, maxHeight, file->GetWidth(), file->GetHeight(), orientation & 4);
+      if (g_OMXImage.DecodeJpegToTexture(file, maxWidth, maxHeight, &m_egl_image) && m_egl_image)
+      {
+        m_hasAlpha = false;
+        if (autoRotate && orientation)
+          m_orientation = orientation - 1;
+        Allocate(maxWidth, maxHeight, XB_FMT_A8R8G8B8);
+        okay = true;
+      }
+      g_OMXImage.CloseJpeg(file);
+      if (okay)
+        return true;
+    }
+  }
+  return CGLTexture::LoadFromFileInternal(texturePath, maxWidth, maxHeight, autoRotate);
+}
+
+#endif
diff --git a/xbmc/guilib/TexturePi.h b/xbmc/guilib/TexturePi.h
new file mode 100644 (file)
index 0000000..8df1cf2
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ *      Copyright (C) 2013 Team XBMC
+ *      http://xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, see
+ *  <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#pragma once
+
+#include "TextureGL.h"
+
+#if defined(HAS_OMXPLAYER)
+
+#include "system_gl.h"
+
+/************************************************************************/
+/*    CGLTexture                                                       */
+/************************************************************************/
+class CPiTexture : public CGLTexture
+{
+public:
+  CPiTexture(unsigned int width = 0, unsigned int height = 0, unsigned int format = XB_FMT_A8R8G8B8);
+  virtual ~CPiTexture();
+  void CreateTextureObject();
+  void LoadToGPU();
+  void Update(unsigned int width, unsigned int height, unsigned int pitch, unsigned int format, const unsigned char *pixels, bool loadToGPU);
+  void Allocate(unsigned int width, unsigned int height, unsigned int format);
+  bool LoadFromFileInternal(const CStdString& texturePath, unsigned int maxWidth, unsigned int maxHeight, bool autoRotate);
+
+protected:
+
+private:
+  void *m_egl_image;
+};
+
+#endif
index 8ffdca1..247cd29 100644 (file)
@@ -134,6 +134,7 @@ JsonRpcMethodMap CJSONServiceDescription::m_methodMaps[] = {
   { "VideoLibrary.GetRecentlyAddedEpisodes",        CVideoLibrary::GetRecentlyAddedEpisodes },
   { "VideoLibrary.GetRecentlyAddedMusicVideos",     CVideoLibrary::GetRecentlyAddedMusicVideos },
   { "VideoLibrary.SetMovieDetails",                 CVideoLibrary::SetMovieDetails },
+  { "VideoLibrary.SetMovieSetDetails",              CVideoLibrary::SetMovieSetDetails },
   { "VideoLibrary.SetTVShowDetails",                CVideoLibrary::SetTVShowDetails },
   { "VideoLibrary.SetSeasonDetails",                CVideoLibrary::SetSeasonDetails },
   { "VideoLibrary.SetEpisodeDetails",               CVideoLibrary::SetEpisodeDetails },
index d2fe036..1c58d9d 100644 (file)
@@ -22,7 +22,7 @@
 namespace JSONRPC
 {
   const char* const JSONRPC_SERVICE_ID          = "http://xbmc.org/jsonrpc/ServiceDescription.json";
-  const char* const JSONRPC_SERVICE_VERSION     = "6.11.0";
+  const char* const JSONRPC_SERVICE_VERSION     = "6.12.0";
   const char* const JSONRPC_SERVICE_DESCRIPTION = "JSON-RPC API of XBMC";
 
   const char* const JSONRPC_SERVICE_TYPES[] = {  
@@ -2699,6 +2699,18 @@ namespace JSONRPC
       "],"
       "\"returns\": \"string\""
     "}",
+    "\"VideoLibrary.SetMovieSetDetails\": {"
+      "\"type\": \"method\","
+      "\"description\": \"Update the given movie set with the given details\","
+      "\"transport\": \"Response\","
+      "\"permission\": \"UpdateData\","
+      "\"params\": ["
+        "{ \"name\": \"setid\", \"$ref\": \"Library.Id\", \"required\": true },"
+        "{ \"name\": \"title\", \"$ref\": \"Optional.String\" },"
+        "{ \"name\": \"art\", \"type\": [ \"null\", { \"$ref\": \"Media.Artwork.Set\", \"required\": true } ], \"default\": null }"
+      "],"
+      "\"returns\": \"string\""
+    "}",
     "\"VideoLibrary.SetTVShowDetails\": {"
       "\"type\": \"method\","
       "\"description\": \"Update the given tvshow with the given details\","
index 89b5acf..cdd84b6 100644 (file)
@@ -518,6 +518,39 @@ JSONRPC_STATUS CVideoLibrary::SetMovieDetails(const CStdString &method, ITranspo
   return ACK;
 }
 
+JSONRPC_STATUS CVideoLibrary::SetMovieSetDetails(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+{
+  int id = (int)parameterObject["setid"].asInteger();
+
+  CVideoDatabase videodatabase;
+  if (!videodatabase.Open())
+    return InternalError;
+
+  CVideoInfoTag infos;
+  videodatabase.GetSetInfo(id, infos);
+  if (infos.m_iDbId <= 0)
+  {
+    videodatabase.Close();
+    return InvalidParams;
+  }
+
+  // get artwork
+  std::map<std::string, std::string> artwork;
+  videodatabase.GetArtForItem(infos.m_iDbId, infos.m_type, artwork);
+
+  std::set<std::string> removedArtwork;
+  UpdateVideoTag(parameterObject, infos, artwork, removedArtwork);
+
+  if (videodatabase.SetDetailsForMovieSet(infos, artwork, id) <= 0)
+    return InternalError;
+
+  if (!videodatabase.RemoveArtForItem(infos.m_iDbId, "set", removedArtwork))
+    return InternalError;
+
+  CJSONRPCUtils::NotifyItemUpdated();
+  return ACK;
+}
+
 JSONRPC_STATUS CVideoLibrary::SetTVShowDetails(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
   int id = (int)parameterObject["tvshowid"].asInteger();
index 1ba996b..919f0f0 100644 (file)
@@ -53,6 +53,7 @@ namespace JSONRPC
     static JSONRPC_STATUS GetGenres(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
 
     static JSONRPC_STATUS SetMovieDetails(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS SetMovieSetDetails(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
     static JSONRPC_STATUS SetTVShowDetails(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
     static JSONRPC_STATUS SetSeasonDetails(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
     static JSONRPC_STATUS SetEpisodeDetails(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
index 33248c5..3b51be1 100644 (file)
     ],
     "returns": "string"
   },
+  "VideoLibrary.SetMovieSetDetails": {
+    "type": "method",
+    "description": "Update the given movie set with the given details",
+    "transport": "Response",
+    "permission": "UpdateData",
+    "params": [
+      { "name": "setid", "$ref": "Library.Id", "required": true },
+      { "name": "title", "$ref": "Optional.String" },
+      { "name": "art", "type": [ "null", { "$ref": "Media.Artwork.Set", "required": true } ], "default": null }
+    ],
+    "returns": "string"
+  },
   "VideoLibrary.SetTVShowDetails": {
     "type": "method",
     "description": "Update the given tvshow with the given details",
index 22c7e97..db01a33 100644 (file)
@@ -1322,18 +1322,80 @@ OMX_ERRORTYPE COMXCoreComponent::DisablePort(unsigned int port, bool wait)
 
 OMX_ERRORTYPE COMXCoreComponent::UseEGLImage(OMX_BUFFERHEADERTYPE** ppBufferHdr, OMX_U32 nPortIndex, OMX_PTR pAppPrivate, void* eglImage)
 {
+  OMX_ERRORTYPE omx_err = OMX_ErrorNone;
+
   if(!m_handle)
     return OMX_ErrorUndefined;
 
-  OMX_ERRORTYPE omx_err;
+  m_omx_output_use_buffers = false;
 
-  omx_err = OMX_UseEGLImage(m_handle, ppBufferHdr, nPortIndex, pAppPrivate, eglImage);
-  if(omx_err != OMX_ErrorNone) 
+  OMX_PARAM_PORTDEFINITIONTYPE portFormat;
+  OMX_INIT_STRUCTURE(portFormat);
+  portFormat.nPortIndex = m_output_port;
+
+  omx_err = OMX_GetParameter(m_handle, OMX_IndexParamPortDefinition, &portFormat);
+  if(omx_err != OMX_ErrorNone)
+    return omx_err;
+
+  if(GetState() != OMX_StateIdle)
   {
-    CLog::Log(LOGERROR, "COMXCoreComponent::UseEGLImage - %s failed with omx_err(0x%x)\n", 
+    if(GetState() != OMX_StateLoaded)
+      SetStateForComponent(OMX_StateLoaded);
+
+    SetStateForComponent(OMX_StateIdle);
+  }
+
+  omx_err = EnablePort(m_output_port, false);
+  if(omx_err != OMX_ErrorNone)
+  {
+    CLog::Log(LOGERROR, "%s::%s - %s EnablePort failed with omx_err(0x%x)", CLASSNAME, __func__,
               m_componentName.c_str(), omx_err);
+    return omx_err;
+  }
+
+  m_output_alignment     = portFormat.nBufferAlignment;
+  m_output_buffer_count  = portFormat.nBufferCountActual;
+  m_output_buffer_size   = portFormat.nBufferSize;
+
+  if (portFormat.nBufferCountActual != 1)
+  {
+    CLog::Log(LOGERROR, "%s::%s - %s nBufferCountActual unexpected %d", CLASSNAME, __func__,
+              m_componentName.c_str(), portFormat.nBufferCountActual);
+    return omx_err;
+  }
+
+  CLog::Log(LOGDEBUG, "%s::%s component(%s) - port(%d), nBufferCountMin(%u), nBufferCountActual(%u), nBufferSize(%u) nBufferAlignmen(%u)\n",
+            CLASSNAME, __func__, m_componentName.c_str(), m_output_port, portFormat.nBufferCountMin,
+            portFormat.nBufferCountActual, portFormat.nBufferSize, portFormat.nBufferAlignment);
+
+  for (size_t i = 0; i < portFormat.nBufferCountActual; i++)
+  {
+    omx_err = OMX_UseEGLImage(m_handle, ppBufferHdr, nPortIndex, pAppPrivate, eglImage);
+    if(omx_err != OMX_ErrorNone)
+    {
+      CLog::Log(LOGERROR, "%s::%s - %s failed with omx_err(0x%x)\n",
+                CLASSNAME, __func__, m_componentName.c_str(), omx_err);
+      return omx_err;
+    }
+
+    OMX_BUFFERHEADERTYPE *buffer = *ppBufferHdr;
+    buffer->nOutputPortIndex = m_output_port;
+    buffer->nFilledLen       = 0;
+    buffer->nOffset          = 0;
+    buffer->pAppPrivate      = (void*)i;
+    m_omx_output_buffers.push_back(buffer);
+    m_omx_output_available.push(buffer);
   }
 
+  omx_err = WaitForCommand(OMX_CommandPortEnable, m_output_port);
+  if(omx_err != OMX_ErrorNone)
+  {
+    CLog::Log(LOGERROR, " %s::%s - %s EnablePort failed with omx_err(0x%x)\n",
+              CLASSNAME, __func__, m_componentName.c_str(), omx_err);
+      return omx_err;
+  }
+  m_flush_output = false;
+
   return omx_err;
 }
 
index b68fce6..ef48935 100644 (file)
@@ -23,6 +23,8 @@
 
 #include "utils/log.h"
 
+#include "cores/omxplayer/OMXImage.h"
+
 CRBP::CRBP()
 {
   m_initialized     = false;
@@ -58,6 +60,8 @@ bool CRBP::Initialize()
   if (vc_gencmd(response, sizeof response, "get_mem gpu") == 0)
     vc_gencmd_number_property(response, "gpu", &m_gpu_mem);
 
+  g_OMXImage.Initialize();
+  m_omx_image_init = true;
   return true;
 }
 
@@ -128,6 +132,9 @@ unsigned char *CRBP::CaptureDisplay(int width, int height, int *pstride, bool sw
 
 void CRBP::Deinitialize()
 {
+  if (m_omx_image_init)
+    g_OMXImage.Deinitialize();
+
   if(m_omx_initialized)
     m_OMX->Deinitialize();
 
@@ -136,6 +143,7 @@ void CRBP::Deinitialize()
   if(m_initialized)
     m_DllBcmHost->Unload();
 
+  m_omx_image_init  = false;
   m_initialized     = false;
   m_omx_initialized = false;
 }
index 666fac6..f742934 100644 (file)
@@ -58,6 +58,7 @@ private:
   DllBcmHost *m_DllBcmHost;
   bool       m_initialized;
   bool       m_omx_initialized;
+  bool       m_omx_image_init;
   int        m_arm_mem;
   int        m_gpu_mem;
   COMXCore   *m_OMX;
index 0e55d3b..ce3e6dc 100644 (file)
@@ -80,11 +80,6 @@ CProfilesManager& CProfilesManager::Get()
   return sProfilesManager;
 }
 
-bool CProfilesManager::OnSettingsLoading()
-{
-  return true;
-}
-
 void CProfilesManager::OnSettingsLoaded()
 {
   // check them all
index e974913..8d7b4fa 100644 (file)
@@ -32,7 +32,6 @@ class CProfilesManager : public ISettingsHandler
 public:
   static CProfilesManager& Get();
 
-  virtual bool OnSettingsLoading();
   virtual void OnSettingsLoaded();
   virtual bool OnSettingsSaved();
   virtual void OnSettingsCleared();
index a90164d..226669a 100644 (file)
@@ -930,6 +930,7 @@ void CSettings::InitializeISettingCallbacks()
   settingSet.insert("audiooutput.audiodevice");
   settingSet.insert("audiooutput.passthroughdevice");
   settingSet.insert("audiooutput.streamsilence");
+  settingSet.insert("audiooutput.normalizelevels");
   settingSet.insert("lookandfeel.skin");
   settingSet.insert("lookandfeel.skinsettings");
   settingSet.insert("lookandfeel.font");
index 5eaa2a9..f507385 100644 (file)
@@ -153,7 +153,7 @@ bool CSettingsManager::Initialize(const TiXmlElement *root)
 
 bool CSettingsManager::Load(const TiXmlElement *root, bool &updated, bool triggerEvents /* = true */, std::map<std::string, CSetting*> *loadedSettings /* = NULL */)
 {
-  CExclusiveLock lock(m_critical);
+  CSharedLock lock(m_critical);
   CExclusiveLock settingsLock(m_settingsCritical);
   if (m_loaded || root == NULL)
     return false;
index 66ae360..8b77fec 100644 (file)
@@ -2,6 +2,7 @@ SRCS=   \
        TestBasicEnvironment.cpp \
        TestFileItem.cpp \
        TestTextureCache.cpp \
+       TestURL.cpp \
        TestUtils.cpp \
        xbmc-test.cpp
 
diff --git a/xbmc/test/TestURL.cpp b/xbmc/test/TestURL.cpp
new file mode 100644 (file)
index 0000000..80ca150
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ *      Copyright (C) 2005-2013 Team XBMC
+ *      http://xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, see
+ *  <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "URL.h"
+
+#include "gtest/gtest.h"
+
+using ::testing::Test;
+using ::testing::WithParamInterface;
+using ::testing::ValuesIn;
+
+struct TestURLGetWithoutUserDetailsData
+{
+  std::string input;
+  std::string expected;
+  bool redact;
+};
+
+std::ostream& operator<<(std::ostream& os,
+                       const TestURLGetWithoutUserDetailsData& rhs)
+{
+  return os << "(Input: " << rhs.input <<
+    "; Redact: " << (rhs.redact?"true":"false") <<
+    "; Expected: " << rhs.expected << ")";
+}
+
+class TestURLGetWithoutUserDetails : public Test,
+                                     public WithParamInterface<TestURLGetWithoutUserDetailsData>
+{
+};
+
+TEST_P(TestURLGetWithoutUserDetails, GetWithoutUserDetails)
+{
+  CURL input(GetParam().input);
+  std::string result = input.GetWithoutUserDetails(GetParam().redact);
+  EXPECT_EQ(result, GetParam().expected);
+}
+
+const TestURLGetWithoutUserDetailsData values[] = {
+  { std::string("smb://example.com/example"), std::string("smb://example.com/example"), false },
+  { std::string("smb://example.com/example"), std::string("smb://example.com/example"), true },
+  { std::string("smb://god:universe@example.com/example"), std::string("smb://example.com/example"), false },
+  { std::string("smb://god@example.com/example"), std::string("smb://USERNAME@example.com/example"), true },
+  { std::string("smb://god:universe@example.com/example"), std::string("smb://USERNAME:PASSWORD@example.com/example"), true },
+  { std::string("http://god:universe@example.com:8448/example|auth=digest"), std::string("http://USERNAME:PASSWORD@example.com:8448/example|auth=digest"), true }
+  };
+
+INSTANTIATE_TEST_CASE_P(URL, TestURLGetWithoutUserDetails, ValuesIn(values));
index 8a46b9c..0ed56dc 100644 (file)
@@ -71,7 +71,8 @@ bool CSaveFileStateJob::DoWork()
 #endif
     if (m_item.IsVideo())
     {
-      CLog::Log(LOGDEBUG, "%s - Saving file state for video item %s", __FUNCTION__, progressTrackingFile.c_str());
+      std::string redactPath = CURL::GetRedacted(progressTrackingFile);
+      CLog::Log(LOGDEBUG, "%s - Saving file state for video item %s", __FUNCTION__, redactPath.c_str());
 
       CVideoDatabase videodatabase;
       if (!videodatabase.Open())
@@ -86,7 +87,7 @@ bool CSaveFileStateJob::DoWork()
         {
           if (m_updatePlayCount)
           {
-            CLog::Log(LOGDEBUG, "%s - Marking video item %s as watched", __FUNCTION__, progressTrackingFile.c_str());
+            CLog::Log(LOGDEBUG, "%s - Marking video item %s as watched", __FUNCTION__, redactPath.c_str());
 
             // consider this item as played
             videodatabase.IncrementPlayCount(m_item);
@@ -172,7 +173,8 @@ bool CSaveFileStateJob::DoWork()
 
     if (m_item.IsAudio())
     {
-      CLog::Log(LOGDEBUG, "%s - Saving file state for audio item %s", __FUNCTION__, m_item.GetPath().c_str());
+      std::string redactPath = CURL::GetRedacted(progressTrackingFile);
+      CLog::Log(LOGDEBUG, "%s - Saving file state for audio item %s", __FUNCTION__, redactPath.c_str());
 
       if (m_updatePlayCount)
       {
@@ -190,7 +192,7 @@ bool CSaveFileStateJob::DoWork()
           else
           {
             // consider this item as played
-            CLog::Log(LOGDEBUG, "%s - Marking audio item %s as listened", __FUNCTION__, m_item.GetPath().c_str());
+            CLog::Log(LOGDEBUG, "%s - Marking audio item %s as listened", __FUNCTION__, redactPath.c_str());
 
             musicdatabase.IncrementPlayCount(m_item);
             musicdatabase.Close();
index 21c8dad..3d9e914 100644 (file)
@@ -195,6 +195,15 @@ const CStdString URIUtils::GetFileName(const CStdString& strFileNameAndPath)
 void URIUtils::Split(const CStdString& strFileNameAndPath,
                      CStdString& strPath, CStdString& strFileName)
 {
+  std::string strPathT, strFileNameT;
+  Split(strFileNameAndPath, strPathT, strFileNameT);
+  strPath = strPathT;
+  strFileName = strFileNameT;
+}
+
+void URIUtils::Split(const std::string& strFileNameAndPath,
+                     std::string& strPath, std::string& strFileName)
+{
   //Splits a full filename in path and file.
   //ex. smb://computer/share/directory/filename.ext -> strPath:smb://computer/share/directory/ and strFileName:filename.ext
   //Trailing slash will be preserved
@@ -211,8 +220,10 @@ void URIUtils::Split(const CStdString& strFileNameAndPath,
   if (i == 0)
     i--;
 
-  strPath = strFileNameAndPath.Left(i + 1);
-  strFileName = strFileNameAndPath.Right(strFileNameAndPath.size() - i - 1);
+  // take left including the directory separator
+  strPath = strFileNameAndPath.substr(0, i+1);
+  // everything to the right of the directory separator
+  strFileName = strFileNameAndPath.substr(i+1);
 }
 
 CStdStringArray URIUtils::SplitPath(const CStdString& strPath)
index 413434d..7844509 100644 (file)
@@ -61,6 +61,8 @@ public:
                                      const CStdString& strNewExtension);
   static void Split(const CStdString& strFileNameAndPath, 
                     CStdString& strPath, CStdString& strFileName);
+  static void Split(const std::string& strFileNameAndPath, 
+                    std::string& strPath, std::string& strFileName);
   static CStdStringArray SplitPath(const CStdString& strPath);
 
   static void GetCommonPath(CStdString& strPath, const CStdString& strPath2);
index eef9a17..b78b9da 100644 (file)
@@ -979,7 +979,7 @@ int CVideoDatabase::GetMovieId(const CStdString& strFilenameAndPath)
     else
       strSQL=PrepareSQL("select idMovie from movie where idFile=%i", idFile);
 
-    CLog::Log(LOGDEBUG, "%s (%s), query = %s", __FUNCTION__, strFilenameAndPath.c_str(), strSQL.c_str());
+    CLog::Log(LOGDEBUG, "%s (%s), query = %s", __FUNCTION__, CURL::GetRedacted(strFilenameAndPath).c_str(), strSQL.c_str());
     m_pDS->query(strSQL.c_str());
     if (m_pDS->num_rows() > 0)
       idMovie = m_pDS->fv("idMovie").get_asInt();
@@ -1061,7 +1061,7 @@ int CVideoDatabase::GetEpisodeId(const CStdString& strFilenameAndPath, int idEpi
 
     CStdString strSQL=PrepareSQL("select idEpisode from episode where idFile=%i", idFile);
 
-    CLog::Log(LOGDEBUG, "%s (%s), query = %s", __FUNCTION__, strFilenameAndPath.c_str(), strSQL.c_str());
+    CLog::Log(LOGDEBUG, "%s (%s), query = %s", __FUNCTION__, CURL::GetRedacted(strFilenameAndPath).c_str(), strSQL.c_str());
     pDS->query(strSQL.c_str());
     if (pDS->num_rows() > 0)
     {
@@ -1112,7 +1112,7 @@ int CVideoDatabase::GetMusicVideoId(const CStdString& strFilenameAndPath)
 
     CStdString strSQL=PrepareSQL("select idMVideo from musicvideo where idFile=%i", idFile);
 
-    CLog::Log(LOGDEBUG, "%s (%s), query = %s", __FUNCTION__, strFilenameAndPath.c_str(), strSQL.c_str());
+    CLog::Log(LOGDEBUG, "%s (%s), query = %s", __FUNCTION__, CURL::GetRedacted(strFilenameAndPath).c_str(), strSQL.c_str());
     m_pDS->query(strSQL.c_str());
     int idMVideo=-1;
     if (m_pDS->num_rows() > 0)
@@ -1146,7 +1146,6 @@ int CVideoDatabase::AddMovie(const CStdString& strFilenameAndPath)
       CStdString strSQL=PrepareSQL("insert into movie (idMovie, idFile) values (NULL, %i)", idFile);
       m_pDS->exec(strSQL.c_str());
       idMovie = (int)m_pDS->lastinsertid();
-//      CommitTransaction();
     }
 
     return idMovie;
@@ -1200,8 +1199,6 @@ int CVideoDatabase::AddTvShow(const CStdString& strPath)
     strSQL=PrepareSQL("insert into tvshowlinkpath values (%i,%i)",idTvShow,idPath);
     m_pDS->exec(strSQL.c_str());
 
-//    CommitTransaction();
-
     return idTvShow;
   }
   catch (...)
@@ -2077,7 +2074,7 @@ int CVideoDatabase::SetDetailsForMovie(const CStdString& strFilenameAndPath, con
     // query DB for any movies matching imdbid and year
     CStdString strSQL = PrepareSQL("select files.playCount, files.lastPlayed from movie,files where files.idFile=movie.idFile and movie.c%02d='%s' and movie.c%02d=%i and movie.idMovie!=%i and files.playCount > 0", VIDEODB_ID_IDENT, details.m_strIMDBNumber.c_str(), VIDEODB_ID_YEAR, details.m_iYear, idMovie);
     m_pDS->query(strSQL.c_str());
-       
+
     if (!m_pDS->eof())
     {
       int playCount = m_pDS->fv("files.playCount").get_asInt();
@@ -2114,6 +2111,41 @@ int CVideoDatabase::SetDetailsForMovie(const CStdString& strFilenameAndPath, con
   return -1;
 }
 
+int CVideoDatabase::SetDetailsForMovieSet(const CVideoInfoTag& details, const std::map<std::string, std::string> &artwork, int idSet /* = -1 */)
+{
+  if (details.m_strTitle.empty())
+    return -1;
+
+  try
+  {
+    BeginTransaction();
+    if (idSet < 0)
+    {
+      idSet = AddSet(details.m_strTitle);
+      if (idSet < 0)
+      {
+        RollbackTransaction();
+        return -1;
+      }
+    }
+
+    SetArtForItem(idSet, "set", artwork);
+
+    // and insert the new row
+    CStdString sql = PrepareSQL("UPDATE sets SET strSet='%s' WHERE idSet=%i", details.m_strTitle.c_str(), idSet);
+    m_pDS->exec(sql.c_str());
+    CommitTransaction();
+
+    return idSet;
+  }
+  catch (...)
+  {
+    CLog::Log(LOGERROR, "%s (%i) failed", __FUNCTION__, idSet);
+  }
+  RollbackTransaction();
+  return -1;
+}
+
 int CVideoDatabase::SetDetailsForTvShow(const CStdString& strPath, const CVideoInfoTag& details, const map<string, string> &artwork, const map<int, map<string, string> > &seasonArt, int idTvShow /*= -1 */)
 {
   try
index acd8bb7..4a78bd6 100644 (file)
@@ -446,6 +446,7 @@ public:
   void GetEpisodesByFile(const CStdString& strFilenameAndPath, std::vector<CVideoInfoTag>& episodes);
 
   int SetDetailsForMovie(const CStdString& strFilenameAndPath, const CVideoInfoTag& details, const std::map<std::string, std::string> &artwork, int idMovie = -1);
+  int SetDetailsForMovieSet(const CVideoInfoTag& details, const std::map<std::string, std::string> &artwork, int idSet = -1);
   int SetDetailsForTvShow(const CStdString& strPath, const CVideoInfoTag& details, const std::map<std::string, std::string> &artwork, const std::map<int, std::map<std::string, std::string> > &seasonArt, int idTvShow = -1);
   int SetDetailsForSeason(const CVideoInfoTag& details, const std::map<std::string, std::string> &artwork, int idShow, int idSeason = -1);
   int SetDetailsForEpisode(const CStdString& strFilenameAndPath, const CVideoInfoTag& details, const std::map<std::string, std::string> &artwork, int idShow, int idEpisode=-1);
index cef6aa4..932b026 100644 (file)
@@ -266,7 +266,7 @@ namespace VIDEO
       CStdString fastHash = GetFastHash(strDirectory);
       if (m_database.GetPathHash(strDirectory, dbHash) && !fastHash.IsEmpty() && fastHash == dbHash)
       { // fast hashes match - no need to process anything
-        CLog::Log(LOGDEBUG, "VideoInfoScanner: Skipping dir '%s' due to no change (fasthash)", strDirectory.c_str());
+        CLog::Log(LOGDEBUG, "VideoInfoScanner: Skipping dir '%s' due to no change (fasthash)", CURL::GetRedacted(strDirectory).c_str());
         hash = fastHash;
         bSkip = true;
       }
@@ -279,19 +279,19 @@ namespace VIDEO
         if (hash != dbHash && !hash.IsEmpty())
         {
           if (dbHash.IsEmpty())
-            CLog::Log(LOGDEBUG, "VideoInfoScanner: Scanning dir '%s' as not in the database", strDirectory.c_str());
+            CLog::Log(LOGDEBUG, "VideoInfoScanner: Scanning dir '%s' as not in the database", CURL::GetRedacted(strDirectory).c_str());
           else
-            CLog::Log(LOGDEBUG, "VideoInfoScanner: Rescanning dir '%s' due to change (%s != %s)", strDirectory.c_str(), dbHash.c_str(), hash.c_str());
+            CLog::Log(LOGDEBUG, "VideoInfoScanner: Rescanning dir '%s' due to change (%s != %s)", CURL::GetRedacted(strDirectory).c_str(), dbHash.c_str(), hash.c_str());
         }
         else
         { // they're the same or the hash is empty (dir empty/dir not retrievable)
           if (hash.IsEmpty() && !dbHash.IsEmpty())
           {
-            CLog::Log(LOGDEBUG, "VideoInfoScanner: Skipping dir '%s' as it's empty or doesn't exist - adding to clean list", strDirectory.c_str());
+            CLog::Log(LOGDEBUG, "VideoInfoScanner: Skipping dir '%s' as it's empty or doesn't exist - adding to clean list", CURL::GetRedacted(strDirectory).c_str());
             m_pathsToClean.insert(m_database.GetPathId(strDirectory));
           }
           else
-            CLog::Log(LOGDEBUG, "VideoInfoScanner: Skipping dir '%s' due to no change", strDirectory.c_str());
+            CLog::Log(LOGDEBUG, "VideoInfoScanner: Skipping dir '%s' due to no change", CURL::GetRedacted(strDirectory).c_str());
           bSkip = true;
           if (m_handle)
             OnDirectoryScanned(strDirectory);
@@ -338,13 +338,13 @@ namespace VIDEO
         {
           m_database.SetPathHash(strDirectory, hash);
           m_pathsToClean.insert(m_database.GetPathId(strDirectory));
-          CLog::Log(LOGDEBUG, "VideoInfoScanner: Finished adding information from dir %s", strDirectory.c_str());
+          CLog::Log(LOGDEBUG, "VideoInfoScanner: Finished adding information from dir %s", CURL::GetRedacted(strDirectory).c_str());
         }
       }
       else
       {
         m_pathsToClean.insert(m_database.GetPathId(strDirectory));
-        CLog::Log(LOGDEBUG, "VideoInfoScanner: No (new) information was found in dir %s", strDirectory.c_str());
+        CLog::Log(LOGDEBUG, "VideoInfoScanner: No (new) information was found in dir %s", CURL::GetRedacted(strDirectory).c_str());
       }
     }
     else if (hash != dbHash && (content == CONTENT_MOVIES || content == CONTENT_MUSICVIDEOS))
@@ -427,7 +427,7 @@ namespace VIDEO
         ret = RetrieveInfoForMusicVideo(pItem.get(), bDirNames, info2, useLocal, pURL, pDlgProgress);
       else
       {
-        CLog::Log(LOGERROR, "VideoInfoScanner: Unknown content type %d (%s)", info2->Content(), pItem->GetPath().c_str());
+        CLog::Log(LOGERROR, "VideoInfoScanner: Unknown content type %d (%s)", info2->Content(), CURL::GetRedacted(pItem->GetPath()).c_str());
         FoundSomeInfo = false;
         break;
       }
@@ -439,7 +439,9 @@ namespace VIDEO
       if (ret == INFO_ADDED || ret == INFO_HAVE_ALREADY)
         FoundSomeInfo = true;
       else if (ret == INFO_NOT_FOUND)
-        CLog::Log(LOGWARNING, "No information found for item '%s', it won't be added to the library.", pItem->GetPath().c_str());
+      {
+        CLog::Log(LOGWARNING, "No information found for item '%s', it won't be added to the library.", CURL::GetRedacted(pItem->GetPath()).c_str());
+      }
 
       pURL = NULL;
 
@@ -768,7 +770,7 @@ namespace VIDEO
       {
         CStdString decode(items[i]->GetPath());
         CURL::Decode(decode);
-        CLog::Log(LOGDEBUG, "VideoInfoScanner: Could not enumerate file %s", decode.c_str());
+        CLog::Log(LOGDEBUG, "VideoInfoScanner: Could not enumerate file %s", CURL::GetRedacted(decode).c_str());
       }
     }
   }
@@ -1071,7 +1073,11 @@ namespace VIDEO
       strTitle.Format("%s - %ix%i - %s", showInfo->m_strTitle.c_str(), movieDetails.m_iSeason, movieDetails.m_iEpisode, strTitle.c_str());
     }
 
-    CLog::Log(LOGDEBUG, "VideoInfoScanner: Adding new item to %s:%s", TranslateContent(content).c_str(), pItem->GetPath().c_str());
+    std::string redactPath = pItem->GetPath();
+    CURL::Decode(redactPath);
+    redactPath = CURL::GetRedacted(redactPath);
+
+    CLog::Log(LOGDEBUG, "VideoInfoScanner: Adding new item to %s:%s", TranslateContent(content).c_str(), redactPath.c_str());
     long lResult = -1;
 
     if (content == CONTENT_MOVIES)
@@ -1841,7 +1847,7 @@ namespace VIDEO
           type = "malformed";
       }
       if (result != CNfoFile::NO_NFO)
-        CLog::Log(LOGDEBUG, "VideoInfoScanner: Found matching %s NFO file: %s", type.c_str(), strNfoFile.c_str());
+        CLog::Log(LOGDEBUG, "VideoInfoScanner: Found matching %s NFO file: %s", type.c_str(), CURL::GetRedacted(strNfoFile).c_str());
       if (result == CNfoFile::FULL_NFO)
       {
         if (info->Content() == CONTENT_TVSHOWS)
@@ -1860,7 +1866,7 @@ namespace VIDEO
       }
     }
     else
-      CLog::Log(LOGDEBUG, "VideoInfoScanner: No NFO file found. Using title search for '%s'", pItem->GetPath().c_str());
+      CLog::Log(LOGDEBUG, "VideoInfoScanner: No NFO file found. Using title search for '%s'", CURL::GetRedacted(pItem->GetPath()).c_str());
 
     return result;
   }
index 4ba7d72..741bd98 100644 (file)
@@ -93,7 +93,7 @@ bool CThumbExtractor::DoWork()
   bool result=false;
   if (m_thumb)
   {
-    CLog::Log(LOGDEBUG,"%s - trying to extract thumb from video file %s", __FUNCTION__, m_item.GetPath().c_str());
+    CLog::Log(LOGDEBUG,"%s - trying to extract thumb from video file %s", __FUNCTION__, CURL::GetRedacted(m_item.GetPath()).c_str());
     // construct the thumb cache file
     CTextureDetails details;
     details.file = CTextureCache::GetCacheFile(m_target) + ".jpg";
@@ -120,7 +120,7 @@ bool CThumbExtractor::DoWork()
   else if (!m_item.HasVideoInfoTag() || !m_item.GetVideoInfoTag()->HasStreamDetails())
   {
     // No tag or no details set, so extract them
-    CLog::Log(LOGDEBUG,"%s - trying to extract filestream details from video file %s", __FUNCTION__, m_item.GetPath().c_str());
+    CLog::Log(LOGDEBUG,"%s - trying to extract filestream details from video file %s", __FUNCTION__, CURL::GetRedacted(m_item.GetPath()).c_str());
     result = CDVDFileInfo::GetFileStreamDetails(&m_item);
   }
 
index 7bd2c8c..3fa9b14 100644 (file)
@@ -1476,7 +1476,7 @@ bool CGUIWindowVideoBase::OnPlayMedia(int iItem)
     item.SetPath(pItem->GetVideoInfoTag()->m_strFileNameAndPath);
     item.SetProperty("original_listitem_url", pItem->GetPath());
   }
-  CLog::Log(LOGDEBUG, "%s %s", __FUNCTION__, item.GetPath().c_str());
+  CLog::Log(LOGDEBUG, "%s %s", __FUNCTION__, CURL::GetRedacted(item.GetPath()).c_str());
 
   if (item.GetPath().Left(17) == "pvr://recordings/")
   {
index 73303ac..d9b3151 100644 (file)
@@ -60,13 +60,13 @@ public:
 
   EGLConfig     GetEGLConfig();
 
+  EGLDisplay    GetEGLDisplay();
+  EGLContext    GetEGLContext();
 protected:
   virtual bool  PresentRenderImpl(const CDirtyRegionList &dirty);
   virtual void  SetVSyncImpl(bool enable);
 
   bool          CreateWindow(RESOLUTION_INFO &res);
-  EGLDisplay    GetEGLDisplay();
-  EGLContext    GetEGLContext();
 
   int                   m_displayWidth;
   int                   m_displayHeight;
index afa337d..a92ec59 100644 (file)
@@ -653,8 +653,9 @@ bool CGUIMediaWindow::GetDirectory(const CStdString &strDirectory, CFileItemList
 
   CStdString strParentPath = m_history.GetParentPath();
 
-  CLog::Log(LOGDEBUG,"CGUIMediaWindow::GetDirectory (%s)", strDirectory.c_str());
-  CLog::Log(LOGDEBUG,"  ParentPath = [%s]", strParentPath.c_str());
+  CLog::Log(LOGDEBUG,"CGUIMediaWindow::GetDirectory (%s)",
+            CURL::GetRedacted(strDirectory).c_str());
+  CLog::Log(LOGDEBUG,"  ParentPath = [%s]", CURL::GetRedacted(strParentPath).c_str());
 
   // see if we can load a previously cached folder
   CFileItemList cachedItems(strDirectory);
@@ -755,7 +756,7 @@ bool CGUIMediaWindow::Update(const CStdString &strDirectory, bool updateFilterPa
   CFileItemList items;
   if (!GetDirectory(directory, items))
   {
-    CLog::Log(LOGERROR,"CGUIMediaWindow::GetDirectory(%s) failed", strDirectory.c_str());
+    CLog::Log(LOGERROR,"CGUIMediaWindow::GetDirectory(%s) failed", url.GetRedacted().c_str());
     // Try to return to the previous directory, if not the same
     // else fallback to root
     if (strDirectory.Equals(strCurrentDirectory) || !Update(m_history.RemoveParentPath()))
@@ -1306,7 +1307,7 @@ bool CGUIMediaWindow::OnPlayMedia(int iItem)
   g_playlistPlayer.SetCurrentPlaylist(PLAYLIST_NONE);
   CFileItemPtr pItem=m_vecItems->Get(iItem);
 
-  CLog::Log(LOGDEBUG, "%s %s", __FUNCTION__, pItem->GetPath().c_str());
+  CLog::Log(LOGDEBUG, "%s %s", __FUNCTION__, CURL::GetRedacted(pItem->GetPath()).c_str());
 
   bool bResult = false;
   if (pItem->IsInternetStream() || pItem->IsPlayList())