From 21edb0eda3ce4d37a65cfcc2c33c364c181c4f29 Mon Sep 17 00:00:00 2001 From: Jason Pontious Date: Mon, 12 Sep 2016 15:11:02 -0400 Subject: [PATCH] Added AC3 core passthrough from EAC3 stream --- xbmc/cores/AudioEngine/Utils/AEStreamInfo.cpp | 20 +++++++++++++++---- xbmc/cores/AudioEngine/Utils/AEStreamInfo.h | 1 + .../Audio/DVDAudioCodecPassthrough.cpp | 19 ++++++++++++++---- xbmc/cores/dvdplayer/DVDPlayerAudio.cpp | 7 +++++++ 4 files changed, 39 insertions(+), 8 deletions(-) diff --git a/xbmc/cores/AudioEngine/Utils/AEStreamInfo.cpp b/xbmc/cores/AudioEngine/Utils/AEStreamInfo.cpp index df50725f57..5e9ba45e5c 100644 --- a/xbmc/cores/AudioEngine/Utils/AEStreamInfo.cpp +++ b/xbmc/cores/AudioEngine/Utils/AEStreamInfo.cpp @@ -67,6 +67,7 @@ CAEStreamParser::CAEStreamParser() : m_needBytes (0), m_syncFunc (&CAEStreamParser::DetectType), m_hasSync (false), + m_detectedEAC3 (false), m_coreSize (0), m_dtsBlocks (0), m_fsize (0), @@ -255,10 +256,15 @@ void CAEStreamParser::GetPacket(uint8_t **buffer, unsigned int *bufferSize) /* if the caller wants the packet */ if (buffer) { - /* if it is dtsHD and we only want the core, just fetch that */ + /* if it is dtsHD/eac3 and we only want the core, just fetch that */ unsigned int size = m_fsize; - if (m_info.m_type == CAEStreamInfo::STREAM_TYPE_DTSHD_CORE) + if ((m_info.m_type == CAEStreamInfo::STREAM_TYPE_DTSHD_CORE || m_info.m_type == CAEStreamInfo::STREAM_TYPE_AC3) && + m_fsize) + { size = m_coreSize; + m_coreSize = 0; + } + /* make sure the buffer is allocated and big enough */ if (!*buffer || !bufferSize || *bufferSize < size) @@ -277,7 +283,6 @@ void CAEStreamParser::GetPacket(uint8_t **buffer, unsigned int *bufferSize) m_bufferSize -= m_fsize; memmove(m_buffer, m_buffer + m_fsize, m_bufferSize); m_fsize = 0; - m_coreSize = 0; } /* SYNC FUNCTIONS */ @@ -394,10 +399,12 @@ unsigned int CAEStreamParser::SyncAC3(uint8_t *data, unsigned int size) m_fsize = framesize << 1; m_info.m_sampleRate = AC3FSCod[fscod]; + m_coreSize = m_fsize; /* dont do extensive testing if we have not lost sync */ /* this may be the main stream of EAC3 */ - if (m_info.m_type == CAEStreamInfo::STREAM_TYPE_EAC3 && skip == 0) + if ((m_info.m_type == CAEStreamInfo::STREAM_TYPE_EAC3 || + (m_info.m_type == CAEStreamInfo::STREAM_TYPE_AC3 && m_detectedEAC3 && m_coreOnly)) && skip == 0) { m_fsizeMain = m_fsize; m_fsize = 0; @@ -464,6 +471,11 @@ unsigned int CAEStreamParser::SyncAC3(uint8_t *data, unsigned int size) m_fsize += m_fsizeMain; } m_fsizeMain = 0; + m_detectedEAC3 = true; + + if (m_coreOnly && m_info.m_type == CAEStreamInfo::STREAM_TYPE_AC3 && m_hasSync && skip == 0 && + strmtyp == 1) + return 0; m_info.m_repeat = MAX_EAC3_BLOCKS / blocks; diff --git a/xbmc/cores/AudioEngine/Utils/AEStreamInfo.h b/xbmc/cores/AudioEngine/Utils/AEStreamInfo.h index e03a5f5b1e..1c2651519a 100644 --- a/xbmc/cores/AudioEngine/Utils/AEStreamInfo.h +++ b/xbmc/cores/AudioEngine/Utils/AEStreamInfo.h @@ -94,6 +94,7 @@ class CAEStreamParser unsigned int m_needBytes; ParseFunc m_syncFunc; bool m_hasSync; + bool m_detectedEAC3; unsigned int m_coreSize; /* core size for dtsHD */ unsigned int m_dtsBlocks; diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Audio/DVDAudioCodecPassthrough.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Audio/DVDAudioCodecPassthrough.cpp index 33f9955734..99758bc245 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Audio/DVDAudioCodecPassthrough.cpp +++ b/xbmc/cores/dvdplayer/DVDCodecs/Audio/DVDAudioCodecPassthrough.cpp @@ -80,15 +80,26 @@ bool CDVDAudioCodecPassthrough::Open(CDVDStreamInfo &hints, CDVDCodecOptions &op bool ret = CAEFactory::SupportsRaw(format); m_parser.SetCoreOnly(false); - if (!ret && hints.codec == AV_CODEC_ID_DTS) + if (!ret && (hints.codec == AV_CODEC_ID_DTS || hints.codec == AV_CODEC_ID_EAC3)) { - format.m_streamInfo.m_type = CAEStreamInfo::STREAM_TYPE_DTSHD_CORE; + if (hints.codec == AV_CODEC_ID_DTS) + format.m_streamInfo.m_type = CAEStreamInfo::STREAM_TYPE_DTSHD_CORE; + else + format.m_streamInfo.m_type = CAEStreamInfo::STREAM_TYPE_AC3; + ret = CAEFactory::SupportsRaw(format); - // only get the dts core from the parser if we don't support dtsHD + // only get the core from the parser if we don't support dtsHD/EAC3 m_parser.SetCoreOnly(true); } - + else if (ret && hints.codec == AV_CODEC_ID_AC3) + { + // check for EAC3 passthrough support. If not enabled then set for core only + AEAudioFormat eac3format = format; + eac3format.m_streamInfo.m_type = CAEStreamInfo::STREAM_TYPE_EAC3; + m_parser.SetCoreOnly(!CAEFactory::SupportsRaw(eac3format)); + } + #if defined(TARGET_DARWIN_TVOS) // tvos doesn't like 44100 dts passthrough even if it generally can do 44100 samplerate if (hints.codec == AV_CODEC_ID_DTS && hints.samplerate != 48000) diff --git a/xbmc/cores/dvdplayer/DVDPlayerAudio.cpp b/xbmc/cores/dvdplayer/DVDPlayerAudio.cpp index 7a6d9d7d71..a95b9c9fa6 100644 --- a/xbmc/cores/dvdplayer/DVDPlayerAudio.cpp +++ b/xbmc/cores/dvdplayer/DVDPlayerAudio.cpp @@ -119,6 +119,13 @@ bool CDVDPlayerAudio::OpenStream(CDVDStreamInfo &hints) //if (hints.realtime) // allowpassthrough = false; + // Handle special case where switching from AC3 -> EAC3 and no passthrough support for EAC3 + if (allowpassthrough && m_pAudioCodec && + m_pAudioCodec->GetFormat().m_streamInfo.m_type == CAEStreamInfo::STREAM_TYPE_AC3 && + hints.codec == AV_CODEC_ID_EAC3 && m_pAudioCodec->NeedPassthrough() && + !CSettings::GetInstance().GetBool(CSettings::SETTING_AUDIOOUTPUT_EAC3PASSTHROUGH)) + allowpassthrough = false; + CDVDAudioCodec* codec = CDVDFactoryCodec::CreateAudioCodec(hints, allowpassthrough); if(!codec) {