diff --git a/genericfileelement.h b/genericfileelement.h index 52123e1..f27a938 100644 --- a/genericfileelement.h +++ b/genericfileelement.h @@ -186,6 +186,7 @@ public: void validateSubsequentElementStructure(NotificationList &gatheredNotifications, uint64 *paddingSize = nullptr); static constexpr uint32 maximumIdLengthSupported(); static constexpr uint32 maximumSizeLengthSupported(); + static constexpr byte minimumElementSize(); void copyHeader(std::ostream &targetStream); void copyWithoutChilds(std::ostream &targetStream); void copyEntirely(std::ostream &targetStream); @@ -833,7 +834,7 @@ void GenericFileElement::copyInternal(std::ostream &targetSt template typename GenericFileElement::implementationType *GenericFileElement::denoteFirstChild(uint32 relativeFirstChildOffset) { - if(relativeFirstChildOffset + 4 < dataSize()) { + if(relativeFirstChildOffset + minimumElementSize() <= totalSize()) { m_firstChild.reset(new implementationType(static_cast(*this), startOffset() + relativeFirstChildOffset)); } else { m_firstChild.reset(); @@ -859,6 +860,15 @@ inline constexpr uint32 GenericFileElement::maximumSizeLengt return sizeof(dataSizeType); } +/*! + * \brief Returns the mimimum element size. + */ +template +inline constexpr byte GenericFileElement::minimumElementSize() +{ + return FileElementTraits::minimumElementSize(); +} + /*! * \fn GenericFileElement::internalParse() * \brief This method is called to perform parsing. diff --git a/mediaformat.cpp b/mediaformat.cpp index 7009446..3959bc7 100644 --- a/mediaformat.cpp +++ b/mediaformat.cpp @@ -196,7 +196,11 @@ const char *MediaFormat::name() const case GeneralMediaFormat::Smv: return "SMV"; case GeneralMediaFormat::StreamingTextStream: return "Streaming Text Stream"; case GeneralMediaFormat::SynthesizedTextureStream: return "Synthesized Texture Stream"; - case GeneralMediaFormat::Systems: return "Systems"; + case GeneralMediaFormat::Systems: + switch(sub) { + case 2: return "Systems v2"; + default: return "Systems"; + } case GeneralMediaFormat::TextSubtitle: switch(sub) { case SubFormats::TextSubBasicUtf8: return "UTF-8 Plain Text subtitles"; diff --git a/mp4/mp4atom.cpp b/mp4/mp4atom.cpp index 184aefe..d9e6622 100644 --- a/mp4/mp4atom.cpp +++ b/mp4/mp4atom.cpp @@ -57,7 +57,7 @@ void Mp4Atom::internalParse() { invalidateStatus(); static const string context("parsing MP4 atom"); - if(maxTotalSize() < 8) { + if(maxTotalSize() < minimumElementSize()) { addNotification(NotificationType::Critical, "Atom is smaller then 8 byte and hence invalid. The maximum size within the parent atom is " + numberToString(maxTotalSize()) + ".", context); throw TruncatedDataException(); } @@ -95,7 +95,7 @@ void Mp4Atom::internalParse() m_dataSize -= headerSize(); Mp4Atom *child = nullptr; if(uint64 firstChildOffset = this->firstChildOffset()) { - if(firstChildOffset + 8 <= totalSize()) { + if(firstChildOffset + minimumElementSize() <= totalSize()) { child = new Mp4Atom(static_cast(*this), startOffset() + firstChildOffset); } } diff --git a/mp4/mp4atom.h b/mp4/mp4atom.h index f48a4cc..d3eb9b5 100644 --- a/mp4/mp4atom.h +++ b/mp4/mp4atom.h @@ -44,6 +44,14 @@ public: * \brief The implementation type is Mp4Atom. */ typedef Mp4Atom implementationType; + + /*! + * \brief Returns the minimal atom size which is 8 byte. + */ + static constexpr byte minimumElementSize() + { + return 8; + } }; class LIB_EXPORT Mp4Atom : public GenericFileElement diff --git a/mp4/mp4ids.cpp b/mp4/mp4ids.cpp index c974528..4b694cb 100644 --- a/mp4/mp4ids.cpp +++ b/mp4/mp4ids.cpp @@ -56,8 +56,7 @@ MediaFormat fourccToMediaFormat(uint32 fourccId) case Avc1: case Avc2: case Avc3: case Avc4: case H264Decoder1: case H264Decoder2: case H264Decoder3: case H264Decoder4: case H264Decoder5: case H264Decoder6: return MediaFormat(GeneralMediaFormat::Avc); - case Divx4Decoder1: case Divx4Decoder2: case Divx4Decoder3: - case Divx4Decoder4: case Divx4Decoder5: case Divx4Decoder6: case Divx4Decoder7: + case Divx4Decoder1: case Divx4Decoder2: case H263Quicktime: case H2633GPP: case XvidDecoder1: case XvidDecoder2: case XvidDecoder3: case XvidDecoder4: case XvidDecoder5: case Divx5Decoder: return MediaFormat(GeneralMediaFormat::Mpeg4Video, SubFormats::Mpeg4AdvancedSimpleProfile0); diff --git a/mp4/mp4ids.h b/mp4/mp4ids.h index 963d546..67bf62b 100644 --- a/mp4/mp4ids.h +++ b/mp4/mp4ids.h @@ -246,12 +246,7 @@ enum KnownValue : uint32 { Divx3Decoder8 = 0x4D503433, Divx3Decoder9 = 0x4D504733, Divx4Decoder1 = 0x44495658, - Divx4Decoder2 = 0x4D345332, - Divx4Decoder3 = 0x4D503453, - Divx4Decoder4 = 0x554D5034, - Divx4Decoder5 = 0x64697678, - Divx4Decoder6 = 0x6D347332, - Divx4Decoder7 = 0x6D703473, + Divx4Decoder2 = 0x64697678, Divx5Decoder = 0x44583530, Drms = 0x64726D73, Drmi = 0x64726D69, @@ -324,7 +319,7 @@ enum KnownValue : uint32 { Mpeg4Decoder1 = 0x464D5034, Mpeg4Decoder2 = 0x53454447, Mpeg4Decoder3 = 0x57563146, - Mpeg4Stream = 0x6d703473, /**< MPEG-4 stream (other then video/audio) */ + Mpeg4Sample = 0x6d703473, /**< MPEG-4 stream (other then video/audio) */ Mpeg4Video = 0x6d703476, /**< MPEG-4 video */ MsMpeg4V1Decoder1 = 0x44495631, MsMpeg4V1Decoder2 = 0x4D504734, diff --git a/mp4/mp4track.cpp b/mp4/mp4track.cpp index b75105b..65f1eed 100644 --- a/mp4/mp4track.cpp +++ b/mp4/mp4track.cpp @@ -595,6 +595,7 @@ unique_ptr Mp4Track::parseAudioSpecificConfig(Mpeg4Des auto buff = make_unique(decSpecInfoDesc->dataSize()); m_istream->read(buff.get(), decSpecInfoDesc->dataSize()); BitReader bitReader(buff.get(), decSpecInfoDesc->dataSize()); + cout << "buff: " << reinterpret_cast(buff.get()) << ", " << decSpecInfoDesc->dataSize() << endl; auto audioCfg = make_unique(); try { // read audio object type @@ -1334,6 +1335,13 @@ void Mp4Track::internalParseHeader() esDescParentAtom = codecConfigContainerAtom; } break; + case FourccIds::Mpeg4Sample: + //m_istream->seekg(6 + 2, ios_base::cur); // skip reserved bytes and data reference index + codecConfigContainerAtom->denoteFirstChild(codecConfigContainerAtom->headerSize() + 8); + if(!esDescParentAtom) { + esDescParentAtom = codecConfigContainerAtom; + } + break; case Mp4AtomIds::PixalAspectRatio: break; // TODO case Mp4AtomIds::CleanAperature: diff --git a/mp4/mpeg4descriptor.cpp b/mp4/mpeg4descriptor.cpp index 6b85d9e..ad33bed 100644 --- a/mp4/mpeg4descriptor.cpp +++ b/mp4/mpeg4descriptor.cpp @@ -54,8 +54,8 @@ std::string Mpeg4Descriptor::idToString() const void Mpeg4Descriptor::internalParse() { invalidateStatus(); - if(maxTotalSize() < 4) { - addNotification(NotificationType::Critical, "Descriptor is smaller then 4 byte and hence invalid. The maximum size within the encloding element is " + numberToString(maxTotalSize()) + ".", "parsing MPEG-4 descriptor"); + if(maxTotalSize() < minimumElementSize()) { + addNotification(NotificationType::Critical, "Descriptor is smaller then 2 byte and hence invalid. The maximum size within the encloding element is " + numberToString(maxTotalSize()) + ".", "parsing MPEG-4 descriptor"); throw TruncatedDataException(); } stream().seekg(startOffset()); @@ -63,7 +63,7 @@ void Mpeg4Descriptor::internalParse() m_idLength = m_sizeLength = 1; m_id = reader().readByte(); // read data size - byte tmp = reader().readByte() & 0x80; + byte tmp = reader().readByte(); m_dataSize = tmp & 0x7F; while(tmp & 0x80) { m_dataSize = (m_dataSize << 7) | ((tmp = reader().readByte()) & 0x7F); diff --git a/mp4/mpeg4descriptor.h b/mp4/mpeg4descriptor.h index 9861412..efc2b87 100644 --- a/mp4/mpeg4descriptor.h +++ b/mp4/mpeg4descriptor.h @@ -36,6 +36,14 @@ public: * \brief The implementation type is Mp4Atom. */ typedef Mpeg4Descriptor implementationType; + + /*! + * \brief Returns the minimal descriptor size which is 2 byte. + */ + static constexpr byte minimumElementSize() + { + return 2; + } }; class LIB_EXPORT Mpeg4Descriptor : public GenericFileElement