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<MediaSource> 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;
61 
62     // for DRM
63     virtual char* getDrmTrackInfo(size_t trackID, int *len);
64 
65 protected:
66     virtual ~MPEG4Extractor();
67 
68 private:
69 
70     struct PsshInfo {
71         uint8_t uuid[16];
72         uint32_t datalen;
73         uint8_t *data;
74     };
75     struct Track {
76         Track *next;
77         sp<MetaData> meta;
78         uint32_t timescale;
79         sp<SampleTable> sampleTable;
80         bool includes_expensive_metadata;
81         bool skipTrack;
82     };
83 
84     Vector<SidxEntry> mSidxEntries;
85     off64_t mMoofOffset;
86     bool mMoofFound;
87     bool mMdatFound;
88 
89     Vector<PsshInfo> mPssh;
90 
91     Vector<Trex> mTrex;
92 
93     sp<DataSource> mDataSource;
94     status_t mInitCheck;
95     bool mHasVideo;
96     uint32_t mHeaderTimescale;
97 
98     Track *mFirstTrack, *mLastTrack;
99 
100     sp<MetaData> mFileMetaData;
101 
102     Vector<uint32_t> mPath;
103     String8 mLastCommentMean;
104     String8 mLastCommentName;
105     String8 mLastCommentData;
106 
107     KeyedVector<uint32_t, AString> mMetaKeyMap;
108 
109     status_t readMetaData();
110     status_t parseChunk(off64_t *offset, int depth);
111     status_t parseITunesMetaData(off64_t offset, size_t size);
112     status_t parse3GPPMetaData(off64_t offset, size_t size, int depth);
113     void parseID3v2MetaData(off64_t offset);
114     status_t parseQTMetaKey(off64_t data_offset, size_t data_size);
115     status_t parseQTMetaVal(int32_t keyId, off64_t data_offset, size_t data_size);
116 
117     status_t updateAudioTrackInfoFromESDS_MPEG4Audio(
118             const void *esds_data, size_t esds_size);
119 
120     static status_t verifyTrack(Track *track);
121 
122     struct SINF {
123         SINF *next;
124         uint16_t trackID;
125         uint8_t IPMPDescriptorID;
126         ssize_t len;
127         char *IPMPData;
128     };
129 
130     SINF *mFirstSINF;
131 
132     bool mIsDrm;
133     status_t parseDrmSINF(off64_t *offset, off64_t data_offset);
134 
135     status_t parseTrackHeader(off64_t data_offset, off64_t data_size);
136 
137     status_t parseSegmentIndex(off64_t data_offset, size_t data_size);
138 
139     Track *findTrackByMimePrefix(const char *mimePrefix);
140 
141     MPEG4Extractor(const MPEG4Extractor &);
142     MPEG4Extractor &operator=(const MPEG4Extractor &);
143 };
144 
145 bool SniffMPEG4(
146         const sp<DataSource> &source, String8 *mimeType, float *confidence,
147         sp<AMessage> *);
148 
149 }  // namespace android
150 
151 #endif  // MPEG4_EXTRACTOR_H_
152