Home | History | Annotate | Download | only in mp4
      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;
     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 
     99         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         }
    112         ~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