Skip to content

Commit

Permalink
AE: test type of stream for passthough modes
Browse files Browse the repository at this point in the history
  • Loading branch information
FernetMenta committed Nov 17, 2015
1 parent 3f44006 commit ae27506
Show file tree
Hide file tree
Showing 9 changed files with 120 additions and 42 deletions.
21 changes: 14 additions & 7 deletions xbmc/cores/AudioEngine/AEFactory.cpp
Expand Up @@ -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"
Expand Down Expand Up @@ -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))
Expand All @@ -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;
}
Expand Down
3 changes: 2 additions & 1 deletion xbmc/cores/AudioEngine/AEFactory.h
Expand Up @@ -25,6 +25,7 @@
#include "Interfaces/AE.h"

class CSetting;
class CAEStreamInfo;

class CAEFactory
{
Expand All @@ -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();
Expand Down
17 changes: 12 additions & 5 deletions xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp
Expand Up @@ -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"

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
Expand Down
2 changes: 1 addition & 1 deletion xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.h
Expand Up @@ -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();
Expand Down
43 changes: 42 additions & 1 deletion xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAESink.cpp
Expand Up @@ -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"
Expand Down Expand Up @@ -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;

This comment has been minimized.

Copy link
@koying

koying Nov 17, 2015

Please note that those samplerate tweaks are only for IEC61937.
For "RAW" passthrough, we use the nominal samplerate in the sink (i.e. mostly 48000)

This comment has been minimized.

Copy link
@FernetMenta

FernetMenta Nov 17, 2015

Author Owner

yes, I know. see comment 10 lines above "IEC packed"
anyway, this is intermediate and will disappear after change of enumeration of sinks
sinks should signal whether they are capable of taking a particular stream type raw or iec packed.

This comment has been minimized.

Copy link
@koying

koying Nov 17, 2015

Oki. Just that, in the current state, you are checking the sink with those values, so it was confusing to me ;)
But it's probably too soon to actually check code, is it? If so, just ping me when you are satisfied with it.

This comment has been minimized.

Copy link
@FernetMenta

FernetMenta Nov 17, 2015

Author Owner

I'd be grateful for every comments and input here. I have vague ideas and discussions help a lot in this phase. I thought it makes more sense to go in small steps with little changes than a big bang where it would take days or even weeks to get something working again.

This comment has been minimized.

Copy link
@koying

koying Nov 17, 2015

Okido. Thanks for your efforts.

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)
{
Expand All @@ -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;
}
}
}
}
Expand Down
4 changes: 3 additions & 1 deletion xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAESink.h
Expand Up @@ -27,6 +27,8 @@
#include "cores/AudioEngine/AESinkFactory.h"
#include "cores/AudioEngine/Engines/ActiveAE/ActiveAEBuffer.h"

class CAEStreamInfo;

namespace ActiveAE
{
using namespace Actor;
Expand Down Expand Up @@ -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;

Expand Down
3 changes: 2 additions & 1 deletion xbmc/cores/AudioEngine/Interfaces/AE.h
Expand Up @@ -37,6 +37,7 @@ class IAESound;
class IAEPacketizer;
class IAudioCallback;
class IAEClockCallback;
class CAEStreamInfo;

/* sound options */
#define AE_SOUND_OFF 0 /* disable sounds */
Expand Down Expand Up @@ -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
Expand Down
17 changes: 10 additions & 7 deletions xbmc/cores/AudioEngine/Utils/AEDeviceInfo.h
Expand Up @@ -23,9 +23,11 @@
#include <vector>
#include "AEAudioFormat.h"
#include "cores/AudioEngine/Utils/AEChannelInfo.h"
#include "cores/AudioEngine/Utils/AEStreamInfo.h"

typedef std::vector<unsigned int > AESampleRateList;
typedef std::vector<unsigned int> AESampleRateList;
typedef std::vector<enum AEDataFormat> AEDataFormatList;
typedef std::vector<CAEStreamInfo::DataType> AEDataTypeList;

enum AEDeviceType {
AE_DEVTYPE_PCM,
Expand All @@ -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);
Expand Down
52 changes: 34 additions & 18 deletions xbmc/cores/VideoPlayer/DVDCodecs/Audio/DVDAudioCodecPassthrough.cpp
Expand Up @@ -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()
Expand Down

0 comments on commit ae27506

Please sign in to comment.