#ifndef TAG_PARSER_MP4TRACK_H #define TAG_PARSER_MP4TRACK_H #include "../abstracttrack.h" #include #include namespace TagParser { class Mp4Atom; class Mpeg4Descriptor; struct AvcConfiguration; struct Av1Configuration; struct TrackHeaderInfo; class TAG_PARSER_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; }; class TAG_PARSER_EXPORT Mpeg4VideoSpecificConfig { public: Mpeg4VideoSpecificConfig(); byte profile; std::string userData; }; class TAG_PARSER_EXPORT Mpeg4ElementaryStreamInfo { public: Mpeg4ElementaryStreamInfo(); bool dependencyFlag() const; bool urlFlag() const; bool ocrFlag() const; byte priority() const; byte streamTypeId() const; bool upstream() const; uint16 id; byte esDescFlags; uint16 dependsOnId; std::string url; uint16 ocrId; byte objectTypeId; byte decCfgDescFlags; uint32 bufferSize; uint32 maxBitrate; uint32 averageBitrate; std::unique_ptr audioSpecificConfig; std::unique_ptr videoSpecificConfig; }; 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; } class TAG_PARSER_EXPORT Mp4Track : public AbstractTrack { public: Mp4Track(Mp4Atom &trakAtom); ~Mp4Track() override; TrackType type() const override; // getter methods specific for MP4 tracks Mp4Atom &trakAtom(); const std::vector &sampleSizes() const; unsigned int chunkOffsetSize() const; uint32 chunkCount() const; uint32 sampleToChunkEntryCount() const; const Mpeg4ElementaryStreamInfo *mpeg4ElementaryStreamInfo() const; const AvcConfiguration *avcConfiguration() const; const Av1Configuration *av1Configuration() const; // methods to parse configuration details from the track header static std::unique_ptr parseMpeg4ElementaryStreamInfo( IoUtilities::BinaryReader &reader, Mp4Atom *esDescAtom, Diagnostics &diag); static std::unique_ptr parseAudioSpecificConfig( std::istream &stream, uint64 startOffset, uint64 size, Diagnostics &diag); static std::unique_ptr parseVideoSpecificConfig( IoUtilities::BinaryReader &reader, uint64 startOffset, uint64 size, Diagnostics &diag); // methods to read the "index" (chunk offsets and sizes) std::vector readChunkOffsets(bool parseFragments, Diagnostics &diag); std::vector> readSampleToChunkTable(Diagnostics &diag); std::vector readChunkSizes(TagParser::Diagnostics &diag); // methods to make the track header void bufferTrackAtoms(Diagnostics &diag); uint64 requiredSize(Diagnostics &diag) const; void makeTrack(Diagnostics &diag); void makeTrackHeader(Diagnostics &diag); void makeMedia(Diagnostics &diag); void makeMediaInfo(Diagnostics &diag); void makeSampleTable(Diagnostics &diag); // methods to update chunk offsets void updateChunkOffsets(const std::vector &oldMdatOffsets, const std::vector &newMdatOffsets); void updateChunkOffsets(const std::vector &chunkOffsets); void updateChunkOffset(uint32 chunkIndex, uint64 offset); static void addInfo(const AvcConfiguration &avcConfig, AbstractTrack &track); static void addInfo(const Av1Configuration &av1Config, AbstractTrack &track); protected: void internalParseHeader(Diagnostics &diag) override; private: // private helper methods uint64 accumulateSampleSizes(size_t &sampleIndex, size_t count, Diagnostics &diag); void addChunkSizeEntries(std::vector &chunkSizeTable, size_t count, size_t &sampleIndex, uint32 sampleCount, Diagnostics &diag); TrackHeaderInfo verifyPresentTrackHeader() const; 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; uint16 m_framesPerSample; std::vector m_sampleSizes; unsigned int m_chunkOffsetSize; uint32 m_chunkCount; uint32 m_sampleToChunkEntryCount; std::unique_ptr m_esInfo; std::unique_ptr m_avcConfig; std::unique_ptr m_av1Config; }; /*! * \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 &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; } /*! * \brief Returns information about the MPEG-4 elementary stream. * \remarks * - 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. * - The track keeps ownership over the returned object. */ inline const Mpeg4ElementaryStreamInfo *Mp4Track::mpeg4ElementaryStreamInfo() const { return m_esInfo.get(); } /*! * \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(); } /*! * \brief Returns the AV1 configuration. * \remarks * - The track must be parsed before this information becomes available. * - The track keeps ownership over the returned object. */ inline const Av1Configuration *Mp4Track::av1Configuration() const { return m_av1Config.get(); } } // namespace TagParser #endif // TAG_PARSER_MP4TRACK_H