diff --git a/packages/mediacenter/kodi/patches/kodi-010.01-pr23411-backport-eac3-fixes.patch b/packages/mediacenter/kodi/patches/kodi-010.01-pr23411-backport-eac3-fixes.patch new file mode 100644 index 0000000000..c2b259bff3 --- /dev/null +++ b/packages/mediacenter/kodi/patches/kodi-010.01-pr23411-backport-eac3-fixes.patch @@ -0,0 +1,966 @@ +From 50f7310fc8162f1885e5b6bf9b76e00e07900415 Mon Sep 17 00:00:00 2001 +From: Dom Cobley +Date: Tue, 25 Apr 2023 18:19:07 +0100 +Subject: [PATCH 1/4] AEStreamInfo: Support EAC3 independent + EAC3 (dependent) + streams + +Fixes: https://github.com/xbmc/xbmc/issues/19182 +--- + xbmc/cores/AudioEngine/Utils/AEStreamInfo.cpp | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +diff --git a/xbmc/cores/AudioEngine/Utils/AEStreamInfo.cpp b/xbmc/cores/AudioEngine/Utils/AEStreamInfo.cpp +index 1489a8be7f204..aac2356177b8e 100644 +--- a/xbmc/cores/AudioEngine/Utils/AEStreamInfo.cpp ++++ b/xbmc/cores/AudioEngine/Utils/AEStreamInfo.cpp +@@ -446,6 +446,25 @@ bool CAEStreamParser::TrySyncAC3(uint8_t *data, unsigned int size, bool resyncin + m_fsize = framesize << 1; + m_info.m_repeat = MAX_EAC3_BLOCKS / blocks; + ++ /* EAC3 can have a dependent stream too */ ++ if (!wantEAC3dependent) ++ { ++ unsigned int fsizeMain = m_fsize; ++ unsigned int reqBytes = fsizeMain + 8; ++ if (size < reqBytes) { ++ /* not enough data to check for E-AC3 dependent frame, request more */ ++ m_needBytes = reqBytes; ++ m_fsize = 0; ++ /* no need to resync => return true */ ++ return true; ++ } ++ if (TrySyncAC3(data + fsizeMain, size - fsizeMain, resyncing, /*wantEAC3dependent*/ true)) { ++ /* concatenate the main and dependent frames */ ++ m_fsize += fsizeMain; ++ return true; ++ } ++ } ++ + if (m_info.m_type == CAEStreamInfo::STREAM_TYPE_EAC3 && m_hasSync && !resyncing) + return true; + + +From afb9169af87ed5de2afaacb3382d718eb985028c Mon Sep 17 00:00:00 2001 +From: Dom Cobley +Date: Fri, 5 May 2023 18:18:51 +0100 +Subject: [PATCH 2/4] AEStreamInfo: Apply clang-format to file + +No functional change +--- + xbmc/cores/AudioEngine/Utils/AEStreamInfo.cpp | 181 +++++++++--------- + 1 file changed, 94 insertions(+), 87 deletions(-) + +diff --git a/xbmc/cores/AudioEngine/Utils/AEStreamInfo.cpp b/xbmc/cores/AudioEngine/Utils/AEStreamInfo.cpp +index aac2356177b8e..5ce9a33ce471e 100644 +--- a/xbmc/cores/AudioEngine/Utils/AEStreamInfo.cpp ++++ b/xbmc/cores/AudioEngine/Utils/AEStreamInfo.cpp +@@ -13,50 +13,34 @@ + #include + #include + +-#define DTS_PREAMBLE_14BE 0x1FFFE800 +-#define DTS_PREAMBLE_14LE 0xFF1F00E8 +-#define DTS_PREAMBLE_16BE 0x7FFE8001 +-#define DTS_PREAMBLE_16LE 0xFE7F0180 +-#define DTS_PREAMBLE_HD 0x64582025 +-#define DTS_PREAMBLE_XCH 0x5a5a5a5a +-#define DTS_PREAMBLE_XXCH 0x47004a03 +-#define DTS_PREAMBLE_X96K 0x1d95f262 +-#define DTS_PREAMBLE_XBR 0x655e315e +-#define DTS_PREAMBLE_LBR 0x0a801921 +-#define DTS_PREAMBLE_XLL 0x41a29547 +-#define DTS_SFREQ_COUNT 16 +-#define MAX_EAC3_BLOCKS 6 ++#define DTS_PREAMBLE_14BE 0x1FFFE800 ++#define DTS_PREAMBLE_14LE 0xFF1F00E8 ++#define DTS_PREAMBLE_16BE 0x7FFE8001 ++#define DTS_PREAMBLE_16LE 0xFE7F0180 ++#define DTS_PREAMBLE_HD 0x64582025 ++#define DTS_PREAMBLE_XCH 0x5a5a5a5a ++#define DTS_PREAMBLE_XXCH 0x47004a03 ++#define DTS_PREAMBLE_X96K 0x1d95f262 ++#define DTS_PREAMBLE_XBR 0x655e315e ++#define DTS_PREAMBLE_LBR 0x0a801921 ++#define DTS_PREAMBLE_XLL 0x41a29547 ++#define DTS_SFREQ_COUNT 16 ++#define MAX_EAC3_BLOCKS 6 + #define UNKNOWN_DTS_EXTENSION 255 + +-static const uint16_t AC3Bitrates [] = {32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 448, 512, 576, 640}; +-static const uint16_t AC3FSCod [] = {48000, 44100, 32000, 0}; +-static const uint8_t AC3BlkCod [] = {1, 2, 3, 6}; +-static const uint8_t AC3Channels [] = {2, 1, 2, 3, 3, 4, 4, 5}; +-static const uint8_t DTSChannels [] = {1, 2, 2, 2, 2, 3, 3, 4, 4, 5, 6, 6, 6, 7, 8, 8}; +-static const uint8_t THDChanMap [] = {2, 1, 1, 2, 2, 2, 2, 1, 1, 2, 2, 1, 1}; ++static const uint16_t AC3Bitrates[] = {32, 40, 48, 56, 64, 80, 96, 112, 128, 160, ++ 192, 224, 256, 320, 384, 448, 512, 576, 640}; ++static const uint16_t AC3FSCod[] = {48000, 44100, 32000, 0}; ++static const uint8_t AC3BlkCod[] = {1, 2, 3, 6}; ++static const uint8_t AC3Channels[] = {2, 1, 2, 3, 3, 4, 4, 5}; ++static const uint8_t DTSChannels[] = {1, 2, 2, 2, 2, 3, 3, 4, 4, 5, 6, 6, 6, 7, 8, 8}; ++static const uint8_t THDChanMap[] = {2, 1, 1, 2, 2, 2, 2, 1, 1, 2, 2, 1, 1}; + +-static const uint32_t DTSSampleRates[DTS_SFREQ_COUNT] = +-{ +- 0 , +- 8000 , +- 16000 , +- 32000 , +- 64000 , +- 128000, +- 11025 , +- 22050 , +- 44100 , +- 88200 , +- 176400, +- 12000 , +- 24000 , +- 48000 , +- 96000 , +- 192000 +-}; +- +-CAEStreamParser::CAEStreamParser() : +- m_syncFunc (&CAEStreamParser::DetectType) ++static const uint32_t DTSSampleRates[DTS_SFREQ_COUNT] = {0, 8000, 16000, 32000, 64000, 128000, ++ 11025, 22050, 44100, 88200, 176400, 12000, ++ 24000, 48000, 96000, 192000}; ++ ++CAEStreamParser::CAEStreamParser() : m_syncFunc(&CAEStreamParser::DetectType) + { + av_crc_init(m_crcTrueHD, 0, 16, 0x2D, sizeof(m_crcTrueHD)); + } +@@ -74,9 +58,7 @@ double CAEStreamInfo::GetDuration() const + break; + case STREAM_TYPE_TRUEHD: + int rate; +- if (m_sampleRate == 48000 || +- m_sampleRate == 96000 || +- m_sampleRate == 192000) ++ if (m_sampleRate == 48000 || m_sampleRate == 96000 || m_sampleRate == 192000) + rate = 192000; + else + rate = 176400; +@@ -120,7 +102,10 @@ void CAEStreamParser::Reset() + m_hasSync = false; + } + +-int CAEStreamParser::AddData(uint8_t *data, unsigned int size, uint8_t **buffer/* = NULL */, unsigned int *bufferSize/* = 0 */) ++int CAEStreamParser::AddData(uint8_t* data, ++ unsigned int size, ++ uint8_t** buffer /* = NULL */, ++ unsigned int* bufferSize /* = 0 */) + { + if (size == 0) + { +@@ -154,7 +139,7 @@ int CAEStreamParser::AddData(uint8_t *data, unsigned int size, uint8_t **buffer/ + unsigned int consumed = 0; + unsigned int offset = 0; + unsigned int room = sizeof(m_buffer) - m_bufferSize; +- while(true) ++ while (true) + { + if (!size) + { +@@ -223,7 +208,7 @@ int CAEStreamParser::AddData(uint8_t *data, unsigned int size, uint8_t **buffer/ + } + } + +-void CAEStreamParser::GetPacket(uint8_t **buffer, unsigned int *bufferSize) ++void CAEStreamParser::GetPacket(uint8_t** buffer, unsigned int* bufferSize) + { + /* if the caller wants the packet */ + if (buffer) +@@ -236,7 +221,7 @@ void CAEStreamParser::GetPacket(uint8_t **buffer, unsigned int *bufferSize) + /* make sure the buffer is allocated and big enough */ + if (!*buffer || !bufferSize || *bufferSize < size) + { +- delete[] *buffer; ++ delete[] * buffer; + *buffer = new uint8_t[size]; + } + +@@ -261,18 +246,16 @@ void CAEStreamParser::GetPacket(uint8_t **buffer, unsigned int *bufferSize) + m_syncFunc to itself. This function will only be called again if total sync is lost, which + allows is to switch stream types on the fly much like a real receiver does. + */ +-unsigned int CAEStreamParser::DetectType(uint8_t *data, unsigned int size) ++unsigned int CAEStreamParser::DetectType(uint8_t* data, unsigned int size) + { +- unsigned int skipped = 0; ++ unsigned int skipped = 0; + unsigned int possible = 0; + + while (size > 8) + { + /* if it could be DTS */ + unsigned int header = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]; +- if (header == DTS_PREAMBLE_14LE || +- header == DTS_PREAMBLE_14BE || +- header == DTS_PREAMBLE_16LE || ++ if (header == DTS_PREAMBLE_14LE || header == DTS_PREAMBLE_14BE || header == DTS_PREAMBLE_16LE || + header == DTS_PREAMBLE_16BE) + { + unsigned int skip = SyncDTS(data, size); +@@ -311,7 +294,10 @@ unsigned int CAEStreamParser::DetectType(uint8_t *data, unsigned int size) + return possible ? possible : skipped; + } + +-bool CAEStreamParser::TrySyncAC3(uint8_t *data, unsigned int size, bool resyncing, bool wantEAC3dependent) ++bool CAEStreamParser::TrySyncAC3(uint8_t* data, ++ unsigned int size, ++ bool resyncing, ++ bool wantEAC3dependent) + { + if (size < 8) + return false; +@@ -320,14 +306,14 @@ bool CAEStreamParser::TrySyncAC3(uint8_t *data, unsigned int size, bool resyncin + if (data[0] != 0x0b || data[1] != 0x77) + return false; + +- uint8_t bsid = data[5] >> 3; ++ uint8_t bsid = data[5] >> 3; + uint8_t acmod = data[6] >> 5; + uint8_t lfeon; + + int8_t pos = 4; + if ((acmod & 0x1) && (acmod != 0x1)) + pos -= 2; +- if (acmod & 0x4 ) ++ if (acmod & 0x4) + pos -= 2; + if (acmod == 0x2) + pos -= 2; +@@ -356,9 +342,15 @@ bool CAEStreamParser::TrySyncAC3(uint8_t *data, unsigned int size, bool resyncin + unsigned int framesize = 0; + switch (fscod) + { +- case 0: framesize = bitRate * 2; break; +- case 1: framesize = (320 * bitRate / 147 + (frmsizecod & 1 ? 1 : 0)); break; +- case 2: framesize = bitRate * 4; break; ++ case 0: ++ framesize = bitRate * 2; ++ break; ++ case 1: ++ framesize = (320 * bitRate / 147 + (frmsizecod & 1 ? 1 : 0)); ++ break; ++ case 2: ++ framesize = bitRate * 4; ++ break; + } + + m_fsize = framesize << 1; +@@ -371,14 +363,16 @@ bool CAEStreamParser::TrySyncAC3(uint8_t *data, unsigned int size, bool resyncin + /* this may be the main stream of EAC3 */ + unsigned int fsizeMain = m_fsize; + unsigned int reqBytes = fsizeMain + 8; +- if (size < reqBytes) { ++ if (size < reqBytes) ++ { + /* not enough data to check for E-AC3 dependent frame, request more */ + m_needBytes = reqBytes; + m_fsize = 0; + /* no need to resync => return true */ + return true; + } +- if (TrySyncAC3(data + fsizeMain, size - fsizeMain, resyncing, /*wantEAC3dependent*/ true)) { ++ if (TrySyncAC3(data + fsizeMain, size - fsizeMain, resyncing, /*wantEAC3dependent*/ true)) ++ { + /* concatenate the main and dependent frames */ + m_fsize += fsizeMain; + return true; +@@ -451,14 +445,16 @@ bool CAEStreamParser::TrySyncAC3(uint8_t *data, unsigned int size, bool resyncin + { + unsigned int fsizeMain = m_fsize; + unsigned int reqBytes = fsizeMain + 8; +- if (size < reqBytes) { ++ if (size < reqBytes) ++ { + /* not enough data to check for E-AC3 dependent frame, request more */ + m_needBytes = reqBytes; + m_fsize = 0; + /* no need to resync => return true */ + return true; + } +- if (TrySyncAC3(data + fsizeMain, size - fsizeMain, resyncing, /*wantEAC3dependent*/ true)) { ++ if (TrySyncAC3(data + fsizeMain, size - fsizeMain, resyncing, /*wantEAC3dependent*/ true)) ++ { + /* concatenate the main and dependent frames */ + m_fsize += fsizeMain; + return true; +@@ -481,7 +477,7 @@ bool CAEStreamParser::TrySyncAC3(uint8_t *data, unsigned int size, bool resyncin + } + } + +-unsigned int CAEStreamParser::SyncAC3(uint8_t *data, unsigned int size) ++unsigned int CAEStreamParser::SyncAC3(uint8_t* data, unsigned int size) + { + unsigned int skip = 0; + +@@ -498,7 +494,7 @@ unsigned int CAEStreamParser::SyncAC3(uint8_t *data, unsigned int size) + return skip; + } + +-unsigned int CAEStreamParser::SyncDTS(uint8_t *data, unsigned int size) ++unsigned int CAEStreamParser::SyncDTS(uint8_t* data, unsigned int size) + { + if (size < 13) + { +@@ -535,7 +531,7 @@ unsigned int CAEStreamParser::SyncDTS(uint8_t *data, unsigned int size) + ext_type = ((data[11] & 0xe) >> 1); + sfreq = data[9] & 0xF; + lfe = (data[12] & 0x18) >> 3; +- m_info.m_dataIsLE = false; ++ m_info.m_dataIsLE = false; + bits = 14; + break; + +@@ -598,9 +594,15 @@ unsigned int CAEStreamParser::SyncDTS(uint8_t *data, unsigned int size) + CAEStreamInfo::DataType dataType; + switch (dtsBlocks << 5) + { +- case 512 : dataType = CAEStreamInfo::STREAM_TYPE_DTS_512 ; break; +- case 1024: dataType = CAEStreamInfo::STREAM_TYPE_DTS_1024; break; +- case 2048: dataType = CAEStreamInfo::STREAM_TYPE_DTS_2048; break; ++ case 512: ++ dataType = CAEStreamInfo::STREAM_TYPE_DTS_512; ++ break; ++ case 1024: ++ dataType = CAEStreamInfo::STREAM_TYPE_DTS_1024; ++ break; ++ case 2048: ++ dataType = CAEStreamInfo::STREAM_TYPE_DTS_2048; ++ break; + default: + invalid = true; + break; +@@ -617,23 +619,28 @@ unsigned int CAEStreamParser::SyncDTS(uint8_t *data, unsigned int size) + if (size - skip < m_fsize + 10) + { + /* we can assume DTS sync at this point */ +- m_syncFunc = &CAEStreamParser::SyncDTS; ++ m_syncFunc = &CAEStreamParser::SyncDTS; + m_needBytes = m_fsize + 10; +- m_fsize = 0; ++ m_fsize = 0; + + return skip; + } + + /* look for DTS-HD */ +- hd_sync = (data[m_fsize] << 24) | (data[m_fsize + 1] << 16) | (data[m_fsize + 2] << 8) | data[m_fsize + 3]; ++ hd_sync = (data[m_fsize] << 24) | (data[m_fsize + 1] << 16) | (data[m_fsize + 2] << 8) | ++ data[m_fsize + 3]; + if (hd_sync == DTS_PREAMBLE_HD) + { + int hd_size; + bool blownup = (data[m_fsize + 5] & 0x20) != 0; + if (blownup) +- hd_size = (((data[m_fsize + 6] & 0x01) << 19) | (data[m_fsize + 7] << 11) | (data[m_fsize + 8] << 3) | ((data[m_fsize + 9] & 0xe0) >> 5)) + 1; ++ hd_size = (((data[m_fsize + 6] & 0x01) << 19) | (data[m_fsize + 7] << 11) | ++ (data[m_fsize + 8] << 3) | ((data[m_fsize + 9] & 0xe0) >> 5)) + ++ 1; + else +- hd_size = (((data[m_fsize + 6] & 0x1f) << 11) | (data[m_fsize + 7] << 3) | ((data[m_fsize + 8] & 0xe0) >> 5)) + 1; ++ hd_size = (((data[m_fsize + 6] & 0x1f) << 11) | (data[m_fsize + 7] << 3) | ++ ((data[m_fsize + 8] & 0xe0) >> 5)) + ++ 1; + + int header_size; + if (blownup) +@@ -641,17 +648,16 @@ unsigned int CAEStreamParser::SyncDTS(uint8_t *data, unsigned int size) + else + header_size = (((data[m_fsize + 5] & 0x1f) << 3) | ((data[m_fsize + 6] & 0xe0) >> 5)) + 1; + +- hd_sync = data[m_fsize + header_size] << 24 | data[m_fsize + header_size + 1] << 16 | data[m_fsize + header_size + 2] << 8 | data[m_fsize + header_size + 3]; ++ hd_sync = data[m_fsize + header_size] << 24 | data[m_fsize + header_size + 1] << 16 | ++ data[m_fsize + header_size + 2] << 8 | data[m_fsize + header_size + 3]; + + /* set the type according to core or not */ + if (m_coreOnly) + dataType = CAEStreamInfo::STREAM_TYPE_DTSHD_CORE; + else if (hd_sync == DTS_PREAMBLE_XLL) + dataType = CAEStreamInfo::STREAM_TYPE_DTSHD_MA; +- else if (hd_sync == DTS_PREAMBLE_XCH || +- hd_sync == DTS_PREAMBLE_XXCH || +- hd_sync == DTS_PREAMBLE_X96K || +- hd_sync == DTS_PREAMBLE_XBR || ++ else if (hd_sync == DTS_PREAMBLE_XCH || hd_sync == DTS_PREAMBLE_XXCH || ++ hd_sync == DTS_PREAMBLE_X96K || hd_sync == DTS_PREAMBLE_XBR || + hd_sync == DTS_PREAMBLE_LBR) + dataType = CAEStreamInfo::STREAM_TYPE_DTSHD; + else +@@ -662,7 +668,8 @@ unsigned int CAEStreamParser::SyncDTS(uint8_t *data, unsigned int size) + } + + unsigned int sampleRate = DTSSampleRates[sfreq]; +- if (!m_hasSync || skip || dataType != m_info.m_type || sampleRate != m_info.m_sampleRate || dtsBlocks != m_dtsBlocks) ++ if (!m_hasSync || skip || dataType != m_info.m_type || sampleRate != m_info.m_sampleRate || ++ dtsBlocks != m_dtsBlocks) + { + m_hasSync = true; + m_info.m_type = dataType; +@@ -683,7 +690,8 @@ unsigned int CAEStreamParser::SyncDTS(uint8_t *data, unsigned int size) + } + else + { +- m_info.m_dtsPeriod = (m_info.m_sampleRate * (2 >> 1)) * (m_dtsBlocks << 5) / m_info.m_sampleRate; ++ m_info.m_dtsPeriod = ++ (m_info.m_sampleRate * (2 >> 1)) * (m_dtsBlocks << 5) / m_info.m_sampleRate; + } + + std::string type; +@@ -746,7 +754,7 @@ inline unsigned int CAEStreamParser::GetTrueHDChannels(const uint16_t chanmap) + return channels; + } + +-unsigned int CAEStreamParser::SyncTrueHD(uint8_t *data, unsigned int size) ++unsigned int CAEStreamParser::SyncTrueHD(uint8_t* data, unsigned int size) + { + unsigned int left = size; + unsigned int skip = 0; +@@ -759,7 +767,7 @@ unsigned int CAEStreamParser::SyncTrueHD(uint8_t *data, unsigned int size) + return size; + + /* if its a major audio unit */ +- uint16_t length = ((data[0] & 0x0F) << 8 | data[1]) << 1; ++ uint16_t length = ((data[0] & 0x0F) << 8 | data[1]) << 1; + uint32_t syncword = ((((data[4] << 8 | data[5]) << 8) | data[6]) << 8) | data[7]; + if (syncword == 0xf8726fba) + { +@@ -822,7 +830,7 @@ unsigned int CAEStreamParser::SyncTrueHD(uint8_t *data, unsigned int size) + return skip; + + /* verify the parity */ +- int p = 0; ++ int p = 0; + uint8_t check = 0; + for (int i = -1; i < m_substreams; ++i) + { +@@ -839,7 +847,7 @@ unsigned int CAEStreamParser::SyncTrueHD(uint8_t *data, unsigned int size) + if ((((check >> 4) ^ check) & 0xF) != 0xF) + { + /* lost sync */ +- m_hasSync = false; ++ m_hasSync = false; + CLog::Log(LOGINFO, "CAEStreamParser::SyncTrueHD - Sync Lost"); + continue; + } +@@ -852,7 +860,6 @@ unsigned int CAEStreamParser::SyncTrueHD(uint8_t *data, unsigned int size) + } + + /* lost sync */ +- m_hasSync = false; ++ m_hasSync = false; + return skip; + } +- + +From 57df7a71ad80d644075dcba971d65fd1fe7cf1f6 Mon Sep 17 00:00:00 2001 +From: Dom Cobley +Date: Fri, 5 May 2023 18:29:28 +0100 +Subject: [PATCH 3/4] AEStreamInfo: Make comments follow code guidelines + +No functional change +--- + xbmc/cores/AudioEngine/Utils/AEStreamInfo.cpp | 132 +++++++++--------- + 1 file changed, 65 insertions(+), 67 deletions(-) + +diff --git a/xbmc/cores/AudioEngine/Utils/AEStreamInfo.cpp b/xbmc/cores/AudioEngine/Utils/AEStreamInfo.cpp +index 5ce9a33ce471e..c98a306827880 100644 +--- a/xbmc/cores/AudioEngine/Utils/AEStreamInfo.cpp ++++ b/xbmc/cores/AudioEngine/Utils/AEStreamInfo.cpp +@@ -104,8 +104,8 @@ void CAEStreamParser::Reset() + + int CAEStreamParser::AddData(uint8_t* data, + unsigned int size, +- uint8_t** buffer /* = NULL */, +- unsigned int* bufferSize /* = 0 */) ++ uint8_t** buffer, ++ unsigned int* bufferSize) + { + if (size == 0) + { +@@ -166,12 +166,12 @@ int CAEStreamParser::AddData(uint8_t* data, + break; + else + { +- /* lost sync */ ++ // lost sync + m_syncFunc = &CAEStreamParser::DetectType; + m_info.m_type = CAEStreamInfo::STREAM_TYPE_NULL; + m_info.m_repeat = 1; + +- /* if the buffer is full, or the offset < the buffer size */ ++ // if the buffer is full, or the offset < the buffer size + if (m_bufferSize == sizeof(m_buffer) || offset < m_bufferSize) + { + m_bufferSize -= offset; +@@ -181,16 +181,16 @@ int CAEStreamParser::AddData(uint8_t* data, + } + } + +- /* if we got here, we acquired sync on the buffer */ ++ // if we got here, we acquired sync on the buffer + +- /* align the buffer */ ++ // align the buffer + if (offset) + { + m_bufferSize -= offset; + memmove(m_buffer, m_buffer + offset, m_bufferSize); + } + +- /* bytes to skip until the next packet */ ++ // bytes to skip until the next packet + m_skipBytes = std::max(0, (int)m_fsize - (int)m_bufferSize); + if (m_skipBytes) + { +@@ -210,42 +210,40 @@ int CAEStreamParser::AddData(uint8_t* data, + + void CAEStreamParser::GetPacket(uint8_t** buffer, unsigned int* bufferSize) + { +- /* if the caller wants the packet */ ++ // 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 and we only want the core, just fetch that + unsigned int size = m_fsize; + if (m_info.m_type == CAEStreamInfo::STREAM_TYPE_DTSHD_CORE) + size = m_coreSize; + +- /* make sure the buffer is allocated and big enough */ ++ // make sure the buffer is allocated and big enough + if (!*buffer || !bufferSize || *bufferSize < size) + { + delete[] * buffer; + *buffer = new uint8_t[size]; + } + +- /* copy the data into the buffer and update the size */ ++ // copy the data into the buffer and update the size + memcpy(*buffer, m_buffer, size); + if (bufferSize) + *bufferSize = size; + } + +- /* remove the parsed data from the buffer */ ++ // remove the parsed data from the buffer + m_bufferSize -= m_fsize; + memmove(m_buffer, m_buffer + m_fsize, m_bufferSize); + m_fsize = 0; + m_coreSize = 0; + } + +-/* SYNC FUNCTIONS */ ++// SYNC FUNCTIONS + +-/* +- This function looks for sync words across the types in parallel, and only does an exhaustive +- test if it finds a syncword. Once sync has been established, the relevant sync function sets +- m_syncFunc to itself. This function will only be called again if total sync is lost, which +- allows is to switch stream types on the fly much like a real receiver does. +-*/ ++// This function looks for sync words across the types in parallel, and only does an exhaustive ++// test if it finds a syncword. Once sync has been established, the relevant sync function sets ++// m_syncFunc to itself. This function will only be called again if total sync is lost, which ++// allows is to switch stream types on the fly much like a real receiver does. + unsigned int CAEStreamParser::DetectType(uint8_t* data, unsigned int size) + { + unsigned int skipped = 0; +@@ -253,7 +251,7 @@ unsigned int CAEStreamParser::DetectType(uint8_t* data, unsigned int size) + + while (size > 8) + { +- /* if it could be DTS */ ++ // if it could be DTS + unsigned int header = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]; + if (header == DTS_PREAMBLE_14LE || header == DTS_PREAMBLE_14BE || header == DTS_PREAMBLE_16LE || + header == DTS_PREAMBLE_16BE) +@@ -265,7 +263,7 @@ unsigned int CAEStreamParser::DetectType(uint8_t* data, unsigned int size) + possible = skipped; + } + +- /* if it could be AC3 */ ++ // if it could be AC3 + if (data[0] == 0x0b && data[1] == 0x77) + { + unsigned int skip = SyncAC3(data, size); +@@ -275,7 +273,7 @@ unsigned int CAEStreamParser::DetectType(uint8_t* data, unsigned int size) + possible = skipped; + } + +- /* if it could be TrueHD */ ++ // if it could be TrueHD + if (data[4] == 0xf8 && data[5] == 0x72 && data[6] == 0x6f && data[7] == 0xba) + { + unsigned int skip = SyncTrueHD(data, size); +@@ -285,7 +283,7 @@ unsigned int CAEStreamParser::DetectType(uint8_t* data, unsigned int size) + possible = skipped; + } + +- /* move along one byte */ ++ // move along one byte + --size; + ++skipped; + ++data; +@@ -302,7 +300,7 @@ bool CAEStreamParser::TrySyncAC3(uint8_t* data, + if (size < 8) + return false; + +- /* look for an ac3 sync word */ ++ // look for an ac3 sync word + if (data[0] != 0x0b || data[1] != 0x77) + return false; + +@@ -327,7 +325,7 @@ bool CAEStreamParser::TrySyncAC3(uint8_t* data, + + if (bsid <= 10) + { +- /* Normal AC-3 */ ++ // Normal AC-3 + + if (wantEAC3dependent) + return false; +@@ -337,7 +335,7 @@ bool CAEStreamParser::TrySyncAC3(uint8_t* data, + if (fscod == 3 || frmsizecod > 37) + return false; + +- /* get the details we need to check crc1 and framesize */ ++ // get the details we need to check crc1 and framesize + unsigned int bitRate = AC3Bitrates[frmsizecod >> 1]; + unsigned int framesize = 0; + switch (fscod) +@@ -356,30 +354,30 @@ bool CAEStreamParser::TrySyncAC3(uint8_t* data, + m_fsize = framesize << 1; + m_info.m_sampleRate = AC3FSCod[fscod]; + +- /* dont do extensive testing if we have not lost sync */ ++ // dont do extensive testing if we have not lost sync + if (m_info.m_type == CAEStreamInfo::STREAM_TYPE_AC3 && !resyncing) + return true; + +- /* this may be the main stream of EAC3 */ ++ // this may be the main stream of EAC3 + unsigned int fsizeMain = m_fsize; + unsigned int reqBytes = fsizeMain + 8; + if (size < reqBytes) + { +- /* not enough data to check for E-AC3 dependent frame, request more */ ++ // not enough data to check for E-AC3 dependent frame, request more + m_needBytes = reqBytes; + m_fsize = 0; +- /* no need to resync => return true */ ++ // no need to resync => return true + return true; + } +- if (TrySyncAC3(data + fsizeMain, size - fsizeMain, resyncing, /*wantEAC3dependent*/ true)) ++ if (TrySyncAC3(data + fsizeMain, size - fsizeMain, resyncing, true)) + { +- /* concatenate the main and dependent frames */ ++ // concatenate the main and dependent frames + m_fsize += fsizeMain; + return true; + } + + unsigned int crc_size; +- /* if we have enough data, validate the entire packet, else try to validate crc2 (5/8 of the packet) */ ++ // if we have enough data, validate the entire packet, else try to validate crc2 (5/8 of the packet) + if (framesize <= size) + crc_size = framesize - 1; + else +@@ -389,7 +387,7 @@ bool CAEStreamParser::TrySyncAC3(uint8_t* data, + if (av_crc(av_crc_get_table(AV_CRC_16_ANSI), 0, &data[2], crc_size * 2)) + return false; + +- /* if we get here, we can sync */ ++ // if we get here, we can sync + m_hasSync = true; + m_info.m_channels = AC3Channels[acmod] + lfeon; + m_syncFunc = &CAEStreamParser::SyncAC3; +@@ -440,22 +438,22 @@ bool CAEStreamParser::TrySyncAC3(uint8_t* data, + m_fsize = framesize << 1; + m_info.m_repeat = MAX_EAC3_BLOCKS / blocks; + +- /* EAC3 can have a dependent stream too */ ++ // EAC3 can have a dependent stream too + if (!wantEAC3dependent) + { + unsigned int fsizeMain = m_fsize; + unsigned int reqBytes = fsizeMain + 8; + if (size < reqBytes) + { +- /* not enough data to check for E-AC3 dependent frame, request more */ ++ // not enough data to check for E-AC3 dependent frame, request more + m_needBytes = reqBytes; + m_fsize = 0; +- /* no need to resync => return true */ ++ // no need to resync => return true + return true; + } +- if (TrySyncAC3(data + fsizeMain, size - fsizeMain, resyncing, /*wantEAC3dependent*/ true)) ++ if (TrySyncAC3(data + fsizeMain, size - fsizeMain, resyncing, true)) + { +- /* concatenate the main and dependent frames */ ++ // concatenate the main and dependent frames + m_fsize += fsizeMain; + return true; + } +@@ -484,7 +482,7 @@ unsigned int CAEStreamParser::SyncAC3(uint8_t* data, unsigned int size) + for (; size - skip > 7; ++skip, ++data) + { + bool resyncing = (skip != 0); +- if (TrySyncAC3(data, size - skip, resyncing, /*wantEAC3dependent*/ false)) ++ if (TrySyncAC3(data, size - skip, resyncing, false)) + return skip; + } + +@@ -519,7 +517,7 @@ unsigned int CAEStreamParser::SyncDTS(uint8_t* data, unsigned int size) + + switch (header) + { +- /* 14bit BE */ ++ // 14bit BE + case DTS_PREAMBLE_14BE: + if (data[4] != 0x07 || (data[5] & 0xf0) != 0xf0) + continue; +@@ -535,7 +533,7 @@ unsigned int CAEStreamParser::SyncDTS(uint8_t* data, unsigned int size) + bits = 14; + break; + +- /* 14bit LE */ ++ // 14bit LE + case DTS_PREAMBLE_14LE: + if (data[5] != 0x07 || (data[4] & 0xf0) != 0xf0) + continue; +@@ -551,7 +549,7 @@ unsigned int CAEStreamParser::SyncDTS(uint8_t* data, unsigned int size) + bits = 14; + break; + +- /* 16bit BE */ ++ // 16bit BE + case DTS_PREAMBLE_16BE: + dtsBlocks = (((data[4] & 0x1) << 7) | ((data[5] & 0xFC) >> 2)) + 1; + m_fsize = (((((data[5] & 0x3) << 8) | data[6]) << 4) | ((data[7] & 0xF0) >> 4)) + 1; +@@ -565,7 +563,7 @@ unsigned int CAEStreamParser::SyncDTS(uint8_t* data, unsigned int size) + bits = 16; + break; + +- /* 16bit LE */ ++ // 16bit LE + case DTS_PREAMBLE_16LE: + dtsBlocks = (((data[5] & 0x1) << 7) | ((data[4] & 0xFC) >> 2)) + 1; + m_fsize = (((((data[4] & 0x3) << 8) | data[7]) << 4) | ((data[6] & 0xF0) >> 4)) + 1; +@@ -586,7 +584,7 @@ unsigned int CAEStreamParser::SyncDTS(uint8_t* data, unsigned int size) + if (sfreq == 0 || sfreq >= DTS_SFREQ_COUNT) + continue; + +- /* make sure the framesize is sane */ ++ // make sure the framesize is sane + if (m_fsize < 96 || m_fsize > 16384) + continue; + +@@ -611,14 +609,14 @@ unsigned int CAEStreamParser::SyncDTS(uint8_t* data, unsigned int size) + if (invalid) + continue; + +- /* adjust the fsize for 14 bit streams */ ++ // adjust the fsize for 14 bit streams + if (bits == 14) + m_fsize = m_fsize / 14 * 16; + +- /* we need enough data to check for DTS-HD */ ++ // we need enough data to check for DTS-HD + if (size - skip < m_fsize + 10) + { +- /* we can assume DTS sync at this point */ ++ // we can assume DTS sync at this point + m_syncFunc = &CAEStreamParser::SyncDTS; + m_needBytes = m_fsize + 10; + m_fsize = 0; +@@ -626,7 +624,7 @@ unsigned int CAEStreamParser::SyncDTS(uint8_t* data, unsigned int size) + return skip; + } + +- /* look for DTS-HD */ ++ // look for DTS-HD + hd_sync = (data[m_fsize] << 24) | (data[m_fsize + 1] << 16) | (data[m_fsize + 2] << 8) | + data[m_fsize + 3]; + if (hd_sync == DTS_PREAMBLE_HD) +@@ -651,7 +649,7 @@ unsigned int CAEStreamParser::SyncDTS(uint8_t* data, unsigned int size) + hd_sync = data[m_fsize + header_size] << 24 | data[m_fsize + header_size + 1] << 16 | + data[m_fsize + header_size + 2] << 8 | data[m_fsize + header_size + 3]; + +- /* set the type according to core or not */ ++ // set the type according to core or not + if (m_coreOnly) + dataType = CAEStreamInfo::STREAM_TYPE_DTSHD_CORE; + else if (hd_sync == DTS_PREAMBLE_XLL) +@@ -681,7 +679,7 @@ unsigned int CAEStreamParser::SyncDTS(uint8_t* data, unsigned int size) + + if (dataType == CAEStreamInfo::STREAM_TYPE_DTSHD_MA) + { +- m_info.m_channels += 2; /* FIXME: this needs to be read out, not sure how to do that yet */ ++ m_info.m_channels += 2; // FIXME: this needs to be read out, not sure how to do that yet + m_info.m_dtsPeriod = (192000 * (8 >> 1)) * (m_dtsBlocks << 5) / m_info.m_sampleRate; + } + else if (dataType == CAEStreamInfo::STREAM_TYPE_DTSHD) +@@ -740,7 +738,7 @@ unsigned int CAEStreamParser::SyncDTS(uint8_t* data, unsigned int size) + return skip; + } + +- /* lost sync */ ++ // lost sync + CLog::Log(LOGINFO, "CAEStreamParser::SyncDTS - DTS sync lost"); + m_hasSync = false; + return skip; +@@ -759,23 +757,23 @@ unsigned int CAEStreamParser::SyncTrueHD(uint8_t* data, unsigned int size) + unsigned int left = size; + unsigned int skip = 0; + +- /* if MLP */ ++ // if MLP + for (; left; ++skip, ++data, --left) + { +- /* if we dont have sync and there is less the 8 bytes, then break out */ ++ // if we dont have sync and there is less the 8 bytes, then break out + if (!m_hasSync && left < 8) + return size; + +- /* if its a major audio unit */ ++ // if its a major audio unit + uint16_t length = ((data[0] & 0x0F) << 8 | data[1]) << 1; + uint32_t syncword = ((((data[4] << 8 | data[5]) << 8) | data[6]) << 8) | data[7]; + if (syncword == 0xf8726fba) + { +- /* we need 32 bytes to sync on a master audio unit */ ++ // we need 32 bytes to sync on a master audio unit + if (left < 32) + return skip; + +- /* get the rate and ensure its valid */ ++ // get the rate and ensure its valid + int rate = (data[8] & 0xf0) >> 4; + if (rate == 0xF) + continue; +@@ -783,7 +781,7 @@ unsigned int CAEStreamParser::SyncTrueHD(uint8_t* data, unsigned int size) + unsigned int major_sync_size = 28; + if (data[29] & 1) + { +- /* extension(s) present, look up count */ ++ // extension(s) present, look up count + int extension_count = data[30] >> 4; + major_sync_size += 2 + extension_count * 2; + } +@@ -791,17 +789,17 @@ unsigned int CAEStreamParser::SyncTrueHD(uint8_t* data, unsigned int size) + if (left < 4 + major_sync_size) + return skip; + +- /* verify the crc of the audio unit */ ++ // verify the crc of the audio unit + uint16_t crc = av_crc(m_crcTrueHD, 0, data + 4, major_sync_size - 4); + crc ^= (data[4 + major_sync_size - 3] << 8) | data[4 + major_sync_size - 4]; + if (((data[4 + major_sync_size - 1] << 8) | data[4 + major_sync_size - 2]) != crc) + continue; + +- /* get the sample rate and substreams, we have a valid master audio unit */ ++ // get the sample rate and substreams, we have a valid master audio unit + m_info.m_sampleRate = (rate & 0x8 ? 44100 : 48000) << (rate & 0x7); + m_substreams = (data[20] & 0xF0) >> 4; + +- /* get the number of encoded channels */ ++ // get the number of encoded channels + uint16_t channel_map = ((data[10] & 0x1F) << 8) | data[11]; + if (!channel_map) + channel_map = (data[9] << 1) | (data[10] >> 7); +@@ -821,15 +819,15 @@ unsigned int CAEStreamParser::SyncTrueHD(uint8_t* data, unsigned int size) + } + else + { +- /* we cant sink to a subframe until we have the information from a master audio unit */ ++ // we cant sink to a subframe until we have the information from a master audio unit + if (!m_hasSync) + continue; + +- /* if there is not enough data left to verify the packet, just return the skip amount */ ++ // if there is not enough data left to verify the packet, just return the skip amount + if (left < (unsigned int)m_substreams * 4) + return skip; + +- /* verify the parity */ ++ // verify the parity + int p = 0; + uint8_t check = 0; + for (int i = -1; i < m_substreams; ++i) +@@ -843,10 +841,10 @@ unsigned int CAEStreamParser::SyncTrueHD(uint8_t* data, unsigned int size) + } + } + +- /* if the parity nibble does not match */ ++ // if the parity nibble does not match + if ((((check >> 4) ^ check) & 0xF) != 0xF) + { +- /* lost sync */ ++ // lost sync + m_hasSync = false; + CLog::Log(LOGINFO, "CAEStreamParser::SyncTrueHD - Sync Lost"); + continue; +@@ -859,7 +857,7 @@ unsigned int CAEStreamParser::SyncTrueHD(uint8_t* data, unsigned int size) + } + } + +- /* lost sync */ ++ // lost sync + m_hasSync = false; + return skip; + } + +From eb85829058e27d9c92ccc1449cbd650186c01c17 Mon Sep 17 00:00:00 2001 +From: Stephan Sundermann +Date: Wed, 17 May 2023 22:29:08 +0200 +Subject: [PATCH 4/4] [StreamInfo] Fix EAC3 frame size + +The field m_ac3FrameSize was never updated with the concatenated value of the independent and dependent substream +--- + xbmc/cores/AudioEngine/Utils/AEStreamInfo.cpp | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/xbmc/cores/AudioEngine/Utils/AEStreamInfo.cpp b/xbmc/cores/AudioEngine/Utils/AEStreamInfo.cpp +index c98a306827880..f12a0253e17ee 100644 +--- a/xbmc/cores/AudioEngine/Utils/AEStreamInfo.cpp ++++ b/xbmc/cores/AudioEngine/Utils/AEStreamInfo.cpp +@@ -369,6 +369,7 @@ bool CAEStreamParser::TrySyncAC3(uint8_t* data, + // no need to resync => return true + return true; + } ++ m_info.m_ac3FrameSize = fsizeMain; + if (TrySyncAC3(data + fsizeMain, size - fsizeMain, resyncing, true)) + { + // concatenate the main and dependent frames +@@ -392,7 +393,7 @@ bool CAEStreamParser::TrySyncAC3(uint8_t* data, + m_info.m_channels = AC3Channels[acmod] + lfeon; + m_syncFunc = &CAEStreamParser::SyncAC3; + m_info.m_type = CAEStreamInfo::STREAM_TYPE_AC3; +- m_info.m_ac3FrameSize = m_fsize; ++ m_info.m_ac3FrameSize += m_fsize; + m_info.m_repeat = 1; + + CLog::Log(LOGINFO, "CAEStreamParser::TrySyncAC3 - AC3 stream detected ({} channels, {}Hz)", +@@ -451,6 +452,7 @@ bool CAEStreamParser::TrySyncAC3(uint8_t* data, + // no need to resync => return true + return true; + } ++ m_info.m_ac3FrameSize = fsizeMain; + if (TrySyncAC3(data + fsizeMain, size - fsizeMain, resyncing, true)) + { + // concatenate the main and dependent frames +@@ -467,7 +469,7 @@ bool CAEStreamParser::TrySyncAC3(uint8_t* data, + m_info.m_channels = AC3Channels[acmod] + lfeon; + m_syncFunc = &CAEStreamParser::SyncAC3; + m_info.m_type = CAEStreamInfo::STREAM_TYPE_EAC3; +- m_info.m_ac3FrameSize = m_fsize; ++ m_info.m_ac3FrameSize += m_fsize; + + CLog::Log(LOGINFO, "CAEStreamParser::TrySyncAC3 - E-AC3 stream detected ({} channels, {}Hz)", + m_info.m_channels, m_info.m_sampleRate);