diff options
author | davilla <davilla@xbmc.org> | 2013-02-09 11:35:13 -0800 |
---|---|---|
committer | davilla <davilla@xbmc.org> | 2013-02-09 11:35:13 -0800 |
commit | 3cfc1c8e2896a537d6c4c1ecd815d4cb6e6a76e6 (patch) | |
tree | 4a6a1dcccdf23b83e9c7e854fe505bf4dc4aca26 | |
parent | 2ba85f9090d62053aa8bb90797dcd01688c48183 (diff) | |
parent | cc49b02bc4725a3a65195898d1537505f32373b5 (diff) |
Merge pull request #2152 from fritsch/ae-fix-proposal
AE: make forced enumeration possible
-rw-r--r-- | xbmc/cores/AudioEngine/AESinkFactory.cpp | 10 | ||||
-rw-r--r-- | xbmc/cores/AudioEngine/AESinkFactory.h | 2 | ||||
-rw-r--r-- | xbmc/cores/AudioEngine/Engines/SoftAE/SoftAE.cpp | 183 | ||||
-rw-r--r-- | xbmc/cores/AudioEngine/Engines/SoftAE/SoftAE.h | 6 | ||||
-rw-r--r-- | xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp | 39 | ||||
-rw-r--r-- | xbmc/cores/AudioEngine/Sinks/AESinkALSA.h | 4 | ||||
-rw-r--r-- | xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.cpp | 2 | ||||
-rw-r--r-- | xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.h | 2 | ||||
-rw-r--r-- | xbmc/cores/AudioEngine/Sinks/AESinkDirectSound.cpp | 2 | ||||
-rw-r--r-- | xbmc/cores/AudioEngine/Sinks/AESinkDirectSound.h | 2 | ||||
-rw-r--r-- | xbmc/cores/AudioEngine/Sinks/AESinkOSS.cpp | 2 | ||||
-rw-r--r-- | xbmc/cores/AudioEngine/Sinks/AESinkOSS.h | 2 | ||||
-rw-r--r-- | xbmc/cores/AudioEngine/Sinks/AESinkWASAPI.cpp | 2 | ||||
-rw-r--r-- | xbmc/cores/AudioEngine/Sinks/AESinkWASAPI.h | 4 |
14 files changed, 202 insertions, 60 deletions
diff --git a/xbmc/cores/AudioEngine/AESinkFactory.cpp b/xbmc/cores/AudioEngine/AESinkFactory.cpp index b066ecd30e..9917f11722 100644 --- a/xbmc/cores/AudioEngine/AESinkFactory.cpp +++ b/xbmc/cores/AudioEngine/AESinkFactory.cpp @@ -129,15 +129,15 @@ IAESink *CAESinkFactory::Create(std::string &device, AEAudioFormat &desiredForma return NULL; } -#define ENUMERATE_SINK(SINK) { \ +#define ENUMERATE_SINK(SINK, force) { \ AESinkInfo info; \ info.m_sinkName = #SINK; \ - CAESink ##SINK::EnumerateDevicesEx(info.m_deviceInfoList); \ + CAESink ##SINK::EnumerateDevicesEx(info.m_deviceInfoList, force); \ if(!info.m_deviceInfoList.empty()) \ list.push_back(info); \ } -void CAESinkFactory::EnumerateEx(AESinkInfoList &list) +void CAESinkFactory::EnumerateEx(AESinkInfoList &list, bool force) { #if defined(TARGET_WINDOWS) ENUMERATE_SINK(DirectSound); @@ -147,10 +147,10 @@ void CAESinkFactory::EnumerateEx(AESinkInfoList &list) ENUMERATE_SINK(AUDIOTRACK); #elif defined(TARGET_LINUX) || defined(TARGET_FREEBSD) #if defined(HAS_ALSA) - ENUMERATE_SINK(ALSA); + ENUMERATE_SINK(ALSA, force); #endif - ENUMERATE_SINK(OSS); + ENUMERATE_SINK(OSS, force); #endif } diff --git a/xbmc/cores/AudioEngine/AESinkFactory.h b/xbmc/cores/AudioEngine/AESinkFactory.h index 99c53f9be2..185f562274 100644 --- a/xbmc/cores/AudioEngine/AESinkFactory.h +++ b/xbmc/cores/AudioEngine/AESinkFactory.h @@ -40,6 +40,6 @@ class CAESinkFactory public: static void ParseDevice(std::string &device, std::string &driver); static IAESink *Create(std::string &device, AEAudioFormat &desiredFormat, bool rawPassthrough); - static void EnumerateEx(AESinkInfoList &list); + static void EnumerateEx(AESinkInfoList &list, bool force = false); /* The force flag can be used to indicate the rescan devices */ }; diff --git a/xbmc/cores/AudioEngine/Engines/SoftAE/SoftAE.cpp b/xbmc/cores/AudioEngine/Engines/SoftAE/SoftAE.cpp index 410e20ce41..5676c721b1 100644 --- a/xbmc/cores/AudioEngine/Engines/SoftAE/SoftAE.cpp +++ b/xbmc/cores/AudioEngine/Engines/SoftAE/SoftAE.cpp @@ -59,6 +59,8 @@ CSoftAE::CSoftAE(): m_audiophile (true ), m_running (false ), m_reOpen (false ), + m_closeSink (false ), + m_sinkIsSuspended (false ), m_isSuspended (false ), m_softSuspend (false ), m_softSuspendTimer (0 ), @@ -74,21 +76,18 @@ CSoftAE::CSoftAE(): m_outputStageFn (NULL ), m_streamStageFn (NULL ) { + unsigned int c_retry = 5; CAESinkFactory::EnumerateEx(m_sinkInfoList); - for (AESinkInfoList::iterator itt = m_sinkInfoList.begin(); itt != m_sinkInfoList.end(); ++itt) + while(m_sinkInfoList.size() == 0 && c_retry > 0) { - CLog::Log(LOGNOTICE, "Enumerated %s devices:", itt->m_sinkName.c_str()); - int count = 0; - for (AEDeviceInfoList::iterator itt2 = itt->m_deviceInfoList.begin(); itt2 != itt->m_deviceInfoList.end(); ++itt2) - { - CLog::Log(LOGNOTICE, " Device %d", ++count); - CAEDeviceInfo& info = *itt2; - std::stringstream ss((std::string)info); - std::string line; - while(std::getline(ss, line, '\n')) - CLog::Log(LOGNOTICE, " %s", line.c_str()); - } + CLog::Log(LOGNOTICE, "No Devices found - retry: %d", c_retry); + Sleep(2000); + c_retry--; + // retry the enumeration + CAESinkFactory::EnumerateEx(m_sinkInfoList, true); } + CLog::Log(LOGNOTICE, "Found %lu Lists of Devices", m_sinkInfoList.size()); + PrintSinks(); } CSoftAE::~CSoftAE() @@ -179,6 +178,20 @@ void CSoftAE::OpenSink() m_wake.Set(); } +void CSoftAE::InternalCloseSink() +{ + /* close the old sink if it was open */ + if (m_sink) + { + CExclusiveLock sinkLock(m_sinkLock); + m_sink->Drain(); + m_sink->Deinitialize(); + delete m_sink; + m_sink = NULL; + } + m_closeSink = false; + m_closeEvent.Set(); +} /* this must NEVER be called from outside the main thread or Initialization */ void CSoftAE::InternalOpenSink() { @@ -305,15 +318,8 @@ void CSoftAE::InternalOpenSink() CExclusiveLock sinkLock(m_sinkLock); reInit = true; - - /* we are going to open, so close the old sink if it was open */ - if (m_sink) - { - m_sink->Drain(); - m_sink->Deinitialize(); - delete m_sink; - m_sink = NULL; - } + //close the sink cause it gets reinited + InternalCloseSink(); /* get the display name of the device */ GetDeviceFriendlyName(device); @@ -867,10 +873,17 @@ IAEStream *CSoftAE::FreeStream(IAEStream *stream) RemoveStream(m_playingStreams, (CSoftAEStream*)stream); RemoveStream(m_streams , (CSoftAEStream*)stream); lock.Leave(); - - /* if it was the master stream we need to reopen before deletion */ - if (m_masterStream == stream) - OpenSink(); + // Close completely when we go to suspend, reopen as it was old behaviour. + // Not opening when masterstream stops means clipping on S/PDIF. + if(m_isSuspended) + { + m_closeEvent.Reset(); + m_closeSink = true; + m_closeEvent.Wait(); + m_wake.Set(); + } + else if (m_masterStream == stream) + OpenSink(); delete (CSoftAEStream*)stream; return NULL; @@ -976,14 +989,54 @@ bool CSoftAE::Suspend() CSoftAEStream *stream = *itt; stream->Flush(); } + #if defined(TARGET_LINUX) + /*workaround sinks not playing sound after resume */ + StopAllSounds(); + CExclusiveLock sinkLock(m_sinkLock); + for (AESinkInfoList::iterator itt = m_sinkInfoList.begin(); itt != m_sinkInfoList.end(); ++itt) + { + itt->m_deviceInfoList.pop_back(); + } + if(m_sink) + { + /* Deinitialize and delete current m_sink */ + // we don't want that Run reopens our device, so we wait. + m_saveSuspend.Reset(); + // wait until we are looping in ProcessSuspend() + m_saveSuspend.Wait(); + m_sink->Drain(); + m_sink->Deinitialize(); + delete m_sink; + m_sink = NULL; + // signal anybody, that the sink is closed now + // this should help us not to run into deadlocks + if(m_closeSink) + m_closeEvent.Set(); + } + // The device list is now empty and must be reenumerated afterwards. + m_sinkInfoList.clear(); + #endif return true; } bool CSoftAE::Resume() { +#if defined(TARGET_LINUX) + // We must make sure, that we don't return empty. + if(m_isSuspended || m_sinkInfoList.empty()) + { + CLog::Log(LOGDEBUG, "CSoftAE::Resume - Re Enumerating Sinks"); + CExclusiveLock sinkLock(m_sinkLock); + // Forced enumeration - we are sure that we start completely fresh. + CAESinkFactory::EnumerateEx(m_sinkInfoList, true); + sinkLock.Leave(); // we leave here explicitly to not lock while printing new sinks + PrintSinks(); + } +#endif CLog::Log(LOGDEBUG, "CSoftAE::Resume - Resuming AE processing"); m_isSuspended = false; + // we flag reopen m_reOpen = true; return true; @@ -1000,6 +1053,16 @@ void CSoftAE::Run() { bool restart = false; + /* Clean Up what the suspend guy might have forgotten */ + // ProcessSuspending() cannot guarantee that we get our sink back softresumed + // that is a big problem as another thread could start adding packets + // this must be checked here, before writing anything on the sinks + if(m_sinkIsSuspended) + { + CLog::Log(LOGDEBUG, "CSoftAE::Run - Someone has forgotten to resume us (device resumed)"); + m_sink->SoftResume(); + m_sinkIsSuspended = false; + } if ((this->*m_outputStageFn)(hasAudio) > 0) hasAudio = false; /* taken some audio - reset our silence flag */ @@ -1020,6 +1083,12 @@ void CSoftAE::Run() restart = true; } + //we are told to close the sink + if(m_closeSink) + { + InternalCloseSink(); + } + /* Handle idle or forced suspend */ ProcessSuspend(); @@ -1028,8 +1097,8 @@ void CSoftAE::Run() { CLog::Log(LOGDEBUG, "CSoftAE::Run - Sink restart flagged"); InternalOpenSink(); - m_isSuspended = false; // exit Suspend state } + #if defined(TARGET_ANDROID) else if (m_playingStreams.empty() && m_playing_sounds.empty() @@ -1280,6 +1349,24 @@ int CSoftAE::RunTranscodeStage(bool hasAudio) return encodedFrames; } +void CSoftAE::PrintSinks() +{ + for (AESinkInfoList::iterator itt = m_sinkInfoList.begin(); itt != m_sinkInfoList.end(); ++itt) + { + CLog::Log(LOGNOTICE, "Enumerated %s devices:", itt->m_sinkName.c_str()); + int count = 0; + for (AEDeviceInfoList::iterator itt2 = itt->m_deviceInfoList.begin(); itt2 != itt->m_deviceInfoList.end(); ++itt2) + { + CLog::Log(LOGNOTICE, " Device %d", ++count); + CAEDeviceInfo& info = *itt2; + std::stringstream ss((std::string)info); + std::string line; + while(std::getline(ss, line, '\n')) + CLog::Log(LOGNOTICE, " %s", line.c_str()); + } + } +} + unsigned int CSoftAE::RunRawStreamStage(unsigned int channelCount, void *out, bool &restart) { StreamList resumeStreams; @@ -1395,10 +1482,9 @@ inline void CSoftAE::RemoveStream(StreamList &streams, CSoftAEStream *stream) inline void CSoftAE::ProcessSuspend() { - bool sinkIsSuspended = false; + m_sinkIsSuspended = false; unsigned int curSystemClock = 0; - -#if defined(TARGET_WINDOWS) +#if defined(TARGET_WINDOWS) || defined(TARGET_LINUX) if (!m_softSuspend && m_playingStreams.empty() && m_playing_sounds.empty() && !g_advancedSettings.m_streamSilence) { @@ -1410,37 +1496,54 @@ inline void CSoftAE::ProcessSuspend() if (m_softSuspend) curSystemClock = XbmcThreads::SystemClockMillis(); #endif - /* idle while in Suspend() state until Resume() called */ /* idle if nothing to play and user hasn't enabled */ /* continuous streaming (silent stream) in as.xml */ - while ((m_isSuspended || (m_softSuspend && (curSystemClock > m_softSuspendTimer))) && - m_running && !m_reOpen) + /* In case of Suspend stay in there until Resume is called from outer thread */ + while (m_isSuspended || ((m_softSuspend && (curSystemClock > m_softSuspendTimer)) && + m_running && !m_reOpen)) { - if (m_sink && !sinkIsSuspended) + if (!m_isSuspended && m_sink && !m_sinkIsSuspended) { /* put the sink in Suspend mode */ CExclusiveLock sinkLock(m_sinkLock); - if (!m_sink->SoftSuspend()) + if (m_sink && !m_sink->SoftSuspend()) { - sinkIsSuspended = false; //sink cannot be suspended + m_sinkIsSuspended = false; //sink cannot be suspended m_softSuspend = false; //break suspend loop break; } else - sinkIsSuspended = true; //sink has suspended processing + { + CLog::Log(LOGDEBUG, "Suspended the Sink"); + m_sinkIsSuspended = true; //sink has suspended processing + } sinkLock.Leave(); } + // Signal that the Suspend can go on now. + // Idea: Outer thread calls Suspend() - but + // because of AddPackets does not care about locks, we must make + // sure, that our school bus (AE::Run) is currently driving through + // some gas station, before we move away the sink. + if(m_isSuspended) + m_saveSuspend.Set(); /* idle for platform-defined time */ m_wake.WaitMSec(SOFTAE_IDLE_WAIT_MSEC); - /* check if we need to resume for stream or sound */ + /* check if we need to resume for stream or sound or somebody wants to open us + * the suspend checks are only there to: + * a) not run out of softSuspend directly when we are sleeping + * b) nail(!) the thread during real Suspend into this method + * Note: It is not enough to check the streams buffer, cause it might not be filled yet + * We have to check after ProcessSuspending() if the sink is still in softsleep and resume it + */ if (!m_isSuspended && (!m_playingStreams.empty() || !m_playing_sounds.empty())) { - m_reOpen = !m_sink->SoftResume(); // sink returns false if it requires reinit - sinkIsSuspended = false; //sink processing data - m_softSuspend = false; //break suspend loop + m_reOpen = m_reOpen || !m_sink->SoftResume(); // sink returns false if it requires reinit + m_sinkIsSuspended = false; //sink processing data + m_softSuspend = false; //break suspend loop (under some conditions) + CLog::Log(LOGDEBUG, "Resumed the Sink"); break; } } diff --git a/xbmc/cores/AudioEngine/Engines/SoftAE/SoftAE.h b/xbmc/cores/AudioEngine/Engines/SoftAE/SoftAE.h index 56fb417123..e131851591 100644 --- a/xbmc/cores/AudioEngine/Engines/SoftAE/SoftAE.h +++ b/xbmc/cores/AudioEngine/Engines/SoftAE/SoftAE.h @@ -116,6 +116,7 @@ private: void OpenSink(); void InternalOpenSink(); + void InternalCloseSink(); void ResetEncoder(); bool SetupEncoder(AEAudioFormat &format); void Deinitialize(); @@ -136,11 +137,15 @@ private: /* internal vars */ bool m_running, m_reOpen; + bool m_closeSink; + bool m_sinkIsSuspended; /* The sink is in unusable state, e.g. SoftSuspended */ bool m_isSuspended; /* engine suspended by external function to release audio context */ bool m_softSuspend; /* latches after last stream or sound played for timer below for idle */ unsigned int m_softSuspendTimer; /* time in milliseconds to hold sink open before soft suspend for idle */ CEvent m_reOpenEvent; CEvent m_wake; + CEvent m_closeEvent; + CEvent m_saveSuspend; CCriticalSection m_runningLock; /* released when the thread exits */ CCriticalSection m_streamLock; /* m_streams lock */ @@ -242,5 +247,6 @@ private: void RunNormalizeStage (unsigned int channelCount, void *out, unsigned int mixed); void RemoveStream(StreamList &streams, CSoftAEStream *stream); + void PrintSinks(); }; diff --git a/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp b/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp index 91218a48c3..60a0b7d51b 100644 --- a/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp +++ b/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp @@ -426,7 +426,6 @@ void CAESinkALSA::Deinitialize() if (m_pcm) { - snd_pcm_drop (m_pcm); snd_pcm_close(m_pcm); m_pcm = NULL; } @@ -487,7 +486,13 @@ double CAESinkALSA::GetCacheTotal() unsigned int CAESinkALSA::AddPackets(uint8_t *data, unsigned int frames, bool hasAudio) { if (!m_pcm) - return 0; + { + SoftResume(); + if(!m_pcm) + return 0; + + CLog::Log(LOGDEBUG, "CAESinkALSA - the grAEken is hunger, feed it (I am the downmost fallback - fix your code)"); + } int ret; @@ -676,12 +681,17 @@ bool CAESinkALSA::OpenPCMDevice(const std::string &name, const std::string ¶ return false; } -void CAESinkALSA::EnumerateDevicesEx(AEDeviceInfoList &list) +void CAESinkALSA::EnumerateDevicesEx(AEDeviceInfoList &list, bool force) { /* ensure that ALSA has been initialized */ snd_lib_error_set_handler(sndLibErrorHandler); - if(!snd_config) + if(!snd_config || force) + { + if(force) + snd_config_update_free_global(); + snd_config_update(); + } snd_config_t *config; snd_config_copy(&config, snd_config); @@ -1125,6 +1135,27 @@ bool CAESinkALSA::GetELD(snd_hctl_t *hctl, int device, CAEDeviceInfo& info, bool return true; } +bool CAESinkALSA::SoftSuspend() +{ + if(m_pcm) // it is still there + Deinitialize(); + + return true; +} +bool CAESinkALSA::SoftResume() +{ + // reinit all the clibber + if(!m_pcm) + { + if (!snd_config) + snd_config_update(); + + Initialize(m_initFormat, m_initDevice); + } + //we want that AE loves us again + return false; // force reinit +} + void CAESinkALSA::sndLibErrorHandler(const char *file, int line, const char *function, int err, const char *fmt, ...) { va_list arg; diff --git a/xbmc/cores/AudioEngine/Sinks/AESinkALSA.h b/xbmc/cores/AudioEngine/Sinks/AESinkALSA.h index db1ba80290..c60f8407ff 100644 --- a/xbmc/cores/AudioEngine/Sinks/AESinkALSA.h +++ b/xbmc/cores/AudioEngine/Sinks/AESinkALSA.h @@ -49,8 +49,10 @@ public: virtual double GetCacheTotal (); virtual unsigned int AddPackets (uint8_t *data, unsigned int frames, bool hasAudio); virtual void Drain (); + virtual bool SoftSuspend(); + virtual bool SoftResume(); - static void EnumerateDevicesEx(AEDeviceInfoList &list); + static void EnumerateDevicesEx(AEDeviceInfoList &list, bool force = false); private: CAEChannelInfo GetChannelLayout(AEAudioFormat format); void GetAESParams(const AEAudioFormat format, std::string& params); diff --git a/xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.cpp b/xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.cpp index e8a787606a..8f23b41187 100644 --- a/xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.cpp +++ b/xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.cpp @@ -236,7 +236,7 @@ void CAESinkAUDIOTRACK::SetVolume(float scale) m_volume_changed = true; } -void CAESinkAUDIOTRACK::EnumerateDevicesEx(AEDeviceInfoList &list) +void CAESinkAUDIOTRACK::EnumerateDevicesEx(AEDeviceInfoList &list, bool force) { m_info.m_channels.Reset(); m_info.m_dataFormats.clear(); diff --git a/xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.h b/xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.h index 46b35515f1..bbb7856e98 100644 --- a/xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.h +++ b/xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.h @@ -43,7 +43,7 @@ public: virtual void Drain (); virtual bool HasVolume (); virtual void SetVolume (float scale); - static void EnumerateDevicesEx(AEDeviceInfoList &list); + static void EnumerateDevicesEx(AEDeviceInfoList &list, bool force = false); private: virtual void Process(); diff --git a/xbmc/cores/AudioEngine/Sinks/AESinkDirectSound.cpp b/xbmc/cores/AudioEngine/Sinks/AESinkDirectSound.cpp index fe57258b93..f0fb225b6e 100644 --- a/xbmc/cores/AudioEngine/Sinks/AESinkDirectSound.cpp +++ b/xbmc/cores/AudioEngine/Sinks/AESinkDirectSound.cpp @@ -464,7 +464,7 @@ double CAESinkDirectSound::GetCacheTotal() return (double)m_dwBufferLen / (double)m_AvgBytesPerSec; } -void CAESinkDirectSound::EnumerateDevicesEx(AEDeviceInfoList &deviceInfoList) +void CAESinkDirectSound::EnumerateDevicesEx(AEDeviceInfoList &deviceInfoList, bool force) { CAEDeviceInfo deviceInfo; diff --git a/xbmc/cores/AudioEngine/Sinks/AESinkDirectSound.h b/xbmc/cores/AudioEngine/Sinks/AESinkDirectSound.h index 8d64001fd1..ffd281648c 100644 --- a/xbmc/cores/AudioEngine/Sinks/AESinkDirectSound.h +++ b/xbmc/cores/AudioEngine/Sinks/AESinkDirectSound.h @@ -43,8 +43,8 @@ public: virtual double GetCacheTime (); virtual double GetCacheTotal (); virtual unsigned int AddPackets (uint8_t *data, unsigned int frames, bool hasAudio); - static void EnumerateDevicesEx (AEDeviceInfoList &deviceInfoList); static std::string GetDefaultDevice (); + static void EnumerateDevicesEx (AEDeviceInfoList &deviceInfoList, bool force = false); private: void AEChannelsFromSpeakerMask(DWORD speakers); DWORD SpeakerMaskFromAEChannels(const CAEChannelInfo &channels); diff --git a/xbmc/cores/AudioEngine/Sinks/AESinkOSS.cpp b/xbmc/cores/AudioEngine/Sinks/AESinkOSS.cpp index 06b9a7fc4f..970e2365ed 100644 --- a/xbmc/cores/AudioEngine/Sinks/AESinkOSS.cpp +++ b/xbmc/cores/AudioEngine/Sinks/AESinkOSS.cpp @@ -427,7 +427,7 @@ void CAESinkOSS::Drain() // ??? } -void CAESinkOSS::EnumerateDevicesEx(AEDeviceInfoList &list) +void CAESinkOSS::EnumerateDevicesEx(AEDeviceInfoList &list, bool force) { int mixerfd; const char * mixerdev = "/dev/mixer"; diff --git a/xbmc/cores/AudioEngine/Sinks/AESinkOSS.h b/xbmc/cores/AudioEngine/Sinks/AESinkOSS.h index aa8a9f8f9a..7e2db8beb8 100644 --- a/xbmc/cores/AudioEngine/Sinks/AESinkOSS.h +++ b/xbmc/cores/AudioEngine/Sinks/AESinkOSS.h @@ -43,7 +43,7 @@ public: virtual double GetCacheTotal () { return 0.0; } /* FIXME */ virtual unsigned int AddPackets (uint8_t *data, unsigned int frames, bool hasAudio); virtual void Drain (); - static void EnumerateDevicesEx(AEDeviceInfoList &list); + static void EnumerateDevicesEx(AEDeviceInfoList &list, bool force = false); private: int m_fd; std::string m_device; diff --git a/xbmc/cores/AudioEngine/Sinks/AESinkWASAPI.cpp b/xbmc/cores/AudioEngine/Sinks/AESinkWASAPI.cpp index 8475d60f7e..f238d75421 100644 --- a/xbmc/cores/AudioEngine/Sinks/AESinkWASAPI.cpp +++ b/xbmc/cores/AudioEngine/Sinks/AESinkWASAPI.cpp @@ -559,7 +559,7 @@ bool CAESinkWASAPI::SoftResume() return false; } -void CAESinkWASAPI::EnumerateDevicesEx(AEDeviceInfoList &deviceInfoList) +void CAESinkWASAPI::EnumerateDevicesEx(AEDeviceInfoList &deviceInfoList, bool force) { IMMDeviceEnumerator* pEnumerator = NULL; IMMDeviceCollection* pEnumDevices = NULL; diff --git a/xbmc/cores/AudioEngine/Sinks/AESinkWASAPI.h b/xbmc/cores/AudioEngine/Sinks/AESinkWASAPI.h index a0c567ae7b..7111ea97a7 100644 --- a/xbmc/cores/AudioEngine/Sinks/AESinkWASAPI.h +++ b/xbmc/cores/AudioEngine/Sinks/AESinkWASAPI.h @@ -45,7 +45,7 @@ public: virtual unsigned int AddPackets (uint8_t *data, unsigned int frames, bool hasAudio); virtual bool SoftSuspend (); virtual bool SoftResume (); - static void EnumerateDevicesEx (AEDeviceInfoList &deviceInfoList); + static void EnumerateDevicesEx (AEDeviceInfoList &deviceInfoList, bool force = false); private: bool InitializeExclusive(AEAudioFormat &format); void AEChannelsFromSpeakerMask(DWORD speakers); @@ -78,4 +78,4 @@ private: unsigned int m_uiBufferLen; /* wasapi endpoint buffer size, in frames */ double m_avgTimeWaiting; /* time between next buffer of data from SoftAE and driver call for data */ double m_sinkLatency; /* time in seconds of total duration of the two WASAPI buffers */ -};
\ No newline at end of file +}; |