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//#define LOG_NDEBUG 0 18#define LOG_TAG "MediaExtractor" 19#include <utils/Log.h> 20 21#include "include/AMRExtractor.h" 22#include "include/MP3Extractor.h" 23#include "include/MPEG4Extractor.h" 24#include "include/WAVExtractor.h" 25#include "include/OggExtractor.h" 26#include "include/MPEG2PSExtractor.h" 27#include "include/MPEG2TSExtractor.h" 28#include "include/DRMExtractor.h" 29#include "include/WVMExtractor.h" 30#include "include/FLACExtractor.h" 31#include "include/AACExtractor.h" 32 33#include "matroska/MatroskaExtractor.h" 34 35#include <media/stagefright/foundation/AMessage.h> 36#include <media/stagefright/DataSource.h> 37#include <media/stagefright/MediaDefs.h> 38#include <media/stagefright/MediaExtractor.h> 39#include <media/stagefright/MetaData.h> 40#include <utils/String8.h> 41 42namespace android { 43 44sp<MetaData> MediaExtractor::getMetaData() { 45 return new MetaData; 46} 47 48uint32_t MediaExtractor::flags() const { 49 return CAN_SEEK_BACKWARD | CAN_SEEK_FORWARD | CAN_PAUSE | CAN_SEEK; 50} 51 52// static 53sp<MediaExtractor> MediaExtractor::Create( 54 const sp<DataSource> &source, const char *mime) { 55 sp<AMessage> meta; 56 57 String8 tmp; 58 if (mime == NULL) { 59 float confidence; 60 if (!source->sniff(&tmp, &confidence, &meta)) { 61 LOGV("FAILED to autodetect media content."); 62 63 return NULL; 64 } 65 66 mime = tmp.string(); 67 LOGV("Autodetected media content as '%s' with confidence %.2f", 68 mime, confidence); 69 } 70 71 bool isDrm = false; 72 // DRM MIME type syntax is "drm+type+original" where 73 // type is "es_based" or "container_based" and 74 // original is the content's cleartext MIME type 75 if (!strncmp(mime, "drm+", 4)) { 76 const char *originalMime = strchr(mime+4, '+'); 77 if (originalMime == NULL) { 78 // second + not found 79 return NULL; 80 } 81 ++originalMime; 82 if (!strncmp(mime, "drm+es_based+", 13)) { 83 // DRMExtractor sets container metadata kKeyIsDRM to 1 84 return new DRMExtractor(source, originalMime); 85 } else if (!strncmp(mime, "drm+container_based+", 20)) { 86 mime = originalMime; 87 isDrm = true; 88 } else { 89 return NULL; 90 } 91 } 92 93 MediaExtractor *ret = NULL; 94 if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MPEG4) 95 || !strcasecmp(mime, "audio/mp4")) { 96 ret = new MPEG4Extractor(source); 97 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) { 98 ret = new MP3Extractor(source, meta); 99 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB) 100 || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) { 101 ret = new AMRExtractor(source); 102 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) { 103 ret = new FLACExtractor(source); 104 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_WAV)) { 105 ret = new WAVExtractor(source); 106 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_OGG)) { 107 ret = new OggExtractor(source); 108 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MATROSKA)) { 109 ret = new MatroskaExtractor(source); 110 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MPEG2TS)) { 111 ret = new MPEG2TSExtractor(source); 112 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_WVM)) { 113 ret = new WVMExtractor(source); 114 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC_ADTS)) { 115 ret = new AACExtractor(source); 116 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MPEG2PS)) { 117 ret = new MPEG2PSExtractor(source); 118 } 119 120 if (ret != NULL) { 121 if (isDrm) { 122 ret->setDrmFlag(true); 123 } else { 124 ret->setDrmFlag(false); 125 } 126 } 127 128 return ret; 129} 130 131} // namespace android 132