From 741693ba593154f29dd3905de8dfff7d73b60e83 Mon Sep 17 00:00:00 2001 From: Martchus Date: Sat, 18 Jul 2015 00:55:35 +0200 Subject: [PATCH] added ADTS frame parser --- adts/adtsframe.cpp | 31 +++++++++++ adts/adtsframe.h | 132 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 163 insertions(+) create mode 100644 adts/adtsframe.cpp create mode 100644 adts/adtsframe.h diff --git a/adts/adtsframe.cpp b/adts/adtsframe.cpp new file mode 100644 index 0000000..4a49ecb --- /dev/null +++ b/adts/adtsframe.cpp @@ -0,0 +1,31 @@ +#include "adtsframe.h" +#include "../exceptions.h" + +#include + +using namespace std; +using namespace IoUtilities; + +namespace Media { + +/*! + * \class Media::AdtsFrame + * \brief The AdtsFrame class is used to parse "Audio Data Transport Stream" frames. + */ + +/*! + * \brief Parses the header read using the specified \a reader. + * \throws Throws InvalidDataException if the data read from the stream is + * no valid frame header. + */ +void AdtsFrame::parseHeader(IoUtilities::BinaryReader &reader) +{ + m_header1 = reader.readUInt16BE(); + if(!isValid()) { + throw InvalidDataException(); + } + m_header2 = hasCrc() ? reader.readUInt56BE() : (reader.readUInt40BE() << 2); +} + +} // namespace Media + diff --git a/adts/adtsframe.h b/adts/adtsframe.h new file mode 100644 index 0000000..a0c0c9e --- /dev/null +++ b/adts/adtsframe.h @@ -0,0 +1,132 @@ +#ifndef MEDIA_ADTSFRAME_H +#define MEDIA_ADTSFRAME_H + +#include +#include + +namespace IoUtilities { +class BinaryReader; +} + +namespace Media { + +class LIB_EXPORT AdtsFrame +{ +public: + AdtsFrame(); + + void parseHeader(IoUtilities::BinaryReader &reader); + + bool isValid() const; + bool isMpeg4() const; + bool hasCrc() const; + byte mpeg4AudioObjectId() const; + byte mpeg4SampleRateIndex() const; + byte mpeg4ChannelConfig() const; + uint16 length() const; + uint16 bufferFullness() const; + byte frameCount() const; + uint16 crc() const; + +private: + uint16 m_header1; + uint64 m_header2; +}; + +/*! + * \brief Constructs a new frame. + */ +inline AdtsFrame::AdtsFrame() : + m_header1(0) +{} + +/*! + * \brief Returns an indication whether the frame is valid. + */ +inline bool AdtsFrame::isValid() const +{ + return (m_header1 & 0xFFF6u) == 0xFFF0u; +} + +/*! + * \brief Returns whether the MPEG version is MPEG-4; otherwise the MPEG version is MPEG-2. + */ +inline bool AdtsFrame::isMpeg4() const +{ + return m_header1 & 0x8u; +} + +/*! + * \brief Returns whether a CRC-16 checksum is present. + */ +inline bool AdtsFrame::hasCrc() const +{ + return m_header1 & 0x1u; +} + +/*! + * \brief Returns the MPEG-4 audio object type ID. + * \sa Media::Mpeg4AudioObjectIds + * \sa Mpeg4AudioObjectIds::idToMediaFormat() + */ +inline byte AdtsFrame::mpeg4AudioObjectId() const +{ + return (m_header2 >> 0x36) + 0x1u; +} + +/*! + * \brief Returns the MPEG-4 sample rate index. + * \sa Media::mpeg4SampleRateTable + */ +inline byte AdtsFrame::mpeg4SampleRateIndex() const +{ + return (m_header2 >> 0x32) & 0xFu; +} + +/*! + * \brief Returns the MPEG-4 channel configuration. + * \sa Media::Mpeg4ChannelConfigs + * \sa Media::mpeg4SampleRateTable::channelConfigString() + */ +inline byte AdtsFrame::mpeg4ChannelConfig() const +{ + return (m_header2 >> 0x2E) & 0x7u; +} + +/*! + * \brief Returns the length of the frame (including the header) in bytes. + */ +inline uint16 AdtsFrame::length() const +{ + return (m_header2 >> 0x1D) & 0x1FFFu; +} + +/*! + * \brief Returns the buffer fullness. + */ +inline uint16 AdtsFrame::bufferFullness() const +{ + return (m_header2 >> 0x12) & 0x7FFu; +} + +/*! + * \brief Returns the number of AAC frames (RDBs) in the ADTS frame. + */ +inline byte AdtsFrame::frameCount() const +{ + return ((m_header2 >> 0x10) & 0x3u) + 0x1u; +} + +/*! + * \brief Returns the CRC-16 checksum of the frame. + * \sa hasCrc() + */ +inline uint16 AdtsFrame::crc() const +{ + return m_header2 & 0xFFFFu; +} + + +} // namespace Media + +#endif // MEDIA_ADTSFRAME_H