diff options
Diffstat (limited to 'media')
-rw-r--r-- | media/libstagefright/Android.mk | 1 | ||||
-rw-r--r-- | media/libstagefright/DataSource.cpp | 2 | ||||
-rw-r--r-- | media/libstagefright/FragmentedMP4Extractor.cpp | 464 | ||||
-rw-r--r-- | media/libstagefright/MediaExtractor.cpp | 8 | ||||
-rw-r--r-- | media/libstagefright/include/FragmentedMP4Extractor.h | 70 |
5 files changed, 1 insertions, 544 deletions
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 @@ LOCAL_SRC_FILES:= \ 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 @@ void DataSource::RegisterSniffer(SnifferFunc func) { // 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 @@ sp<MediaExtractor> MediaExtractor::Create( 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_ |