Remove FragmentedMP4Extractor

MPEG4Extractor now supports fragmented mp4 files.

Change-Id: I5659a51f4e5e4407a12535e69238fe3abffda7dc
diff --git a/media/libstagefright/Android.mk b/media/libstagefright/Android.mk
index 6934e59..acc3abf 100644
--- a/media/libstagefright/Android.mk
+++ b/media/libstagefright/Android.mk
@@ -19,7 +19,6 @@
         ESDS.cpp                          \
         FileSource.cpp                    \
         FLACExtractor.cpp                 \
-        FragmentedMP4Extractor.cpp        \
         HTTPBase.cpp                      \
         JPEGSource.cpp                    \
         MP3Extractor.cpp                  \
diff --git a/media/libstagefright/DataSource.cpp b/media/libstagefright/DataSource.cpp
index bcf333e..19b38ee 100644
--- a/media/libstagefright/DataSource.cpp
+++ b/media/libstagefright/DataSource.cpp
@@ -23,7 +23,6 @@
 #include "include/AACExtractor.h"
 #include "include/DRMExtractor.h"
 #include "include/FLACExtractor.h"
-#include "include/FragmentedMP4Extractor.h"
 #include "include/HTTPBase.h"
 #include "include/MP3Extractor.h"
 #include "include/MPEG2PSExtractor.h"
