Permalink
Browse files

Merge pull request #4441 from Memphiz/osxdevicereset

[osx] - fix issues with turning off/on tv when playback is paused
  • Loading branch information...
2 parents 57a497d + e7151dd commit 0cfc102b34d0cb8b51d9163bf862b2acfb3e93bc @jmarshallnz jmarshallnz committed Mar 22, 2014
View
5 xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp
@@ -433,6 +433,7 @@ void CActiveAE::StateMachine(int signal, Protocol *port, Message *msg)
case CActiveAEControlProtocol::DEVICECHANGE:
time_t now;
time(&now);
+ CLog::Log(LOGDEBUG,"CActiveAE - device change event");
while (!m_extLastDeviceChange.empty() && (now - m_extLastDeviceChange.front() > 0))
{
m_extLastDeviceChange.pop();
@@ -444,6 +445,7 @@ void CActiveAE::StateMachine(int signal, Protocol *port, Message *msg)
}
m_extLastDeviceChange.push(now);
UnconfigureSink();
+ m_controlPort.PurgeOut(CActiveAEControlProtocol::DEVICECHANGE);
m_sink.EnumerateSinkList(true);
LoadSettings();
m_extError = false;
@@ -458,7 +460,6 @@ void CActiveAE::StateMachine(int signal, Protocol *port, Message *msg)
m_state = AE_TOP_ERROR;
m_extTimeout = 500;
}
- m_controlPort.PurgeOut(CActiveAEControlProtocol::DEVICECHANGE);
return;
case CActiveAEControlProtocol::PAUSESTREAM:
CActiveAEStream *stream;
@@ -632,11 +633,13 @@ void CActiveAE::StateMachine(int signal, Protocol *port, Message *msg)
switch (signal)
{
case CActiveAEControlProtocol::DISPLAYRESET:
+ CLog::Log(LOGDEBUG,"CActiveAE - display reset event");
displayReset = true;
case CActiveAEControlProtocol::INIT:
m_extError = false;
if (!displayReset)
{
+ m_controlPort.PurgeOut(CActiveAEControlProtocol::DEVICECHANGE);
m_sink.EnumerateSinkList(true);
LoadSettings();
}
View
15 xbmc/cores/AudioEngine/Sinks/AESinkDARWINOSX.cpp
@@ -414,18 +414,21 @@ bool CAESinkDARWINOSX::Initialize(AEAudioFormat &format, std::string &device)
if (StringUtils::EqualsNoCase(device, "default"))
{
CCoreAudioHardware::GetOutputDeviceName(device);
+ deviceID = CCoreAudioHardware::GetDefaultOutputDevice();
CLog::Log(LOGNOTICE, "%s: Opening default device %s", __PRETTY_FUNCTION__, device.c_str());
}
-
- for (size_t i = 0; i < devices.size(); i++)
+ else
{
- if (device.find(devices[i].second.m_deviceName) != std::string::npos)
+ for (size_t i = 0; i < devices.size(); i++)
{
- m_info = devices[i].second;
- deviceID = devices[i].first;
- break;
+ if (device.find(devices[i].second.m_deviceName) != std::string::npos)
+ {
+ deviceID = devices[i].first;
+ break;
+ }
}
}
+
if (!deviceID)
{
CLog::Log(LOGERROR, "%s: Unable to find device %s", __FUNCTION__, device.c_str());
View
13 xbmc/windowing/osx/WinSystemOSX.h
@@ -24,18 +24,23 @@
#include "windowing/WinSystem.h"
#include "threads/CriticalSection.h"
+#include "threads/Timer.h"
typedef struct SDL_Surface SDL_Surface;
class IDispResource;
class CWinEventsOSX;
-class CWinSystemOSX : public CWinSystemBase
+class CWinSystemOSX : public CWinSystemBase, public ITimerCallback
{
public:
+
CWinSystemOSX();
virtual ~CWinSystemOSX();
+ // ITimerCallback interface
+ virtual void OnTimeout();
+
// CWinSystemBase
virtual bool InitWindowSystem();
virtual bool DestroyWindowSystem();
@@ -69,7 +74,10 @@ class CWinSystemOSX : public CWinSystemBase
void WindowChangedScreen();
- void CheckDisplayChanging(u_int32_t flags);
+ void AnnounceOnLostDevice();
+ void AnnounceOnResetDevice();
+ void StartLostDeviceTimer();
+ void StopLostDeviceTimer();
void* GetCGLContextObj();
@@ -104,6 +112,7 @@ class CWinSystemOSX : public CWinSystemBase
CCriticalSection m_resourceSection;
std::vector<IDispResource*> m_resources;
+ CTimer m_lostDeviceTimer;
};
#endif
View
89 xbmc/windowing/osx/WinSystemOSX.mm
@@ -177,6 +177,11 @@ - (void) windowDidChangeScreenNotification:(NSNotification*) note;
#define MAX_DISPLAYS 32
+// if there was a devicelost callback
+// but no device reset for 3 secs
+// a timeout fires the reset callback
+// (for ensuring that e.x. AE isn't stuck)
+#define LOST_DEVICE_TIMEOUT_MS 3000
static NSWindow* blankingWindows[MAX_DISPLAYS];
void* CWinSystemOSX::m_lastOwnedContext = 0;
@@ -514,10 +519,18 @@ static void DisplayReconfigured(CGDirectDisplayID display,
CGDisplayChangeSummaryFlags flags, void* userData)
{
CWinSystemOSX *winsys = (CWinSystemOSX*)userData;
- if (!winsys)
+ if (!winsys)
return;
- if (flags & kCGDisplaySetModeFlag || flags & kCGDisplayBeginConfigurationFlag)
+ CLog::Log(LOGDEBUG, "CWinSystemOSX::DisplayReconfigured with flags %d", flags);
+
+ // we fire the callbacks on start of configuration
+ // or when the mode set was finished
+ // or when we are called with flags == 0 (which is undocumented but seems to happen
+ // on some macs - we treat it as device reset)
+
+ // first check if we need to call OnLostDevice
+ if (flags & kCGDisplayBeginConfigurationFlag)
{
// pre/post-reconfiguration changes
RESOLUTION res = g_graphicsContext.GetVideoResolution();
@@ -532,22 +545,37 @@ static void DisplayReconfigured(CGDirectDisplayID display,
pScreen = [[NSScreen screens] objectAtIndex:screenIdx];
}
+ // kCGDisplayBeginConfigurationFlag is only fired while the screen is still
+ // valid
if (pScreen)
{
CGDirectDisplayID xbmc_display = GetDisplayIDFromScreen(pScreen);
if (xbmc_display == display)
{
// we only respond to changes on the display we are running on.
- CLog::Log(LOGDEBUG, "CWinSystemOSX::DisplayReconfigured");
- winsys->CheckDisplayChanging(flags);
+ winsys->AnnounceOnLostDevice();
+ winsys->StartLostDeviceTimer();
}
}
}
+ else // the else case checks if we need to call OnResetDevice
+ {
+ // we fire if kCGDisplaySetModeFlag is set or if flags == 0
+ // (which is undocumented but seems to happen
+ // on some macs - we treat it as device reset)
+ // we also don't check the screen here as we might not even have
+ // one anymore (e.x. when tv is turned off)
+ if (flags & kCGDisplaySetModeFlag || flags == 0)
+ {
+ winsys->StopLostDeviceTimer(); // no need to timeout - we've got the callback
+ winsys->AnnounceOnResetDevice();
+ }
+ }
}
//---------------------------------------------------------------------------------
//---------------------------------------------------------------------------------
-CWinSystemOSX::CWinSystemOSX() : CWinSystemBase()
+CWinSystemOSX::CWinSystemOSX() : CWinSystemBase(), m_lostDeviceTimer(this)
{
m_eWindowSystem = WINDOW_SYSTEM_OSX;
m_glContext = 0;
@@ -566,6 +594,24 @@ static void DisplayReconfigured(CGDirectDisplayID display,
{
};
+void CWinSystemOSX::StartLostDeviceTimer()
+{
+ if (m_lostDeviceTimer.IsRunning())
+ m_lostDeviceTimer.Restart();
+ else
+ m_lostDeviceTimer.Start(LOST_DEVICE_TIMEOUT_MS, false);
+}
+
+void CWinSystemOSX::StopLostDeviceTimer()
+{
+ m_lostDeviceTimer.Stop();
+}
+
+void CWinSystemOSX::OnTimeout()
+{
+ AnnounceOnResetDevice();
+}
+
bool CWinSystemOSX::InitWindowSystem()
{
SDL_EnableUNICODE(1);
@@ -1689,25 +1735,22 @@ static void DisplayReconfigured(CGDirectDisplayID display,
m_movedToOtherScreen = true;
}
-void CWinSystemOSX::CheckDisplayChanging(u_int32_t flags)
+void CWinSystemOSX::AnnounceOnLostDevice()
{
- if (flags)
- {
- CSingleLock lock(m_resourceSection);
- // tell any shared resources
- if (flags & kCGDisplayBeginConfigurationFlag)
- {
- CLog::Log(LOGDEBUG, "CWinSystemOSX::CheckDisplayChanging:OnLostDevice");
- for (std::vector<IDispResource *>::iterator i = m_resources.begin(); i != m_resources.end(); i++)
- (*i)->OnLostDevice();
- }
- if (flags & kCGDisplaySetModeFlag)
- {
- CLog::Log(LOGDEBUG, "CWinSystemOSX::CheckDisplayChanging:OnResetDevice");
- for (std::vector<IDispResource *>::iterator i = m_resources.begin(); i != m_resources.end(); i++)
- (*i)->OnResetDevice();
- }
- }
+ CSingleLock lock(m_resourceSection);
+ // tell any shared resources
+ CLog::Log(LOGDEBUG, "CWinSystemOSX::AnnounceOnLostDevice");
+ for (std::vector<IDispResource *>::iterator i = m_resources.begin(); i != m_resources.end(); i++)
+ (*i)->OnLostDevice();
+}
+
+void CWinSystemOSX::AnnounceOnResetDevice()
+{
+ CSingleLock lock(m_resourceSection);
+ // tell any shared resources
+ CLog::Log(LOGDEBUG, "CWinSystemOSX::AnnounceOnResetDevice");
+ for (std::vector<IDispResource *>::iterator i = m_resources.begin(); i != m_resources.end(); i++)
+ (*i)->OnResetDevice();
}
void* CWinSystemOSX::GetCGLContextObj()

0 comments on commit 0cfc102

Please sign in to comment.