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