@@ -137,7 +136,6 @@
 // static
 void DataSource::RegisterDefaultSniffers() {
     RegisterSniffer(SniffMPEG4);
-    RegisterSniffer(SniffFragmentedMP4);
     RegisterSniffer(SniffMatroska);
     RegisterSniffer(SniffOgg);
     RegisterSniffer(SniffWAV);
diff --git a/media/libstagefright/FragmentedMP4Extractor.cpp b/media/libstagefright/FragmentedMP4Extractor.cpp
deleted file mode 100644
index 496828d..0000000
--- a/media/libstagefright/FragmentedMP4Extractor.cpp
+++ /dev/null
@@ -1,464 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "FragmentedMP4Extractor"
-#include <utils/Log.h>
-
-#include "include/FragmentedMP4Extractor.h"
-#include "include/SampleTable.h"
-#include "include/ESDS.h"
-
-#include <arpa/inet.h>
-
-#include <ctype.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <cutils/properties.h> // for property_get
-
-#include <media/stagefright/foundation/ABitReader.h>
-#include <media/stagefright/foundation/ABuffer.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/AMessage.h>
-#include <media/stagefright/DataSource.h>
-#include <media/stagefright/MediaBuffer.h>
-#include <media/stagefright/MediaBufferGroup.h>
-#include <media/stagefright/MediaDefs.h>
-#include <media/stagefright/MediaSource.h>
-#include <media/stagefright/MetaData.h>
-#include <media/stagefright/Utils.h>
-#include <utils/String8.h>
-
-namespace android {
-
-class FragmentedMPEG4Source : public MediaSource {
-public:
-    // Caller retains ownership of the Parser
-    FragmentedMPEG4Source(bool audio,
-                const sp<MetaData> &format,
-                const sp<FragmentedMP4Parser> &parser,
-                const sp<FragmentedMP4Extractor> &extractor);
-
-    virtual status_t start(MetaData *params = NULL);
-    virtual status_t stop();
-
-    virtual sp<MetaData> getFormat();
-
-    virtual status_t read(
-            MediaBuffer **buffer, const ReadOptions *options = NULL);
-
-protected:
-    virtual ~FragmentedMPEG4Source();
-
-private:
-    Mutex mLock;
-
-    sp<MetaData> mFormat;
-    sp<FragmentedMP4Parser> mParser;
-    sp<FragmentedMP4Extractor> mExtractor;
-    bool mIsAudioTrack;
-    uint32_t mCurrentSampleIndex;
-
-    bool mIsAVC;
-    size_t mNALLengthSize;
-
-    bool mStarted;
-
-    MediaBufferGroup *mGroup;
-
-    bool mWantsNALFragments;
-
-    uint8_t *mSrcBuffer;
-
-    FragmentedMPEG4Source(const FragmentedMPEG4Source &);
-    FragmentedMPEG4Source &operator=(const FragmentedMPEG4Source &);
-};
-
-
-FragmentedMP4Extractor::FragmentedMP4Extractor(const sp<DataSource> &source)
-    : mLooper(new ALooper),
-      mParser(new FragmentedMP4Parser()),
-      mDataSource(source),
-      mInitCheck(NO_INIT),
-      mFileMetaData(new MetaData) {
-    ALOGV("FragmentedMP4Extractor");
-    mLooper->registerHandler(mParser);
-    mLooper->start(false /* runOnCallingThread */);
-    mParser->start(mDataSource);
-
-    bool hasVideo = mParser->getFormat(false /* audio */, true /* synchronous */) != NULL;
-    bool hasAudio = mParser->getFormat(true /* audio */, true /* synchronous */) != NULL;
-
-    ALOGV("number of tracks: %d", countTracks());
-
-    if (hasVideo) {
-        mFileMetaData->setCString(
-                kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_MPEG4);
-    } else if (hasAudio) {
-        mFileMetaData->setCString(kKeyMIMEType, "audio/mp4");
-    } else {
-        ALOGE("no audio and no video, no idea what file type this is");
-    }
-    // tracks are numbered such that video track is first, audio track is second
-    if (hasAudio && hasVideo) {
-        mTrackCount = 2;
-        mAudioTrackIndex = 1;
-    } else if (hasAudio) {
-        mTrackCount = 1;
-        mAudioTrackIndex = 0;
-    } else if (hasVideo) {
-        mTrackCount = 1;
-        mAudioTrackIndex = -1;
-    } else {
-        mTrackCount = 0;
-        mAudioTrackIndex = -1;
-    }
-}
-
-FragmentedMP4Extractor::~FragmentedMP4Extractor() {
-    ALOGV("~FragmentedMP4Extractor");
-    mLooper->stop();
-}
-
-uint32_t FragmentedMP4Extractor::flags() const {
-    return CAN_PAUSE |
-            (mParser->isSeekable() ? (CAN_SEEK_BACKWARD | CAN_SEEK_FORWARD | CAN_SEEK) : 0);
-}
-
-sp<MetaData> FragmentedMP4Extractor::getMetaData() {
-    return mFileMetaData;
-}
-
-size_t FragmentedMP4Extractor::countTracks() {
-    return mTrackCount;
-}
-
-
-sp<MetaData> FragmentedMP4Extractor::getTrackMetaData(
-        size_t index, uint32_t flags) {
-    if (index >= countTracks()) {
-        return NULL;
-    }
-
-    sp<AMessage> msg = mParser->getFormat(index == mAudioTrackIndex, true /* synchronous */);
-
-    if (msg == NULL) {
-        ALOGV("got null format for track %d", index);
-        return NULL;
-    }
-
-    sp<MetaData> meta = new MetaData();
-    convertMessageToMetaData(msg, meta);
-    return meta;
-}
-
-static void MakeFourCCString(uint32_t x, char *s) {
-    s[0] = x >> 24;
-    s[1] = (x >> 16) & 0xff;
-    s[2] = (x >> 8) & 0xff;
-    s[3] = x & 0xff;
-    s[4] = '\0';
-}
-
-sp<MediaSource> FragmentedMP4Extractor::getTrack(size_t index) {
-    if (index >= countTracks()) {
-        return NULL;
-    }
-    return new FragmentedMPEG4Source(index == mAudioTrackIndex, getTrackMetaData(index, 0), mParser, this);
-}
-
-
-////////////////////////////////////////////////////////////////////////////////
-
-FragmentedMPEG4Source::FragmentedMPEG4Source(
-        bool audio,
-        const sp<MetaData> &format,
-        const sp<FragmentedMP4Parser> &parser,
-        const sp<FragmentedMP4Extractor> &extractor)
-    : mFormat(format),
-      mParser(parser),
-      mExtractor(extractor),
-      mIsAudioTrack(audio),
-      mStarted(false),
-      mGroup(NULL),
-      mWantsNALFragments(false),
-      mSrcBuffer(NULL) {
-}
-
-FragmentedMPEG4Source::~FragmentedMPEG4Source() {
-    if (mStarted) {
-        stop();
-    }
-}
-
-status_t FragmentedMPEG4Source::start(MetaData *params) {
-    Mutex::Autolock autoLock(mLock);
-
-    CHECK(!mStarted);
-
-    int32_t val;
-    if (params && params->findInt32(kKeyWantsNALFragments, &val)
-        && val != 0) {
-        mWantsNALFragments = true;
-    } else {
-        mWantsNALFragments = false;
-    }
-    ALOGV("caller wants NAL fragments: %s", mWantsNALFragments ? "yes" : "no");
-
-    mGroup = new MediaBufferGroup;
-
-    // for video, make the buffer big enough for an extremely poorly compressed 1080p frame.
-    int32_t max_size = mIsAudioTrack ? 65536 : 3110400;
-
-    mGroup->add_buffer(new MediaBuffer(max_size));
-
-    mSrcBuffer = new uint8_t[max_size];
-
-    mStarted = true;
-
-    return OK;
-}
-
-status_t FragmentedMPEG4Source::stop() {
-    Mutex::Autolock autoLock(mLock);
-
-    CHECK(mStarted);
-
-    delete[] mSrcBuffer;
-    mSrcBuffer = NULL;
-
-    delete mGroup;
-    mGroup = NULL;
-
-    mStarted = false;
-    mCurrentSampleIndex = 0;
-
-    return OK;
-}
-
-sp<MetaData> FragmentedMPEG4Source::getFormat() {
-    Mutex::Autolock autoLock(mLock);
-
-    return mFormat;
-}
-
-
-status_t FragmentedMPEG4Source::read(
-        MediaBuffer **out, const ReadOptions *options) {
-    int64_t seekTimeUs;
-    ReadOptions::SeekMode mode;
-    if (options && options->getSeekTo(&seekTimeUs, &mode)) {
-        mParser->seekTo(mIsAudioTrack, seekTimeUs);
-    }
-    MediaBuffer *buffer = NULL;
-    mGroup->acquire_buffer(&buffer);
-    sp<ABuffer> parseBuffer;
-
-    status_t ret = mParser->dequeueAccessUnit(mIsAudioTrack, &parseBuffer, true /* synchronous */);
-    if (ret != OK) {
-        buffer->release();
-        ALOGV("returning %d", ret);
-        return ret;
-    }
-    sp<AMessage> meta = parseBuffer->meta();
-    int64_t timeUs;
-    CHECK(meta->findInt64("timeUs", &timeUs));
-    int32_t isSync;
-    if (meta->findInt32("is-sync-frame", &isSync) && isSync != 0) {
-        buffer->meta_data()->setInt32(kKeyIsSyncFrame, 1);
-    }
-    buffer->meta_data()->setInt64(kKeyTime, timeUs);
-    buffer->set_range(0, parseBuffer->size());
-    memcpy(buffer->data(), parseBuffer->data(), parseBuffer->size());
-    *out = buffer;
-    return OK;
-}
-
-
-static bool isCompatibleBrand(uint32_t fourcc) {
-    static const uint32_t kCompatibleBrands[] = {
-        FOURCC('i', 's', 'o', 'm'),
-        FOURCC('i', 's', 'o', '2'),
-        FOURCC('a', 'v', 'c', '1'),
-        FOURCC('3', 'g', 'p', '4'),
-        FOURCC('m', 'p', '4', '1'),
-        FOURCC('m', 'p', '4', '2'),
-
-        // Won't promise that the following file types can be played.
-        // Just give these file types a chance.
-        FOURCC('q', 't', ' ', ' '),  // Apple's QuickTime
-        FOURCC('M', 'S', 'N', 'V'),  // Sony's PSP
-
-        FOURCC('3', 'g', '2', 'a'),  // 3GPP2
-        FOURCC('3', 'g', '2', 'b'),
-    };
-
-    for (size_t i = 0;
-         i < sizeof(kCompatibleBrands) / sizeof(kCompatibleBrands[0]);
-         ++i) {
-        if (kCompatibleBrands[i] == fourcc) {
-            return true;
-        }
-    }
-
-    return false;
-}
-
-// Attempt to actually parse the 'ftyp' atom and determine if a suitable
-// compatible brand is present.
-// Also try to identify where this file's metadata ends
-// (end of the 'moov' atom) and report it to the caller as part of
-// the metadata.
-static bool Sniff(
-        const sp<DataSource> &source, String8 *mimeType, float *confidence,
-        sp<AMessage> *meta) {
-    // We scan up to 128k bytes to identify this file as an MP4.
-    static const off64_t kMaxScanOffset = 128ll * 1024ll;
-
-    off64_t offset = 0ll;
-    bool foundGoodFileType = false;
-    bool isFragmented = false;
-    off64_t moovAtomEndOffset = -1ll;
-    bool done = false;
-
-    while (!done && offset < kMaxScanOffset) {
-        uint32_t hdr[2];
-        if (source->readAt(offset, hdr, 8) < 8) {
-            return false;
-        }
-
-        uint64_t chunkSize = ntohl(hdr[0]);
-        uint32_t chunkType = ntohl(hdr[1]);
-        off64_t chunkDataOffset = offset + 8;
-
-        if (chunkSize == 1) {
-            if (source->readAt(offset + 8, &chunkSize, 8) < 8) {
-                return false;
-            }
-
-            chunkSize = ntoh64(chunkSize);
-            chunkDataOffset += 8;
-
-            if (chunkSize < 16) {
-                // The smallest valid chunk is 16 bytes long in this case.
-                return false;
-            }
-        } else if (chunkSize < 8) {
-            // The smallest valid chunk is 8 bytes long.
-            return false;
-        }
-
-        off64_t chunkDataSize = offset + chunkSize - chunkDataOffset;
-
-        char chunkstring[5];
-        MakeFourCCString(chunkType, chunkstring);
-        ALOGV("saw chunk type %s, size %lld @ %lld", chunkstring, chunkSize, offset);
-        switch (chunkType) {
-            case FOURCC('f', 't', 'y', 'p'):
-            {
-                if (chunkDataSize < 8) {
-                    return false;
-                }
-
-                uint32_t numCompatibleBrands = (chunkDataSize - 8) / 4;
-                for (size_t i = 0; i < numCompatibleBrands + 2; ++i) {
-                    if (i == 1) {
-                        // Skip this index, it refers to the minorVersion,
-                        // not a brand.
-                        continue;
-                    }
-
-                    uint32_t brand;
-                    if (source->readAt(
-                                chunkDataOffset + 4 * i, &brand, 4) < 4) {
-                        return false;
-                    }
-
-                    brand = ntohl(brand);
-                    char brandstring[5];
-                    MakeFourCCString(brand, brandstring);
-                    ALOGV("Brand: %s", brandstring);
-
-                    if (isCompatibleBrand(brand)) {
-                        foundGoodFileType = true;
-                        break;
-                    }
-                }
-
-                if (!foundGoodFileType) {
-                    return false;
-                }
-
-                break;
-            }
-
-            case FOURCC('m', 'o', 'o', 'v'):
-            {
-                moovAtomEndOffset = offset + chunkSize;
-                break;
-            }
-
-            case FOURCC('m', 'o', 'o', 'f'):
-            {
-                // this is kind of broken, since we might not actually find a
-                // moof box in the first 128k.
-                isFragmented = true;
-                done = true;
-                break;
-            }
-
-            default:
-                break;
-        }
-
-        offset += chunkSize;
-    }
-
-    if (!foundGoodFileType || !isFragmented) {
-        return false;
-    }
-
-    *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4;
-    *confidence = 0.5f; // slightly more than MPEG4Extractor
-
-    if (moovAtomEndOffset >= 0) {
-        *meta = new AMessage;
-        (*meta)->setInt64("meta-data-size", moovAtomEndOffset);
-        (*meta)->setInt32("fragmented", 1); // tell MediaExtractor what to instantiate
-
-        ALOGV("found metadata size: %lld", moovAtomEndOffset);
-    }
-
-    return true;
-}
-
-// used by DataSource::RegisterDefaultSniffers
-bool SniffFragmentedMP4(
-        const sp<DataSource> &source, String8 *mimeType, float *confidence,
-        sp<AMessage> *meta) {
-    ALOGV("SniffFragmentedMP4");
-    char prop[PROPERTY_VALUE_MAX];
-    if (property_get("media.stagefright.use-fragmp4", prop, NULL)
-            && (!strcmp(prop, "1") || !strcasecmp(prop, "true"))) {
-        return Sniff(source, mimeType, confidence, meta);
-    }
-
-    return false;
-}
-
-}  // namespace android
diff --git a/media/libstagefright/MediaExtractor.cpp b/media/libstagefright/MediaExtractor.cpp
index b18c916..9ab6611 100644
--- a/media/libstagefright/MediaExtractor.cpp
+++ b/media/libstagefright/MediaExtractor.cpp
@@ -21,7 +21,6 @@
 #include "include/AMRExtractor.h"
 #include "include/MP3Extractor.h"
 #include "include/MPEG4Extractor.h"
-#include "include/FragmentedMP4Extractor.h"
 #include "include/WAVExtractor.h"
 #include "include/OggExtractor.h"
 #include "include/MPEG2PSExtractor.h"
@@ -94,12 +93,7 @@
     MediaExtractor *ret = NULL;
     if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MPEG4)
             || !strcasecmp(mime, "audio/mp4")) {
-        int fragmented = 0;
-        if (meta != NULL && meta->findInt32("fragmented", &fragmented) && fragmented) {
-            ret = new FragmentedMP4Extractor(source);
-        } else {
-            ret = new MPEG4Extractor(source);
-        }
+        ret = new MPEG4Extractor(source);
     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
         ret = new MP3Extractor(source, meta);
     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)
