Skip to content

Commit

Permalink
Merge pull request #530 from ksooo/aac_rds
Browse files Browse the repository at this point in the history
Add support for RDS data contained in AAC streams
  • Loading branch information
ksooo authored Aug 22, 2021
2 parents 12f95ae + 4e768a9 commit aac1504
Show file tree
Hide file tree
Showing 34 changed files with 2,554 additions and 38 deletions.
41 changes: 41 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,39 @@ set(HTS_SOURCES src/addon.h
src/Tvheadend.cpp
src/Tvheadend.h)

set(HTS_SOURCES_AAC
src/aac/BitStream.cpp
src/aac/BitStream.h
src/aac/Decoder.cpp
src/aac/Decoder.h
src/aac/Profile.h
src/aac/SampleFrequency.h)

set(HTS_SOURCES_AAC_ELEMENTS
src/aac/elements/CCE.cpp
src/aac/elements/CCE.h
src/aac/elements/CPE.cpp
src/aac/elements/CPE.h
src/aac/elements/DSE.cpp
src/aac/elements/DSE.h
src/aac/elements/FIL.cpp
src/aac/elements/FIL.h
src/aac/elements/ICS.cpp
src/aac/elements/ICS.h
src/aac/elements/ICSInfo.cpp
src/aac/elements/ICSInfo.h
src/aac/elements/LFE.cpp
src/aac/elements/LFE.h
src/aac/elements/PCE.cpp
src/aac/elements/PCE.h
src/aac/elements/SCE.cpp
src/aac/elements/SCE.h)

set(HTS_SOURCES_AAC_HUFFMAN
src/aac/huffman/Codebooks.h
src/aac/huffman/Decoder.cpp
src/aac/huffman/Decoder.h)

