Index: skin/Project Mayhem III/PAL/Home.xml
===================================================================
--- skin/Project Mayhem III/PAL/Home.xml (revision 30593)
+++ skin/Project Mayhem III/PAL/Home.xml (working copy)
@@ -680,6 +680,7 @@
96
9
5
+ XBMC.System.PWMControl(#FF0000)
home-focus.gif
-
30
@@ -705,6 +706,7 @@
96
2
3
+ XBMC.System.PWMControl(#00FF00)
home-focus.gif
-
30
@@ -730,6 +732,7 @@
96
5
4
+ XBMC.System.PWMControl(#FFFFFF,#000000,#000000,#000000,firework,500)
home-focus.gif
-
30
@@ -755,6 +758,7 @@
96
3
7
+ XBMC.System.PWMControl(#FF00FF)
home-focus.gif
-
30
@@ -780,6 +784,7 @@
96
4
9
+ XBMC.System.PWMControl(#FFFF00)
home-focus.gif
-
30
@@ -820,6 +825,7 @@
6
10
5
+ XBMC.System.PWMControl(#00FFFF)
home-focus.gif
-
20
@@ -838,6 +844,7 @@
96
10
5
+ XBMC.System.PWMControl(#FFFFFF)
home-focus.gif
-
20
Index: userdata/AdvancedSettings.xml
===================================================================
--- userdata/AdvancedSettings.xml (revision 0)
+++ userdata/AdvancedSettings.xml (revision 0)
@@ -0,0 +1,13 @@
+
+
+ true
+ 30
+ 1
+ 1.2
+ 1.0
+ 0.8
+ 2
+ 50
+ 20
+
+
Index: xbmc/AdvancedSettings.cpp
===================================================================
--- xbmc/AdvancedSettings.cpp (revision 30593)
+++ xbmc/AdvancedSettings.cpp (working copy)
@@ -217,6 +217,22 @@
m_bAutoFatxLimit = true;
m_bgInfoLoaderMaxThreads = 1;
+
+ m_ambiLight = false;
+ m_ambiLightSpaceBetweenPixels = 30;
+ m_ambiLightFloatingAverageFrames = 1;
+ m_ambiLightMinRGB = 2;
+ m_ambiLightMaxRGB = 255;
+ m_ambiLightMode = "linear";
+ m_ambiLightPosition = "all";
+ m_ambiLightGammaR = 1.2f;
+ m_ambiLightGammaG = 1.0f;
+ m_ambiLightGammaB = 0.8f;
+ m_ambiLightIntensityR = 1.0f;
+ m_ambiLightIntensityG = 1.0f;
+ m_ambiLightIntensityB = 1.0f;
+ m_ambiLightFilterThreshold = 50;
+ m_ambiLightDarknessLimit = 20;
}
bool CAdvancedSettings::Load()
@@ -432,6 +448,26 @@
XMLUtils::GetBoolean(pElement, "verbose", m_bPythonVerbose);
}
+ pElement = pRootElement->FirstChildElement("ambilight");
+ if (pElement)
+ {
+ XMLUtils::GetBoolean(pElement, "enabled", m_ambiLight);
+ XMLUtils::GetInt(pElement, "spaceBetweenPixels", m_ambiLightSpaceBetweenPixels);
+ XMLUtils::GetInt(pElement, "floatingAverageFrames", m_ambiLightFloatingAverageFrames);
+ XMLUtils::GetInt(pElement, "minRGB", m_ambiLightMinRGB);
+ XMLUtils::GetInt(pElement, "maxRGB", m_ambiLightMaxRGB);
+ XMLUtils::GetString(pElement, "mode", m_ambiLightMode);
+ XMLUtils::GetString(pElement, "position", m_ambiLightPosition);
+ XMLUtils::GetFloat(pElement, "gammaR", m_ambiLightGammaR);
+ XMLUtils::GetFloat(pElement, "gammaG", m_ambiLightGammaG);
+ XMLUtils::GetFloat(pElement, "gammaB", m_ambiLightGammaB);
+ XMLUtils::GetFloat(pElement, "intensityR", m_ambiLightIntensityR);
+ XMLUtils::GetFloat(pElement, "intensityG", m_ambiLightIntensityG);
+ XMLUtils::GetFloat(pElement, "intensityB", m_ambiLightIntensityB);
+ XMLUtils::GetInt(pElement, "filterThreshold", m_ambiLightFilterThreshold);
+ XMLUtils::GetInt(pElement, "darknessLimit", m_ambiLightDarknessLimit);
+ }
+
XMLUtils::GetBoolean(pRootElement, "autofatxlimit", m_bAutoFatxLimit);
XMLUtils::GetString(pRootElement, "cddbaddress", m_cddbAddress);
Index: xbmc/AdvancedSettings.h
===================================================================
--- xbmc/AdvancedSettings.h (revision 30593)
+++ xbmc/AdvancedSettings.h (working copy)
@@ -41,183 +41,199 @@
class CAdvancedSettings
{
- public:
- CAdvancedSettings();
+public:
+ CAdvancedSettings();
- bool Load();
- void Clear();
+ bool Load();
+ void Clear();
- static void GetCustomTVRegexps(TiXmlElement *pRootElement, SETTINGS_TVSHOWLIST& settings);
- static void GetCustomRegexps(TiXmlElement *pRootElement, CStdStringArray& settings);
- static void GetCustomRegexpReplacers(TiXmlElement *pRootElement, CStdStringArray& settings);
- static void GetCustomExtensions(TiXmlElement *pRootElement, CStdString& extensions);
+ static void GetCustomTVRegexps(TiXmlElement *pRootElement, SETTINGS_TVSHOWLIST& settings);
+ static void GetCustomRegexps(TiXmlElement *pRootElement, CStdStringArray& settings);
+ static void GetCustomRegexpReplacers(TiXmlElement *pRootElement, CStdStringArray& settings);
+ static void GetCustomExtensions(TiXmlElement *pRootElement, CStdString& extensions);
- // multipath testing
- // multipath testing
- bool m_useMultipaths;
- bool m_DisableModChipDetection;
+ // multipath testing
+ // multipath testing
+ bool m_useMultipaths;
+ bool m_DisableModChipDetection;
- int m_audioHeadRoom;
- float m_karaokeSyncDelay;
- float m_ac3Gain;
- float m_audioPlayCountMinimumPercent;
+ int m_audioHeadRoom;
+ float m_karaokeSyncDelay;
+ float m_ac3Gain;
+ float m_audioPlayCountMinimumPercent;
- float m_videoSubsDelayRange;
- float m_videoAudioDelayRange;
- int m_videoSmallStepBackSeconds;
- int m_videoSmallStepBackTries;
- int m_videoSmallStepBackDelay;
- bool m_videoUseTimeSeeking;
- int m_videoTimeSeekForward;
- int m_videoTimeSeekBackward;
- int m_videoTimeSeekForwardBig;
- int m_videoTimeSeekBackwardBig;
- int m_videoPercentSeekForward;
- int m_videoPercentSeekBackward;
- int m_videoPercentSeekForwardBig;
- int m_videoPercentSeekBackwardBig;
- CStdString m_videoPPFFmpegDeint;
- CStdString m_videoPPFFmpegPostProc;
+ float m_videoSubsDelayRange;
+ float m_videoAudioDelayRange;
+ int m_videoSmallStepBackSeconds;
+ int m_videoSmallStepBackTries;
+ int m_videoSmallStepBackDelay;
+ bool m_videoUseTimeSeeking;
+ int m_videoTimeSeekForward;
+ int m_videoTimeSeekBackward;
+ int m_videoTimeSeekForwardBig;
+ int m_videoTimeSeekBackwardBig;
+ int m_videoPercentSeekForward;
+ int m_videoPercentSeekBackward;
+ int m_videoPercentSeekForwardBig;
+ int m_videoPercentSeekBackwardBig;
+ CStdString m_videoPPFFmpegDeint;
+ CStdString m_videoPPFFmpegPostProc;
- bool m_musicUseTimeSeeking;
- int m_musicTimeSeekForward;
- int m_musicTimeSeekBackward;
- int m_musicTimeSeekForwardBig;
- int m_musicTimeSeekBackwardBig;
- int m_musicPercentSeekForward;
- int m_musicPercentSeekBackward;
- int m_musicPercentSeekForwardBig;
- int m_musicPercentSeekBackwardBig;
- int m_musicResample;
- int m_videoBlackBarColour;
- int m_videoIgnoreAtStart;
- int m_videoIgnoreAtEnd;
- bool m_audioApplyDrc;
+ bool m_musicUseTimeSeeking;
+ int m_musicTimeSeekForward;
+ int m_musicTimeSeekBackward;
+ int m_musicTimeSeekForwardBig;
+ int m_musicTimeSeekBackwardBig;
+ int m_musicPercentSeekForward;
+ int m_musicPercentSeekBackward;
+ int m_musicPercentSeekForwardBig;
+ int m_musicPercentSeekBackwardBig;
+ int m_musicResample;
+ int m_videoBlackBarColour;
+ int m_videoIgnoreAtStart;
+ int m_videoIgnoreAtEnd;
+ bool m_audioApplyDrc;
- float m_videoPlayCountMinimumPercent;
+ float m_videoPlayCountMinimumPercent;
- int m_cacheMemBufferSize;
+ int m_cacheMemBufferSize;
- float m_slideshowBlackBarCompensation;
- float m_slideshowZoomAmount;
- float m_slideshowPanAmount;
+ float m_slideshowBlackBarCompensation;
+ float m_slideshowZoomAmount;
+ float m_slideshowPanAmount;
- int m_lcdRows;
- int m_lcdColumns;
- int m_lcdAddress1;
- int m_lcdAddress2;
- int m_lcdAddress3;
- int m_lcdAddress4;
+ int m_lcdRows;
+ int m_lcdColumns;
+ int m_lcdAddress1;
+ int m_lcdAddress2;
+ int m_lcdAddress3;
+ int m_lcdAddress4;
- int m_autoDetectPingTime;
+ int m_autoDetectPingTime;
- int m_songInfoDuration;
- int m_busyDialogDelay;
- int m_logLevel;
- CStdString m_cddbAddress;
- bool m_usePCDVDROM;
- bool m_fullScreenOnMovieStart;
- bool m_noDVDROM;
- CStdString m_cachePath;
- bool m_displayRemoteCodes;
- CStdString m_videoCleanDateTimeRegExp;
- CStdStringArray m_videoCleanStringRegExps;
- CStdStringArray m_videoExcludeFromListingRegExps;
- CStdStringArray m_moviesExcludeFromScanRegExps;
- CStdStringArray m_tvshowExcludeFromScanRegExps;
- CStdStringArray m_audioExcludeFromListingRegExps;
- CStdStringArray m_audioExcludeFromScanRegExps;
- CStdStringArray m_pictureExcludeFromListingRegExps;
- CStdStringArray m_videoStackRegExps;
- CStdStringArray m_trailerMatchRegExps;
- SETTINGS_TVSHOWLIST m_tvshowStackRegExps;
- CStdString m_tvshowMultiPartStackRegExp;
- CStdStringArray m_pathSubstitutions;
- int m_remoteRepeat;
- float m_controllerDeadzone;
- bool m_FTPShowCache;
+ int m_songInfoDuration;
+ int m_busyDialogDelay;
+ int m_logLevel;
+ CStdString m_cddbAddress;
+ bool m_usePCDVDROM;
+ bool m_fullScreenOnMovieStart;
+ bool m_noDVDROM;
+ CStdString m_cachePath;
+ bool m_displayRemoteCodes;
+ CStdString m_videoCleanDateTimeRegExp;
+ CStdStringArray m_videoCleanStringRegExps;
+ CStdStringArray m_videoExcludeFromListingRegExps;
+ CStdStringArray m_moviesExcludeFromScanRegExps;
+ CStdStringArray m_tvshowExcludeFromScanRegExps;
+ CStdStringArray m_audioExcludeFromListingRegExps;
+ CStdStringArray m_audioExcludeFromScanRegExps;
+ CStdStringArray m_pictureExcludeFromListingRegExps;
+ CStdStringArray m_videoStackRegExps;
+ CStdStringArray m_trailerMatchRegExps;
+ SETTINGS_TVSHOWLIST m_tvshowStackRegExps;
+ CStdString m_tvshowMultiPartStackRegExp;
+ CStdStringArray m_pathSubstitutions;
+ int m_remoteRepeat;
+ float m_controllerDeadzone;
+ bool m_FTPShowCache;
- bool m_playlistAsFolders;
- bool m_detectAsUdf;
+ bool m_playlistAsFolders;
+ bool m_detectAsUdf;
- int m_thumbSize;
- int m_fanartHeight;
+ int m_thumbSize;
+ int m_fanartHeight;
- int m_sambaclienttimeout;
- CStdString m_sambadoscodepage;
- bool m_sambastatfiles;
-
- bool m_bHTTPDirectoryStatFilesize;
+ int m_sambaclienttimeout;
+ CStdString m_sambadoscodepage;
+ bool m_sambastatfiles;
- bool m_bFTPThumbs;
+ bool m_bHTTPDirectoryStatFilesize;
- CStdString m_musicThumbs;
- CStdString m_dvdThumbs;
- CStdString m_fanartImages;
+ bool m_bFTPThumbs;
- bool m_bMusicLibraryHideAllItems;
- int m_iMusicLibraryRecentlyAddedItems;
- bool m_bMusicLibraryAllItemsOnBottom;
- bool m_bMusicLibraryAlbumsSortByArtistThenYear;
- CStdString m_strMusicLibraryAlbumFormat;
- CStdString m_strMusicLibraryAlbumFormatRight;
- bool m_prioritiseAPEv2tags;
- CStdString m_musicItemSeparator;
- CStdString m_videoItemSeparator;
- std::vector m_musicTagsFromFileFilters;
+ CStdString m_musicThumbs;
+ CStdString m_dvdThumbs;
+ CStdString m_fanartImages;
- bool m_bVideoLibraryHideAllItems;
- bool m_bVideoLibraryAllItemsOnBottom;
- int m_iVideoLibraryRecentlyAddedItems;
- bool m_bVideoLibraryHideRecentlyAddedItems;
- bool m_bVideoLibraryHideEmptySeries;
- bool m_bVideoLibraryCleanOnUpdate;
- bool m_bVideoLibraryExportAutoThumbs;
- bool m_bVideoLibraryMyMoviesCategoriesToGenres;
- bool m_bVideoLibraryImportWatchedState;
+ bool m_bMusicLibraryHideAllItems;
+ int m_iMusicLibraryRecentlyAddedItems;
+ bool m_bMusicLibraryAllItemsOnBottom;
+ bool m_bMusicLibraryAlbumsSortByArtistThenYear;
+ CStdString m_strMusicLibraryAlbumFormat;
+ CStdString m_strMusicLibraryAlbumFormatRight;
+ bool m_prioritiseAPEv2tags;
+ CStdString m_musicItemSeparator;
+ CStdString m_videoItemSeparator;
+ std::vector m_musicTagsFromFileFilters;
- bool m_bVideoScannerIgnoreErrors;
+ bool m_bVideoLibraryHideAllItems;
+ bool m_bVideoLibraryAllItemsOnBottom;
+ int m_iVideoLibraryRecentlyAddedItems;
+ bool m_bVideoLibraryHideRecentlyAddedItems;
+ bool m_bVideoLibraryHideEmptySeries;
+ bool m_bVideoLibraryCleanOnUpdate;
+ bool m_bVideoLibraryExportAutoThumbs;
+ bool m_bVideoLibraryMyMoviesCategoriesToGenres;
+ bool m_bVideoLibraryImportWatchedState;
- bool m_bUseEvilB;
- std::vector m_vecTokens; // cleaning strings tied to language
- //TuxBox
- int m_iTuxBoxStreamtsPort;
- bool m_bTuxBoxSubMenuSelection;
- int m_iTuxBoxDefaultSubMenu;
- int m_iTuxBoxDefaultRootMenu;
- bool m_bTuxBoxAudioChannelSelection;
- bool m_bTuxBoxPictureIcon;
- int m_iTuxBoxEpgRequestTime;
- int m_iTuxBoxZapWaitTime;
- bool m_bTuxBoxSendAllAPids;
- bool m_bTuxBoxZapstream;
- int m_iTuxBoxZapstreamPort;
+ bool m_bVideoScannerIgnoreErrors;
- int m_iMythMovieLength; // minutes
+ bool m_bUseEvilB;
+ std::vector m_vecTokens; // cleaning strings tied to language
+ //TuxBox
+ int m_iTuxBoxStreamtsPort;
+ bool m_bTuxBoxSubMenuSelection;
+ int m_iTuxBoxDefaultSubMenu;
+ int m_iTuxBoxDefaultRootMenu;
+ bool m_bTuxBoxAudioChannelSelection;
+ bool m_bTuxBoxPictureIcon;
+ int m_iTuxBoxEpgRequestTime;
+ int m_iTuxBoxZapWaitTime;
+ bool m_bTuxBoxSendAllAPids;
+ bool m_bTuxBoxZapstream;
+ int m_iTuxBoxZapstreamPort;
- // EDL Commercial Break
- bool m_bEdlMergeShortCommBreaks;
- int m_iEdlMaxCommBreakLength; // seconds
- int m_iEdlMinCommBreakLength; // seconds
- int m_iEdlMaxCommBreakGap; // seconds
- int m_iEdlMaxStartGap; // seconds
- int m_iEdlCommBreakAutowait; // seconds
- int m_iEdlCommBreakAutowind; // seconds
+ int m_iMythMovieLength; // minutes
- bool m_bFirstLoop;
- int m_curlconnecttimeout;
- int m_curllowspeedtime;
- int m_curlretries;
+ // EDL Commercial Break
+ bool m_bEdlMergeShortCommBreaks;
+ int m_iEdlMaxCommBreakLength; // seconds
+ int m_iEdlMinCommBreakLength; // seconds
+ int m_iEdlMaxCommBreakGap; // seconds
+ int m_iEdlMaxStartGap; // seconds
+ int m_iEdlCommBreakAutowait; // seconds
+ int m_iEdlCommBreakAutowind; // seconds
- int m_playlistRetries;
- int m_playlistTimeout;
- int m_iSkipLoopFilter;
- bool m_bVirtualShares;
- bool m_bNavVKeyboard; // if true we navigate the virtual keyboard using cursor keys
-
- bool m_bPythonVerbose;
- bool m_bAutoFatxLimit;
- int m_bgInfoLoaderMaxThreads;
+ bool m_bFirstLoop;
+ int m_curlconnecttimeout;
+ int m_curllowspeedtime;
+ int m_curlretries;
+
+ int m_playlistRetries;
+ int m_playlistTimeout;
+ int m_iSkipLoopFilter;
+ bool m_bVirtualShares;
+ bool m_bNavVKeyboard; // if true we navigate the virtual keyboard using cursor keys
+
+ bool m_bPythonVerbose;
+ bool m_bAutoFatxLimit;
+ int m_bgInfoLoaderMaxThreads;
+
+ bool m_ambiLight;
+ int m_ambiLightSpaceBetweenPixels;
+ int m_ambiLightFloatingAverageFrames;
+ int m_ambiLightMinRGB;
+ int m_ambiLightMaxRGB;
+ CStdString m_ambiLightMode;
+ CStdString m_ambiLightPosition;
+ float m_ambiLightGammaR;
+ float m_ambiLightGammaG;
+ float m_ambiLightGammaB;
+ float m_ambiLightIntensityR;
+ float m_ambiLightIntensityG;
+ float m_ambiLightIntensityB;
+ int m_ambiLightFilterThreshold;
+ int m_ambiLightDarknessLimit;
};
extern CAdvancedSettings g_advancedSettings;
Index: xbmc/Application.cpp
===================================================================
--- xbmc/Application.cpp (revision 30593)
+++ xbmc/Application.cpp (working copy)
@@ -2790,6 +2790,7 @@
}
UpdateLCD();
+ g_iledSmartxxrgb.AmbiLightUpdateFrameNumber();
// read raw input from controller, remote control, mouse and keyboard
ReadInput();
Index: xbmc/cores/dvdplayer/DVDPlayerVideo.cpp
===================================================================
--- xbmc/cores/dvdplayer/DVDPlayerVideo.cpp (revision 30593)
+++ xbmc/cores/dvdplayer/DVDPlayerVideo.cpp (working copy)
@@ -18,7 +18,7 @@
* http://www.gnu.org/copyleft/gpl.html
*
*/
-
+
#include "stdafx.h"
#include "AdvancedSettings.h"
#include "GUISettings.h"
@@ -38,15 +38,16 @@
#include "DVDCodecs/Overlay/DVDOverlaySSA.h"
#include
#include
+#include "utils/LED.h"
using namespace std;
CDVDPlayerVideo::CDVDPlayerVideo( CDVDClock* pClock
- , CDVDOverlayContainer* pOverlayContainer
- , CDVDMessageQueue& parent)
-: CThread()
-, m_messageQueue("video")
-, m_messageParent(parent)
+ , CDVDOverlayContainer* pOverlayContainer
+ , CDVDMessageQueue& parent)
+ : CThread()
+ , m_messageQueue("video")
+ , m_messageParent(parent)
{
m_pClock = pClock;
m_pOverlayContainer = pOverlayContainer;
@@ -81,7 +82,7 @@
{
StopThread();
g_dvdPerformanceCounter.DisableVideoQueue();
-
+
#ifdef HAS_VIDEO_PLAYBACK
if(m_output.inited)
{
@@ -93,16 +94,16 @@
double CDVDPlayerVideo::GetOutputDelay()
{
- double time = m_messageQueue.GetPacketCount(CDVDMsg::DEMUXER_PACKET);
- if( m_fFrameRate )
- time = (time * DVD_TIME_BASE) / m_fFrameRate;
- else
- time = 0.0;
+ double time = m_messageQueue.GetPacketCount(CDVDMsg::DEMUXER_PACKET);
+ if( m_fFrameRate )
+ time = (time * DVD_TIME_BASE) / m_fFrameRate;
+ else
+ time = 0.0;
- if( m_speed != 0 )
- time = time * DVD_PLAYSPEED_NORMAL / abs(m_speed);
+ if( m_speed != 0 )
+ time = time * DVD_PLAYSPEED_NORMAL / abs(m_speed);
- return time;
+ return time;
}
bool CDVDPlayerVideo::OpenStream( CDVDStreamInfo &hint )
@@ -197,7 +198,7 @@
{
CThread::SetName("CDVDPlayerVideo");
m_iDroppedFrames = 0;
-
+
m_iCurrentPts = DVD_NOPTS_VALUE;
m_FlipTimeStamp = m_pClock->GetAbsoluteClock();
@@ -381,8 +382,8 @@
bRequestDrop = false;
#else
if (m_messageQueue.GetDataSize() == 0
- || m_iNrOfPicturesNotToSkip > 0
- || m_speed < 0)
+ || m_iNrOfPicturesNotToSkip > 0
+ || m_speed < 0)
{
bRequestDrop = false;
m_iDroppedRequest = 0;
@@ -440,6 +441,23 @@
memset(&picture, 0, sizeof(DVDVideoPicture));
if (m_pVideoCodec->GetPicture(&picture))
{
+
+ // AMBI-LIGHT STUFF
+ if(g_advancedSettings.m_ambiLight)
+ {
+ g_iledSmartxxrgb.AmbiLightUpdate();
+ g_iledSmartxxrgb.AmbiLightParamsUpdate(0,picture.iWidth,2);
+
+ for(unsigned int i=0;iiGroupId;
@@ -594,6 +612,8 @@
m_pOverlayCodecCC = NULL;
}
+ //g_iledSmartxxrgb.AmbiLightStop();
+
CLog::Log(LOGNOTICE, "thread end: video_thread");
}
@@ -690,7 +710,7 @@
bool bHasSpecialOverlay = m_pOverlayContainer->ContainsOverlayType(DVDOVERLAY_TYPE_SPU)
|| m_pOverlayContainer->ContainsOverlayType(DVDOVERLAY_TYPE_IMAGE)
|| m_pOverlayContainer->ContainsOverlayType(DVDOVERLAY_TYPE_SSA);
-
+
if (bHasSpecialOverlay)
{
if (m_pTempOverlayPicture && (m_pTempOverlayPicture->iWidth != pSource->iWidth || m_pTempOverlayPicture->iHeight != pSource->iHeight))
@@ -698,7 +718,7 @@
CDVDCodecUtils::FreePicture(m_pTempOverlayPicture);
m_pTempOverlayPicture = NULL;
}
-
+
if (!m_pTempOverlayPicture) m_pTempOverlayPicture = CDVDCodecUtils::AllocatePicture(pSource->iWidth, pSource->iHeight);
}
@@ -706,7 +726,7 @@
CDVDCodecUtils::CopyPicture(m_pTempOverlayPicture, pSource);
else
CDVDCodecUtils::CopyPicture(pDest, pSource);
-
+
m_pOverlayContainer->Lock();
VecOverlays* pVecOverlays = m_pOverlayContainer->GetOverlays();
@@ -735,7 +755,7 @@
}
m_pOverlayContainer->Unlock();
-
+
if (bHasSpecialOverlay && m_pTempOverlayPicture)
CDVDCodecUtils::CopyPicture(pDest, m_pTempOverlayPicture);
}
@@ -746,13 +766,13 @@
#ifdef HAS_VIDEO_PLAYBACK
/* check so that our format or aspect has changed. if it has, reconfigure renderer */
if (!g_renderManager.IsConfigured()
- || m_output.width != pPicture->iWidth
- || m_output.height != pPicture->iHeight
- || m_output.dwidth != pPicture->iDisplayWidth
- || m_output.dheight != pPicture->iDisplayHeight
- || m_output.framerate != m_fFrameRate
- || ( m_output.color_matrix != pPicture->color_matrix && pPicture->color_matrix != 0 ) // don't reconfigure on unspecified
- || m_output.color_range != pPicture->color_range)
+ || m_output.width != pPicture->iWidth
+ || m_output.height != pPicture->iHeight
+ || m_output.dwidth != pPicture->iDisplayWidth
+ || m_output.dheight != pPicture->iDisplayHeight
+ || m_output.framerate != m_fFrameRate
+ || ( m_output.color_matrix != pPicture->color_matrix && pPicture->color_matrix != 0 ) // don't reconfigure on unspecified
+ || m_output.color_range != pPicture->color_range)
{
CLog::Log(LOGNOTICE, " fps: %f, pwidth: %i, pheight: %i, dwidth: %i, dheight: %i",
m_fFrameRate, pPicture->iWidth, pPicture->iHeight, pPicture->iDisplayWidth, pPicture->iDisplayHeight);
@@ -762,19 +782,19 @@
switch(pPicture->color_matrix)
{
- case 7: // SMPTE 240M (1987)
- flags |= CONF_FLAGS_YUVCOEF_240M;
- break;
- case 6: // SMPTE 170M
- case 5: // ITU-R BT.470-2
- case 4: // FCC
- flags |= CONF_FLAGS_YUVCOEF_BT601;
- break;
- case 3: // RESERVED
- case 2: // UNSPECIFIED
- case 1: // ITU-R Rec.709 (1990) -- BT.709
- default:
- flags |= CONF_FLAGS_YUVCOEF_BT709;
+ case 7: // SMPTE 240M (1987)
+ flags |= CONF_FLAGS_YUVCOEF_240M;
+ break;
+ case 6: // SMPTE 170M
+ case 5: // ITU-R BT.470-2
+ case 4: // FCC
+ flags |= CONF_FLAGS_YUVCOEF_BT601;
+ break;
+ case 3: // RESERVED
+ case 2: // UNSPECIFIED
+ case 1: // ITU-R Rec.709 (1990) -- BT.709
+ default:
+ flags |= CONF_FLAGS_YUVCOEF_BT709;
}
if(m_bAllowFullscreen)
@@ -818,7 +838,7 @@
// calculate the time we need to delay this picture before displaying
double iSleepTime, iClockSleep, iFrameSleep, iCurrentClock, iFrameDuration;
-
+
iCurrentClock = m_pClock->GetAbsoluteClock(); // snapshot current clock
iClockSleep = pts - m_pClock->GetClock(); //sleep calculated by pts to clock comparison
iFrameSleep = m_FlipTimeStamp - iCurrentClock; // sleep calculated by duration of frame
@@ -902,7 +922,7 @@
if( m_speed < 0 )
{
if( iClockSleep < -DVD_MSEC_TO_TIME(200)
- && !(pPicture->iFlags & DVP_FLAG_NOSKIP) )
+ && !(pPicture->iFlags & DVP_FLAG_NOSKIP) )
return result | EOS_DROPPED;
}
@@ -950,7 +970,7 @@
// video device might not be done yet
while (index < 0 && !CThread::m_bStop &&
- CDVDClock::GetAbsoluteClock() < iCurrentClock + iSleepTime )
+ CDVDClock::GetAbsoluteClock() < iCurrentClock + iSleepTime )
{
Sleep(1);
index = g_renderManager.GetImage(&image);
Index: xbmc/cores/VideoRenderers/XBoxRenderer.cpp
===================================================================
--- xbmc/cores/VideoRenderers/XBoxRenderer.cpp (revision 30593)
+++ xbmc/cores/VideoRenderers/XBoxRenderer.cpp (working copy)
@@ -24,6 +24,7 @@
#include "Application.h"
#include "XBVideoConfig.h"
#include "Settings.h"
+#include "utils/LED.h"
// http://www.martinreddy.net/gfx/faqs/colorconv.faq
@@ -283,7 +284,7 @@
xscale = 1.0f;
yscale = 1.0f;
}
-
+
// horizontal centering, and align to bottom of subtitles line
osdRect.left = (float)rv.left + (float)(rv.right - rv.left - (float)w * xscale) / 2.0f;
osdRect.right = osdRect.left + (float)w * xscale;
@@ -306,7 +307,7 @@
if (
D3D_OK != m_pD3DDevice->CreateTexture(m_iOSDTextureWidth, m_iOSDTextureHeight[iOSDBuffer], 1, 0, D3DFMT_LIN_L8, 0, &m_pOSDYTexture[iOSDBuffer]) ||
D3D_OK != m_pD3DDevice->CreateTexture(m_iOSDTextureWidth, m_iOSDTextureHeight[iOSDBuffer], 1, 0, D3DFMT_LIN_A8, 0, &m_pOSDATexture[iOSDBuffer])
- )
+ )
{
CLog::Log(LOGERROR, "Could not create OSD/Sub textures");
DeleteOSDTextures(iOSDBuffer);
@@ -337,7 +338,7 @@
if (
(D3D_OK == m_pOSDYTexture[iOSDBuffer]->LockRect(0, &lr, &rc, 0)) &&
(D3D_OK == m_pOSDATexture[iOSDBuffer]->LockRect(0, &lra, &rc, 0))
- )
+ )
{
//clear the textures
memset(lr.pBits, 0, lr.Pitch*m_iOSDTextureHeight[iOSDBuffer]);
@@ -392,7 +393,7 @@
//m_pD3DDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_INVSRCALPHA );
//m_pD3DDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_SRCALPHA );
- // Note the mplayer code actually does this
+ // Note the mplayer code actually does this
//m_pD3DDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_ONE );
//m_pD3DDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_SRCALPHA );
}
@@ -559,7 +560,7 @@
DeleteYV12Texture(i);
}
if(m_iYV12RenderBuffer > i)
- m_iYV12RenderBuffer = i;
+ m_iYV12RenderBuffer = i;
m_NumYV12Buffers = i+1;
}
}
@@ -671,16 +672,16 @@
// If the TV has no HD support widescreen mode is chossen according to video AR
if (g_videoConfig.Has1080i()) // Widescreen TV with 1080i res
- m_iResolution = HDTV_1080i;
+ m_iResolution = HDTV_1080i;
else if (g_videoConfig.Has720p()) // Widescreen TV with 720p res
- m_iResolution = HDTV_720p;
+ m_iResolution = HDTV_720p;
else if (g_videoConfig.Has480p()) // Widescreen TV with 480p
{
if (bWideScreenMode) // Choose widescreen mode according to video AR
m_iResolution = HDTV_480p_16x9;
else
m_iResolution = HDTV_480p_4x3;
- }
+ }
else if (bWideScreenMode) // Standard 16:9 TV set with no HD
m_iResolution = NTSC_16x9;
else
@@ -692,7 +693,7 @@
// We choose 16:9 resolution only for 16:9 video sources
if (m_fSourceFrameRatio >= 16.0f / 9.0f)
- {
+ {
// The video fits best into widescreen modes so they are
// the first choices
if (g_videoConfig.Has1080i())
@@ -738,7 +739,7 @@
m_fps = fps;
m_iFlags = flags;
m_bConfigured = true;
-
+
// setup what colorspace we live in
if(flags & CONF_FLAGS_YUV_FULLRANGE)
m_yuvrange = yuv_range_full;
@@ -747,18 +748,21 @@
switch(CONF_FLAGS_YUVCOEF_MASK(flags))
{
- case CONF_FLAGS_YUVCOEF_240M:
- m_yuvcoef = yuv_coef_smtp240m; break;
- case CONF_FLAGS_YUVCOEF_BT709:
- m_yuvcoef = yuv_coef_bt709; break;
- case CONF_FLAGS_YUVCOEF_BT601:
- m_yuvcoef = yuv_coef_bt601; break;
- case CONF_FLAGS_YUVCOEF_EBU:
- m_yuvcoef = yuv_coef_ebu; break;
- default:
- m_yuvcoef = yuv_coef_bt601; break;
+ case CONF_FLAGS_YUVCOEF_240M:
+ m_yuvcoef = yuv_coef_smtp240m; break;
+ case CONF_FLAGS_YUVCOEF_BT709:
+ m_yuvcoef = yuv_coef_bt709; break;
+ case CONF_FLAGS_YUVCOEF_BT601:
+ m_yuvcoef = yuv_coef_bt601; break;
+ case CONF_FLAGS_YUVCOEF_EBU:
+ m_yuvcoef = yuv_coef_ebu; break;
+ default:
+ m_yuvcoef = yuv_coef_bt601; break;
}
+ // init Params for AmbiLight
+ g_iledSmartxxrgb.AmbiLightParamsInit(width,height,m_yuvcoef,m_yuvrange);
+
// calculate the input frame aspect ratio
CalculateFrameAspectRatio(d_width, d_height);
ChooseBestResolution(m_fps);
@@ -798,16 +802,16 @@
source = NextYV12Texture();
#ifdef MP_DIRECTRENDERING
- if( source < 0 )
- { /* no free source existed, so create one */
- CSingleLock lock(g_graphicsContext);
- if( CreateYV12Texture(m_NumYV12Buffers) )
- {
- source = m_NumYV12Buffers;
- m_NumYV12Buffers++;
- m_image[source].flags |= IMAGE_FLAG_DYNAMIC;
- }
+ if( source < 0 )
+ { /* no free source existed, so create one */
+ CSingleLock lock(g_graphicsContext);
+ if( CreateYV12Texture(m_NumYV12Buffers) )
+ {
+ source = m_NumYV12Buffers;
+ m_NumYV12Buffers++;
+ m_image[source].flags |= IMAGE_FLAG_DYNAMIC;
}
+ }
#endif
if( source >= 0 && m_image[source].plane[0] )
@@ -833,7 +837,7 @@
{
if( m_image[source].flags & IMAGE_FLAG_WRITING )
SetEvent(m_eventTexturesDone[source]);
-
+
m_image[source].flags &= ~IMAGE_FLAG_INUSE;
/* if image should be preserved reserve it so it's not auto seleceted */
@@ -918,10 +922,15 @@
unsigned int CXBoxRenderer::DrawSlice(unsigned char *src[], int stride[], int w, int h, int x, int y)
{
- BYTE *s;
- BYTE *d;
- int i, p;
+ BYTE *s0,*s1,*s2;
+ BYTE *d0,*d1,*d2;
+ int w2,h2,x2,y2;
+
+ // check if we've finished the recent Frame and push it to the SmartXX...
+ if(g_advancedSettings.m_ambiLight)
+ g_iledSmartxxrgb.AmbiLightUpdate();
+
int index = NextYV12Texture();
if( index < 0 )
return -1;
@@ -930,40 +939,47 @@
CLog::Log(LOGWARNING, CStdString(__FUNCTION__) + " - Timeout waiting for texture %d", index);
YV12Image &im = m_image[index];
- // copy Y
- p = 0;
- d = (BYTE*)im.plane[p] + im.stride[p] * y + x;
- s = src[p];
- for (i = 0;i < h;i++)
- {
- memcpy(d, s, w);
- s += stride[p];
- d += im.stride[p];
- }
+ // Y
+ d0 = (BYTE*)im.plane[0] + im.stride[0] * y + x;
+ s0 = src[0];
- w >>= im.cshift_x; h >>= im.cshift_y;
- x >>= im.cshift_x; y >>= im.cshift_y;
+ w2 = w >> im.cshift_x; h2 = h >> im.cshift_y;
+ x2 = x >> im.cshift_x; y2 = y >> im.cshift_y;
- // copy U
- p = 1;
- d = (BYTE*)im.plane[p] + im.stride[p] * y + x;
- s = src[p];
- for (i = 0;i < h;i++)
+ // U
+ d1 = (BYTE*)im.plane[1] + im.stride[1] * y2 + x2;
+ s1 = src[1];
+
+ // V
+ d2 = (BYTE*)im.plane[2] + im.stride[2] * y2 + x2;
+ s2 = src[2];
+
+ int widthRatio = (int)(w/w2);
+ int heightRatio = (int)(h/h2);
+
+ //Update AmbiLights params...
+ if(g_advancedSettings.m_ambiLight)
+ g_iledSmartxxrgb.AmbiLightParamsUpdate(x,w,widthRatio);
+
+ for (int i = 0;i < h;i++)
{
- memcpy(d, s, w);
- s += stride[p];
- d += im.stride[p];
- }
+ memcpy(d0, s0, w);
+ s0 += stride[0];
+ d0 += im.stride[0];
- // copy V
- p = 2;
- d = (BYTE*)im.plane[p] + im.stride[p] * y + x;
- s = src[p];
- for (i = 0;i < h;i++)
- {
- memcpy(d, s, w);
- s += stride[p];
- d += im.stride[p];
+ if(i % heightRatio == 0)
+ {
+ memcpy(d1, s1, w2);
+ s1 += stride[1];
+ d1 += im.stride[1];
+
+ memcpy(d2, s2, w2);
+ s2 += stride[2];
+ d2 += im.stride[2];
+ }
+ // calculate RGB-values for the recent row of the frame...
+ if(g_advancedSettings.m_ambiLight)
+ g_iledSmartxxrgb.AmbiLightRGBCalculate(s0,s1,s2);
}
SetEvent(m_eventTexturesDone[index]);
@@ -1038,13 +1054,14 @@
DeleteYV12Texture(i);
DeleteOSDTextures(i);
}
-
+
if (m_hLowMemShader)
{
m_pD3DDevice->DeletePixelShader(m_hLowMemShader);
m_hLowMemShader = 0;
}
+ g_iledSmartxxrgb.AmbiLightStop();
m_bConfigured = false;
}
@@ -1357,7 +1374,7 @@
void CXBoxRenderer::DeleteYV12Texture(int index)
{
CSingleLock lock(g_graphicsContext);
-
+
YV12Image &im = m_image[index];
YUVFIELDS &fields = m_YUVTexture[index];
@@ -1382,7 +1399,7 @@
im.plane[p] = NULL;
m_NumYV12Buffers = 0;
-
+
CLog::Log(LOGDEBUG, "Deleted YV12 texture %i", index);
}
@@ -1439,24 +1456,24 @@
p = 0;
stride = im.stride[p];
im.plane[p] = (BYTE*)dwTextureSize;
- XGSetTextureHeader(im.width , im.height>>1 , 1, 0, D3DFMT_LIN_L8, 0, fields[2][p], dwTextureSize + stride, stride<<1);
- XGSetTextureHeader(im.width , im.height>>1 , 1, 0, D3DFMT_LIN_L8, 0, fields[1][p], dwTextureSize, stride<<1);
+ XGSetTextureHeader(im.width , im.height>>1 , 1, 0, D3DFMT_LIN_L8, 0, fields[2][p], dwTextureSize + stride, stride<<1);
+ XGSetTextureHeader(im.width , im.height>>1 , 1, 0, D3DFMT_LIN_L8, 0, fields[1][p], dwTextureSize, stride<<1);
dwTextureSize += XGSetTextureHeader(im.width , im.height , 1, 0, D3DFMT_LIN_L8, 0, fields[0][p], dwTextureSize, stride);
/* U */
p = 1;
stride = im.stride[p];
im.plane[p] = (BYTE*)dwTextureSize;
- XGSetTextureHeader(im.width>>im.cshift_x, im.height>>im.cshift_y>>1, 1, 0, D3DFMT_LIN_L8, 0, fields[2][p], dwTextureSize + stride, stride<<1);
- XGSetTextureHeader(im.width>>im.cshift_x, im.height>>im.cshift_y>>1, 1, 0, D3DFMT_LIN_L8, 0, fields[1][p], dwTextureSize, stride<<1);
+ XGSetTextureHeader(im.width>>im.cshift_x, im.height>>im.cshift_y>>1, 1, 0, D3DFMT_LIN_L8, 0, fields[2][p], dwTextureSize + stride, stride<<1);
+ XGSetTextureHeader(im.width>>im.cshift_x, im.height>>im.cshift_y>>1, 1, 0, D3DFMT_LIN_L8, 0, fields[1][p], dwTextureSize, stride<<1);
dwTextureSize += XGSetTextureHeader(im.width>>im.cshift_x, im.height>>im.cshift_y, 1, 0, D3DFMT_LIN_L8, 0, fields[0][p], dwTextureSize, stride);
/* V */
p = 2;
stride = im.stride[p];
im.plane[p] = (BYTE*)dwTextureSize;
- XGSetTextureHeader(im.width>>im.cshift_x, im.height>>im.cshift_y>>1, 1, 0, D3DFMT_LIN_L8, 0, fields[2][p], dwTextureSize + stride, stride<<1);
- XGSetTextureHeader(im.width>>im.cshift_x, im.height>>im.cshift_y>>1, 1, 0, D3DFMT_LIN_L8, 0, fields[1][p], dwTextureSize, stride<<1);
+ XGSetTextureHeader(im.width>>im.cshift_x, im.height>>im.cshift_y>>1, 1, 0, D3DFMT_LIN_L8, 0, fields[2][p], dwTextureSize + stride, stride<<1);
+ XGSetTextureHeader(im.width>>im.cshift_x, im.height>>im.cshift_y>>1, 1, 0, D3DFMT_LIN_L8, 0, fields[1][p], dwTextureSize, stride<<1);
dwTextureSize += XGSetTextureHeader(im.width>>im.cshift_x, im.height>>im.cshift_y, 1, 0, D3DFMT_LIN_L8, 0, fields[0][p], dwTextureSize, stride);
BYTE* data = (BYTE*)XPhysicalAlloc(dwTextureSize, MAXULONG_PTR, D3DTEXTURE_ALIGNMENT, memflags);
Index: xbmc/Util.cpp
===================================================================
--- xbmc/Util.cpp (revision 30593)
+++ xbmc/Util.cpp (working copy)
@@ -4397,14 +4397,21 @@
strWhiteB= arSplit[3].c_str();
strTran = arSplit[4].c_str();
iTrTime = atoi(arSplit[5].c_str());
+ CUtil::PWMControl(strRgbA,strRgbB,strWhiteA,strWhiteB,strTran, iTrTime);
}
- else if(parameter.size() > 6)
+ else if(parameter.size() == 7)
{
strRgbA = strRgbB = parameter;
strWhiteA = strWhiteB = "#000000";
- strTran = "none";
+ strTran = "fade2";
+ tRGBColor rgb;
+ sscanf(parameter,"#%2X%2X%2X",&rgb.r,&rgb.g,&rgb.b);
+
+ //CUtil::PWMControl(strRgbA,strRgbB,strWhiteA,strWhiteB,strTran, iTrTime);
+ g_iledSmartxxrgb.SetRGBState(rgb);
}
- CUtil::PWMControl(strRgbA,strRgbB,strWhiteA,strWhiteB,strTran, iTrTime);
+ else
+ CLog::Log(LOGDEBUG,"System.PWMControl(): Invalid parameters - use: System.PWMControl(#rgb1,#rgb2,#white1,#white2,mode,time)");
}
else if (execute.Equals("backupsysteminfo"))
{
Index: xbmc/utils/LED.cpp
===================================================================
--- xbmc/utils/LED.cpp (revision 30593)
+++ xbmc/utils/LED.cpp (working copy)
@@ -50,9 +50,23 @@
#include "xbox/XKUtils.h"
#include "LCD.h"
#include "GUISettings.h"
+#include "Settings.h"
#include
+// set accuracy of color calculation
+#define h_MAX 255
+#define s_MAX 255
+#define v_MAX 255
+#define POS_DIV(a, b) ( (a)/(b) + ( ((a)%(b) >= (b)/2 ) ? 1 : 0) )
+
+#define WINDOW_SIZE 5
+#define HUE_WINDOW 5
+#define MIN_PERCENTAGE 0.01
+#define FADE2_MAX_TIME 1000
+#define SLOWLIMIT 12
+#define SLOWTIMES 4
+
ILEDSmartxxRGB g_iledSmartxxrgb;
void ILED::CLEDControl(int ixLED)
@@ -88,17 +102,20 @@
ILEDSmartxxRGB::ILEDSmartxxRGB()
{
- strCurrentStatus = "NULL";
- strLastStatus = "NULL";
-
+ strCurrentStatus = "NULL";
+ strLastStatus = "NULL";
+
s_RGBs.strTransition = "NULL";
- s_CurRGB.red = 0;
- s_CurRGB.green = 0;
- s_CurRGB.blue = 0;
+ s_CurRGB.red = 0;
+ s_CurRGB.green = 0;
+ s_CurRGB.blue = 0;
s_CurRGB.white = 0;
-
+
dwLastTime = 0;
bRepeat = false;
+ isPaused = false;
+
+ AmbiLightParams.AmbiLightIsPlaying=false;
}
ILEDSmartxxRGB::~ILEDSmartxxRGB()
@@ -108,119 +125,317 @@
{
if (g_sysinfo.SmartXXModCHIP().Equals("SmartXX V3") || g_sysinfo.SmartXXModCHIP().Equals("SmartXX OPX"))
{
- SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_LOWEST);
- CLog::Log(LOGDEBUG,"Starting SmartXX RGB LED thread");
+ //SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_LOWEST);
+ //SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_HIGHEST);
+ SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_HIGHEST);
+ CLog::Log(LOGDEBUG,"Starting SmartXX RGB LED thread");
SetRGBStatus("general");
}
}
void ILEDSmartxxRGB::Process()
{
- while(!m_bStop)
- {
- dwFrameTime = timeGetTime() - dwLastTime;
+ while(!m_bStop)
+ {
+ if(!isPaused)
+ {
+ dwFrameTime = timeGetTime() - dwLastTime;
- if( (s_RGBs.strTransition.IsEmpty() || s_RGBs.strTransition.Equals("none")) && !strLastTransition.Equals("none") )
- {
- strLastTransition = "none";
- s_CurRGB.red = s_RGBs.red1;
- s_CurRGB.green = s_RGBs.green1;
- s_CurRGB.blue = s_RGBs.blue1;
- s_CurRGB.white = s_RGBs.white1;
-
- SetRGBLed(s_CurRGB.red,s_CurRGB.green,s_CurRGB.blue, s_CurRGB.white);
- }
- else if(s_RGBs.strTransition.Equals("switch") && !strLastTransition.Equals("switch"))
- {
- if(dwFrameTime >= s_RGBs.iTime )
- {
- s_CurRGB.red = s_RGBs.red2;
- s_CurRGB.green = s_RGBs.green2;
- s_CurRGB.blue = s_RGBs.blue2;
- s_CurRGB.white = s_RGBs.white2;
- strLastTransition = "switch";
- SetRGBLed(s_CurRGB.red,s_CurRGB.green,s_CurRGB.blue,s_CurRGB.white);
- }
- else
+ if( (s_RGBs.strTransition.IsEmpty() || s_RGBs.strTransition.Equals("none")) && !strLastTransition.Equals("none") )
{
s_CurRGB.red = s_RGBs.red1;
- s_CurRGB.green = s_RGBs.green1;
+ s_CurRGB.green = s_RGBs.green1;
s_CurRGB.blue = s_RGBs.blue1;
s_CurRGB.white = s_RGBs.white1;
- SetRGBLed(s_CurRGB.red,s_CurRGB.green,s_CurRGB.blue,s_CurRGB.white);
+
+ SetRGBLed(s_CurRGB.red,s_CurRGB.green,s_CurRGB.blue, s_CurRGB.white);
}
-
- }
- else if(s_RGBs.strTransition.Equals("blink"))
- {
- strLastTransition = "blink";
- if(dwFrameTime >= s_RGBs.iTime )
- {
- s_CurRGB.red = (s_CurRGB.red != s_RGBs.red1) ? s_RGBs.red1 : s_RGBs.red2;
- s_CurRGB.green = (s_CurRGB.green != s_RGBs.green1) ? s_RGBs.green1 : s_RGBs.green2;
- s_CurRGB.blue = (s_CurRGB.blue != s_RGBs.blue1) ? s_RGBs.blue1 : s_RGBs.blue2;
- s_CurRGB.white= (s_CurRGB.white != s_RGBs.white1) ? s_RGBs.white1 : s_RGBs.white2;
- dwLastTime = timeGetTime();
- SetRGBLed(s_CurRGB.red,s_CurRGB.green,s_CurRGB.blue,s_CurRGB.white);
- }
- }
- else if(s_RGBs.strTransition.Equals("fade") || s_RGBs.strTransition.Equals("fadeloop") || s_RGBs.strTransition.Equals("faderepeat"))
- {
+ else if(s_RGBs.strTransition.Equals("switch") && !strLastTransition.Equals("switch"))
+ {
+ if(dwFrameTime >= s_RGBs.iTime )
+ {
+ s_CurRGB.red = s_RGBs.red2;
+ s_CurRGB.green = s_RGBs.green2;
+ s_CurRGB.blue = s_RGBs.blue2;
+ s_CurRGB.white = s_RGBs.white2;
+ SetRGBLed(s_CurRGB.red,s_CurRGB.green,s_CurRGB.blue,s_CurRGB.white);
+ }
+ else
+ {
+ s_CurRGB.red = s_RGBs.red1;
+ s_CurRGB.green = s_RGBs.green1;
+ s_CurRGB.blue = s_RGBs.blue1;
+ s_CurRGB.white = s_RGBs.white1;
+ SetRGBLed(s_CurRGB.red,s_CurRGB.green,s_CurRGB.blue,s_CurRGB.white);
+ }
+ }
+ else if(s_RGBs.strTransition.Equals("blink"))
+ {
+ strLastTransition = "blink";
+ if(dwFrameTime >= s_RGBs.iTime )
+ {
+ s_CurRGB.red = (s_CurRGB.red != s_RGBs.red1) ? s_RGBs.red1 : s_RGBs.red2;
+ s_CurRGB.green = (s_CurRGB.green != s_RGBs.green1) ? s_RGBs.green1 : s_RGBs.green2;
+ s_CurRGB.blue = (s_CurRGB.blue != s_RGBs.blue1) ? s_RGBs.blue1 : s_RGBs.blue2;
+ s_CurRGB.white= (s_CurRGB.white != s_RGBs.white1) ? s_RGBs.white1 : s_RGBs.white2;
+ dwLastTime = timeGetTime();
+ SetRGBLed(s_CurRGB.red,s_CurRGB.green,s_CurRGB.blue,s_CurRGB.white);
+ }
+ }
+ else if(s_RGBs.strTransition.Equals("fade") || s_RGBs.strTransition.Equals("fadeloop") || s_RGBs.strTransition.Equals("faderepeat"))
+ {
+ static double distanceR,distanceG,distanceB,distanceW;
+
+ if(!strLastTransition.Equals("fade"))
+ {
+ distanceR = bRepeat ? s_RGBs.red1-s_RGBs.red2 : s_RGBs.red2-s_RGBs.red1;
+ distanceG = bRepeat ? s_RGBs.green1-s_RGBs.green2 : s_RGBs.green2-s_RGBs.green1;
+ distanceB = bRepeat ? s_RGBs.blue1-s_RGBs.blue2 : s_RGBs.blue2-s_RGBs.blue1;
+ distanceW = bRepeat ? s_RGBs.white1-s_RGBs.white2 : s_RGBs.white2-s_RGBs.white1;
+
+ strLastTransition = "fade";
+
+ if(s_RGBs.strTransition.Equals("faderepeat"))bRepeat=!bRepeat;
+ }
+
+ if(dwFrameTime <= s_RGBs.iTime )
+ {
+ double stepR=distanceR/s_RGBs.iTime*dwFrameTime;
+ double stepG=distanceG/s_RGBs.iTime*dwFrameTime;
+ double stepB=distanceB/s_RGBs.iTime*dwFrameTime;
+ double stepW=distanceW/s_RGBs.iTime*dwFrameTime;
+
+ s_CurRGB.red=(bRepeat ? s_RGBs.red1 : s_RGBs.red2) +(int)stepR;
+ s_CurRGB.green=(bRepeat ? s_RGBs.green1 : s_RGBs.green2)+(int)stepG;
+ s_CurRGB.blue=(bRepeat ? s_RGBs.blue1 : s_RGBs.blue2)+(int)stepB;
+ s_CurRGB.white=(bRepeat ? s_RGBs.white1 : s_RGBs.white2)+(int)stepW;
+
+ SetRGBLed(s_CurRGB.red,s_CurRGB.green,s_CurRGB.blue,s_CurRGB.white);
+ }
+ else if(s_RGBs.strTransition.Equals("fadeloop") || s_RGBs.strTransition.Equals("faderepeat"))
+ {
+ strLastTransition="none";
+ dwLastTime = timeGetTime();
+ }
+ }
+ else if(s_RGBs.strTransition.Equals("fade2"))
+ {
+ static int distanceR,distanceG,distanceB,distanceW;
+ static int maxDiffR,maxDiffG,maxDiffB;
+
+ if(!strLastTransition.Equals("fade2"))
+ {
+ strLastTransition = "fade2";
+ dwFrameTime = 0;
+ dwLastTime = timeGetTime();
+
+ s_RGBs.red1 =s_CurRGB.red;
+ s_RGBs.green1 =s_CurRGB.green;
+ s_RGBs.blue1 =s_CurRGB.blue ;
+
+ distanceR = s_RGBs.red2-s_RGBs.red1;
+ distanceG = s_RGBs.green2-s_RGBs.green1;
+ distanceB = s_RGBs.blue2-s_RGBs.blue1;
+ distanceW = s_RGBs.white2-s_RGBs.white1;
+
+ /*maxDiffR=(int)((float)distanceR/FADE2_MAX_TIME*2);
+ maxDiffG=(int)((float)distanceG/FADE2_MAX_TIME*2);
+ maxDiffB=(int)((float)distanceB/FADE2_MAX_TIME*2);
+ if(maxDiffR==0)maxDiffR=1;
+ if(maxDiffG==0)maxDiffG=1;
+ if(maxDiffB==0)maxDiffB=1;*/
+
+
+ int max=abs(MAX(distanceR,distanceG,distanceB));
+
+ //max eine sekunde transition time
+ s_RGBs.iTime = int((max/255.0f)*FADE2_MAX_TIME);
+ }
+
+ if(dwFrameTime <= s_RGBs.iTime && (s_CurRGB.red!=s_RGBs.red2 || s_CurRGB.blue!=s_RGBs.blue2 || s_CurRGB.green!=s_RGBs.green2))
+ {
+ // how far do we need to be according to current time...
+ int stepR=(int)((double)distanceR/s_RGBs.iTime*dwFrameTime);
+ int stepG=(int)((double)distanceG/s_RGBs.iTime*dwFrameTime);
+ int stepB=(int)((double)distanceB/s_RGBs.iTime*dwFrameTime);
+ int stepW=(int)((double)distanceW/s_RGBs.iTime*dwFrameTime);
+
+
+ /*int diffR=abs(s_CurRGB.red-s_RGBs.red1+stepR);
+ int diffG=abs(s_CurRGB.green-s_RGBs.green1+stepG);
+ int diffB=abs(s_CurRGB.blue-s_RGBs.blue1+stepB);
+
+ if(diffR>maxDiffR)
+ stepR=s_CurRGB.red+maxDiffR-s_RGBs.red1;
+ if(diffG>maxDiffG)
+ stepG=s_CurRGB.green+maxDiffG-s_RGBs.green1;
+ if(diffB>maxDiffB)
+ stepB=s_CurRGB.blue+maxDiffB-s_RGBs.blue1;*/
+
+ s_CurRGB.red=s_RGBs.red1+stepR;
+ s_CurRGB.green=s_RGBs.green1+stepG;
+ s_CurRGB.blue=s_RGBs.blue1+stepB;
+ s_CurRGB.white=s_RGBs.white1+stepW;
+
+ /*if(s_CurRGB.red<=SLOWLIMIT)
+ {
+ static int counter=0;
+ if(counter==SLOWTIMES)
+ {
+ if(s_CurRGB.reds_RGBs.red2) s_CurRGB.red--;
+ counter=0;
+ }
+ counter++;
+ }
+ else
+ {
+ if(s_CurRGB.reds_RGBs.red2) s_CurRGB.red--;
+ }
+
+ if(s_CurRGB.blue<=SLOWLIMIT)
+ {
+ static int counter=0;
+ if(counter==SLOWTIMES)
+ {
+ if(s_CurRGB.blues_RGBs.blue2) s_CurRGB.blue--;
+ counter=0;
+ }
+ counter++;
+ }
+ else
+ {
+ if(s_CurRGB.blues_RGBs.blue2) s_CurRGB.blue--;
+ }
+
+
+ if(s_CurRGB.green<=SLOWLIMIT)
+ {
+ static int counter=0;
+ if(counter==SLOWTIMES)
+ {
+ if(s_CurRGB.greens_RGBs.green2) s_CurRGB.green--;
+ counter=0;
+ }
+ counter++;
+ }
+ else
+ {
+ if(s_CurRGB.greens_RGBs.green2) s_CurRGB.green--;
+ }*/
+
+
+ SetRGBLed(s_CurRGB.red,s_CurRGB.green,s_CurRGB.blue,s_CurRGB.white);
+
+ /*static int i=0,minR=255,minG=255,minB=255,maxR=0,maxG=0,maxB=0;
+ minR=s_CurRGB.redmaxR?s_CurRGB.red:maxR;
+ maxG=s_CurRGB.green>maxG?s_CurRGB.green:maxG;
+ maxB=s_CurRGB.blue>maxB?s_CurRGB.blue:maxB;
+
+ static int dwLastTime=0;
+ i=(i+1) % 100;
+ if(i==0)
+ {
+ CLog::DebugLog("AmbiTime: %i minR%i G%i B%i maxR%i G%i B%i",timeGetTime()-dwLastTime,minR,minG,minB,maxR,maxG,maxB);
+ dwLastTime=timeGetTime();
+ minR=minG=minB=255;
+ maxR=maxG=maxB=0;
+ }*/
+ }
+ else
+ {
+ strLastTransition = "reset";
+ }
+ }
+ /*else if(s_RGBs.strTransition.Equals("firework"))
+ {
static double distanceR,distanceG,distanceB,distanceW;
+ static double logScaleR,logScaleG,logScaleB,logScaleW;
+ static int counter;
- if(!strLastTransition.Equals("fade"))
- {
- distanceR = bRepeat ? s_RGBs.red1-s_RGBs.red2 : s_RGBs.red2-s_RGBs.red1;
- distanceG = bRepeat ? s_RGBs.green1-s_RGBs.green2 : s_RGBs.green2-s_RGBs.green1;
- distanceB = bRepeat ? s_RGBs.blue1-s_RGBs.blue2 : s_RGBs.blue2-s_RGBs.blue1;
- distanceW = bRepeat ? s_RGBs.white1-s_RGBs.white2 : s_RGBs.white2-s_RGBs.white1;
+ if(!strLastTransition.Equals("firework"))
+ {
+ counter=0;
+ strLastTransition="reset";
+ }
- strLastTransition = "fade";
+ if(strLastTransition.Equals("reset"))
+ {
+ distanceR = s_RGBs.red1-s_RGBs.red2;
+ distanceG = s_RGBs.green1-s_RGBs.green2;
+ distanceB = s_RGBs.blue1-s_RGBs.blue2;
+ distanceW = s_RGBs.white1-s_RGBs.white2;
- if(s_RGBs.strTransition.Equals("faderepeat"))bRepeat=!bRepeat;
- }
+ logScaleR = 127/log(distanceR);
+ logScaleG = 127/log(distanceG);
+ logScaleB = 127/log(distanceB);
+ logScaleW = 127/log(distanceW);
- if(dwFrameTime <= s_RGBs.iTime )
- {
- double stepR=distanceR/s_RGBs.iTime*dwFrameTime;
- double stepG=distanceG/s_RGBs.iTime*dwFrameTime;
- double stepB=distanceB/s_RGBs.iTime*dwFrameTime;
- double stepW=distanceW/s_RGBs.iTime*dwFrameTime;
+ counter++;
+ }
- s_CurRGB.red=(bRepeat ? s_RGBs.red1 : s_RGBs.red2) +(int)stepR;
- s_CurRGB.green=(bRepeat ? s_RGBs.green1 : s_RGBs.green2)+(int)stepG;
- s_CurRGB.blue=(bRepeat ? s_RGBs.blue1 : s_RGBs.blue2)+(int)stepB;
- s_CurRGB.white=(bRepeat ? s_RGBs.white1 : s_RGBs.white2)+(int)stepW;
-
- SetRGBLed(s_CurRGB.red,s_CurRGB.green,s_CurRGB.blue,s_CurRGB.white);
- }
- else if(s_RGBs.strTransition.Equals("fadeloop") || s_RGBs.strTransition.Equals("faderepeat"))
+ if(counter<=3)
{
- strLastTransition="none";
- dwFrameTime = 0;
- dwLastTime = timeGetTime();
+ if(dwFrameTime <= s_RGBs.iTime )
+ {
+ double stepR=log(distanceR/s_RGBs.iTime*dwFrameTime)*logScaleR*-1;
+ double stepG=log(distanceG/s_RGBs.iTime*dwFrameTime)*logScaleG*-1;
+ double stepB=log(distanceB/s_RGBs.iTime*dwFrameTime)*logScaleB*-1;
+ double stepW=log(distanceW/s_RGBs.iTime*dwFrameTime)*logScaleW*-1;
+
+ s_CurRGB.red=s_RGBs.red1+(int)stepR;
+ s_CurRGB.green=s_RGBs.green1+(int)stepG;
+ s_CurRGB.blue=s_RGBs.blue1+(int)stepB;
+ s_CurRGB.white=s_RGBs.white1+(int)stepW;
+
+ SetRGBLed(s_CurRGB.red,s_CurRGB.green,s_CurRGB.blue,s_CurRGB.white);
}
- }
-
- Sleep(10);
- }
+ else
+ {
+ SetRGBLed(0,0,0,s_CurRGB.white);
+ Sleep(200);
+ strLastTransition="reset";
+ dwLastTime = timeGetTime();
+ }
+ }
+ }*/
+ }
+ for(int i=0;i<10;i++)
+ Sleep(1);
+ }
}
void ILEDSmartxxRGB::OnExit()
{
- SetRGBLed(0,0,0,0xb); //r=0,g=0,b=0 w=0xb (Status LED ON)
+ // this can also be called when navigationg in the XBMC while a movie runs in background.
+ // when in menu it can happen that parallel to AmbiLight PWMControl will be started. In that
+ // case we want AmbiLight to stay on and so the ambilight will stop the rgb-thread. To avoid
+ // flashing of LEDs in this case we don't turn them off.
+ if(!AmbiLightParams.AmbiLightIsPlaying)
+ {
+ SetRGBLed(0,0,0,0xb); //r=0,g=0,b=0 w=0xb (Status LED ON)
- // SmartXX OPX port for RGB-Red is the same port for display brightness control
- // Restoring brightness value from the settings
- if ( g_sysinfo.SmartXXModCHIP().Equals("SmartXX OPX") )
- g_lcd->SetBackLight(g_guiSettings.GetInt("lcd.backlight"));
+ // SmartXX OPX port for RGB-Red is the same port for display brightness control
+ // Restoring brightness value from the settings
+ if ( g_sysinfo.SmartXXModCHIP().Equals("SmartXX OPX") )
+ g_lcd->SetBackLight(g_guiSettings.GetInt("lcd.backlight"));
- CLog::Log(LOGDEBUG,"Stopping SmartXX RGB LED thread");
+ CLog::Log(LOGDEBUG,"Stopping SmartXX RGB LED thread");
+ }
}
bool ILEDSmartxxRGB::Start()
{
- if (g_sysinfo.SmartXXModCHIP().Equals("SmartXX V3") || g_sysinfo.SmartXXModCHIP().Equals("SmartXX OPX"))
- {
+ if ((g_sysinfo.SmartXXModCHIP().Equals("SmartXX V3") || g_sysinfo.SmartXXModCHIP().Equals("SmartXX OPX"))) // && !AmbiLightParams.AmbiLightIsPlaying && !isPaused)
+ {
Create();
return true;
}
@@ -232,61 +447,76 @@
StopThread();
}
bool ILEDSmartxxRGB::IsRunning()
-{
+{
return (m_ThreadHandle != NULL);
}
+void ILEDSmartxxRGB::Pause()
+{
+ //isPaused=true;
+}
+void ILEDSmartxxRGB::Continue()
+{
+ if(isPaused)
+ dwLastTime=timeGetTime();
+ isPaused=false;
+}
+bool ILEDSmartxxRGB::IsPaused()
+{
+ return isPaused;
+}
+
void ILEDSmartxxRGB::getRGBValues(const CStdString &strRGBa, const CStdString &strRGBb, const CStdString &strWhiteA, const CStdString &strWhiteB, RGBVALUES* s_rgb)
{
- DWORD red=0,green=0,blue=0,white=0;
-
+ DWORD red=0,green=0,blue=0,white=0;
+
int ret = sscanf(strRGBa,"#%2X%2X%2X",&red,&green,&blue);
- if(ret == 3)
- {
- s_rgb->red1 = int(red/2);
- s_rgb->green1 = int(green/2);
- s_rgb->blue1 = int(blue/2);
- }
- else
- {
- s_rgb->red1 = 0;
- s_rgb->green1 = 0;
- s_rgb->blue1 = 0;
- }
+ if(ret == 3)
+ {
+ s_rgb->red1 = int(red/2);
+ s_rgb->green1 = int(green/2);
+ s_rgb->blue1 = int(blue/2);
+ }
+ else
+ {
+ s_rgb->red1 = 0;
+ s_rgb->green1 = 0;
+ s_rgb->blue1 = 0;
+ }
- ret = sscanf(strRGBb,"#%2X%2X%2X",&red,&green,&blue);
- if(ret == 3)
- {
- s_rgb->red2 = int(red/2);
- s_rgb->green2 = int(green/2);
- s_rgb->blue2 = int(blue/2);
- }
- else
- {
- s_rgb->red2 = 0;
- s_rgb->green2 = 0;
- s_rgb->blue2 = 0;
- }
-
+ ret = sscanf(strRGBb,"#%2X%2X%2X",&red,&green,&blue);
+ if(ret == 3)
+ {
+ s_rgb->red2 = int(red/2);
+ s_rgb->green2 = int(green/2);
+ s_rgb->blue2 = int(blue/2);
+ }
+ else
+ {
+ s_rgb->red2 = 0;
+ s_rgb->green2 = 0;
+ s_rgb->blue2 = 0;
+ }
+
ret = sscanf(strWhiteA,"#%2X",&white);
- if(ret == 1)
- {
+ if(ret == 1)
+ {
s_rgb->white1 = int(white/2);
- }
- else
- {
+ }
+ else
+ {
s_rgb->white1 = 0;
- }
+ }
ret = sscanf(strWhiteB,"#%2X",&white);
- if(ret == 1)
- {
+ if(ret == 1)
+ {
s_rgb->white2 = int(white/2);
- }
- else
- {
+ }
+ else
+ {
s_rgb->white2 = 0;
- }
+ }
}
bool ILEDSmartxxRGB::SetRGBStatus(const CStdString &strStatus)
@@ -298,12 +528,28 @@
bool ILEDSmartxxRGB::SetRGBLed(int red, int green, int blue, int white)
{
+ static oldR=0,oldG=0,oldB=0;
+ /*if(abs(oldR-red)>1)
+ CLog::DebugLog("RSkipAmbilight");
+ if(abs(oldG-green)>1)
+ CLog::DebugLog("GSkipAmbilight");
+ if(abs(oldB-blue)>1)
+ CLog::DebugLog("BSkipAmbilight");*/
+ oldR=red;
+ oldG=green;
+ oldB=blue;
+
+
+ red=CLAMP(red/2,0,127);
+ green=CLAMP(green/2,0,127);
+ blue=CLAMP(blue/2,0,127);
+
_outp( g_sysinfo.SmartXXModCHIP().Equals("SmartXX V3") ? SMARTXX_PWD_RED:SMARTXX_OPX_PWD_RED, red);
_outp( g_sysinfo.SmartXXModCHIP().Equals("SmartXX V3") ? SMARTXX_PWD_GREEN:SMARTXX_OPX_PWD_GREEN, green);
_outp( g_sysinfo.SmartXXModCHIP().Equals("SmartXX V3") ? SMARTXX_PWD_BLUE:SMARTXX_OPX_PWD_BLUE, blue);
-
+
_outp( SMARTXX_PWM_STATUS, white);
-
+
return true;
}
@@ -344,3 +590,575 @@
return SetRGBStatus(strTransition);
}
+
+bool ILEDSmartxxRGB::SetRGBState(tRGBColor rgb)
+{
+ // we have a new request: start reset
+ strCurrentStatus = "NULL";
+ strLastStatus = "NULL";
+ strLastTransition = "NULL";
+ s_RGBs.strTransition = "NULL";
+ // is used to identify first frame in blink-mode, 0 is not usable to do this check as zero is
+ // a valid value for a color
+ s_RGBs.strTransition = "fade2";
+ s_RGBs.red2 =rgb.r;
+ s_RGBs.green2 =rgb.g;
+ s_RGBs.blue2 =rgb.b;
+
+ /*s_RGBs.red1 =s_CurRGB.red;
+ s_RGBs.green1 =s_CurRGB.green;
+ s_RGBs.blue1 =s_CurRGB.blue ;*/
+
+ //dwFrameTime = 0;
+ //dwLastTime = timeGetTime();
+ bRepeat = false;
+ // end reset
+
+
+
+ SetRGBStatus(s_RGBs.strTransition);
+
+ if(!IsRunning())
+ Start();
+ return true;
+}
+
+
+void ILEDSmartxxRGB::AmbiLightUpdateFrameNumber()
+{
+ // only do this, if ambilight is enabled...
+ if(g_advancedSettings.m_ambiLight && AmbiLightParams.AmbiLightIsPlaying)
+ {
+ AmbiLightParams.recentFrame=(AmbiLightParams.recentFrame+1) % g_advancedSettings.m_ambiLightFloatingAverageFrames;
+ AmbiLightParams.frameHasChanged=true;
+ }
+}
+
+void ILEDSmartxxRGB::AmbiLightSetAverageColor(unsigned int H,unsigned int S,unsigned int V)
+{
+ // this function is called after we've gotten the average color of the recent frame. It then shifts
+ // the array containing the values of our FloatingAverageArray (if enabled) to push out the oldest value and
+ // insert these new values at the beginning (FIFO).
+
+ // first copy AmbiLightParams to local var for better handling...
+ AMBILIGHT ¶ms=AmbiLightParams;
+ // also copy our FloatingAverageFrames-var to local var...
+ unsigned int FloatingAverageFrames=g_advancedSettings.m_ambiLightFloatingAverageFrames;
+
+ // when mode is linear, then the oldest frame in our floating average counts once, the frame after that counts twice,
+ // the frame after that thrice and so on...
+ /*if(g_advancedSettings.m_ambiLightMode=="linear")
+ {
+ // in this case the sums have to be recalculated from zero...
+ params.sumR=0;
+ params.sumG=0;
+ params.sumB=0;
+ // recalculate RGB arrays, starting with the now oldest frame...
+ // if we have a framenumber of 5 at the moment and FloatingAverageFrames of 10
+ // then the first index is 5 which is the 6th field in the array, which takes now
+ // the oldest value...
+ for(unsigned int i=1;ioldSumH)
+ {
+ oldSumH=sumH;
+ hsv.h=i+1;
+ }
+ }
+ //now find the max inside our window...
+ int maxH=hsv.h;
+ for(int i=hsv.h+1;ihsvHisto.h[maxH]?i:maxH;
+ hsv.h=maxH;
+
+ //window limits for saturation histogram...
+ int iMin=CLAMP(hsv.h-WINDOW_SIZE,0,360);
+ int iMax=CLAMP(hsv.h+WINDOW_SIZE,0,360);
+
+ //now we count all pixels around the
+ int relevantPixelCount=0;
+ for(int i=iMin;i<=iMax;i++)
+ relevantPixelCount+=hsvHisto.h[i];
+
+ // nur wenn die Anzahl der für das Maximum relevanten Pixel eine Fläche einnimmt die größer als die Vorgegebene
+ // Minimalgröße ist wird die Saturation und der Value berechnet (ohne die bleibt die Farbe schwarz)...
+ if(relevantPixelCount*(g_advancedSettings.m_ambiLightSpaceBetweenPixels+1)>=params.SourceWidth*params.SourceHeight*MIN_PERCENTAGE)
+ {
+ //Saturation Histogramm
+ for(int i=0;i<(int)params.PixelCount;i++)
+ {
+ if(params.hsvMatrix[i].h>=iMin && params.hsvMatrix[i].h<=iMax)
+ hsvHisto.s[params.hsvMatrix[i].s]++;
+ }
+
+ //Max Saturation
+ for(int i=0;i<=100;i++)
+ hsv.s=hsvHisto.s[i]>hsvHisto.s[hsv.s] ? i : hsv.s;
+
+ //Value Average
+ int sumV=0;
+ for(int i=0;i<(int)params.PixelCount;i++)
+ sumV+=params.hsvMatrix[i].v;
+
+ if(params.PixelCount>0)
+ hsv.v=sumV/params.PixelCount;
+ }
+
+ rgb=HSV2RGB(hsv);
+
+ // now we take the power of gamma for each RGB-value and use our scale-factor to form an valid RGB-value...
+ // this gamma factor is an simple way to control how fast a LED turns bright especially in lower values. if in dark
+ // passages you always have blue light try an gamme value below 1 so blue will have a lower gamma curve. On the other
+ // hand you could pass Red and green a gamma above 1, common value would be e.g. gammaR=2.2, gammeG=2.0, gammaB=0.8
+ // (as blue often seems to be the brightest LED).
+ rgb.r=(int)(pow((float)rgb.r,params.gammaR)*params.gammaScaleR);
+ rgb.g=(int)(pow((float)rgb.g,params.gammaG)*params.gammaScaleG);
+ rgb.b=(int)(pow((float)rgb.b,params.gammaB)*params.gammaScaleB);
+
+ rgb.r=CLAMP(rgb.r,g_advancedSettings.m_ambiLightMinRGB,g_advancedSettings.m_ambiLightMaxRGB);
+ rgb.g=CLAMP(rgb.g,g_advancedSettings.m_ambiLightMinRGB,g_advancedSettings.m_ambiLightMaxRGB);
+ rgb.b=CLAMP(rgb.b,g_advancedSettings.m_ambiLightMinRGB,g_advancedSettings.m_ambiLightMaxRGB);
+
+
+ // our values get passed to the SmartXX...
+ SetRGBState(rgb);
+ //SetRGBLed(rgb.r,rgb.g,rgb.b,0);
+}
+
+void ILEDSmartxxRGB::AmbiLightParamsInit(unsigned int SourceWidth,unsigned int SourceHeight,YUVCOEF yuvcoef,YUVRANGE yuvrange)
+{
+ AMBILIGHT ¶ms=AmbiLightParams;
+
+ if(g_advancedSettings.m_ambiLight==true)
+ {
+ CLog::DebugLog ("Params x %i w %i",params.x,params.w);
+
+ CLog::Log(LOGDEBUG,"AmbiLight is initializing...");
+
+ s_CurRGB.red=2;
+ s_CurRGB.green=2;
+ s_CurRGB.blue=2;
+ params.AmbiLightIsPlaying=true;
+ // here we initialize our Params, it's always called, when a new movie starts...
+ params.frameHasChanged = false;
+ params.recentFrame = 0;
+
+ params.SourceWidth=SourceWidth;
+ params.SourceHeight=SourceHeight;
+
+ params.yuvcoef=yuvcoef;
+ params.yuvrange=yuvrange;
+
+ params.PixelCount=0;
+ params.RowCount=0;
+ params.PixelOverflow=0;
+
+ params.R=0;
+ params.G=0;
+ params.B=0;
+
+ params.hsvMatrix=new tHSVColor[92161];
+ //memset(¶ms.hsvMatrix,0,sizeof(params.hsvMatrix)*92161);
+
+ if(params.arrH==NULL)
+ {
+ params.hsvh=new tHSVHistogramm[g_advancedSettings.m_ambiLightFloatingAverageFrames];
+ params.arrH=new unsigned int[g_advancedSettings.m_ambiLightFloatingAverageFrames];
+ params.arrS=new unsigned int[g_advancedSettings.m_ambiLightFloatingAverageFrames];
+ params.arrV=new unsigned int[g_advancedSettings.m_ambiLightFloatingAverageFrames];
+ }
+
+ //initialize Array...
+ for(int i=0;i0)
+ {
+ //static unsigned int oldR=0,oldG=0,oldB=0;
+
+ // then we calculate the average of the last frame...
+
+ //unsigned int R=(unsigned int)(params.R/params.PixelCount);
+ //unsigned int G=(unsigned int)(params.G/params.PixelCount);
+ //unsigned int B=(unsigned int)(params.B/params.PixelCount);
+
+ // check, whether we have a skip (e.g. a new scene or st.)
+
+ //AmbiLightCheckSkip(oldR,oldG,oldB,R,G,B);
+ //oldR=R;oldG=G;oldB=B;
+
+ // pass it to SetAverageColor...
+
+ //AmbiLightSetAverageColor(R,G,B);
+
+ // and push it onto the SmartXX...
+ AmbiLightRGBSet();
+ }
+
+ // then the RGB-values get zeroed for a fresh start in this new frame...
+
+ params.R=0;
+ params.G=0;
+ params.B=0;
+
+ //memset(¶ms.hsvMatrix,0,sizeof(params.hsvMatrix)*92161);
+ // the counter is reset...
+
+ params.PixelCount=0;
+
+ // a new startposition for Pixeloverflow is calculated...
+
+ //params.PixelOverflow=g_advancedSettings.m_ambiLightSpaceBetweenPixels*params.recentFrame;
+
+ // and FrameChange Property...
+ params.frameHasChanged = false;
+ // and RowCount is reset...
+ params.RowCount=0;
+ }
+}
+void ILEDSmartxxRGB::AmbiLightCheckSkip(unsigned int oldR,unsigned int oldG,unsigned int oldB,unsigned int newR,unsigned int newG,unsigned int newB)
+{
+ /*AMBILIGHT ¶ms=AmbiLightParams;
+ int skipR=oldR-newR;
+ int skipG=oldG-newG;
+ int skipB=oldB-newB;
+
+ if(skipR<0) skipR*=-1;
+ if(skipG<0) skipG*=-1;
+ if(skipB<0) skipB*=-1;
+
+ if((skipR+skipG+skipB)>g_advancedSettings.m_ambiLightFilterThreshold*3)
+ {
+ for(int i=0;i=params.SourceHeight/2) || position=="left" || position=="right" || position=="all")
+ {
+ // these vars take the x-value from where to start getting pixels and the width. e.g. if you only want to interpret
+ // the left area of the screen, then StartX equals zero and EndX equals StartX+resolutionwidth/2
+ // these are always recalulated as x and w might change during different YUV-chunks...
+ unsigned int StartX;
+ unsigned int EndX;
+ // here we set StartX and EndW for different modes...
+ if(position=="left")
+ {
+ StartX=params.x;
+ EndX=StartX+params.w/2;
+ }
+ else if(position=="right")
+ {
+ StartX=params.x+params.SourceWidth/2;
+ EndX=StartX+params.w/2;
+ }
+ else
+ {
+ StartX=params.x;
+ EndX=StartX+params.w;
+ }
+ // now we go on the first pixel in a line is always Startx+PixelOverflow. PixelOverflow is calculated like this:
+ // when you have a resolution width of 1280px and SpaceBetweenPixels is 499 (means each 500th pixel in a row is
+ // interpreted) then the first Pixel taken is StartX+PixelCount which euals normally 0, then we add SpaceBetweenPixels+1
+ // so our next Pixel in this row is number 500 (between 0 and 500 there's 499px). the next one is, as you guessed
+ // 1000 and the next one should be 1500 but, as our resolution width is only 1280, here's the overflow
+ // (also you have to take notice of FloatingAverageFrames which decreases SpaceBetweenPixels, so if we have
+ // FloatingAverageFrames of 10 then in each Frame we would interpret only each 500*10=5000th pixel)
+ for(unsigned int i=10;i=g_advancedSettings.m_ambiLightDarknessLimit)
+ {
+ params.hsvMatrix[params.PixelCount]=hsv;
+ // this counter is necessary, so we know, how many pixels we've counted in this frame...
+ params.PixelCount++;
+ }
+ }
+ // now our OverFlow-Parameter gets set as described above...
+ params.PixelOverflow=params.PixelOverflow % g_advancedSettings.m_ambiLightSpaceBetweenPixels*g_advancedSettings.m_ambiLightFloatingAverageFrames;
+ }
+ // and the RowCounter gets increased, it's necessary for us to know where we are when mode is top or bottom...
+ params.RowCount++;
+}
+
+tRGBColor ILEDSmartxxRGB::AmbiLightYUV2RGB(BYTE y, BYTE u, BYTE v)
+{
+ YUVCOEF &coef = AmbiLightParams.yuvcoef;
+ YUVRANGE &range = AmbiLightParams.yuvrange;
+
+ // normalize
+ float Yp = (y - range.y_min) * 255.0f / (range.y_max - range.y_min);
+ float Up = (u - range.u_min) * 255.0f / (range.u_max - range.u_min) - 127.5f;
+ float Vp = (v - range.v_min) * 255.0f / (range.v_max - range.v_min) - 127.5f;
+
+ // recalculate
+ tRGBColor rgb;
+ rgb.r = (int)(Yp + coef.r_up * Up + coef.r_vp * Vp);
+ rgb.g = (int)(Yp + coef.g_up * Up + coef.g_vp * Vp);
+ rgb.b = (int)(Yp + coef.b_up * Up + coef.b_vp * Vp);
+
+ // clamp
+ rgb.r = CLAMP(rgb.r, 0, 255);
+ rgb.g = CLAMP(rgb.g, 0, 255);
+ rgb.b = CLAMP(rgb.b, 0, 255);
+
+ return rgb;
+}
+
+tHSVColor ILEDSmartxxRGB::RGB2HSV(tRGBColor rgb)
+{
+ float min,max,delta;
+ float h,s,v;
+ float r,g,b;
+
+ //skalieren der RGB-Werte auf das Intervall [0;1]
+ r=(float)rgb.r/255.0f;
+ g=(float)rgb.g/255.0f;
+ b=(float)rgb.b/255.0f;
+
+ min=MIN(r,g,b);
+ max=MAX(r,g,b);
+
+ v=max; // v
+
+ delta=max-min;
+
+ if(max!=0)
+ {
+ s=delta/max; // s
+
+ if(r==g && g==b)
+ h=0;
+ else if(r==max) // h
+ h=(g-b)/delta;
+ else if(g==max)
+ h=2+(b-r)/delta;
+ else
+ h=4+(r-g)/delta;
+
+ h*=60.0f;
+ if(h<0.0f)
+ h+=360.0f;
+ }
+ else
+ {
+ // r = g = b = 0 // s = 0, v is undefined
+ s=0.0f;
+ h=0.0f;
+ }
+
+ //skalieren: h=[0;360]; s,v=[0;100]
+ tHSVColor hsv;
+ hsv.h=(int)h;
+ hsv.s=(int)(s*100);
+ hsv.v=(int)(v*100);
+
+ return hsv;
+}
+
+tRGBColor ILEDSmartxxRGB::HSV2RGB(tHSVColor hsv)
+{
+ int i;
+ float f,p,q,t;
+ float h,s,v;
+ float r,g,b;
+
+ h=(float)hsv.h;
+ s=(float)hsv.s/100.0f;
+ v=(float)hsv.v/100.0f;
+
+ if(s==0)
+ {
+ r=g=b=v;
+ }
+ else
+ {
+ h/=60;
+ i=(int)h;
+ f=h-i;
+ p=v*(1-s);
+ q=v*(1-s*f);
+ t=v*(1-s*(1-f));
+
+ switch(i)
+ {
+ case 0:
+ case 6:
+ r=v;
+ g=t;
+ b=p;
+ break;
+ case 1:
+ r=q;
+ g=v;
+ b=p;
+ break;
+ case 2:
+ r=p;
+ g=v;
+ b=t;
+ break;
+ case 3:
+ r=p;
+ g=q;
+ b=v;
+ break;
+ case 4:
+ r=t;
+ g=p;
+ b=v;
+ break;
+ default:
+ r=v;
+ g=p;
+ b=q;
+ break;
+ }
+ }
+
+ tRGBColor rgb;
+ rgb.r=(int)(r*255);
+ rgb.g=(int)(g*255);
+ rgb.b=(int)(b*255);
+ return rgb;
+}
Index: xbmc/utils/LED.h
===================================================================
--- xbmc/utils/LED.h (revision 30593)
+++ xbmc/utils/LED.h (working copy)
@@ -22,6 +22,7 @@
*/
#include "Thread.h"
+#include "cores/VideoRenderers/XBoxRenderer.h"
#define SMARTXX_PWD_RED 0xf70c //PWM1: SmartXX V3 port for RGB red output
#define SMARTXX_PWD_GREEN 0xf70d //PWM2: SmartXX V3 port for RGB green output
@@ -35,27 +36,32 @@
//#define SMARTXX_PWM_LIGHT 0xF701 //PWM5: Display Port brightness control
//#define SMARTXX_PWM_CONTRAST 0xF703 //PWM6: Display Port contrast control
+#define MAX(a, b, c) (((a) > (b) && (a) > (c)) ? (a) : ((b) > (c) ? (b) : (c)))
+#define MIN(a, b, c) (((a) < (b) && (a) < (c)) ? (a) : ((b) < (c) ? (b) : (c)))
+
+#define FRAMES 10
+
struct RGBVALUE
{
- unsigned short red;
- unsigned short green;
- unsigned short blue;
+ unsigned short red;
+ unsigned short green;
+ unsigned short blue;
unsigned short white;
};
struct RGBVALUES
{
- CStdString strTransition;
- DWORD iTime;
+ CStdString strTransition;
+ DWORD iTime;
- unsigned short red1;
- unsigned short green1;
- unsigned short blue1;
+ unsigned short red1;
+ unsigned short green1;
+ unsigned short blue1;
unsigned short white1;
- unsigned short red2;
- unsigned short green2;
- unsigned short blue2;
+ unsigned short red2;
+ unsigned short green2;
+ unsigned short blue2;
unsigned short white2;
};
@@ -64,38 +70,129 @@
public:
static void CLEDControl(int ixLED);
};
-class ILEDSmartxxRGB : public CThread
-{
-protected:
- RGBVALUE s_CurRGB;
- RGBVALUES s_RGBs;
- CStdString strCurrentStatus;
- CStdString strLastStatus;
- CStdString strLastTransition;
-
- DWORD dwLastTime;
- DWORD dwFrameTime;
- bool bRepeat;
+// --- tRGBColor --------------------------------------------------------------
+typedef struct {
+ int r, g, b;
+} tRGBColor;
- void getRGBValues(const CStdString &strRGBa, const CStdString &strRGBb, const CStdString &strWhiteA, const CStdString &strWhiteB, RGBVALUES* s_rgb);
- bool SetRGBStatus(const CStdString &strStatus);
-
-public:
- ILEDSmartxxRGB();
- ~ILEDSmartxxRGB();
+// --- tHSVColor --------------------------------------------------------------
+typedef struct {
+ int h, s, v;
+} tHSVColor;
- virtual void OnStartup();
- virtual void OnExit();
- virtual void Process();
- virtual bool IsRunning();
- virtual bool Start();
- virtual void Stop();
- bool SetRGBState(const CStdString &strRGB1, const CStdString &strRGB2, const CStdString &strWhiteA, const CStdString &strWhiteB, const CStdString &strTransition, int iTranTime);
-
- //can used outsite to pass the values directly to the RGB port!
- //Don't forget to check if there is a SmartXX V3/OPX! -> CSysInfo::SmartXXModCHIP()
- bool SetRGBLed(int red, int green, int blue, int white);
+// --- tHSVHistogram ----------------------------------------------------------
+typedef struct {
+ int h[361];
+ int s[101];
+ int v[101];
+} tHSVHistogramm;
-};
-extern ILEDSmartxxRGB g_iledSmartxxrgb;
+struct AMBILIGHT {
+ bool frameHasChanged;
+ bool AmbiLightIsPlaying;
+
+ unsigned int SourceWidth;
+ unsigned int SourceHeight;
+ unsigned int RowCount;
+ unsigned int PixelCount;
+ unsigned int PixelOverflow;
+ int WidthRatio;
+
+ int x;
+ int w;
+
+ unsigned int R;
+ unsigned int G;
+ unsigned int B;
+
+ unsigned int *arrH;
+ unsigned int *arrS;
+ unsigned int *arrV;
+
+ // new calculation
+ tHSVHistogramm *hsvh;
+ tHSVColor *hsvMatrix;
+ // end new calculation
+
+ YUVCOEF yuvcoef;
+ YUVRANGE yuvrange;
+
+ unsigned int recentFrame;
+
+ float gammaR;
+ float gammaG;
+ float gammaB;
+ float gammaScaleR;
+ float gammaScaleG;
+ float gammaScaleB; };
+
+ class ILEDSmartxxRGB : public CThread
+ {
+ protected:
+ RGBVALUE s_CurRGB;
+ RGBVALUES s_RGBs;
+
+ CStdString strCurrentStatus;
+ CStdString strLastStatus;
+ CStdString strLastTransition;
+
+ DWORD dwLastTime;
+ DWORD dwFrameTime;
+ bool bRepeat;
+ bool isPaused;
+
+ void getRGBValues(const CStdString &strRGBa, const CStdString &strRGBb, const CStdString &strWhiteA, const CStdString &strWhiteB, RGBVALUES* s_rgb);
+ bool SetRGBStatus(const CStdString &strStatus);
+
+ public:
+ ILEDSmartxxRGB();
+ ~ILEDSmartxxRGB();
+
+ //virtual void OnStartup();
+ //virtual void OnExit();
+ //virtual void Process();
+ //virtual bool IsRunning();
+ //virtual bool Start();
+ //virtual void Stop();
+ //bool SetRGBState(const CStdString &strRGB1, const CStdString &strRGB2, const CStdString &strWhiteA, const CStdString &strWhiteB, const CStdString &strTransition, int iTranTime);
+
+ //can used outsite to pass the values directly to the RGB port!
+ //Don't forget to check if there is a SmartXX V3/OPX! -> CSysInfo::SmartXXModCHIP()
+ //bool SetRGBLed(int red, int green, int blue, int white);
+
+ AMBILIGHT AmbiLightParams;
+ void AmbiLightSetAverageColor(unsigned int R,unsigned int B,unsigned int G);
+ void AmbiLightRGBSet();
+ tRGBColor AmbiLightYUV2RGB(BYTE y, BYTE u, BYTE v);
+ void AmbiLightCheckSkip(unsigned int oldR,unsigned int oldG,unsigned int oldB,unsigned int newR,unsigned int newG,unsigned int newB);
+ tHSVColor RGB2HSV(tRGBColor rgb);
+ tRGBColor HSV2RGB(tHSVColor color); public:
+ //ILEDSmartxxRGB();
+ //~ILEDSmartxxRGB();
+
+ virtual void OnStartup();
+ virtual void OnExit();
+ virtual void Process();
+ virtual bool IsRunning();
+ virtual bool Start();
+ virtual void Stop();
+ virtual void Pause();
+ virtual void Continue();
+ virtual bool IsPaused();
+
+ bool SetRGBState(const CStdString &strRGB1, const CStdString &strRGB2, const CStdString &strWhiteA, const CStdString &strWhiteB, const CStdString &strTransition, int iTranTime);
+ bool SetRGBState(tRGBColor rgb);
+
+ //can used outsite to pass the values directly to the RGB port!
+ //Don't forget to check if there is a SmartXX V3/OPX! -> CSysInfo::SmartXXModCHIP()
+ bool SetRGBLed(int red, int green, int blue, int white);
+
+ void AmbiLightUpdateFrameNumber();
+ void AmbiLightRGBCalculate(BYTE *s0,BYTE *s1,BYTE *s2);
+ void AmbiLightParamsInit(unsigned int SourceWidth,unsigned int SourceHeight,YUVCOEF yuvcoef,YUVRANGE yuvrange);
+ void AmbiLightParamsUpdate(int x,int w,int widthRatio);
+ void AmbiLightUpdate();
+ void AmbiLightStop();
+ };
+ extern ILEDSmartxxRGB g_iledSmartxxrgb;