2015-04-22 19:22:01 +02:00
|
|
|
#ifndef MP4TRACK_H
|
|
|
|
#define MP4TRACK_H
|
|
|
|
|
2015-09-06 19:57:33 +02:00
|
|
|
#include "../abstracttrack.h"
|
2015-04-22 19:22:01 +02:00
|
|
|
|
|
|
|
#include <vector>
|
2015-06-07 00:18:28 +02:00
|
|
|
#include <memory>
|
2015-04-22 19:22:01 +02:00
|
|
|
|
|
|
|
namespace Media
|
|
|
|
{
|
|
|
|
|
|
|
|
class Mp4Atom;
|
2015-06-10 01:28:22 +02:00
|
|
|
class Mpeg4Descriptor;
|
2016-02-17 20:19:05 +01:00
|
|
|
class AvcConfiguration;
|
2015-06-10 01:28:22 +02:00
|
|
|
|
|
|
|
class LIB_EXPORT Mpeg4AudioSpecificConfig
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
Mpeg4AudioSpecificConfig();
|
|
|
|
|
|
|
|
byte audioObjectType;
|
|
|
|
byte sampleFrequencyIndex;
|
|
|
|
uint32 sampleFrequency;
|
|
|
|
byte channelConfiguration;
|
|
|
|
byte extensionAudioObjectType;
|
|
|
|
bool sbrPresent;
|
|
|
|
bool psPresent;
|
|
|
|
byte extensionSampleFrequencyIndex;
|
|
|
|
uint32 extensionSampleFrequency;
|
|
|
|
byte extensionChannelConfiguration;
|
|
|
|
bool frameLengthFlag;
|
|
|
|
bool dependsOnCoreCoder;
|
|
|
|
uint16 coreCoderDelay;
|
|
|
|
byte extensionFlag;
|
|
|
|
byte layerNr;
|
|
|
|
byte numOfSubFrame;
|
|
|
|
uint16 layerLength;
|
|
|
|
byte resilienceFlags;
|
|
|
|
byte epConfig;
|
|
|
|
};
|
2015-04-22 19:22:01 +02:00
|
|
|
|
2015-07-07 03:01:48 +02:00
|
|
|
class LIB_EXPORT Mpeg4VideoSpecificConfig
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
Mpeg4VideoSpecificConfig();
|
|
|
|
|
|
|
|
byte profile;
|
|
|
|
std::string userData;
|
|
|
|
};
|
|
|
|
|
2015-06-07 00:18:28 +02:00
|
|
|
class LIB_EXPORT Mpeg4ElementaryStreamInfo
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
Mpeg4ElementaryStreamInfo();
|
|
|
|
|
2015-06-10 01:28:22 +02:00
|
|
|
bool dependencyFlag() const;
|
|
|
|
bool urlFlag() const;
|
|
|
|
bool ocrFlag() const;
|
|
|
|
byte priority() const;
|
|
|
|
byte streamTypeId() const;
|
|
|
|
bool upstream() const;
|
|
|
|
|
2015-06-07 00:18:28 +02:00
|
|
|
uint16 id;
|
|
|
|
byte esDescFlags;
|
|
|
|
uint16 dependsOnId;
|
|
|
|
std::string url;
|
|
|
|
uint16 ocrId;
|
|
|
|
byte objectTypeId;
|
|
|
|
byte decCfgDescFlags;
|
|
|
|
uint32 bufferSize;
|
|
|
|
uint32 maxBitrate;
|
|
|
|
uint32 averageBitrate;
|
2015-06-10 01:28:22 +02:00
|
|
|
std::unique_ptr<Mpeg4AudioSpecificConfig> audioSpecificConfig;
|
2015-07-07 03:01:48 +02:00
|
|
|
std::unique_ptr<Mpeg4VideoSpecificConfig> videoSpecificConfig;
|
2015-06-07 00:18:28 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
inline Mpeg4ElementaryStreamInfo::Mpeg4ElementaryStreamInfo() :
|
|
|
|
id(0),
|
|
|
|
esDescFlags(0),
|
|
|
|
dependsOnId(0),
|
|
|
|
ocrId(0),
|
|
|
|
objectTypeId(0),
|
|
|
|
decCfgDescFlags(0),
|
|
|
|
bufferSize(0),
|
|
|
|
maxBitrate(0),
|
|
|
|
averageBitrate(0)
|
|
|
|
{}
|
|
|
|
|
|
|
|
inline bool Mpeg4ElementaryStreamInfo::dependencyFlag() const
|
|
|
|
{
|
|
|
|
return esDescFlags & 0x80;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline bool Mpeg4ElementaryStreamInfo::urlFlag() const
|
|
|
|
{
|
|
|
|
return esDescFlags & 0x40;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline bool Mpeg4ElementaryStreamInfo::ocrFlag() const
|
|
|
|
{
|
|
|
|
return esDescFlags & 0x20;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline byte Mpeg4ElementaryStreamInfo::priority() const
|
|
|
|
{
|
|
|
|
return esDescFlags & 0x1F;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline byte Mpeg4ElementaryStreamInfo::streamTypeId() const
|
|
|
|
{
|
|
|
|
return decCfgDescFlags >> 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline bool Mpeg4ElementaryStreamInfo::upstream() const
|
|
|
|
{
|
|
|
|
return decCfgDescFlags & 0x02;
|
|
|
|
}
|
|
|
|
|
2015-04-22 19:22:01 +02:00
|
|
|
class LIB_EXPORT Mp4Track : public AbstractTrack
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
Mp4Track(Mp4Atom &trakAtom);
|
|
|
|
~Mp4Track();
|
|
|
|
TrackType type() const;
|
|
|
|
|
2015-06-10 01:28:22 +02:00
|
|
|
// getter methods specific for MP4 tracks
|
|
|
|
Mp4Atom &trakAtom();
|
2015-04-22 19:22:01 +02:00
|
|
|
const std::vector<uint32> &sampleSizes() const;
|
|
|
|
unsigned int chunkOffsetSize() const;
|
|
|
|
uint32 chunkCount() const;
|
|
|
|
uint32 sampleToChunkEntryCount() const;
|
2015-06-07 00:18:28 +02:00
|
|
|
const Mpeg4ElementaryStreamInfo *mpeg4ElementaryStreamInfo() const;
|
2016-02-17 20:19:05 +01:00
|
|
|
const AvcConfiguration *avcConfiguration() const;
|
2015-06-10 01:28:22 +02:00
|
|
|
|
|
|
|
// methods to parse configuration details from the track header
|
2015-08-13 03:23:28 +02:00
|
|
|
static std::unique_ptr<Mpeg4ElementaryStreamInfo> parseMpeg4ElementaryStreamInfo(StatusProvider &statusProvider, IoUtilities::BinaryReader &reader, Mp4Atom *esDescAtom);
|
|
|
|
static std::unique_ptr<Mpeg4AudioSpecificConfig> parseAudioSpecificConfig(StatusProvider &statusProvider, std::istream &stream, uint64 startOffset, uint64 size);
|
|
|
|
static std::unique_ptr<Mpeg4VideoSpecificConfig> parseVideoSpecificConfig(StatusProvider &statusProvider, IoUtilities::BinaryReader &reader, uint64 startOffset, uint64 size);
|
2015-06-10 01:28:22 +02:00
|
|
|
|
|
|
|
// methods to read the "index" (chunk offsets and sizes)
|
2015-04-22 19:22:01 +02:00
|
|
|
std::vector<uint64> readChunkOffsets();
|
|
|
|
std::vector<std::tuple<uint32, uint32, uint32> > readSampleToChunkTable();
|
|
|
|
std::vector<uint64> readChunkSizes();
|
2015-06-10 01:28:22 +02:00
|
|
|
|
|
|
|
// methods to make the track header
|
2015-04-22 19:22:01 +02:00
|
|
|
void makeTrack();
|
2015-12-21 00:04:56 +01:00
|
|
|
uint64 requiredSize() const;
|
2015-04-22 19:22:01 +02:00
|
|
|
void makeTrackHeader();
|
|
|
|
void makeMedia();
|
|
|
|
void makeMediaInfo();
|
|
|
|
void makeSampleTable();
|
|
|
|
|
2015-06-10 01:28:22 +02:00
|
|
|
// methods to update chunk offsets
|
|
|
|
void updateChunkOffsets(const std::vector<int64> &oldMdatOffsets, const std::vector<int64> &newMdatOffsets);
|
2015-11-07 15:23:36 +01:00
|
|
|
void updateChunkOffsets(const std::vector<uint64> &chunkOffsets);
|
2015-06-10 01:28:22 +02:00
|
|
|
void updateChunkOffset(uint32 chunkIndex, uint64 offset);
|
|
|
|
|
2016-02-17 20:19:05 +01:00
|
|
|
static void addInfo(const AvcConfiguration &avcConfig, AbstractTrack &track);
|
|
|
|
|
2015-04-22 19:22:01 +02:00
|
|
|
protected:
|
|
|
|
void internalParseHeader();
|
|
|
|
|
|
|
|
private:
|
2015-06-10 01:28:22 +02:00
|
|
|
// private helper methods
|
2015-04-22 19:22:01 +02:00
|
|
|
uint64 accumulateSampleSizes(size_t &sampleIndex, size_t count);
|
|
|
|
void addChunkSizeEntries(std::vector<uint64> &chunkSizeTable, size_t count, size_t &sampleIndex, uint32 sampleCount);
|
|
|
|
|
|
|
|
Mp4Atom *m_trakAtom;
|
|
|
|
Mp4Atom *m_tkhdAtom;
|
|
|
|
Mp4Atom *m_mdiaAtom;
|
|
|
|
Mp4Atom *m_mdhdAtom;
|
|
|
|
Mp4Atom *m_hdlrAtom;
|
|
|
|
Mp4Atom *m_minfAtom;
|
|
|
|
Mp4Atom *m_stblAtom;
|
|
|
|
Mp4Atom *m_stsdAtom;
|
|
|
|
Mp4Atom *m_stscAtom;
|
|
|
|
Mp4Atom *m_stcoAtom;
|
|
|
|
Mp4Atom *m_stszAtom;
|
2015-06-10 01:28:22 +02:00
|
|
|
//Mp4Atom *m_codecConfigAtom;
|
|
|
|
//Mp4Atom *m_esDescAtom;
|
2015-04-22 19:22:01 +02:00
|
|
|
uint16 m_framesPerSample;
|
|
|
|
std::vector<uint32> m_sampleSizes;
|
|
|
|
unsigned int m_chunkOffsetSize;
|
|
|
|
uint32 m_chunkCount;
|
|
|
|
uint32 m_sampleToChunkEntryCount;
|
2015-06-07 00:18:28 +02:00
|
|
|
std::unique_ptr<Mpeg4ElementaryStreamInfo> m_esInfo;
|
2016-02-17 20:19:05 +01:00
|
|
|
std::unique_ptr<AvcConfiguration> m_avcConfig;
|
2015-04-22 19:22:01 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
/*!
|
|
|
|
* \brief Returns the trak atom for the current instance.
|
|
|
|
*/
|
|
|
|
inline Mp4Atom &Mp4Track::trakAtom()
|
|
|
|
{
|
|
|
|
return *m_trakAtom;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
* \brief Returns the sample size table for the track.
|
|
|
|
* \remarks If the table contains only one size this is the constant
|
|
|
|
* sample size.
|
|
|
|
* \remarks The table is empty if the track denotes 64-bit sample sizes.
|
|
|
|
* \sa sampleSizes64()
|
|
|
|
*/
|
|
|
|
inline const std::vector<uint32> &Mp4Track::sampleSizes() const
|
|
|
|
{
|
|
|
|
return m_sampleSizes;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
* \brief Returns the size of a single chunk offset denotation within the stco atom.
|
|
|
|
*
|
|
|
|
* Valid values are 4 and 8 bytes.
|
|
|
|
*/
|
|
|
|
inline unsigned int Mp4Track::chunkOffsetSize() const
|
|
|
|
{
|
|
|
|
return m_chunkOffsetSize;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
* \brief Returns the number of chunks denoted by the stco atom.
|
|
|
|
*/
|
|
|
|
inline uint32 Mp4Track::chunkCount() const
|
|
|
|
{
|
|
|
|
return m_chunkCount;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
* \brief Returns the number of "sample to chunk" entries within the stsc atom.
|
|
|
|
*/
|
|
|
|
inline uint32 Mp4Track::sampleToChunkEntryCount() const
|
|
|
|
{
|
|
|
|
return m_sampleToChunkEntryCount;
|
|
|
|
}
|
|
|
|
|
2015-06-07 00:18:28 +02:00
|
|
|
/*!
|
|
|
|
* \brief Returns information about the MPEG-4 elementary stream.
|
|
|
|
* \remarks
|
2016-02-17 20:19:05 +01:00
|
|
|
* - The track must be parsed before this information becomes available.
|
|
|
|
* - The information is only available, if the track has an MPEG-4 elementary stream descriptor atom.
|
2015-06-07 00:18:28 +02:00
|
|
|
* - The track keeps ownership over the returned object.
|
|
|
|
*/
|
|
|
|
inline const Mpeg4ElementaryStreamInfo *Mp4Track::mpeg4ElementaryStreamInfo() const
|
|
|
|
{
|
|
|
|
return m_esInfo.get();
|
|
|
|
}
|
|
|
|
|
2016-02-17 20:19:05 +01:00
|
|
|
/*!
|
|
|
|
* \brief Returns the AVC configuration.
|
|
|
|
* \remarks
|
|
|
|
* - The track must be parsed before this information becomes available.
|
|
|
|
* - The track keeps ownership over the returned object.
|
|
|
|
*/
|
|
|
|
inline const AvcConfiguration *Mp4Track::avcConfiguration() const
|
|
|
|
{
|
|
|
|
return m_avcConfig.get();
|
|
|
|
}
|
|
|
|
|
2015-04-22 19:22:01 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
#endif // MP4TRACK_H
|