improved format detection for MP4 tracks
This commit is contained in:
parent
78c23779a6
commit
15a03a0029
|
@ -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<ImplementationType>::copyInternal(std::ostream &targetSt
|
|||
template <class ImplementationType>
|
||||
typename GenericFileElement<ImplementationType>::implementationType *GenericFileElement<ImplementationType>::denoteFirstChild(uint32 relativeFirstChildOffset)
|
||||
{
|
||||
if(relativeFirstChildOffset + 4 < dataSize()) {
|
||||
if(relativeFirstChildOffset + minimumElementSize() <= totalSize()) {
|
||||
m_firstChild.reset(new implementationType(static_cast<implementationType &>(*this), startOffset() + relativeFirstChildOffset));
|
||||
} else {
|
||||
m_firstChild.reset();
|
||||
|
@ -859,6 +860,15 @@ inline constexpr uint32 GenericFileElement<ImplementationType>::maximumSizeLengt
|
|||
return sizeof(dataSizeType);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns the mimimum element size.
|
||||
*/
|
||||
template <class ImplementationType>
|
||||
inline constexpr byte GenericFileElement<ImplementationType>::minimumElementSize()
|
||||
{
|
||||
return FileElementTraits<ImplementationType>::minimumElementSize();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \fn GenericFileElement<ImplementationType>::internalParse()
|
||||
* \brief This method is called to perform parsing.
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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<Mp4Atom &>(*this), startOffset() + firstChildOffset);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<Mp4Atom>
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -595,6 +595,7 @@ unique_ptr<Mpeg4AudioSpecificConfig> Mp4Track::parseAudioSpecificConfig(Mpeg4Des
|
|||
auto buff = make_unique<char []>(decSpecInfoDesc->dataSize());
|
||||
m_istream->read(buff.get(), decSpecInfoDesc->dataSize());
|
||||
BitReader bitReader(buff.get(), decSpecInfoDesc->dataSize());
|
||||
cout << "buff: " << reinterpret_cast<uint64>(buff.get()) << ", " << decSpecInfoDesc->dataSize() << endl;
|
||||
auto audioCfg = make_unique<Mpeg4AudioSpecificConfig>();
|
||||
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:
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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<Mpeg4Descriptor>
|
||||
|
|
Loading…
Reference in New Issue