Skip to content

Commit aac1504

Browse files
authored
Merge pull request #530 from ksooo/aac_rds
Add support for RDS data contained in AAC streams
2 parents 12f95ae + 4e768a9 commit aac1504

34 files changed

+2554
-38
lines changed

CMakeLists.txt

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,39 @@ set(HTS_SOURCES src/addon.h
1414
src/Tvheadend.cpp
1515
src/Tvheadend.h)
1616

17+
set(HTS_SOURCES_AAC
18+
src/aac/BitStream.cpp
19+
src/aac/BitStream.h
20+
src/aac/Decoder.cpp
21+
src/aac/Decoder.h
22+
src/aac/Profile.h
23+
src/aac/SampleFrequency.h)
24+
25+
set(HTS_SOURCES_AAC_ELEMENTS
26+
src/aac/elements/CCE.cpp
27+
src/aac/elements/CCE.h
28+
src/aac/elements/CPE.cpp
29+
src/aac/elements/CPE.h
30+
src/aac/elements/DSE.cpp
31+
src/aac/elements/DSE.h
32+
src/aac/elements/FIL.cpp
33+
src/aac/elements/FIL.h
34+
src/aac/elements/ICS.cpp
35+
src/aac/elements/ICS.h
36+
src/aac/elements/ICSInfo.cpp
37+
src/aac/elements/ICSInfo.h
38+
src/aac/elements/LFE.cpp
39+
src/aac/elements/LFE.h
40+
src/aac/elements/PCE.cpp
41+
src/aac/elements/PCE.h
42+
src/aac/elements/SCE.cpp
43+
src/aac/elements/SCE.h)
44+
45+
set(HTS_SOURCES_AAC_HUFFMAN
46+
src/aac/huffman/Codebooks.h
47+
src/aac/huffman/Decoder.cpp
48+
src/aac/huffman/Decoder.h)
49+
1750
set(HTS_SOURCES_TVHEADEND
1851
src/tvheadend/AutoRecordings.cpp
1952
src/tvheadend/AutoRecordings.h
@@ -69,11 +102,16 @@ set(HTS_SOURCES_TVHEADEND_UTILITIES
69102
src/tvheadend/utilities/LifetimeMapper.h
70103
src/tvheadend/utilities/AsyncState.cpp
71104
src/tvheadend/utilities/AsyncState.h
105+
src/tvheadend/utilities/RDSExtractor.h
106+
src/tvheadend/utilities/RDSExtractor.cpp
72107
src/tvheadend/utilities/SyncedBuffer.h
73108
src/tvheadend/utilities/TCPSocket.h
74109
src/tvheadend/utilities/TCPSocket.cpp)
75110

76111
source_group("Source Files" FILES ${HTS_SOURCES})
112+
source_group("Source Files\\aac" FILES ${HTS_SOURCES_AAC})
113+
source_group("Source Files\\aac\\elements" FILES ${HTS_SOURCES_AAC_ELEMENTS})
114+
source_group("Source Files\\aac\\huffman" FILES ${HTS_SOURCES_AAC_HUFFMAN})
77115
source_group("Source Files\\tvheadend" FILES ${HTS_SOURCES_TVHEADEND})
78116
source_group("Source Files\\tvheadend\\entity" FILES ${HTS_SOURCES_TVHEADEND_ENTITY})
79117
source_group("Source Files\\tvheadend\\status" FILES ${HTS_SOURCES_TVHEADEND_STATUS})
@@ -92,6 +130,9 @@ source_group("Resource Files" FILES ${HTS_RESOURCES})
92130

93131
# Combine the file lists
94132
list(APPEND HTS_SOURCES
133+
${HTS_SOURCES_AAC}
134+
${HTS_SOURCES_AAC_ELEMENTS}
135+
${HTS_SOURCES_AAC_HUFFMAN}
95136
${HTS_SOURCES_TVHEADEND}
96137
${HTS_SOURCES_TVHEADEND_ENTITY}
97138
${HTS_SOURCES_TVHEADEND_STATUS}

pvr.hts/addon.xml.in

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<addon
33
id="pvr.hts"
4-
version="8.3.4"
4+
version="8.4.0"
55
name="Tvheadend HTSP Client"
66
provider-name="Adam Sutton, Sam Stenvall, Lars Op den Kamp, Kai Sommerfeld">
77
<requires>@ADDON_DEPENDS@</requires>

pvr.hts/changelog.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
v8.4.0
2+
- Add support for RDS data contained in AAC streams.
3+
- Translations updates from Weblate
4+
15
v8.3.4
26
- Fixed 'Use HTTPS' setting init/write
37

src/aac/BitStream.cpp

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
/*
2+
* Copyright (C) 2005-2021 Team Kodi
3+
* https://kodi.tv
4+
*
5+
* SPDX-License-Identifier: GPL-2.0-or-later
6+
* See LICENSE.md for more information.
7+
*/
8+
9+
#include "BitStream.h"
10+
11+
#include <stdexcept>
12+
13+
using namespace aac;
14+
15+
BitStream::BitStream(const uint8_t* data, unsigned int dataLen) : m_data(data), m_dataLen(dataLen)
16+
{
17+
}
18+
19+
int BitStream::GetBitsLeft() const
20+
{
21+
return 8 * (m_dataLen - m_pos) + m_bitsCached;
22+
}
23+
24+
int BitStream::ReadBit()
25+
{
26+
int result;
27+
28+
if (m_bitsCached > 0)
29+
{
30+
m_bitsCached--;
31+
}
32+
else
33+
{
34+
m_cache = ReadCache();
35+
m_bitsCached = 31;
36+
}
37+
38+
result = (m_cache >> m_bitsCached) & 0x1;
39+
m_bitsRead++;
40+
41+
return result;
42+
}
43+
44+
int BitStream::ReadBits(int n)
45+
{
46+
if (n > 32)
47+
throw std::invalid_argument("aac::BitStream::ReadBits - Attempt to read more than 32 bits");
48+
49+
int result;
50+
51+
if (m_bitsCached >= n)
52+
{
53+
m_bitsCached -= n;
54+
result = (m_cache >> m_bitsCached) & MaskBits(n);
55+
}
56+
else
57+
{
58+
const uint32_t c = m_cache & MaskBits(m_bitsCached);
59+
const int left = n - m_bitsCached;
60+
61+
m_cache = ReadCache();
62+
m_bitsCached = 32 - left;
63+
result = ((m_cache >> m_bitsCached) & MaskBits(left)) | (c << left);
64+
}
65+
66+
m_bitsRead += n;
67+
return result;
68+
}
69+
70+
void BitStream::SkipBit()
71+
{
72+
m_bitsRead++;
73+
if (m_bitsCached > 0)
74+
{
75+
m_bitsCached--;
76+
}
77+
else
78+
{
79+
m_cache = ReadCache();
80+
m_bitsCached = 31;
81+
}
82+
}
83+
84+
void BitStream::SkipBits(int n)
85+
{
86+
m_bitsRead += n;
87+
if (n <= m_bitsCached)
88+
{
89+
m_bitsCached -= n;
90+
}
91+
else
92+
{
93+
n -= m_bitsCached;
94+
95+
while (n >= 32)
96+
{
97+
n -= 32;
98+
ReadCache();
99+
}
100+
101+
if (n > 0)
102+
{
103+
m_cache = ReadCache();
104+
m_bitsCached = 32 - n;
105+
}
106+
else
107+
{
108+
m_cache = 0;
109+
m_bitsCached = 0;
110+
}
111+
}
112+
}
113+
114+
void BitStream::ByteAlign()
115+
{
116+
const int toFlush = m_bitsCached & 0x7;
117+
if (toFlush > 0)
118+
SkipBits(toFlush);
119+
}
120+
121+
uint32_t BitStream::ReadCache()
122+
{
123+
if (m_pos == m_dataLen)
124+
{
125+
throw std::out_of_range("aac::BitStream::ReadCache - Attempt to read past end of stream");
126+
}
127+
else if (m_pos > m_dataLen - 4)
128+
{
129+
// read near end of stream; read last 1 to 3 bytes
130+
int toRead = m_dataLen - m_pos;
131+
int i = 0;
132+
if (toRead-- > 0)
133+
i = ((m_data[m_pos] & 0xFF) << 24);
134+
if (toRead-- > 0)
135+
i |= ((m_data[m_pos + 1] & 0xFF) << 16);
136+
if (toRead-- > 0)
137+
i |= ((m_data[m_pos + 2] & 0xFF) << 8);
138+
139+
m_pos = m_dataLen;
140+
return i;
141+
}
142+
else
143+
{
144+
// read next 4 bytes
145+
const uint32_t i = ((m_data[m_pos] & 0xFF) << 24) | ((m_data[m_pos + 1] & 0xFF) << 16) |
146+
((m_data[m_pos + 2] & 0xFF) << 8) | (m_data[m_pos + 3] & 0xFF);
147+
148+
m_pos += 4;
149+
return i;
150+
}
151+
}
152+
153+
int BitStream::MaskBits(int n)
154+
{
155+
return (n == 32) ? -1 : (1 << n) - 1;
156+
}

src/aac/BitStream.h

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
* Copyright (C) 2005-2021 Team Kodi
3+
* https://kodi.tv
4+
*
5+
* SPDX-License-Identifier: GPL-2.0-or-later
6+
* See LICENSE.md for more information.
7+
*/
8+
9+
#pragma once
10+
11+
#include <cstdint>
12+
13+
namespace aac
14+
{
15+
16+
class BitStream
17+
{
18+
public:
19+
BitStream() = delete;
20+
BitStream(const uint8_t* data, unsigned int dataLen);
21+
22+
unsigned int GetLength() const { return m_dataLen; }
23+
24+
int GetBitsLeft() const;
25+
26+
int ReadBit();
27+
int ReadBits(int n);
28+
29+
bool ReadBool() { return (ReadBit() & 0x1) != 0; }
30+
31+
void SkipBit();
32+
void SkipBits(int n);
33+
34+
void ByteAlign();
35+
36+
private:
37+
uint32_t ReadCache();
38+
int MaskBits(int n);
39+
40+
const uint8_t* m_data = nullptr;
41+
const unsigned int m_dataLen = 0;
42+
43+
unsigned int m_pos = 0; // offset in the data array
44+
uint32_t m_cache = 0; // current 4 bytes, that are read from data
45+
unsigned int m_bitsCached = 0; // remaining bits in current cache
46+
unsigned int m_bitsRead = 0; // number of total bits read
47+
};
48+
49+
} // namespace aac

0 commit comments

Comments
 (0)