120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber/*
220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Copyright (C) 2009 The Android Open Source Project
320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *
420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * you may not use this file except in compliance with the License.
620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * You may obtain a copy of the License at
720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *
820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *
1020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Unless required by applicable law or agreed to in writing, software
1120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
1220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * See the License for the specific language governing permissions and
1420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * limitations under the License.
1520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber */
1620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber//#define LOG_NDEBUG 0
1820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#define LOG_TAG "MediaExtractor"
1920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <utils/Log.h>
2020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
2166326a5ee0869f1ee4d136a477e6effba428b3cbAndreas Huber#include "include/AMRExtractor.h"
2266326a5ee0869f1ee4d136a477e6effba428b3cbAndreas Huber#include "include/MP3Extractor.h"
2366326a5ee0869f1ee4d136a477e6effba428b3cbAndreas Huber#include "include/MPEG4Extractor.h"
240dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber#include "include/WAVExtractor.h"
25ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huber#include "include/OggExtractor.h"
262944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber#include "include/MPEG2PSExtractor.h"
27cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include "include/MPEG2TSExtractor.h"
28dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang#include "include/DRMExtractor.h"
29b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang#include "include/WVMExtractor.h"
30856990b491d84b7ed4fefe337485c8997ba9dd02Glenn Kasten#include "include/FLACExtractor.h"
3150c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang#include "include/AACExtractor.h"
3266326a5ee0869f1ee4d136a477e6effba428b3cbAndreas Huber
33093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber#include "matroska/MatroskaExtractor.h"
34093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
355a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber#include <media/stagefright/foundation/AMessage.h>
3620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/DataSource.h>
3718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber#include <media/stagefright/MediaDefs.h>
3820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaExtractor.h>
39fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber#include <media/stagefright/MetaData.h>
4020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <utils/String8.h>
4120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
4220111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubernamespace android {
4320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
44fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Hubersp<MetaData> MediaExtractor::getMetaData() {
45fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber    return new MetaData;
46fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber}
47fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber
48acdd9d0f59c3d8bdc3de80664a609527ec3d21e2Andreas Huberuint32_t MediaExtractor::flags() const {
4970f521de2675ce6eedf4b22beed94ea1289b0f38Andreas Huber    return CAN_SEEK_BACKWARD | CAN_SEEK_FORWARD | CAN_PAUSE | CAN_SEEK;
50acdd9d0f59c3d8bdc3de80664a609527ec3d21e2Andreas Huber}
51acdd9d0f59c3d8bdc3de80664a609527ec3d21e2Andreas Huber
5220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber// static
53693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubersp<MediaExtractor> MediaExtractor::Create(
54693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        const sp<DataSource> &source, const char *mime) {
555a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber    sp<AMessage> meta;
565a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber
5720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    String8 tmp;
5820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mime == NULL) {
5920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        float confidence;
605a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber        if (!source->sniff(&tmp, &confidence, &meta)) {
613856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("FAILED to autodetect media content.");
6220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
6320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            return NULL;
6420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
6520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
6620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mime = tmp.string();
673856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("Autodetected media content as '%s' with confidence %.2f",
6820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber             mime, confidence);
6920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
7020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
718ddeebb93cb41e7a8e9fe763afb6c6016b21fa61Glenn Kasten    bool isDrm = false;
728c8f24dce1dfc2d1eed8f7856ffceaa349afa2a6Glenn Kasten    // DRM MIME type syntax is "drm+type+original" where
738c8f24dce1dfc2d1eed8f7856ffceaa349afa2a6Glenn Kasten    // type is "es_based" or "container_based" and
748c8f24dce1dfc2d1eed8f7856ffceaa349afa2a6Glenn Kasten    // original is the content's cleartext MIME type
758c8f24dce1dfc2d1eed8f7856ffceaa349afa2a6Glenn Kasten    if (!strncmp(mime, "drm+", 4)) {
768c8f24dce1dfc2d1eed8f7856ffceaa349afa2a6Glenn Kasten        const char *originalMime = strchr(mime+4, '+');
778c8f24dce1dfc2d1eed8f7856ffceaa349afa2a6Glenn Kasten        if (originalMime == NULL) {
788c8f24dce1dfc2d1eed8f7856ffceaa349afa2a6Glenn Kasten            // second + not found
798c8f24dce1dfc2d1eed8f7856ffceaa349afa2a6Glenn Kasten            return NULL;
808c8f24dce1dfc2d1eed8f7856ffceaa349afa2a6Glenn Kasten        }
818c8f24dce1dfc2d1eed8f7856ffceaa349afa2a6Glenn Kasten        ++originalMime;
828c8f24dce1dfc2d1eed8f7856ffceaa349afa2a6Glenn Kasten        if (!strncmp(mime, "drm+es_based+", 13)) {
838ddeebb93cb41e7a8e9fe763afb6c6016b21fa61Glenn Kasten            // DRMExtractor sets container metadata kKeyIsDRM to 1
84dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            return new DRMExtractor(source, originalMime);
858c8f24dce1dfc2d1eed8f7856ffceaa349afa2a6Glenn Kasten        } else if (!strncmp(mime, "drm+container_based+", 20)) {
86dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            mime = originalMime;
878ddeebb93cb41e7a8e9fe763afb6c6016b21fa61Glenn Kasten            isDrm = true;
88dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        } else {
89dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            return NULL;
90dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        }
91dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    }
92dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
938ddeebb93cb41e7a8e9fe763afb6c6016b21fa61Glenn Kasten    MediaExtractor *ret = NULL;
9418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MPEG4)
9518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            || !strcasecmp(mime, "audio/mp4")) {
96ab89ac209fd1c3b0a2227168a48d7f3ae9bc43f3Marco Nelissen        ret = new MPEG4Extractor(source);
9718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
988ddeebb93cb41e7a8e9fe763afb6c6016b21fa61Glenn Kasten        ret = new MP3Extractor(source, meta);
9918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)
10018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
1018ddeebb93cb41e7a8e9fe763afb6c6016b21fa61Glenn Kasten        ret = new AMRExtractor(source);
102856990b491d84b7ed4fefe337485c8997ba9dd02Glenn Kasten    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
1038ddeebb93cb41e7a8e9fe763afb6c6016b21fa61Glenn Kasten        ret = new FLACExtractor(source);
1040dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_WAV)) {
1058ddeebb93cb41e7a8e9fe763afb6c6016b21fa61Glenn Kasten        ret = new WAVExtractor(source);
106ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_OGG)) {
1078ddeebb93cb41e7a8e9fe763afb6c6016b21fa61Glenn Kasten        ret = new OggExtractor(source);
108093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MATROSKA)) {
1098ddeebb93cb41e7a8e9fe763afb6c6016b21fa61Glenn Kasten        ret = new MatroskaExtractor(source);
110cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MPEG2TS)) {
1118ddeebb93cb41e7a8e9fe763afb6c6016b21fa61Glenn Kasten        ret = new MPEG2TSExtractor(source);
112b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_WVM)) {
1131d02a827bc0bb5023a551bc9ce3fb37457240daaFred Gylys-Colwell        // Return now.  WVExtractor should not have the DrmFlag set in the block below.
1141d02a827bc0bb5023a551bc9ce3fb37457240daaFred Gylys-Colwell        return new WVMExtractor(source);
11550c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC_ADTS)) {
11614da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber        ret = new AACExtractor(source, meta);
1172944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MPEG2PS)) {
1182944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        ret = new MPEG2PSExtractor(source);
1198ddeebb93cb41e7a8e9fe763afb6c6016b21fa61Glenn Kasten    }
1200d0edfb024f65f7e1097bf1814ae229ce9cb367dGloria Wang
1210d0edfb024f65f7e1097bf1814ae229ce9cb367dGloria Wang    if (ret != NULL) {
1220d0edfb024f65f7e1097bf1814ae229ce9cb367dGloria Wang       if (isDrm) {
1230d0edfb024f65f7e1097bf1814ae229ce9cb367dGloria Wang           ret->setDrmFlag(true);
1240d0edfb024f65f7e1097bf1814ae229ce9cb367dGloria Wang       } else {
1250d0edfb024f65f7e1097bf1814ae229ce9cb367dGloria Wang           ret->setDrmFlag(false);
1260d0edfb024f65f7e1097bf1814ae229ce9cb367dGloria Wang       }
12720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
12820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1298ddeebb93cb41e7a8e9fe763afb6c6016b21fa61Glenn Kasten    return ret;
13020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
13120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
13220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}  // namespace android
133