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/stagefright/DataSource.h>
24 #include <media/stagefright/MediaExtractor.h>
25 #include <media/stagefright/Utils.h>
26 #include <utils/List.h>
27 #include <utils/Vector.h>
28 #include <utils/String8.h>
29 
30 namespace android {
31 
32 struct AMessage;
33 class DataSource;
34 class SampleTable;
35 class String8;
36 
37 struct SidxEntry {
38     size_t mSize;
39     uint32_t mDurationUs;
40 };
41 
42 struct Trex {
43     uint32_t track_ID;
44     uint32_t default_sample_description_index;
45     uint32_t default_sample_duration;
46     uint32_t default_sample_size;
47     uint32_t default_sample_flags;
48 };
49 
50 class MPEG4Extractor : public MediaExtractor {
51 public:
52     // Extractor assumes ownership of "source".
53     MPEG4Extractor(const sp<DataSource> &source);
54 
55     virtual size_t countTracks();
56     virtual sp<IMediaSource> getTrack(size_t index);
57     virtual sp<MetaData> getTrackMetaData(size_t index, uint32_t flags);
58 
59     virtual sp<MetaData> getMetaData();
60     virtual uint32_t flags() const;
name()61     virtual const char * name() { return "MPEG4Extractor"; }
62 
63     // for DRM
64     virtual char* getDrmTrackInfo(size_t trackID, int *len);
65 
66 protected:
67     virtual ~MPEG4Extractor();
68 
69 private:
70 
71     struct PsshInfo {
72         uint8_t uuid[16];
73         uint32_t datalen;
74         uint8_t *data;
75     };
76     struct Track {
77         Track *next;
78         sp<MetaData> meta;
79         uint32_t timescale;
80         sp<SampleTable> sampleTable;
81         bool includes_expensive_metadata;
82         bool skipTrack;
83     };
84 
85     Vector<SidxEntry> mSidxEntries;
86     off64_t mMoofOffset;
87     bool mMoofFound;
88     bool mMdatFound;
89 
90     Vector<PsshInfo> mPssh;
91 
92     Vector<Trex> mTrex;
93 
94     sp<DataSource> mDataSource;
95     status_t mInitCheck;
96     bool mHasVideo;
97     uint32_t mHeaderTimescale;
98 
99     Track *mFirstTrack, *mLastTrack;
100 
101     sp<MetaData> mFileMetaData;
102 
103     Vector<uint32_t> mPath;
104     String8 mLastCommentMean;
105     String8 mLastCommentName;
106     String8 mLastCommentData;
107 
108     KeyedVector<uint32_t, AString> mMetaKeyMap;
109 
110     status_t readMetaData();
111     status_t parseChunk(off64_t *offset, int depth);
112     status_t parseITunesMetaData(off64_t offset, size_t size);
113     status_t parseColorInfo(off64_t offset, size_t size);
114     status_t parse3GPPMetaData(off64_t offset, size_t size, int depth);
115     void parseID3v2MetaData(off64_t offset);
116     status_t parseQTMetaKey(off64_t data_offset, size_t data_size);
117     status_t parseQTMetaVal(int32_t keyId, off64_t data_offset, size_t data_size);
118 
119     status_t updateAudioTrackInfoFromESDS_MPEG4Audio(
120             const void *esds_data, size_t esds_size);
121 
122     static status_t verifyTrack(Track *track);
123 
124     struct SINF {
125         SINF *next;
126         uint16_t trackID;
127         uint8_t IPMPDescriptorID;
128         ssize_t len;
129         char *IPMPData;
130     };
131 
132     SINF *mFirstSINF;
133 
134     bool mIsDrm;
135     status_t parseDrmSINF(off64_t *offset, off64_t data_offset);
136 
137     status_t parseTrackHeader(off64_t data_offset, off64_t data_size);
138 
139     status_t parseSegmentIndex(off64_t data_offset, size_t data_size);
140 
141     Track *findTrackByMimePrefix(const char *mimePrefix);
142 
143     MPEG4Extractor(const MPEG4Extractor &);
144     MPEG4Extractor &operator=(const MPEG4Extractor &);
145 };
146 
147 bool SniffMPEG4(
148         const sp<DataSource> &source, String8 *mimeType, float *confidence,
149         sp<AMessage> *);
150 
151 }  // namespace android
152 
153 #endif  // MPEG4_EXTRACTOR_H_
154