-
Notifications
You must be signed in to change notification settings - Fork 93
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #530 from ksooo/aac_rds
Add support for RDS data contained in AAC streams
- Loading branch information
Showing
34 changed files
with
2,554 additions
and
38 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
Oops, something went wrong.