Home | History | Annotate | Download | only in libstagefright
      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 
     42 namespace android {
     43 
     44 sp<MetaData> MediaExtractor::getMetaData() {
     45     return new MetaData;
     46 }
     47 
     48 uint32_t MediaExtractor::flags() const {
     49     return CAN_SEEK_BACKWARD | CAN_SEEK_FORWARD | CAN_PAUSE | CAN_SEEK;
     50 }
     51 
     52 // static
     53 sp<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             ALOGV("FAILED to autodetect media content.");
     62 
     63             return NULL;
     64         }
     65 
     66         mime = tmp.string();
     67         ALOGV("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         // Return now.  WVExtractor should not have the DrmFlag set in the block below.
    114         return new WVMExtractor(source);
    115     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC_ADTS)) {
    116         ret = new AACExtractor(source, meta);
    117     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MPEG2PS)) {
    118         ret = new MPEG2PSExtractor(source);
    119     }
    120 
    121     if (ret != NULL) {
    122        if (isDrm) {
    123            ret->setDrmFlag(true);
    124        } else {
    125            ret->setDrmFlag(false);
    126        }
    127     }
    128 
    129     return ret;
    130 }
    131 
    132 }  // namespace android
    133