aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorfritsch <Peter.Fruehberger@gmail.com>2017-04-18 20:14:06 +0200
committerfritsch <Peter.Fruehberger@gmail.com>2017-10-05 19:22:40 +0200
commitab293a6ced9d553bca1d98bb6a321f1115b67a72 (patch)
tree2f5b7df125578ddaede23a678e58d4bfc7b664a4
parent2c0a184786f3870eb1053bdead148e31a9448f93 (diff)
AESinkAUDIOTRACK: Refactor and separate PCM and Passthrough Enumeration
-rw-r--r--xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.cpp219
-rw-r--r--xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.h5
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;