Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge pull request #4350 from Memphiz/iosbgmusic

[ios] - restore the music background playback ability
  • Loading branch information...
commit fa2681d9621cdc51d5f3aaf551f2df51aff0165d 2 parents 502f150 + 8f87119
Trent Nelson authored
View
4 xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp
@@ -167,7 +167,7 @@ CActiveAE::~CActiveAE()
void CActiveAE::Dispose()
{
-#if defined(HAS_GLX) || defined(TARGET_DARWIN_OSX)
+#if defined(HAS_GLX) || defined(TARGET_DARWIN)
g_Windowing.Unregister(this);
#endif
@@ -2152,7 +2152,7 @@ bool CActiveAE::Initialize()
}
// hook into windowing for receiving display reset events
-#if defined(HAS_GLX) || defined(TARGET_DARWIN_OSX)
+#if defined(HAS_GLX) || defined(TARGET_DARWIN)
g_Windowing.Register(this);
#endif
View
2  xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.h
@@ -181,7 +181,7 @@ class CEngineStats
CCriticalSection m_lock;
};
-#if defined(HAS_GLX) || defined(TARGET_DARWIN_OSX)
+#if defined(HAS_GLX) || defined(TARGET_DARWIN)
class CActiveAE : public IAE, public IDispResource, private CThread
#else
class CActiveAE : public IAE, private CThread
View
52 xbmc/cores/AudioEngine/Sinks/AESinkDARWINIOS.cpp
@@ -114,14 +114,11 @@ class CAAudioUnitSink
static void sessionPropertyCallback(void *inClientData,
AudioSessionPropertyID inID, UInt32 inDataSize, const void *inData);
- static void sessionInterruptionCallback(void *inClientData, UInt32 inInterruption);
-
static OSStatus renderCallback(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp *inTimeStamp, UInt32 inOutputBusNumber, UInt32 inNumberFrames,
AudioBufferList *ioData);
bool m_setup;
- bool m_initialized;
bool m_activated;
AudioUnit m_audioUnit;
AudioStreamBasicDescription m_outputFormat;
@@ -142,8 +139,7 @@ class CAAudioUnitSink
};
CAAudioUnitSink::CAAudioUnitSink()
-: m_initialized(false)
-, m_activated(false)
+: m_activated(false)
, m_buffer(NULL)
, m_playing(false)
, m_playing_saved(false)
@@ -335,25 +331,12 @@ bool CAAudioUnitSink::setupAudio()
if (m_setup && m_audioUnit)
return true;
- // Audio Session Setup
- UInt32 sessionCategory = kAudioSessionCategory_MediaPlayback;
- status = AudioSessionSetProperty(kAudioSessionProperty_AudioCategory,
- sizeof(sessionCategory), &sessionCategory);
- if (status != noErr)
- {
- CLog::Log(LOGERROR, "%s error setting sessioncategory (error: %d)", __PRETTY_FUNCTION__, (int)status);
- return false;
- }
-
AudioSessionAddPropertyListener(kAudioSessionProperty_AudioRouteChange,
sessionPropertyCallback, this);
AudioSessionAddPropertyListener(kAudioSessionProperty_CurrentHardwareOutputVolume,
sessionPropertyCallback, this);
- if (AudioSessionSetActive(true) != noErr)
- return false;
-
// Audio Unit Setup
// Describe a default output unit.
AudioComponentDescription description = {};
@@ -458,17 +441,6 @@ bool CAAudioUnitSink::activateAudioSession()
{
if (!m_activated)
{
- if (!m_initialized)
- {
- OSStatus osstat = AudioSessionInitialize(NULL, kCFRunLoopDefaultMode, sessionInterruptionCallback, this);
- if (osstat == kAudioSessionNoError || osstat == kAudioSessionAlreadyInitialized)
- m_initialized = true;
- else
- {
- CLog::Log(LOGERROR, "%s error initializing audio session (error: %d)", __PRETTY_FUNCTION__, (int)osstat);
- return false;
- }
- }
if (checkAudioRoute() && setupAudio())
m_activated = true;
}
@@ -483,7 +455,6 @@ void CAAudioUnitSink::deactivateAudioSession()
pause();
AudioUnitUninitialize(m_audioUnit);
AudioComponentInstanceDispose(m_audioUnit), m_audioUnit = NULL;
- AudioSessionSetActive(false);
AudioSessionRemovePropertyListenerWithUserData(kAudioSessionProperty_AudioRouteChange,
sessionPropertyCallback, this);
AudioSessionRemovePropertyListenerWithUserData(kAudioSessionProperty_CurrentHardwareOutputVolume,
@@ -511,27 +482,6 @@ void CAAudioUnitSink::sessionPropertyCallback(void *inClientData,
}
}
-void CAAudioUnitSink::sessionInterruptionCallback(void *inClientData, UInt32 inInterruption)
-{
- CAAudioUnitSink *sink = (CAAudioUnitSink*)inClientData;
-
- if (inInterruption == kAudioSessionBeginInterruption)
- {
- CLog::Log(LOGDEBUG, "Bgn interuption");
- sink->m_playing_saved = sink->m_playing;
- sink->pause();
- }
- else if (inInterruption == kAudioSessionEndInterruption)
- {
- CLog::Log(LOGDEBUG, "End interuption");
- if (sink->m_playing_saved)
- {
- sink->m_playing_saved = false;
- sink->play(sink->m_mute);
- }
- }
-}
-
inline void LogLevel(unsigned int got, unsigned int wanted)
{
static unsigned int lastReported = INT_MAX;
View
2  xbmc/guilib/DispResource.h
@@ -20,7 +20,7 @@
#pragma once
-#if defined(HAS_GLX) || defined(TARGET_DARWIN_OSX)
+#if defined(HAS_GLX) || defined(TARGET_DARWIN)
class IDispResource
{
public:
View
12 xbmc/guilib/TextureManager.cpp
@@ -36,6 +36,10 @@
#include "URL.h"
#include <assert.h>
+#if defined(TARGET_DARWIN_IOS) && !defined(TARGET_DARWIN_IOS_ATV2)
+#include "windowing/WindowingFactory.h" // for g_Windowing in CGUITextureManager::FreeUnusedTextures
+#endif
+
using namespace std;
@@ -478,7 +482,13 @@ void CGUITextureManager::FreeUnusedTextures(unsigned int timeDelay)
#if defined(HAS_GL) || defined(HAS_GLES)
for (unsigned int i = 0; i < m_unusedHwTextures.size(); ++i)
{
- glDeleteTextures(1, (GLuint*) &m_unusedHwTextures[i]);
+ // on ios the hw textures might be deleted from the os
+ // when XBMC is backgrounded (e.x. for backgrounded music playback)
+ // sanity check before delete in that case.
+#if defined(TARGET_DARWIN_IOS) && !defined(TARGET_DARWIN_IOS_ATV2)
+ if (!g_Windowing.IsBackgrounded() || glIsTexture(m_unusedHwTextures[i]))
+#endif
+ glDeleteTextures(1, (GLuint*) &m_unusedHwTextures[i]);
}
#endif
m_unusedHwTextures.clear();
View
10 xbmc/osx/ios/XBMCController.mm
@@ -180,7 +180,7 @@ void AnnounceBridge(ANNOUNCEMENT::AnnouncementFlag flag, const char *sender, con
LOG(@"item: %@", item.description);
[g_xbmcController performSelectorOnMainThread:@selector(onPlay:) withObject:item waitUntilDone:NO];
}
- else if (msg == "OnSpeedChanged")
+ else if (msg == "OnSpeedChanged" || msg == "OnPause")
{
NSDictionary *item = [dict valueForKey:@"item"];
NSDictionary *player = [dict valueForKey:@"player"];
@@ -188,10 +188,8 @@ void AnnounceBridge(ANNOUNCEMENT::AnnouncementFlag flag, const char *sender, con
[item setValue:[NSNumber numberWithDouble:g_application.GetTime()] forKey:@"elapsed"];
LOG(@"item: %@", item.description);
[g_xbmcController performSelectorOnMainThread:@selector(OnSpeedChanged:) withObject:item waitUntilDone:NO];
- }
- else if (msg == "OnPause")
- {
- [g_xbmcController performSelectorOnMainThread:@selector(onPause:) withObject:[dict valueForKey:@"item"] waitUntilDone:NO];
+ if (msg == "OnPause")
+ [g_xbmcController performSelectorOnMainThread:@selector(onPause:) withObject:[dict valueForKey:@"item"] waitUntilDone:NO];
}
else if (msg == "OnStop")
{
@@ -1037,11 +1035,13 @@ - (void)enterBackground
m_isPlayingBeforeInactive = YES;
CApplicationMessenger::Get().MediaPauseIfPlaying();
}
+ g_Windowing.OnAppFocusChange(false);
}
- (void)enterForeground
{
PRINT_SIGNATURE();
+ g_Windowing.OnAppFocusChange(true);
// when we come back, restore playing if we were.
if (m_isPlayingBeforeInactive)
{
View
12 xbmc/windowing/osx/WinSystemIOS.h
@@ -27,6 +27,9 @@
#include "windowing/WinSystem.h"
#include "rendering/gles/RenderSystemGLES.h"
#include "utils/GlobalsHandling.h"
+#include "threads/CriticalSection.h"
+
+class IDispResource;
class CWinSystemIOS : public CWinSystemBase, public CRenderSystemGLES
{
@@ -56,12 +59,18 @@ class CWinSystemIOS : public CWinSystemBase, public CRenderSystemGLES
virtual bool BeginRender();
virtual bool EndRender();
+
+ virtual void Register(IDispResource *resource);
+ virtual void Unregister(IDispResource *resource);
+
virtual int GetNumScreens();
virtual int GetCurrentScreen();
void InitDisplayLink(void);
void DeinitDisplayLink(void);
double GetDisplayLinkFPS(void);
+ void OnAppFocusChange(bool focus);
+ bool IsBackgrounded() const { return m_bIsBackgrounded; }
protected:
virtual bool PresentRenderImpl(const CDirtyRegionList &dirty);
@@ -72,6 +81,9 @@ class CWinSystemIOS : public CWinSystemBase, public CRenderSystemGLES
bool m_bWasFullScreenBeforeMinimize;
CStdString m_eglext;
int m_iVSyncErrors;
+ CCriticalSection m_resourceSection;
+ std::vector<IDispResource*> m_resources;
+ bool m_bIsBackgrounded;
private:
bool GetScreenResolution(int* w, int* h, double* fps, int screenIdx);
View
26 xbmc/windowing/osx/WinSystemIOS.mm
@@ -34,6 +34,8 @@
#include "guilib/GraphicContext.h"
#include "guilib/Texture.h"
#include "utils/StringUtils.h"
+#include "guilib/DispResource.h"
+#include "threads/SingleLock.h"
#include <vector>
#undef BOOL
@@ -54,6 +56,7 @@
m_eWindowSystem = WINDOW_SYSTEM_IOS;
m_iVSyncErrors = 0;
+ m_bIsBackgrounded = false;
}
CWinSystemIOS::~CWinSystemIOS()
@@ -318,6 +321,29 @@
return rtn;
}
+void CWinSystemIOS::Register(IDispResource *resource)
+{
+ CSingleLock lock(m_resourceSection);
+ m_resources.push_back(resource);
+}
+
+void CWinSystemIOS::Unregister(IDispResource* resource)
+{
+ CSingleLock lock(m_resourceSection);
+ std::vector<IDispResource*>::iterator i = find(m_resources.begin(), m_resources.end(), resource);
+ if (i != m_resources.end())
+ m_resources.erase(i);
+}
+
+void CWinSystemIOS::OnAppFocusChange(bool focus)
+{
+ CSingleLock lock(m_resourceSection);
+ m_bIsBackgrounded = !focus;
+ CLog::Log(LOGDEBUG, "CWinSystemIOS::OnAppFocusChange: %d", focus ? 1 : 0);
+ for (std::vector<IDispResource *>::iterator i = m_resources.begin(); i != m_resources.end(); i++)
+ (*i)->OnAppFocusChange(focus);
+}
+
void CWinSystemIOS::InitDisplayLink(void)
{
}
Please sign in to comment.
Something went wrong with that request. Please try again.