Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

[ios] - restore the music background playback ability #4351

Closed
wants to merge 6 commits into from

2 participants

Memphiz Trent Nelson
Memphiz
Owner

This is the final Pull Request for restoring the background music playback feature on iOS (which was broken since new iossink was introduced).

It relies on the now merged PR #4292

Please wait for my go (will do some paranoia tests again)

Backport of #4350

Trent Nelson

An RM will handle the back port. Closing this one.

Trent Nelson t-nelson closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Mar 7, 2014
  1. Memphiz

    [ios] - remove the audiosession handling from the sink - its handled …

    Memphiz authored
    …in the UIApplication already
  2. Memphiz

    [ios] - always send a speed change to ios when the player gets paused…

    Memphiz authored
    … (to stop the playback progress bar in the ios control center)
  3. Memphiz
  4. Memphiz
  5. Memphiz
Commits on Mar 10, 2014
  1. Memphiz

    [guilib] - sanity check hw textures before deleting (on ios when back…

    Memphiz authored
    …grounded it seems that ios diddles with textures and might delete them away without xbmc knowing)
This page is out of date. Refresh to see the latest.
4 xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp
View
@@ -166,7 +166,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
@@ -2134,7 +2134,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
2  xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.h
View
@@ -180,7 +180,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
52 xbmc/cores/AudioEngine/Sinks/AESinkDARWINIOS.cpp
View
@@ -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)
@@ -316,25 +312,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 = {};
@@ -439,17 +422,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;
}
@@ -464,7 +436,6 @@ void CAAudioUnitSink::deactivateAudioSession()
pause();
AudioUnitUninitialize(m_audioUnit);
AudioComponentInstanceDispose(m_audioUnit), m_audioUnit = NULL;
- AudioSessionSetActive(false);
AudioSessionRemovePropertyListenerWithUserData(kAudioSessionProperty_AudioRouteChange,
sessionPropertyCallback, this);
AudioSessionRemovePropertyListenerWithUserData(kAudioSessionProperty_CurrentHardwareOutputVolume,
@@ -492,27 +463,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);
- }
- }
-}
-
OSStatus CAAudioUnitSink::renderCallback(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp *inTimeStamp, UInt32 inOutputBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData)
{
2  xbmc/guilib/DispResource.h
View
@@ -20,7 +20,7 @@
#pragma once
-#if defined(HAS_GLX) || defined(TARGET_DARWIN_OSX)
+#if defined(HAS_GLX) || defined(TARGET_DARWIN)
class IDispResource
{
public:
8 xbmc/guilib/TextureManager.cpp
View
@@ -478,7 +478,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 (glIsTexture(m_unusedHwTextures[i]))
+#endif
+ glDeleteTextures(1, (GLuint*) &m_unusedHwTextures[i]);
}
#endif
m_unusedHwTextures.clear();
10 xbmc/osx/ios/XBMCController.mm
View
@@ -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)
{
10 xbmc/windowing/osx/WinSystemIOS.h
View
@@ -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,17 @@ 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);
protected:
virtual bool PresentRenderImpl(const CDirtyRegionList &dirty);
@@ -72,6 +80,8 @@ class CWinSystemIOS : public CWinSystemBase, public CRenderSystemGLES
bool m_bWasFullScreenBeforeMinimize;
CStdString m_eglext;
int m_iVSyncErrors;
+ CCriticalSection m_resourceSection;
+ std::vector<IDispResource*> m_resources;
private:
bool GetScreenResolution(int* w, int* h, double* fps, int screenIdx);
24 xbmc/windowing/osx/WinSystemIOS.mm
View
@@ -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
@@ -318,6 +320,28 @@
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);
+ 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)
{
}
Something went wrong with that request. Please try again.