diff --git a/xbmc/cores/AudioEngine/AEFactory.cpp b/xbmc/cores/AudioEngine/AEFactory.cpp index 51eb46511cc01..10a1ea1b9d07e 100644 --- a/xbmc/cores/AudioEngine/AEFactory.cpp +++ b/xbmc/cores/AudioEngine/AEFactory.cpp @@ -22,6 +22,7 @@ #include "AEFactory.h" #include "Engines/ActiveAE/ActiveAE.h" +#include "Utils/AEStreamInfo.h" #include "guilib/LocalizeStrings.h" #include "settings/lib/Setting.h" @@ -168,7 +169,7 @@ std::string CAEFactory::GetDefaultDevice(bool passthrough) return "default"; } -bool CAEFactory::SupportsRaw(AEDataFormat format, int samplerate) +bool CAEFactory::SupportsRaw(CAEStreamInfo &info) { // check if passthrough is enabled if (!CSettings::GetInstance().GetBool(CSettings::SETTING_AUDIOOUTPUT_PASSTHROUGH)) @@ -179,19 +180,25 @@ bool CAEFactory::SupportsRaw(AEDataFormat format, int samplerate) return false; // check if the format is enabled in settings - if (format == AE_FMT_AC3 && !CSettings::GetInstance().GetBool(CSettings::SETTING_AUDIOOUTPUT_AC3PASSTHROUGH)) + if (info.m_type == CAEStreamInfo::STREAM_TYPE_AC3 && !CSettings::GetInstance().GetBool(CSettings::SETTING_AUDIOOUTPUT_AC3PASSTHROUGH)) return false; - if (format == AE_FMT_DTS && !CSettings::GetInstance().GetBool(CSettings::SETTING_AUDIOOUTPUT_DTSPASSTHROUGH)) + if (info.m_type == CAEStreamInfo::STREAM_TYPE_DTS_512 && !CSettings::GetInstance().GetBool(CSettings::SETTING_AUDIOOUTPUT_DTSPASSTHROUGH)) return false; - if (format == AE_FMT_EAC3 && !CSettings::GetInstance().GetBool(CSettings::SETTING_AUDIOOUTPUT_EAC3PASSTHROUGH)) + if (info.m_type == CAEStreamInfo::STREAM_TYPE_DTS_1024 && !CSettings::GetInstance().GetBool(CSettings::SETTING_AUDIOOUTPUT_DTSPASSTHROUGH)) return false; - if (format == AE_FMT_TRUEHD && !CSettings::GetInstance().GetBool(CSettings::SETTING_AUDIOOUTPUT_TRUEHDPASSTHROUGH)) + if (info.m_type == CAEStreamInfo::STREAM_TYPE_DTS_2048 && !CSettings::GetInstance().GetBool(CSettings::SETTING_AUDIOOUTPUT_DTSPASSTHROUGH)) return false; - if (format == AE_FMT_DTSHD && !CSettings::GetInstance().GetBool(CSettings::SETTING_AUDIOOUTPUT_DTSHDPASSTHROUGH)) + if (info.m_type == CAEStreamInfo::STREAM_TYPE_DTSHD_CORE && !CSettings::GetInstance().GetBool(CSettings::SETTING_AUDIOOUTPUT_DTSPASSTHROUGH)) + return false; + if (info.m_type == CAEStreamInfo::STREAM_TYPE_EAC3 && !CSettings::GetInstance().GetBool(CSettings::SETTING_AUDIOOUTPUT_EAC3PASSTHROUGH)) + return false; + if (info.m_type == CAEStreamInfo::STREAM_TYPE_TRUEHD && !CSettings::GetInstance().GetBool(CSettings::SETTING_AUDIOOUTPUT_TRUEHDPASSTHROUGH)) + return false; + if (info.m_type == CAEStreamInfo::STREAM_TYPE_DTSHD && !CSettings::GetInstance().GetBool(CSettings::SETTING_AUDIOOUTPUT_DTSHDPASSTHROUGH)) return false; if(AE) - return AE->SupportsRaw(format, samplerate); + return AE->SupportsRaw(info); return false; } diff --git a/xbmc/cores/AudioEngine/AEFactory.h b/xbmc/cores/AudioEngine/AEFactory.h index b78da607e4fe9..edeeb9205512b 100644 --- a/xbmc/cores/AudioEngine/AEFactory.h +++ b/xbmc/cores/AudioEngine/AEFactory.h @@ -25,6 +25,7 @@ #include "Interfaces/AE.h" class CSetting; +class CAEStreamInfo; class CAEFactory { @@ -44,7 +45,7 @@ class CAEFactory static void EnumerateOutputDevices(AEDeviceList &devices, bool passthrough); static void VerifyOutputDevice(std::string &device, bool passthrough); static std::string GetDefaultDevice(bool passthrough); - static bool SupportsRaw(AEDataFormat format, int samplerate); + static bool SupportsRaw(CAEStreamInfo &info); static bool SupportsSilenceTimeout(); static bool HasStereoAudioChannelCount(); static bool HasHDAudioChannelCount(); diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp index 093c920162df9..058f05bacfa00 100644 --- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp +++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp @@ -26,6 +26,7 @@ using namespace ActiveAE; #include "cores/AudioEngine/DSPAddons/ActiveAEDSP.h" #include "cores/AudioEngine/DSPAddons/ActiveAEDSPProcess.h" #include "cores/AudioEngine/Utils/AEUtil.h" +#include "cores/AudioEngine/Utils/AEStreamInfo.h" #include "cores/AudioEngine/AEResampleFactory.h" #include "cores/AudioEngine/Encoders/AEEncoderFFmpeg.h" @@ -2545,9 +2546,9 @@ void CActiveAE::OnSettingsChange(const std::string& setting) } } -bool CActiveAE::SupportsRaw(AEDataFormat format, int samplerate) +bool CActiveAE::SupportsRaw(CAEStreamInfo &info) { - if (!m_sink.SupportsFormat(CSettings::GetInstance().GetString(CSettings::SETTING_AUDIOOUTPUT_PASSTHROUGHDEVICE), format, samplerate)) + if (!m_sink.SupportsFormat(CSettings::GetInstance().GetString(CSettings::SETTING_AUDIOOUTPUT_PASSTHROUGHDEVICE), info)) return false; return true; @@ -2608,19 +2609,25 @@ bool CActiveAE::IsSettingVisible(const std::string &settingId) } else if (settingId == CSettings::SETTING_AUDIOOUTPUT_TRUEHDPASSTHROUGH) { - if (m_sink.SupportsFormat(CSettings::GetInstance().GetString(CSettings::SETTING_AUDIOOUTPUT_PASSTHROUGHDEVICE), AE_FMT_TRUEHD, 192000) && + CAEStreamInfo info; + info.m_type = CAEStreamInfo::STREAM_TYPE_TRUEHD; + if (m_sink.SupportsFormat(CSettings::GetInstance().GetString(CSettings::SETTING_AUDIOOUTPUT_PASSTHROUGHDEVICE), info) && CSettings::GetInstance().GetInt(CSettings::SETTING_AUDIOOUTPUT_CONFIG) != AE_CONFIG_FIXED) return true; } else if (settingId == CSettings::SETTING_AUDIOOUTPUT_DTSHDPASSTHROUGH) { - if (m_sink.SupportsFormat(CSettings::GetInstance().GetString(CSettings::SETTING_AUDIOOUTPUT_PASSTHROUGHDEVICE), AE_FMT_DTSHD, 192000) && + CAEStreamInfo info; + info.m_type = CAEStreamInfo::STREAM_TYPE_DTSHD; + if (m_sink.SupportsFormat(CSettings::GetInstance().GetString(CSettings::SETTING_AUDIOOUTPUT_PASSTHROUGHDEVICE), info) && CSettings::GetInstance().GetInt(CSettings::SETTING_AUDIOOUTPUT_CONFIG) != AE_CONFIG_FIXED) return true; } else if (settingId == CSettings::SETTING_AUDIOOUTPUT_EAC3PASSTHROUGH) { - if (m_sink.SupportsFormat(CSettings::GetInstance().GetString(CSettings::SETTING_AUDIOOUTPUT_PASSTHROUGHDEVICE), AE_FMT_EAC3, 192000) && + CAEStreamInfo info; + info.m_type = CAEStreamInfo::STREAM_TYPE_EAC3; + if (m_sink.SupportsFormat(CSettings::GetInstance().GetString(CSettings::SETTING_AUDIOOUTPUT_PASSTHROUGHDEVICE), info) && CSettings::GetInstance().GetInt(CSettings::SETTING_AUDIOOUTPUT_CONFIG) != AE_CONFIG_FIXED) return true; } diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.h b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.h index 6915feb45204b..6e9e0a331052c 100644 --- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.h +++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.h @@ -248,7 +248,7 @@ class CActiveAE : public IAE, private CThread virtual void EnumerateOutputDevices(AEDeviceList &devices, bool passthrough); virtual std::string GetDefaultDevice(bool passthrough); - virtual bool SupportsRaw(AEDataFormat format, int samplerate); + virtual bool SupportsRaw(CAEStreamInfo &info); virtual bool SupportsSilenceTimeout(); virtual bool HasStereoAudioChannelCount(); virtual bool HasHDAudioChannelCount(); diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAESink.cpp b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAESink.cpp index 3665492a1cbb4..04da742f9976c 100644 --- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAESink.cpp +++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAESink.cpp @@ -22,6 +22,7 @@ #include "ActiveAESink.h" #include "cores/AudioEngine/Utils/AEUtil.h" +#include "cores/AudioEngine/Utils/AEStreamInfo.h" #include "utils/EndianSwap.h" #include "ActiveAE.h" #include "cores/AudioEngine/AEResampleFactory.h" @@ -105,10 +106,47 @@ bool CActiveAESink::HasPassthroughDevice() return false; } -bool CActiveAESink::SupportsFormat(const std::string &device, AEDataFormat format, int samplerate) +bool CActiveAESink::SupportsFormat(const std::string &device, CAEStreamInfo &streaminfo) { std::string dev = device; std::string dri; + + // IEC packed + unsigned int samplerate = streaminfo.m_sampleRate; + AEDataFormat format; + switch (streaminfo.m_type) + { + case CAEStreamInfo::STREAM_TYPE_AC3: + format = AE_FMT_AC3; + break; + + case CAEStreamInfo::STREAM_TYPE_EAC3: + format = AE_FMT_EAC3; + samplerate = 4*samplerate; + break; + + case CAEStreamInfo::STREAM_TYPE_TRUEHD: + format = AE_FMT_TRUEHD; + if (samplerate == 48000 || samplerate == 96000 || samplerate == 192000) + samplerate = 192000; + else + samplerate = 176400; + break; + + case CAEStreamInfo::STREAM_TYPE_DTSHD: + samplerate = 192000; + case CAEStreamInfo::STREAM_TYPE_DTSHD_CORE: + case CAEStreamInfo::STREAM_TYPE_DTS_512: + case CAEStreamInfo::STREAM_TYPE_DTS_1024: + case CAEStreamInfo::STREAM_TYPE_DTS_2048: + format = AE_FMT_DTS; + break; + + default: + format = AE_FMT_INVALID; + break; + } + CAESinkFactory::ParseDevice(dev, dri); for (AESinkInfoList::iterator itt = m_sinkInfoList.begin(); itt != m_sinkInfoList.end(); ++itt) { @@ -131,7 +169,10 @@ bool CActiveAESink::SupportsFormat(const std::string &device, AEDataFormat forma return false; } else + { + // TODO - check if sink supports stream type (non IEC packed) return false; + } } } } diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAESink.h b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAESink.h index 9d43d91ec346c..5ba9942597083 100644 --- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAESink.h +++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAESink.h @@ -27,6 +27,8 @@ #include "cores/AudioEngine/AESinkFactory.h" #include "cores/AudioEngine/Engines/ActiveAE/ActiveAEBuffer.h" +class CAEStreamInfo; + namespace ActiveAE { using namespace Actor; @@ -97,7 +99,7 @@ class CActiveAESink : private CThread void Dispose(); AEDeviceType GetDeviceType(const std::string &device); bool HasPassthroughDevice(); - bool SupportsFormat(const std::string &device, AEDataFormat format, int samplerate); + bool SupportsFormat(const std::string &device, CAEStreamInfo &streaminfo); CSinkControlProtocol m_controlPort; CSinkDataProtocol m_dataPort; diff --git a/xbmc/cores/AudioEngine/Interfaces/AE.h b/xbmc/cores/AudioEngine/Interfaces/AE.h index 99059cb7d1970..5f1bcd3126d40 100644 --- a/xbmc/cores/AudioEngine/Interfaces/AE.h +++ b/xbmc/cores/AudioEngine/Interfaces/AE.h @@ -37,6 +37,7 @@ class IAESound; class IAEPacketizer; class IAudioCallback; class IAEClockCallback; +class CAEStreamInfo; /* sound options */ #define AE_SOUND_OFF 0 /* disable sounds */ @@ -206,7 +207,7 @@ class IAE * @see CAEPackIEC61937::CAEPackIEC61937() * @returns true if the AudioEngine is capable of RAW output */ - virtual bool SupportsRaw(AEDataFormat format, int samplerate) { return false; } + virtual bool SupportsRaw(CAEStreamInfo &info) { return false; } /** * Returns true if the AudioEngine supports drain mode which is not streaming silence when idle diff --git a/xbmc/cores/AudioEngine/Utils/AEDeviceInfo.h b/xbmc/cores/AudioEngine/Utils/AEDeviceInfo.h index 79428efccfef4..53abd654f401a 100644 --- a/xbmc/cores/AudioEngine/Utils/AEDeviceInfo.h +++ b/xbmc/cores/AudioEngine/Utils/AEDeviceInfo.h @@ -23,9 +23,11 @@ #include #include "AEAudioFormat.h" #include "cores/AudioEngine/Utils/AEChannelInfo.h" +#include "cores/AudioEngine/Utils/AEStreamInfo.h" -typedef std::vector AESampleRateList; +typedef std::vector AESampleRateList; typedef std::vector AEDataFormatList; +typedef std::vector AEDataTypeList; enum AEDeviceType { AE_DEVTYPE_PCM, @@ -40,13 +42,14 @@ enum AEDeviceType { class CAEDeviceInfo { public: - std::string m_deviceName; /* the driver device name */ - std::string m_displayName; /* the friendly display name */ - std::string m_displayNameExtra; /* additional display name info, ie, monitor name from ELD */ + std::string m_deviceName; /* the driver device name */ + std::string m_displayName; /* the friendly display name */ + std::string m_displayNameExtra; /* additional display name info, ie, monitor name from ELD */ enum AEDeviceType m_deviceType; /* the device type, PCM, IEC958 or HDMI */ - CAEChannelInfo m_channels; /* the channels the device is capable of rendering */ - AESampleRateList m_sampleRates; /* the samplerates the device is capable of rendering */ - AEDataFormatList m_dataFormats; /* the dataformats the device is capable of rendering */ + CAEChannelInfo m_channels; /* the channels the device is capable of rendering */ + AESampleRateList m_sampleRates; /* the samplerates the device is capable of rendering */ + AEDataFormatList m_dataFormats; /* the dataformats the device is capable of rendering */ + AEDataTypeList m_streamTypes; operator std::string(); static std::string DeviceTypeToString(enum AEDeviceType deviceType); diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Audio/DVDAudioCodecPassthrough.cpp b/xbmc/cores/VideoPlayer/DVDCodecs/Audio/DVDAudioCodecPassthrough.cpp index c08b46612611d..451f7a403ebbd 100644 --- a/xbmc/cores/VideoPlayer/DVDCodecs/Audio/DVDAudioCodecPassthrough.cpp +++ b/xbmc/cores/VideoPlayer/DVDCodecs/Audio/DVDAudioCodecPassthrough.cpp @@ -39,28 +39,44 @@ CDVDAudioCodecPassthrough::~CDVDAudioCodecPassthrough(void) bool CDVDAudioCodecPassthrough::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options) { - bool bSupportsAC3Out = CAEFactory::SupportsRaw(AE_FMT_AC3, hints.samplerate); - bool bSupportsEAC3Out = CAEFactory::SupportsRaw(AE_FMT_EAC3, 192000); - bool bSupportsDTSOut = CAEFactory::SupportsRaw(AE_FMT_DTS, hints.samplerate); - bool bSupportsTrueHDOut = CAEFactory::SupportsRaw(AE_FMT_TRUEHD, 192000); - bool bSupportsDTSHDOut = CAEFactory::SupportsRaw(AE_FMT_DTSHD, 192000); - - /* only get the dts core from the parser if we don't support dtsHD */ - m_parser.SetCoreOnly(!bSupportsDTSHDOut); - m_bufferSize = 0; + CAEStreamInfo info; + info.m_sampleRate = hints.samplerate; + switch (hints.codec) + { + case AV_CODEC_ID_AC3: + info.m_type = CAEStreamInfo::STREAM_TYPE_AC3; + break; + + case AV_CODEC_ID_EAC3: + info.m_type = CAEStreamInfo::STREAM_TYPE_EAC3; + break; + + case AV_CODEC_ID_DTS: + info.m_type = CAEStreamInfo::STREAM_TYPE_DTSHD; + break; + + case AV_CODEC_ID_TRUEHD: + info.m_type = CAEStreamInfo::STREAM_TYPE_TRUEHD; + break; - /* 32kHz E-AC-3 passthrough requires 128kHz IEC 60958 stream - * which HDMI does not support, and IEC 61937 does not mention - * reduced sample rate support, so support only 44.1 and 48 */ - if ((hints.codec == AV_CODEC_ID_AC3 && bSupportsAC3Out) || - (hints.codec == AV_CODEC_ID_EAC3 && bSupportsEAC3Out && (hints.samplerate == 44100 || hints.samplerate == 48000)) || - (hints.codec == AV_CODEC_ID_DTS && bSupportsDTSOut) || - (hints.codec == AV_CODEC_ID_TRUEHD && bSupportsTrueHDOut)) + default: + info.m_type = CAEStreamInfo::STREAM_TYPE_NULL; + } + + bool ret = CAEFactory::SupportsRaw(info); + + m_parser.SetCoreOnly(false); + if (!ret && hints.codec == AV_CODEC_ID_DTS) { - return true; + info.m_type = CAEStreamInfo::STREAM_TYPE_DTSHD_CORE; + ret = CAEFactory::SupportsRaw(info); + + // only get the dts core from the parser if we don't support dtsHD + m_parser.SetCoreOnly(true); + m_bufferSize = 0; } - return false; + return ret; } int CDVDAudioCodecPassthrough::GetSampleRate()