MediaExtractor.cpp revision 4453f452577064b4907a941225f7fc6e87800e37
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>
20d5e5b15ddb2fe23dd7183c03cdaf16c67cb35d7cMarco Nelissen#include <inttypes.h>
21b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen#include <pwd.h>
2220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
2366326a5ee0869f1ee4d136a477e6effba428b3cbAndreas Huber#include "include/AMRExtractor.h"
2466326a5ee0869f1ee4d136a477e6effba428b3cbAndreas Huber#include "include/MP3Extractor.h"
2566326a5ee0869f1ee4d136a477e6effba428b3cbAndreas Huber#include "include/MPEG4Extractor.h"
260dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber#include "include/WAVExtractor.h"
27ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huber#include "include/OggExtractor.h"
282944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber#include "include/MPEG2PSExtractor.h"
29cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include "include/MPEG2TSExtractor.h"
30856990b491d84b7ed4fefe337485c8997ba9dd02Glenn Kasten#include "include/FLACExtractor.h"
3150c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang#include "include/AACExtractor.h"
32faf4efc6a41e88adf85f76f48f020a6d681f5ff1Marco Nelissen#include "include/MidiExtractor.h"
3366326a5ee0869f1ee4d136a477e6effba428b3cbAndreas Huber
34093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber#include "matroska/MatroskaExtractor.h"
35093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
36b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen#include <binder/IServiceManager.h>
37b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen#include <binder/MemoryDealer.h>
38b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen
39b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen#include <media/stagefright/foundation/ADebug.h>
405a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber#include <media/stagefright/foundation/AMessage.h>
4120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/DataSource.h>
4218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber#include <media/stagefright/MediaDefs.h>
4320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaExtractor.h>
44fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber#include <media/stagefright/MetaData.h>
45b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen#include <media/IMediaExtractorService.h>
46b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen#include <cutils/properties.h>
4720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <utils/String8.h>
48b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen#include <private/android_filesystem_config.h>
49b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen
5020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
5120111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubernamespace android {
5220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
534453f452577064b4907a941225f7fc6e87800e37Marco NelissenMediaExtractor::MediaExtractor() {
54b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    if (!LOG_NDEBUG) {
55b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        uid_t uid = getuid();
56b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        struct passwd *pw = getpwuid(uid);
57b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        ALOGI("extractor created in uid: %d (%s)", getuid(), pw->pw_name);
58b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    }
59b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen
60b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen}
61b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen
62b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen
63fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Hubersp<MetaData> MediaExtractor::getMetaData() {
64fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber    return new MetaData;
65fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber}
66fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber
67acdd9d0f59c3d8bdc3de80664a609527ec3d21e2Andreas Huberuint32_t MediaExtractor::flags() const {
6870f521de2675ce6eedf4b22beed94ea1289b0f38Andreas Huber    return CAN_SEEK_BACKWARD | CAN_SEEK_FORWARD | CAN_PAUSE | CAN_SEEK;
69acdd9d0f59c3d8bdc3de80664a609527ec3d21e2Andreas Huber}
70acdd9d0f59c3d8bdc3de80664a609527ec3d21e2Andreas Huber
71b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen
72b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen
73b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissenclass RemoteDataSource : public BnDataSource {
74b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissenpublic:
75b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    enum {
76b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        kBufferSize = 64 * 1024,
77b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    };
78b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen
79b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    static sp<IDataSource> wrap(const sp<DataSource> &source);
80b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    virtual ~RemoteDataSource();
81b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen
82b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    virtual sp<IMemory> getIMemory();
83b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    virtual ssize_t readAt(off64_t offset, size_t size);
84b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    virtual status_t getSize(off64_t* size);
85b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    virtual void close();
8610551fcd58b3807fc7351d88e6127ec227b993d1Wei Jia    virtual uint32_t getFlags();
8769d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen    virtual String8 toString();
882a5e49c984befa066e966cd9af2303a54976f163Wei Jia    virtual sp<DecryptHandle> DrmInitialization(const char *mime);
89b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen
90b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissenprivate:
91b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    sp<IMemory> mMemory;
92b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    sp<DataSource> mSource;
9369d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen    String8 mName;
9464a2870d8515fd914638c60803db86dbd92f5b06Chih-Hung Hsieh    explicit RemoteDataSource(const sp<DataSource> &source);
95b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    DISALLOW_EVIL_CONSTRUCTORS(RemoteDataSource);
96b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen};
97b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen
98b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen
99b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissensp<IDataSource> RemoteDataSource::wrap(const sp<DataSource> &source) {
100b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    return new RemoteDataSource(source);
101b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen}
102b2487f03f12dcafdb801fc0007c8df8412397f44Marco NelissenRemoteDataSource::RemoteDataSource(const sp<DataSource> &source) {
103b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    mSource = source;
104b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    sp<MemoryDealer> memoryDealer = new MemoryDealer(kBufferSize, "RemoteDataSource");
105b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    mMemory = memoryDealer->allocate(kBufferSize);
106b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    if (mMemory == NULL) {
107b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        ALOGE("Failed to allocate memory!");
108b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    }
10969d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen    mName = String8::format("RemoteDataSource(%s)", mSource->toString().string());
110b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen}
111b2487f03f12dcafdb801fc0007c8df8412397f44Marco NelissenRemoteDataSource::~RemoteDataSource() {
112b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    close();
113b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen}
114b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissensp<IMemory> RemoteDataSource::getIMemory() {
115b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    return mMemory;
116b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen}
117b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissenssize_t RemoteDataSource::readAt(off64_t offset, size_t size) {
118d5e5b15ddb2fe23dd7183c03cdaf16c67cb35d7cMarco Nelissen    ALOGV("readAt(%" PRId64 ", %zu)", offset, size);
119b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    return mSource->readAt(offset, mMemory->pointer(), size);
120b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen}
121b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissenstatus_t RemoteDataSource::getSize(off64_t* size) {
122b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    return mSource->getSize(size);
123b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen}
124b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissenvoid RemoteDataSource::close() {
125b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    mSource = NULL;
126b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen}
12710551fcd58b3807fc7351d88e6127ec227b993d1Wei Jiauint32_t RemoteDataSource::getFlags() {
12810551fcd58b3807fc7351d88e6127ec227b993d1Wei Jia    return mSource->flags();
12910551fcd58b3807fc7351d88e6127ec227b993d1Wei Jia}
130b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen
13169d3d8a9540b0da787ea0beccad2517f057dd54dMarco NelissenString8 RemoteDataSource::toString() {
13269d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen    return mName;
13369d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen}
13469d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen
1352a5e49c984befa066e966cd9af2303a54976f163Wei Jiasp<DecryptHandle> RemoteDataSource::DrmInitialization(const char *mime) {
1362a5e49c984befa066e966cd9af2303a54976f163Wei Jia    return mSource->DrmInitialization(mime);
1372a5e49c984befa066e966cd9af2303a54976f163Wei Jia}
1382a5e49c984befa066e966cd9af2303a54976f163Wei Jia
13920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber// static
140b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissensp<IMediaExtractor> MediaExtractor::Create(
141b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        const sp<DataSource> &source, const char *mime) {
142b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    ALOGV("MediaExtractor::Create %s", mime);
143b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen
14496626b7f9a4e5c9e1e04f7f710383631d1470364Marco Nelissen    if (!property_get_bool("media.stagefright.extractremote", true)) {
145b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        // local extractor
146b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        ALOGW("creating media extractor in calling process");
147b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        return CreateFromService(source, mime);
148b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    } else {
149d7581056d0962784b50570c7f477b7a406c08a57Wei Jia        // remote extractor
150d7581056d0962784b50570c7f477b7a406c08a57Wei Jia        ALOGV("get service manager");
151d7581056d0962784b50570c7f477b7a406c08a57Wei Jia        sp<IBinder> binder = defaultServiceManager()->getService(String16("media.extractor"));
152d7581056d0962784b50570c7f477b7a406c08a57Wei Jia
153b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        if (binder != 0) {
154b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            sp<IMediaExtractorService> mediaExService(interface_cast<IMediaExtractorService>(binder));
155b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            sp<IMediaExtractor> ex = mediaExService->makeExtractor(RemoteDataSource::wrap(source), mime);
156b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            return ex;
157b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        } else {
158b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            ALOGE("extractor service not running");
159b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            return NULL;
160b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        }
161b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    }
162b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    return NULL;
163b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen}
164b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen
165b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissensp<MediaExtractor> MediaExtractor::CreateFromService(
166693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        const sp<DataSource> &source, const char *mime) {
167b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen
168b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    ALOGV("MediaExtractor::CreateFromService %s", mime);
16992d57f926eb39d72e8fd8f3b3c9e40d25f77ad47Marco Nelissen    RegisterDefaultSniffers();
170b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen
1714453f452577064b4907a941225f7fc6e87800e37Marco Nelissen    // initialize source decryption if needed
1724453f452577064b4907a941225f7fc6e87800e37Marco Nelissen    source->DrmInitialization();
1734453f452577064b4907a941225f7fc6e87800e37Marco Nelissen
1745a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber    sp<AMessage> meta;
1755a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber
17620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    String8 tmp;
17720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mime == NULL) {
17820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        float confidence;
17992d57f926eb39d72e8fd8f3b3c9e40d25f77ad47Marco Nelissen        if (!sniff(source, &tmp, &confidence, &meta)) {
1803856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("FAILED to autodetect media content.");
18120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
18220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            return NULL;
18320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
18420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
18520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mime = tmp.string();
1863856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("Autodetected media content as '%s' with confidence %.2f",
18720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber             mime, confidence);
18820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
18920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1908ddeebb93cb41e7a8e9fe763afb6c6016b21fa61Glenn Kasten    MediaExtractor *ret = NULL;
19118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MPEG4)
19218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            || !strcasecmp(mime, "audio/mp4")) {
193ab89ac209fd1c3b0a2227168a48d7f3ae9bc43f3Marco Nelissen        ret = new MPEG4Extractor(source);
19418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
1958ddeebb93cb41e7a8e9fe763afb6c6016b21fa61Glenn Kasten        ret = new MP3Extractor(source, meta);
19618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)
19718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
1988ddeebb93cb41e7a8e9fe763afb6c6016b21fa61Glenn Kasten        ret = new AMRExtractor(source);
199856990b491d84b7ed4fefe337485c8997ba9dd02Glenn Kasten    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
2008ddeebb93cb41e7a8e9fe763afb6c6016b21fa61Glenn Kasten        ret = new FLACExtractor(source);
2010dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_WAV)) {
2028ddeebb93cb41e7a8e9fe763afb6c6016b21fa61Glenn Kasten        ret = new WAVExtractor(source);
203ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_OGG)) {
2048ddeebb93cb41e7a8e9fe763afb6c6016b21fa61Glenn Kasten        ret = new OggExtractor(source);
205093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MATROSKA)) {
2068ddeebb93cb41e7a8e9fe763afb6c6016b21fa61Glenn Kasten        ret = new MatroskaExtractor(source);
207cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MPEG2TS)) {
2088ddeebb93cb41e7a8e9fe763afb6c6016b21fa61Glenn Kasten        ret = new MPEG2TSExtractor(source);
20950c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC_ADTS)) {
21014da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber        ret = new AACExtractor(source, meta);
2112944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MPEG2PS)) {
2122944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        ret = new MPEG2PSExtractor(source);
213faf4efc6a41e88adf85f76f48f020a6d681f5ff1Marco Nelissen    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MIDI)) {
214faf4efc6a41e88adf85f76f48f020a6d681f5ff1Marco Nelissen        ret = new MidiExtractor(source);
2158ddeebb93cb41e7a8e9fe763afb6c6016b21fa61Glenn Kasten    }
2160d0edfb024f65f7e1097bf1814ae229ce9cb367dGloria Wang
2178ddeebb93cb41e7a8e9fe763afb6c6016b21fa61Glenn Kasten    return ret;
21820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
21920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
22092d57f926eb39d72e8fd8f3b3c9e40d25f77ad47Marco NelissenMutex MediaExtractor::gSnifferMutex;
22192d57f926eb39d72e8fd8f3b3c9e40d25f77ad47Marco NelissenList<MediaExtractor::SnifferFunc> MediaExtractor::gSniffers;
22292d57f926eb39d72e8fd8f3b3c9e40d25f77ad47Marco Nelissenbool MediaExtractor::gSniffersRegistered = false;
22392d57f926eb39d72e8fd8f3b3c9e40d25f77ad47Marco Nelissen
22492d57f926eb39d72e8fd8f3b3c9e40d25f77ad47Marco Nelissen// static
22592d57f926eb39d72e8fd8f3b3c9e40d25f77ad47Marco Nelissenbool MediaExtractor::sniff(
22692d57f926eb39d72e8fd8f3b3c9e40d25f77ad47Marco Nelissen        const sp<DataSource> &source, String8 *mimeType, float *confidence, sp<AMessage> *meta) {
22792d57f926eb39d72e8fd8f3b3c9e40d25f77ad47Marco Nelissen    *mimeType = "";
22892d57f926eb39d72e8fd8f3b3c9e40d25f77ad47Marco Nelissen    *confidence = 0.0f;
22992d57f926eb39d72e8fd8f3b3c9e40d25f77ad47Marco Nelissen    meta->clear();
23092d57f926eb39d72e8fd8f3b3c9e40d25f77ad47Marco Nelissen
23192d57f926eb39d72e8fd8f3b3c9e40d25f77ad47Marco Nelissen    {
23292d57f926eb39d72e8fd8f3b3c9e40d25f77ad47Marco Nelissen        Mutex::Autolock autoLock(gSnifferMutex);
23392d57f926eb39d72e8fd8f3b3c9e40d25f77ad47Marco Nelissen        if (!gSniffersRegistered) {
23492d57f926eb39d72e8fd8f3b3c9e40d25f77ad47Marco Nelissen            return false;
23592d57f926eb39d72e8fd8f3b3c9e40d25f77ad47Marco Nelissen        }
23692d57f926eb39d72e8fd8f3b3c9e40d25f77ad47Marco Nelissen    }
23792d57f926eb39d72e8fd8f3b3c9e40d25f77ad47Marco Nelissen
23892d57f926eb39d72e8fd8f3b3c9e40d25f77ad47Marco Nelissen    for (List<SnifferFunc>::iterator it = gSniffers.begin();
23992d57f926eb39d72e8fd8f3b3c9e40d25f77ad47Marco Nelissen         it != gSniffers.end(); ++it) {
24092d57f926eb39d72e8fd8f3b3c9e40d25f77ad47Marco Nelissen        String8 newMimeType;
24192d57f926eb39d72e8fd8f3b3c9e40d25f77ad47Marco Nelissen        float newConfidence;
24292d57f926eb39d72e8fd8f3b3c9e40d25f77ad47Marco Nelissen        sp<AMessage> newMeta;
24392d57f926eb39d72e8fd8f3b3c9e40d25f77ad47Marco Nelissen        if ((*it)(source, &newMimeType, &newConfidence, &newMeta)) {
24492d57f926eb39d72e8fd8f3b3c9e40d25f77ad47Marco Nelissen            if (newConfidence > *confidence) {
24592d57f926eb39d72e8fd8f3b3c9e40d25f77ad47Marco Nelissen                *mimeType = newMimeType;
24692d57f926eb39d72e8fd8f3b3c9e40d25f77ad47Marco Nelissen                *confidence = newConfidence;
24792d57f926eb39d72e8fd8f3b3c9e40d25f77ad47Marco Nelissen                *meta = newMeta;
24892d57f926eb39d72e8fd8f3b3c9e40d25f77ad47Marco Nelissen            }
24992d57f926eb39d72e8fd8f3b3c9e40d25f77ad47Marco Nelissen        }
25092d57f926eb39d72e8fd8f3b3c9e40d25f77ad47Marco Nelissen    }
25192d57f926eb39d72e8fd8f3b3c9e40d25f77ad47Marco Nelissen
25292d57f926eb39d72e8fd8f3b3c9e40d25f77ad47Marco Nelissen    return *confidence > 0.0;
25392d57f926eb39d72e8fd8f3b3c9e40d25f77ad47Marco Nelissen}
25492d57f926eb39d72e8fd8f3b3c9e40d25f77ad47Marco Nelissen
25592d57f926eb39d72e8fd8f3b3c9e40d25f77ad47Marco Nelissen// static
25692d57f926eb39d72e8fd8f3b3c9e40d25f77ad47Marco Nelissenvoid MediaExtractor::RegisterSniffer_l(SnifferFunc func) {
25792d57f926eb39d72e8fd8f3b3c9e40d25f77ad47Marco Nelissen    for (List<SnifferFunc>::iterator it = gSniffers.begin();
25892d57f926eb39d72e8fd8f3b3c9e40d25f77ad47Marco Nelissen         it != gSniffers.end(); ++it) {
25992d57f926eb39d72e8fd8f3b3c9e40d25f77ad47Marco Nelissen        if (*it == func) {
26092d57f926eb39d72e8fd8f3b3c9e40d25f77ad47Marco Nelissen            return;
26192d57f926eb39d72e8fd8f3b3c9e40d25f77ad47Marco Nelissen        }
26292d57f926eb39d72e8fd8f3b3c9e40d25f77ad47Marco Nelissen    }
26392d57f926eb39d72e8fd8f3b3c9e40d25f77ad47Marco Nelissen
26492d57f926eb39d72e8fd8f3b3c9e40d25f77ad47Marco Nelissen    gSniffers.push_back(func);
26592d57f926eb39d72e8fd8f3b3c9e40d25f77ad47Marco Nelissen}
26692d57f926eb39d72e8fd8f3b3c9e40d25f77ad47Marco Nelissen
26792d57f926eb39d72e8fd8f3b3c9e40d25f77ad47Marco Nelissen// static
26892d57f926eb39d72e8fd8f3b3c9e40d25f77ad47Marco Nelissenvoid MediaExtractor::RegisterDefaultSniffers() {
26992d57f926eb39d72e8fd8f3b3c9e40d25f77ad47Marco Nelissen    Mutex::Autolock autoLock(gSnifferMutex);
27092d57f926eb39d72e8fd8f3b3c9e40d25f77ad47Marco Nelissen    if (gSniffersRegistered) {
27192d57f926eb39d72e8fd8f3b3c9e40d25f77ad47Marco Nelissen        return;
27292d57f926eb39d72e8fd8f3b3c9e40d25f77ad47Marco Nelissen    }
27392d57f926eb39d72e8fd8f3b3c9e40d25f77ad47Marco Nelissen
27492d57f926eb39d72e8fd8f3b3c9e40d25f77ad47Marco Nelissen    RegisterSniffer_l(SniffMPEG4);
27592d57f926eb39d72e8fd8f3b3c9e40d25f77ad47Marco Nelissen    RegisterSniffer_l(SniffMatroska);
27692d57f926eb39d72e8fd8f3b3c9e40d25f77ad47Marco Nelissen    RegisterSniffer_l(SniffOgg);
27792d57f926eb39d72e8fd8f3b3c9e40d25f77ad47Marco Nelissen    RegisterSniffer_l(SniffWAV);
27892d57f926eb39d72e8fd8f3b3c9e40d25f77ad47Marco Nelissen    RegisterSniffer_l(SniffFLAC);
27992d57f926eb39d72e8fd8f3b3c9e40d25f77ad47Marco Nelissen    RegisterSniffer_l(SniffAMR);
28092d57f926eb39d72e8fd8f3b3c9e40d25f77ad47Marco Nelissen    RegisterSniffer_l(SniffMPEG2TS);
28192d57f926eb39d72e8fd8f3b3c9e40d25f77ad47Marco Nelissen    RegisterSniffer_l(SniffMP3);
28292d57f926eb39d72e8fd8f3b3c9e40d25f77ad47Marco Nelissen    RegisterSniffer_l(SniffAAC);
28392d57f926eb39d72e8fd8f3b3c9e40d25f77ad47Marco Nelissen    RegisterSniffer_l(SniffMPEG2PS);
28492d57f926eb39d72e8fd8f3b3c9e40d25f77ad47Marco Nelissen    RegisterSniffer_l(SniffMidi);
28592d57f926eb39d72e8fd8f3b3c9e40d25f77ad47Marco Nelissen
28692d57f926eb39d72e8fd8f3b3c9e40d25f77ad47Marco Nelissen    gSniffersRegistered = true;
28792d57f926eb39d72e8fd8f3b3c9e40d25f77ad47Marco Nelissen}
28892d57f926eb39d72e8fd8f3b3c9e40d25f77ad47Marco Nelissen
28992d57f926eb39d72e8fd8f3b3c9e40d25f77ad47Marco Nelissen
29020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}  // namespace android
291