2015-09-06 19:57:33 +02:00
|
|
|
#include "./mpeg4descriptor.h"
|
|
|
|
#include "./mp4container.h"
|
|
|
|
#include "./mp4ids.h"
|
2015-06-07 00:18:28 +02:00
|
|
|
|
2017-01-27 18:59:22 +01:00
|
|
|
#include <c++utilities/conversion/stringbuilder.h>
|
2018-03-07 01:17:50 +01:00
|
|
|
#include <c++utilities/conversion/stringconversion.h>
|
2017-01-27 18:59:22 +01:00
|
|
|
#include <c++utilities/io/binaryreader.h>
|
2015-06-07 00:18:28 +02:00
|
|
|
|
|
|
|
using namespace std;
|
2019-06-10 22:49:11 +02:00
|
|
|
using namespace CppUtilities;
|
2015-06-07 00:18:28 +02:00
|
|
|
|
2018-03-06 23:09:15 +01:00
|
|
|
namespace TagParser {
|
2015-06-07 00:18:28 +02:00
|
|
|
|
|
|
|
/*!
|
2018-06-03 20:38:32 +02:00
|
|
|
* \class TagParser::Mpeg4Descriptor
|
2015-06-07 00:18:28 +02:00
|
|
|
* \brief The Mpeg4Descriptor class helps to parse MPEG-4 descriptors.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*!
|
|
|
|
* \brief Constructs a new top level descriptor with the specified \a container at the specified \a startOffset
|
|
|
|
* and with the specified \a maxSize.
|
|
|
|
*/
|
2019-03-13 19:06:42 +01:00
|
|
|
Mpeg4Descriptor::Mpeg4Descriptor(ContainerType &container, std::uint64_t startOffset, std::uint64_t maxSize)
|
2018-03-07 01:17:50 +01:00
|
|
|
: GenericFileElement<Mpeg4Descriptor>(container, startOffset, maxSize)
|
|
|
|
{
|
|
|
|
}
|
2015-06-07 00:18:28 +02:00
|
|
|
|
|
|
|
/*!
|
|
|
|
* \brief Constructs a new sub level descriptor with the specified \a parent at the specified \a startOffset.
|
|
|
|
*/
|
2019-03-13 19:06:42 +01:00
|
|
|
Mpeg4Descriptor::Mpeg4Descriptor(Mpeg4Descriptor &parent, std::uint64_t startOffset)
|
2018-03-07 01:17:50 +01:00
|
|
|
: GenericFileElement<Mpeg4Descriptor>(parent, startOffset)
|
|
|
|
{
|
|
|
|
}
|
2015-06-07 00:18:28 +02:00
|
|
|
|
|
|
|
/*!
|
|
|
|
* \brief Returns the parsing context.
|
|
|
|
*/
|
|
|
|
string Mpeg4Descriptor::parsingContext() const
|
2015-06-07 00:16:59 +02:00
|
|
|
{
|
2017-01-30 00:42:35 +01:00
|
|
|
return "parsing " % idToString() % " descriptor at " + startOffset();
|
2015-06-07 00:18:28 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
* \brief Converts the specified atom \a ID to a printable string.
|
|
|
|
*/
|
|
|
|
std::string Mpeg4Descriptor::idToString() const
|
|
|
|
{
|
2019-06-10 22:49:11 +02:00
|
|
|
return "0x" + numberToString(id(), 16);
|
2015-06-07 00:18:28 +02:00
|
|
|
}
|
2015-06-07 00:16:59 +02:00
|
|
|
|
2015-06-07 00:18:28 +02:00
|
|
|
/*!
|
|
|
|
* \brief Parses the MPEG-4 descriptor.
|
|
|
|
* \remarks Does not detect the first child.
|
|
|
|
*/
|
2018-03-05 17:49:29 +01:00
|
|
|
void Mpeg4Descriptor::internalParse(Diagnostics &diag)
|
2015-06-07 00:18:28 +02:00
|
|
|
{
|
2018-03-07 01:17:50 +01:00
|
|
|
if (maxTotalSize() < minimumElementSize()) {
|
|
|
|
diag.emplace_back(DiagLevel::Critical,
|
|
|
|
"Descriptor is smaller than 2 byte and hence invalid. The maximum size within the encloding element is " % numberToString(maxTotalSize())
|
|
|
|
+ '.',
|
|
|
|
"parsing MPEG-4 descriptor");
|
2015-06-07 00:18:28 +02:00
|
|
|
throw TruncatedDataException();
|
|
|
|
}
|
2018-06-02 22:56:08 +02:00
|
|
|
stream().seekg(static_cast<streamoff>(startOffset()));
|
2015-06-07 00:18:28 +02:00
|
|
|
// read ID
|
|
|
|
m_idLength = m_sizeLength = 1;
|
|
|
|
m_id = reader().readByte();
|
|
|
|
// read data size
|
2019-03-13 19:06:42 +01:00
|
|
|
std::uint8_t tmp = reader().readByte();
|
2015-06-07 00:18:28 +02:00
|
|
|
m_dataSize = tmp & 0x7F;
|
2018-03-07 01:17:50 +01:00
|
|
|
while (tmp & 0x80) {
|
2015-06-07 00:18:28 +02:00
|
|
|
m_dataSize = (m_dataSize << 7) | ((tmp = reader().readByte()) & 0x7F);
|
|
|
|
++m_sizeLength;
|
|
|
|
}
|
|
|
|
// check whether the denoted data size exceeds the available data size
|
2018-03-07 01:17:50 +01:00
|
|
|
if (maxTotalSize() < totalSize()) {
|
2018-03-05 17:49:29 +01:00
|
|
|
diag.emplace_back(DiagLevel::Warning, "The descriptor seems to be truncated; unable to parse siblings of that ", parsingContext());
|
2019-03-13 19:06:42 +01:00
|
|
|
m_dataSize = static_cast<std::uint32_t>(maxTotalSize()); // using max size instead
|
2015-06-07 00:18:28 +02:00
|
|
|
}
|
|
|
|
m_firstChild.reset();
|
2018-06-02 22:56:08 +02:00
|
|
|
|
|
|
|
// check for siblings
|
|
|
|
if (totalSize() >= maxTotalSize()) {
|
|
|
|
m_nextSibling.reset();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (parent()) {
|
|
|
|
m_nextSibling.reset(new Mpeg4Descriptor(*(parent()), startOffset() + totalSize()));
|
|
|
|
} else {
|
|
|
|
m_nextSibling.reset(new Mpeg4Descriptor(container(), startOffset() + totalSize(), maxTotalSize() - totalSize()));
|
2015-06-07 00:18:28 +02:00
|
|
|
}
|
2015-06-07 00:16:59 +02:00
|
|
|
}
|
|
|
|
|
2018-03-07 01:17:50 +01:00
|
|
|
} // namespace TagParser
|