1 /* 2 * Copyright (C) 2009 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef MPEG4_EXTRACTOR_H_ 18 19 #define MPEG4_EXTRACTOR_H_ 20 21 #include <arpa/inet.h> 22 23 #include <media/MediaExtractorPluginApi.h> 24 #include <media/MediaExtractorPluginHelper.h> 25 #include <media/NdkMediaFormat.h> 26 #include <media/stagefright/foundation/AString.h> 27 #include <utils/KeyedVector.h> 28 #include <utils/List.h> 29 #include <utils/String8.h> 30 #include <utils/Vector.h> 31 32 namespace android { 33 struct AMessage; 34 struct CDataSource; 35 class DataSourceHelper; 36 class SampleTable; 37 class String8; 38 namespace heif { 39 class ItemTable; 40 } 41 using heif::ItemTable; 42 43 struct SidxEntry { 44 size_t mSize; 45 uint32_t mDurationUs; 46 }; 47 48 struct Trex { 49 uint32_t track_ID; 50 uint32_t default_sample_description_index; 51 uint32_t default_sample_duration; 52 uint32_t default_sample_size; 53 uint32_t default_sample_flags; 54 }; 55 56 class MPEG4Extractor : public MediaExtractorPluginHelper { 57 public: 58 explicit MPEG4Extractor(DataSourceHelper *source, const char *mime = NULL); 59 60 virtual size_t countTracks(); 61 virtual MediaTrackHelper *getTrack(size_t index); 62 virtual media_status_t getTrackMetaData(AMediaFormat *meta, size_t index, uint32_t flags); 63 64 virtual media_status_t getMetaData(AMediaFormat *meta); 65 virtual uint32_t flags() const; name()66 virtual const char * name() { return "MPEG4Extractor"; } 67 68 protected: 69 virtual ~MPEG4Extractor(); 70 71 private: 72 73 struct PsshInfo { 74 uint8_t uuid[16]; 75 uint32_t datalen; 76 uint8_t *data; 77 }; 78 struct Track { 79 Track *next; 80 AMediaFormat *meta; 81 uint32_t timescale; 82 sp<SampleTable> sampleTable; 83 bool includes_expensive_metadata; 84 bool skipTrack; 85 bool elst_needs_processing; 86 /* signed int, ISO Spec allows media_time = -1 for other use cases. 87 * but we don't support empty edits for now. 88 */ 89 int64_t elst_media_time; 90 uint64_t elst_segment_duration; 91 // Shift start offset (move to earlier time) when media_time > 0. 92 uint64_t elst_shift_start_ticks; 93 // Initial start offset (move to later time), from empty edit list entry. 94 uint64_t elst_initial_empty_edit_ticks; 95 bool subsample_encryption; 96 97 uint8_t *mTx3gBuffer; 98 size_t mTx3gSize, mTx3gFilled; 99 100 TrackTrack101 Track() { 102 next = NULL; 103 meta = NULL; 104 timescale = 0; 105 includes_expensive_metadata = false; 106 skipTrack = false; 107 elst_needs_processing = false; 108 elst_media_time = 0; 109 elst_segment_duration = 0; 110 elst_shift_start_ticks = 0; 111 elst_initial_empty_edit_ticks = 0; 112 subsample_encryption = false; 113 mTx3gBuffer = NULL; 114 mTx3gSize = mTx3gFilled = 0; 115 } ~TrackTrack116 ~Track() { 117 if (meta) { 118 AMediaFormat_delete(meta); 119 meta = NULL; 120 } 121 free (mTx3gBuffer); 122 mTx3gBuffer = NULL; 123 } 124 125 private: 126 DISALLOW_EVIL_CONSTRUCTORS(Track); 127 }; 128 129 static const int kTx3gGrowth = 16 * 1024; 130 131 Vector<SidxEntry> mSidxEntries; 132 off64_t mMoofOffset; 133 bool mMoofFound; 134 bool mMdatFound; 135 136 Vector<PsshInfo> mPssh; 137 138 Vector<Trex> mTrex; 139 140 DataSourceHelper *mDataSource; 141 status_t mInitCheck; 142 uint32_t mHeaderTimescale; 143 bool mIsQT; 144 bool mIsHeif; 145 bool mHasMoovBox; 146 bool mPreferHeif; 147 bool mIsAvif; 148 149 Track *mFirstTrack, *mLastTrack; 150 151 AMediaFormat *mFileMetaData; 152 153 Vector<uint32_t> mPath; 154 String8 mLastCommentMean; 155 String8 mLastCommentName; 156 String8 mLastCommentData; 157 158 KeyedVector<uint32_t, AString> mMetaKeyMap; 159 160 status_t readMetaData(); 161 status_t parseChunk(off64_t *offset, int depth); 162 status_t parseITunesMetaData(off64_t offset, size_t size); 163 status_t parseColorInfo(off64_t offset, size_t size); 164 status_t parsePaspBox(off64_t offset, size_t size); 165 status_t parse3GPPMetaData(off64_t offset, size_t size, int depth); 166 void parseID3v2MetaData(off64_t offset, uint64_t size); 167 status_t parseQTMetaKey(off64_t data_offset, size_t data_size); 168 status_t parseQTMetaVal(int32_t keyId, off64_t data_offset, size_t data_size); 169 170 status_t updateAudioTrackInfoFromESDS_MPEG4Audio( 171 const void *esds_data, size_t esds_size); 172 173 static status_t verifyTrack(Track *track); 174 175 sp<ItemTable> mItemTable; 176 177 status_t parseTrackHeader(off64_t data_offset, off64_t data_size); 178 179 status_t parseSegmentIndex(off64_t data_offset, size_t data_size); 180 181 Track *findTrackByMimePrefix(const char *mimePrefix); 182 183 status_t parseChannelCountSampleRate( 184 off64_t *offset, uint16_t *channelCount, uint16_t *sampleRate); 185 status_t parseAC3SpecificBox(off64_t offset); 186 status_t parseEAC3SpecificBox(off64_t offset); 187 status_t parseAC4SpecificBox(off64_t offset); 188 status_t parseALACSampleEntry(off64_t *offset); 189 void adjustRawDefaultFrameSize(); 190 191 MPEG4Extractor(const MPEG4Extractor &); 192 MPEG4Extractor &operator=(const MPEG4Extractor &); 193 }; 194 195 } // namespace android 196 197 #endif // MPEG4_EXTRACTOR_H_ 198