diff --git a/media/libstagefright/include/FragmentedMP4Extractor.h b/media/libstagefright/include/FragmentedMP4Extractor.h
deleted file mode 100644
index 763cd3a..0000000
--- a/media/libstagefright/include/FragmentedMP4Extractor.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef FRAGMENTED_MP4_EXTRACTOR_H_
-
-#define FRAGMENTED_MP4_EXTRACTOR_H_
-
-#include "include/FragmentedMP4Parser.h"
-
-#include <media/stagefright/MediaExtractor.h>
-#include <utils/Vector.h>
-#include <utils/String8.h>
-
-namespace android {
-
-struct AMessage;
-class DataSource;
-class SampleTable;
-class String8;
-
-class FragmentedMP4Extractor : public MediaExtractor {
-public:
-    // Extractor assumes ownership of "source".
-    FragmentedMP4Extractor(const sp<DataSource> &source);
-
-    virtual size_t countTracks();
-    virtual sp<MediaSource> getTrack(size_t index);
-    virtual sp<MetaData> getTrackMetaData(size_t index, uint32_t flags);
-    virtual sp<MetaData> getMetaData();
-    virtual uint32_t flags() const;
-
-protected:
-    virtual ~FragmentedMP4Extractor();
-
-private:
-    sp<ALooper> mLooper;
-    sp<FragmentedMP4Parser> mParser;
-    sp<DataSource> mDataSource;
-    status_t mInitCheck;
-    size_t mAudioTrackIndex;
-    size_t mTrackCount;
-
-    sp<MetaData> mFileMetaData;
-
-    Vector<uint32_t> mPath;
-
-    FragmentedMP4Extractor(const FragmentedMP4Extractor &);
-    FragmentedMP4Extractor &operator=(const FragmentedMP4Extractor &);
-};
-
-bool SniffFragmentedMP4(
-        const sp<DataSource> &source, String8 *mimeType, float *confidence,
-        sp<AMessage> *);
-
-}  // namespace android
-
-#endif  // MPEG4_EXTRACTOR_H_