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
30namespace android {
31
32struct AMessage;
33class DataSource;
34class SampleTable;
35class String8;
36
37struct SidxEntry {
38    size_t mSize;
39    uint32_t mDurationUs;
40};
41
42struct 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
50class MPEG4Extractor : public MediaExtractor {
51public:
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;
61    virtual const char * name() { return "MPEG4Extractor"; }
62
63    // for DRM
64    virtual char* getDrmTrackInfo(size_t trackID, int *len);
65
66protected:
67    virtual ~MPEG4Extractor();
68
69private:
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
147bool SniffMPEG4(
148        const sp<DataSource> &source, String8 *mimeType, float *confidence,
149        sp<AMessage> *);
150
151}  // namespace android
152
153#endif  // MPEG4_EXTRACTOR_H_
154