diff options
author | fritsch <Peter.Fruehberger@gmail.com> | 2017-04-18 20:14:06 +0200 |
---|---|---|
committer | fritsch <Peter.Fruehberger@gmail.com> | 2017-10-05 19:22:40 +0200 |
commit | ab293a6ced9d553bca1d98bb6a321f1115b67a72 (patch) | |
tree | 2f5b7df125578ddaede23a678e58d4bfc7b664a4 | |
parent | 2c0a184786f3870eb1053bdead148e31a9448f93 (diff) |
AESinkAUDIOTRACK: Refactor and separate PCM and Passthrough Enumeration
-rw-r--r-- | xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.cpp | 219 | ||||
-rw-r--r-- | xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.h | 5 |
2 files changed, 128 insertions, 96 deletions
diff --git a/xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.cpp b/xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.cpp index 2d540302fc..e7438f1a9e 100644 --- a/xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.cpp +++ b/xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.cpp @@ -202,6 +202,7 @@ static jni::CJNIAudioTrack *CreateAudioTrack(int stream, int sampleRate, int cha CAEDeviceInfo CAESinkAUDIOTRACK::m_info; std::set<unsigned int> CAESinkAUDIOTRACK::m_sink_sampleRates; +bool CAESinkAUDIOTRACK::m_sinkSupportsFloat = false; //////////////////////////////////////////////////////////////////////////////////////////// CAESinkAUDIOTRACK::CAESinkAUDIOTRACK() @@ -311,7 +312,7 @@ bool CAESinkAUDIOTRACK::Initialize(AEAudioFormat &format, std::string &device) { m_passthrough = false; m_format.m_sampleRate = m_sink_sampleRate; - if (CJNIAudioManager::GetSDKVersion() >= 21 && m_format.m_channelLayout.Count() == 2) + if (m_sinkSupportsFloat && m_format.m_channelLayout.Count() == 2) { m_encoding = CJNIAudioFormat::ENCODING_PCM_FLOAT; m_format.m_dataFormat = AE_FMT_FLOAT; @@ -758,131 +759,159 @@ void CAESinkAUDIOTRACK::Drain() void CAESinkAUDIOTRACK::EnumerateDevicesEx(AEDeviceInfoList &list, bool force) { + // Clear everything m_info.m_channels.Reset(); m_info.m_dataFormats.clear(); m_info.m_sampleRates.clear(); + m_info.m_streamTypes.clear(); + m_sink_sampleRates.clear(); m_info.m_deviceType = AE_DEVTYPE_PCM; m_info.m_deviceName = "AudioTrack"; m_info.m_displayName = "android"; m_info.m_displayNameExtra = "audiotrack"; -#ifdef LIMIT_TO_STEREO_AND_5POINT1_AND_7POINT1 - if (Has71Support()) - m_info.m_channels = AE_CH_LAYOUT_7_1; - else - m_info.m_channels = AE_CH_LAYOUT_5_1; -#else - m_info.m_channels = KnownChannels; -#endif - m_info.m_dataFormats.push_back(AE_FMT_S16LE); - m_sink_sampleRates.clear(); - m_sink_sampleRates.insert(CJNIAudioTrack::getNativeOutputSampleRate(CJNIAudioManager::STREAM_MUSIC)); + UpdateAvailablePCMCapabilities(); - m_info.m_wantsIECPassthrough = true; if (!CXBMCApp::IsHeadsetPlugged()) { - m_info.m_deviceType = AE_DEVTYPE_HDMI; - m_info.m_wantsIECPassthrough = false; - m_info.m_dataFormats.push_back(AE_FMT_RAW); - if (CJNIAudioFormat::ENCODING_AC3 != -1) - { - m_info.m_streamTypes.push_back(CAEStreamInfo::STREAM_TYPE_AC3); - CLog::Log(LOGDEBUG, "Firmware implements AC3 RAW"); - } + UpdateAvailablePassthroughCapabilities(); + } + list.push_back(m_info); +} - // EAC3 working on shield, broken on FireTV - if (CJNIAudioFormat::ENCODING_E_AC3 != -1) - { - m_info.m_streamTypes.push_back(CAEStreamInfo::STREAM_TYPE_EAC3); - CLog::Log(LOGDEBUG, "Firmware implements EAC3 RAW"); - } +void CAESinkAUDIOTRACK::UpdateAvailablePassthroughCapabilities() +{ + m_info.m_deviceType = AE_DEVTYPE_HDMI; + m_info.m_wantsIECPassthrough = false; + m_info.m_dataFormats.push_back(AE_FMT_RAW); + m_info.m_streamTypes.clear(); + if (CJNIAudioFormat::ENCODING_AC3 != -1) + { + m_info.m_streamTypes.push_back(CAEStreamInfo::STREAM_TYPE_AC3); + CLog::Log(LOGDEBUG, "Firmware implements AC3 RAW"); + } - if (CJNIAudioFormat::ENCODING_DTS != -1) + // EAC3 working on shield, broken on FireTV + if (CJNIAudioFormat::ENCODING_E_AC3 != -1) + { + m_info.m_streamTypes.push_back(CAEStreamInfo::STREAM_TYPE_EAC3); + CLog::Log(LOGDEBUG, "Firmware implements EAC3 RAW"); + } + + if (CJNIAudioFormat::ENCODING_DTS != -1) + { + CLog::Log(LOGDEBUG, "Firmware implements DTS RAW"); + m_info.m_streamTypes.push_back(CAEStreamInfo::STREAM_TYPE_DTSHD_CORE); + m_info.m_streamTypes.push_back(CAEStreamInfo::STREAM_TYPE_DTS_1024); + m_info.m_streamTypes.push_back(CAEStreamInfo::STREAM_TYPE_DTS_2048); + m_info.m_streamTypes.push_back(CAEStreamInfo::STREAM_TYPE_DTS_512); + } + + if (aml_present() && CJNIAudioManager::GetSDKVersion() < 23) + { + // passthrough + m_info.m_wantsIECPassthrough = true; + m_sink_sampleRates.insert(44100); + m_sink_sampleRates.insert(48000); + if (HasAmlHD()) { - CLog::Log(LOGDEBUG, "Firmware implements DTS RAW"); - m_info.m_streamTypes.push_back(CAEStreamInfo::STREAM_TYPE_DTSHD_CORE); - m_info.m_streamTypes.push_back(CAEStreamInfo::STREAM_TYPE_DTS_1024); - m_info.m_streamTypes.push_back(CAEStreamInfo::STREAM_TYPE_DTS_2048); - m_info.m_streamTypes.push_back(CAEStreamInfo::STREAM_TYPE_DTS_512); + m_sink_sampleRates.insert(96000); + m_sink_sampleRates.insert(192000); + m_info.m_streamTypes.push_back(CAEStreamInfo::STREAM_TYPE_EAC3); + m_info.m_streamTypes.push_back(CAEStreamInfo::STREAM_TYPE_DTSHD); + m_info.m_streamTypes.push_back(CAEStreamInfo::STREAM_TYPE_TRUEHD); } - - if (aml_present() && CJNIAudioManager::GetSDKVersion() < 23) + std::copy(m_sink_sampleRates.begin(), m_sink_sampleRates.end(), std::back_inserter(m_info.m_sampleRates)); + } + else + { + if (CJNIAudioManager::GetSDKVersion() >= 23) { - // passthrough - m_info.m_wantsIECPassthrough = true; - m_sink_sampleRates.insert(44100); - m_sink_sampleRates.insert(48000); - if (HasAmlHD()) + if (CJNIAudioFormat::ENCODING_DTS_HD != -1) { - m_sink_sampleRates.insert(96000); - m_sink_sampleRates.insert(192000); - m_info.m_streamTypes.push_back(CAEStreamInfo::STREAM_TYPE_EAC3); + CLog::Log(LOGDEBUG, "Firmware implements DTS-HD RAW"); m_info.m_streamTypes.push_back(CAEStreamInfo::STREAM_TYPE_DTSHD); + } + if (CJNIAudioFormat::ENCODING_DOLBY_TRUEHD != -1) + { + CLog::Log(LOGDEBUG, "Firmware implements TrueHD RAW"); m_info.m_streamTypes.push_back(CAEStreamInfo::STREAM_TYPE_TRUEHD); } } - else + // Android v24 and backports can do real IEC API + if (CJNIAudioFormat::ENCODING_IEC61937 != -1) { - bool supports_192khz = false; - int test_sample[] = { 32000, 44100, 48000, 88200, 96000, 176400, 192000 }; - int test_sample_sz = sizeof(test_sample) / sizeof(int); - int encoding = CJNIAudioFormat::ENCODING_PCM_16BIT; - if (CJNIAudioManager::GetSDKVersion() >= 21) - encoding = CJNIAudioFormat::ENCODING_PCM_FLOAT; - for (int i=0; i<test_sample_sz; ++i) - { - if (IsSupported(test_sample[i], CJNIAudioFormat::CHANNEL_OUT_STEREO, encoding)) - { - m_sink_sampleRates.insert(test_sample[i]); - if (test_sample[i] == 192000) - supports_192khz = true; - CLog::Log(LOGDEBUG, "AESinkAUDIOTRACK - %d supported", test_sample[i]); - } - } - if (CJNIAudioManager::GetSDKVersion() >= 23) + bool supports_192khz = m_sink_sampleRates.find(192000) != m_sink_sampleRates.end(); + m_info.m_wantsIECPassthrough = true; + m_info.m_streamTypes.clear(); + m_info.m_dataFormats.push_back(AE_FMT_RAW); + m_info.m_streamTypes.push_back(CAEStreamInfo::STREAM_TYPE_AC3); + m_info.m_streamTypes.push_back(CAEStreamInfo::STREAM_TYPE_DTSHD_CORE); + m_info.m_streamTypes.push_back(CAEStreamInfo::STREAM_TYPE_DTS_1024); + m_info.m_streamTypes.push_back(CAEStreamInfo::STREAM_TYPE_DTS_2048); + m_info.m_streamTypes.push_back(CAEStreamInfo::STREAM_TYPE_DTS_512); + CLog::Log(LOGDEBUG, "AESinkAUDIOTrack: Using IEC PT mode: %d", CJNIAudioFormat::ENCODING_IEC61937); + if (supports_192khz) { - if (CJNIAudioFormat::ENCODING_DTS_HD != -1) - { - CLog::Log(LOGDEBUG, "Firmware implements DTS-HD RAW"); + m_info.m_streamTypes.push_back(CAEStreamInfo::STREAM_TYPE_EAC3); + // Check for IEC 8 channel 192 khz PT + int atChannelMask = AEChannelMapToAUDIOTRACKChannelMask(AE_CH_LAYOUT_7_1); + if (IsSupported(192000, atChannelMask, CJNIAudioFormat::ENCODING_IEC61937)) + { m_info.m_streamTypes.push_back(CAEStreamInfo::STREAM_TYPE_DTSHD); - } - if (CJNIAudioFormat::ENCODING_DOLBY_TRUEHD != -1) - { - CLog::Log(LOGDEBUG, "Firmware implements TrueHD RAW"); m_info.m_streamTypes.push_back(CAEStreamInfo::STREAM_TYPE_TRUEHD); + CLog::Log(LOGDEBUG, "8 Channel PT via IEC61937 is supported"); } - } - // Android v24 and backports can do real IEC API - if (CJNIAudioFormat::ENCODING_IEC61937 != -1) + } + } + } +} + +void CAESinkAUDIOTRACK::UpdateAvailablePCMCapabilities() +{ +#ifdef LIMIT_TO_STEREO_AND_5POINT1_AND_7POINT1 + if (Has71Support()) + m_info.m_channels = AE_CH_LAYOUT_7_1; + else + m_info.m_channels = AE_CH_LAYOUT_5_1; +#else + m_info.m_channels = KnownChannels; +#endif + + // default fallback format + m_info.m_dataFormats.push_back(AE_FMT_S16LE); + unsigned int native_sampleRate = CJNIAudioTrack::getNativeOutputSampleRate(CJNIAudioManager::STREAM_MUSIC); + m_sink_sampleRates.insert(native_sampleRate); + + int encoding = CJNIAudioFormat::ENCODING_PCM_16BIT; + m_sinkSupportsFloat = IsSupported(native_sampleRate, CJNIAudioFormat::CHANNEL_OUT_STEREO, CJNIAudioFormat::ENCODING_PCM_FLOAT); + + if (m_sinkSupportsFloat) + { + encoding = CJNIAudioFormat::ENCODING_PCM_FLOAT; + m_info.m_dataFormats.push_back(AE_FMT_FLOAT); + CLog::Log(LOGNOTICE, "Float is supported"); + } + + // Still AML API 21 and 22 get hardcoded samplerates - we can drop that + // when we stop supporting API < 23 - let's only add the default + // music samplerate + if (!aml_present() || CJNIAudioManager::GetSDKVersion() >= 23) + { + int test_sample[] = { 32000, 44100, 48000, 88200, 96000, 176400, 192000 }; + int test_sample_sz = sizeof(test_sample) / sizeof(int); + + for (int i = 0; i < test_sample_sz; ++i) + { + if (IsSupported(test_sample[i], CJNIAudioFormat::CHANNEL_OUT_STEREO, encoding)) { - m_info.m_wantsIECPassthrough = true; - m_info.m_streamTypes.clear(); - m_info.m_dataFormats.push_back(AE_FMT_RAW); - m_info.m_streamTypes.push_back(CAEStreamInfo::STREAM_TYPE_AC3); - m_info.m_streamTypes.push_back(CAEStreamInfo::STREAM_TYPE_DTSHD_CORE); - m_info.m_streamTypes.push_back(CAEStreamInfo::STREAM_TYPE_DTS_1024); - m_info.m_streamTypes.push_back(CAEStreamInfo::STREAM_TYPE_DTS_2048); - m_info.m_streamTypes.push_back(CAEStreamInfo::STREAM_TYPE_DTS_512); - CLog::Log(LOGDEBUG, "AESinkAUDIOTrack: Using IEC PT mode: %d", CJNIAudioFormat::ENCODING_IEC61937); - - if (supports_192khz) - { - m_info.m_streamTypes.push_back(CAEStreamInfo::STREAM_TYPE_EAC3); - // Check for IEC 8 channel 192 khz PT - int atChannelMask = AEChannelMapToAUDIOTRACKChannelMask(AE_CH_LAYOUT_7_1); - if (IsSupported(192000, atChannelMask, CJNIAudioFormat::ENCODING_IEC61937)) - { - m_info.m_streamTypes.push_back(CAEStreamInfo::STREAM_TYPE_DTSHD); - m_info.m_streamTypes.push_back(CAEStreamInfo::STREAM_TYPE_TRUEHD); - CLog::Log(LOGDEBUG, "8 Channel PT via IEC61937 is supported"); - } - } + m_sink_sampleRates.insert(test_sample[i]); + CLog::Log(LOGDEBUG, "AESinkAUDIOTRACK - %d supported", test_sample[i]); } } - std::copy(m_sink_sampleRates.begin(), m_sink_sampleRates.end(), std::back_inserter(m_info.m_sampleRates)); } - list.push_back(m_info); + std::copy(m_sink_sampleRates.begin(), m_sink_sampleRates.end(), std::back_inserter(m_info.m_sampleRates)); } double CAESinkAUDIOTRACK::GetMovingAverageDelay(double newestdelay) diff --git a/xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.h b/xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.h index a9119e36e8..5cdf0331ad 100644 --- a/xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.h +++ b/xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.h @@ -55,7 +55,9 @@ public: protected: static bool IsSupported(int sampleRateInHz, int channelConfig, int audioFormat); static bool HasAmlHD(); - + static void UpdateAvailablePCMCapabilities(); + static void UpdateAvailablePassthroughCapabilities(); + private: jni::CJNIAudioTrack *m_at_jni; double m_duration_written; @@ -76,6 +78,7 @@ private: static CAEDeviceInfo m_info; static std::set<unsigned int> m_sink_sampleRates; + static bool m_sinkSupportsFloat; AEAudioFormat m_format; double m_volume; |