set(HTS_SOURCES_TVHEADEND
src/tvheadend/AutoRecordings.cpp
src/tvheadend/AutoRecordings.h
Expand Down Expand Up @@ -69,11 +102,16 @@ set(HTS_SOURCES_TVHEADEND_UTILITIES
src/tvheadend/utilities/LifetimeMapper.h
src/tvheadend/utilities/AsyncState.cpp
src/tvheadend/utilities/AsyncState.h
src/tvheadend/utilities/RDSExtractor.h
src/tvheadend/utilities/RDSExtractor.cpp
src/tvheadend/utilities/SyncedBuffer.h
src/tvheadend/utilities/TCPSocket.h
src/tvheadend/utilities/TCPSocket.cpp)

source_group("Source Files" FILES ${HTS_SOURCES})
source_group("Source Files\\aac" FILES ${HTS_SOURCES_AAC})
source_group("Source Files\\aac\\elements" FILES ${HTS_SOURCES_AAC_ELEMENTS})
source_group("Source Files\\aac\\huffman" FILES ${HTS_SOURCES_AAC_HUFFMAN})
source_group("Source Files\\tvheadend" FILES ${HTS_SOURCES_TVHEADEND})
source_group("Source Files\\tvheadend\\entity" FILES ${HTS_SOURCES_TVHEADEND_ENTITY})
source_group("Source Files\\tvheadend\\status" FILES ${HTS_SOURCES_TVHEADEND_STATUS})
Expand All @@ -92,6 +130,9 @@ source_group("Resource Files" FILES ${HTS_RESOURCES})

# Combine the file lists
list(APPEND HTS_SOURCES
${HTS_SOURCES_AAC}
${HTS_SOURCES_AAC_ELEMENTS}
${HTS_SOURCES_AAC_HUFFMAN}
${HTS_SOURCES_TVHEADEND}
${HTS_SOURCES_TVHEADEND_ENTITY}
${HTS_SOURCES_TVHEADEND_STATUS}
Expand Down
2 changes: 1 addition & 1 deletion pvr.hts/addon.xml.in
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<addon
id="pvr.hts"
version="8.3.4"
version="8.4.0"
name="Tvheadend HTSP Client"
provider-name="Adam Sutton, Sam Stenvall, Lars Op den Kamp, Kai Sommerfeld">
<requires>@ADDON_DEPENDS@</requires>
Expand Down
4 changes: 4 additions & 0 deletions pvr.hts/changelog.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
v8.4.0
- Add support for RDS data contained in AAC streams.
- Translations updates from Weblate

v8.3.4
- Fixed 'Use HTTPS' setting init/write

Expand Down
156 changes: 156 additions & 0 deletions src/aac/BitStream.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
/*
* Copyright (C) 2005-2021 Team Kodi
* https://kodi.tv
*
* SPDX-License-Identifier: GPL-2.0-or-later
* See LICENSE.md for more information.
*/

#include "BitStream.h"

#include <stdexcept>

using namespace aac;

BitStream::BitStream(const uint8_t* data, unsigned int dataLen) : m_data(data), m_dataLen(dataLen)
{
}

int BitStream::GetBitsLeft() const
{
return 8 * (m_dataLen - m_pos) + m_bitsCached;
}

int BitStream::ReadBit()
{
int result;

if (m_bitsCached > 0)
{
m_bitsCached--;
}
else
{
m_cache = ReadCache();
m_bitsCached = 31;
}

result = (m_cache >> m_bitsCached) & 0x1;
m_bitsRead++;

return result;
}

int BitStream::ReadBits(int n)
{
if (n > 32)
throw std::invalid_argument("aac::BitStream::ReadBits - Attempt to read more than 32 bits");

int result;

if (m_bitsCached >= n)
{
m_bitsCached -= n;
result = (m_cache >> m_bitsCached) & MaskBits(n);
}
else
{
const uint32_t c = m_cache & MaskBits(m_bitsCached);
const int left = n - m_bitsCached;

m_cache = ReadCache();
m_bitsCached = 32 - left;
result = ((m_cache >> m_bitsCached) & MaskBits(left)) | (c << left);
}

m_bitsRead += n;
return result;
}

void BitStream::SkipBit()
{
m_bitsRead++;
if (m_bitsCached > 0)
{
m_bitsCached--;
}
else
{
m_cache = ReadCache();
m_bitsCached = 31;
}
}

void BitStream::SkipBits(int n)
{
m_bitsRead += n;
if (n <= m_bitsCached)
{
m_bitsCached -= n;
}
else
{
n -= m_bitsCached;

while (n >= 32)
{
n -= 32;
ReadCache();
}

if (n > 0)
{
m_cache = ReadCache();
m_bitsCached = 32 - n;
}
else
{
m_cache = 0;
m_bitsCached = 0;
}
}
}

void BitStream::ByteAlign()
{
const int toFlush = m_bitsCached & 0x7;
if (toFlush > 0)
SkipBits(toFlush);
}

uint32_t BitStream::ReadCache()
{
if (m_pos == m_dataLen)
{
throw std::out_of_range("aac::BitStream::ReadCache - Attempt to read past end of stream");
}
else if (m_pos > m_dataLen - 4)
{
// read near end of stream; read last 1 to 3 bytes
int toRead = m_dataLen - m_pos;
int i = 0;
if (toRead-- > 0)
i = ((m_data[m_pos] & 0xFF) << 24);
if (toRead-- > 0)
i |= ((m_data[m_pos + 1] & 0xFF) << 16);
if (toRead-- > 0)
i |= ((m_data[m_pos + 2] & 0xFF) << 8);

m_pos = m_dataLen;
return i;
}
else
{
// read next 4 bytes
const uint32_t i = ((m_data[m_pos] & 0xFF) << 24) | ((m_data[m_pos + 1] & 0xFF) << 16) |
((m_data[m_pos + 2] & 0xFF) << 8) | (m_data[m_pos + 3] & 0xFF);

m_pos += 4;
return i;
}
}

int BitStream::MaskBits(int n)
{
return (n == 32) ? -1 : (1 << n) - 1;
}
49 changes: 49 additions & 0 deletions src/aac/BitStream.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* Copyright (C) 2005-2021 Team Kodi
* https://kodi.tv
*
* SPDX-License-Identifier: GPL-2.0-or-later
* See LICENSE.md for more information.
*/

#pragma once

#include <cstdint>

namespace aac
{

class BitStream
{
public:
BitStream() = delete;
BitStream(const uint8_t* data, unsigned int dataLen);

unsigned int GetLength() const { return m_dataLen; }

int GetBitsLeft() const;

int ReadBit();
int ReadBits(int n);

bool ReadBool() { return (ReadBit() & 0x1) != 0; }

void SkipBit();
void SkipBits(int n);

void ByteAlign();

private:
uint32_t ReadCache();
int MaskBits(int n);

const uint8_t* m_data = nullptr;
const unsigned int m_dataLen = 0;

unsigned int m_pos = 0; // offset in the data array
uint32_t m_cache = 0; // current 4 bytes, that are read from data
unsigned int m_bitsCached = 0; // remaining bits in current cache
unsigned int m_bitsRead = 0; // number of total bits read
};

} // namespace aac
Loading

0 comments on commit aac1504

Please sign in to comment.