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 has_elst; 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 // unsigned int, shift start offset only when media_time > 0. 92 uint64_t elstShiftStartTicks; 93 bool subsample_encryption; 94 95 uint8_t *mTx3gBuffer; 96 size_t mTx3gSize, mTx3gFilled; 97 98 TrackTrack99 Track() { 100 next = NULL; 101 meta = NULL; 102 timescale = 0; 103 includes_expensive_metadata = false; 104 skipTrack = false; 105 has_elst = false; 106 elst_media_time = 0; 107 elstShiftStartTicks = 0; 108 subsample_encryption = false; 109 mTx3gBuffer = NULL; 110 mTx3gSize = mTx3gFilled = 0; 111 } ~TrackTrack112 ~Track() { 113 if (meta) { 114 AMediaFormat_delete(meta); 115 meta = NULL; 116 } 117 free (mTx3gBuffer); 118 mTx3gBuffer = NULL; 119 } 120 121 private: 122 DISALLOW_EVIL_CONSTRUCTORS(Track); 123 }; 124 125 static const int kTx3gGrowth = 16 * 1024; 126 127 Vector<SidxEntry> mSidxEntries; 128 off64_t mMoofOffset; 129 bool mMoofFound; 130 bool mMdatFound; 131 132 Vector<PsshInfo> mPssh; 133 134 Vector<Trex> mTrex; 135 136 DataSourceHelper *mDataSource; 137 status_t mInitCheck; 138 uint32_t mHeaderTimescale; 139 bool mIsQT; 140 bool mIsHeif; 141 bool mHasMoovBox; 142 bool mPreferHeif; 143 144 Track *mFirstTrack, *mLastTrack; 145 146 AMediaFormat *mFileMetaData; 147 148 Vector<uint32_t> mPath; 149 String8 mLastCommentMean; 150 String8 mLastCommentName; 151 String8 mLastCommentData; 152 153 KeyedVector<uint32_t, AString> mMetaKeyMap; 154 155 status_t readMetaData(); 156 status_t parseChunk(off64_t *offset, int depth); 157 status_t parseITunesMetaData(off64_t offset, size_t size); 158 status_t parseColorInfo(off64_t offset, size_t size); 159 status_t parse3GPPMetaData(off64_t offset, size_t size, int depth); 160 void parseID3v2MetaData(off64_t offset); 161 status_t parseQTMetaKey(off64_t data_offset, size_t data_size); 162 status_t parseQTMetaVal(int32_t keyId, off64_t data_offset, size_t data_size); 163 164 status_t updateAudioTrackInfoFromESDS_MPEG4Audio( 165 const void *esds_data, size_t esds_size); 166 167 static status_t verifyTrack(Track *track); 168 169 sp<ItemTable> mItemTable; 170 171 status_t parseTrackHeader(off64_t data_offset, off64_t data_size); 172 173 status_t parseSegmentIndex(off64_t data_offset, size_t data_size); 174 175 Track *findTrackByMimePrefix(const char *mimePrefix); 176 177 status_t parseChannelCountSampleRate( 178 off64_t *offset, uint16_t *channelCount, uint16_t *sampleRate); 179 status_t parseAC3SpecificBox(off64_t offset); 180 status_t parseEAC3SpecificBox(off64_t offset); 181 status_t parseAC4SpecificBox(off64_t offset); 182 status_t parseALACSampleEntry(off64_t *offset); 183 void adjustRawDefaultFrameSize(); 184 185 MPEG4Extractor(const MPEG4Extractor &); 186 MPEG4Extractor &operator=(const MPEG4Extractor &); 187 }; 188 189 } // namespace android 190 191 #endif // MPEG4_EXTRACTOR_H_ 192