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
# include <c++utilities/conversion/stringconversion.h>
2017-01-27 18:59:22 +01:00
# include <c++utilities/conversion/stringbuilder.h>
# include <c++utilities/io/binaryreader.h>
2015-06-07 00:18:28 +02:00
using namespace std ;
using namespace ConversionUtilities ;
2018-03-06 23:09:15 +01:00
namespace TagParser {
2015-06-07 00:18:28 +02:00
/*!
* \ class Media : : Mpeg4Descriptor
* \ 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 .
*/
2017-03-07 17:16:17 +01:00
Mpeg4Descriptor : : Mpeg4Descriptor ( ContainerType & container , uint64 startOffset , uint64 maxSize ) :
2015-06-07 00:18:28 +02:00
GenericFileElement < Mpeg4Descriptor > ( container , startOffset , maxSize )
{ }
/*!
* \ brief Constructs a new sub level descriptor with the specified \ a parent at the specified \ a startOffset .
*/
2017-03-07 17:16:17 +01:00
Mpeg4Descriptor : : Mpeg4Descriptor ( Mpeg4Descriptor & parent , uint64 startOffset ) :
2015-06-07 00:18:28 +02:00
GenericFileElement < Mpeg4Descriptor > ( parent , startOffset )
{ }
/*!
* \ 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
{
return " 0x " + ConversionUtilities : : numberToString ( id ( ) , 16 ) ;
}
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
{
2015-07-13 00:57:38 +02:00
if ( maxTotalSize ( ) < minimumElementSize ( ) ) {
2018-03-05 17:49:29 +01:00
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 ( ) ;
}
stream ( ) . seekg ( startOffset ( ) ) ;
// read ID
m_idLength = m_sizeLength = 1 ;
m_id = reader ( ) . readByte ( ) ;
// read data size
2015-07-13 00:57:38 +02:00
byte tmp = reader ( ) . readByte ( ) ;
2015-06-07 00:18:28 +02:00
m_dataSize = tmp & 0x7F ;
while ( tmp & 0x80 ) {
m_dataSize = ( m_dataSize < < 7 ) | ( ( tmp = reader ( ) . readByte ( ) ) & 0x7F ) ;
+ + m_sizeLength ;
}
// check whether the denoted data size exceeds the available data size
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 ( ) ) ;
2015-06-07 00:18:28 +02:00
m_dataSize = maxTotalSize ( ) ; // using max size instead
}
m_firstChild . reset ( ) ;
2017-03-07 17:16:17 +01:00
Mpeg4Descriptor * sibling = nullptr ;
2015-06-07 00:18:28 +02:00
if ( totalSize ( ) < maxTotalSize ( ) ) {
if ( parent ( ) ) {
2017-03-07 17:16:17 +01:00
sibling = new Mpeg4Descriptor ( * ( parent ( ) ) , startOffset ( ) + totalSize ( ) ) ;
2015-06-07 00:18:28 +02:00
} else {
2017-03-07 17:16:17 +01:00
sibling = new Mpeg4Descriptor ( container ( ) , startOffset ( ) + totalSize ( ) , maxTotalSize ( ) - totalSize ( ) ) ;
2015-06-07 00:18:28 +02:00
}
}
2015-06-24 00:45:53 +02:00
m_nextSibling . reset ( sibling ) ;
2015-06-07 00:16:59 +02:00
}
2015-06-07 00:18:28 +02:00
}