AMRExtractor.cpp revision fa8de752507feaca695123911915070c1ce463b2
15a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber/*
25a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber * Copyright (C) 2009 The Android Open Source Project
35a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber *
45a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
55a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber * you may not use this file except in compliance with the License.
65a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber * You may obtain a copy of the License at
75a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber *
85a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
95a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber *
105a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber * Unless required by applicable law or agreed to in writing, software
115a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
125a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber * See the License for the specific language governing permissions and
145a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber * limitations under the License.
155a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber */
165a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber
175a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber//#define LOG_NDEBUG 0
185a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber#define LOG_TAG "AMRExtractor"
195a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber#include <utils/Log.h>
205a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber
215a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber#include <media/stagefright/AMRExtractor.h>
225a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber#include <media/stagefright/DataSource.h>
235a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber#include <media/stagefright/MediaBufferGroup.h>
245a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber#include <media/stagefright/MediaDebug.h>
25e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber#include <media/stagefright/MediaDefs.h>
265a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber#include <media/stagefright/MediaErrors.h>
275a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber#include <media/stagefright/MediaSource.h>
285a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber#include <media/stagefright/MetaData.h>
295a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber#include <utils/String8.h>
305a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber
315a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Hubernamespace android {
325a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber
335a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huberclass AMRSource : public MediaSource {
345a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huberpublic:
355a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    AMRSource(const sp<DataSource> &source, bool isWide);
365a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber
375a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    virtual status_t start(MetaData *params = NULL);
385a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    virtual status_t stop();
395a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber
405a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    virtual sp<MetaData> getFormat();
415a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber
425a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    virtual status_t read(
435a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber            MediaBuffer **buffer, const ReadOptions *options = NULL);
445a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber
455a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huberprotected:
465a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    virtual ~AMRSource();
475a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber
485a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huberprivate:
495a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    sp<DataSource> mDataSource;
505a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    bool mIsWide;
515a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber
525a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    off_t mOffset;
535a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    int64_t mCurrentTimeUs;
545a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    bool mStarted;
555a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    MediaBufferGroup *mGroup;
565a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber
575a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    AMRSource(const AMRSource &);
585a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    AMRSource &operator=(const AMRSource &);
595a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber};
605a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber
615a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber////////////////////////////////////////////////////////////////////////////////
625a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber
635a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas HuberAMRExtractor::AMRExtractor(const sp<DataSource> &source)
645a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    : mDataSource(source),
655a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber      mInitCheck(NO_INIT) {
665a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    String8 mimeType;
675a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    float confidence;
685a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    if (SniffAMR(mDataSource, &mimeType, &confidence)) {
695a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber        mInitCheck = OK;
70e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber        mIsWide = (mimeType == MEDIA_MIMETYPE_AUDIO_AMR_WB);
715a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    }
725a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber}
735a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber
745a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas HuberAMRExtractor::~AMRExtractor() {
755a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber}
765a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber
775a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Hubersize_t AMRExtractor::countTracks() {
785a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    return mInitCheck == OK ? 1 : 0;
795a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber}
805a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber
815a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Hubersp<MediaSource> AMRExtractor::getTrack(size_t index) {
825a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    if (mInitCheck != OK || index != 0) {
835a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber        return NULL;
845a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    }
855a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber
865a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    return new AMRSource(mDataSource, mIsWide);
875a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber}
885a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber
895a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Hubersp<MetaData> AMRExtractor::getTrackMetaData(size_t index) {
905a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    if (mInitCheck != OK || index != 0) {
915a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber        return NULL;
925a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    }
935a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber
945a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    return makeAMRFormat(mIsWide);
955a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber}
965a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber
975a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber// static
985a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Hubersp<MetaData> AMRExtractor::makeAMRFormat(bool isWide) {
995a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    sp<MetaData> meta = new MetaData;
100e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber    meta->setCString(
101e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber            kKeyMIMEType, isWide ? MEDIA_MIMETYPE_AUDIO_AMR_WB
102e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber                                 : MEDIA_MIMETYPE_AUDIO_AMR_NB);
103e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber
1045a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    meta->setInt32(kKeyChannelCount, 1);
1055a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    meta->setInt32(kKeySampleRate, isWide ? 16000 : 8000);
1065a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber
1075a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    return meta;
1085a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber}
1095a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber
1105a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber////////////////////////////////////////////////////////////////////////////////
1115a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber
1125a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas HuberAMRSource::AMRSource(const sp<DataSource> &source, bool isWide)
1135a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    : mDataSource(source),
1145a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber      mIsWide(isWide),
1155a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber      mOffset(mIsWide ? 9 : 6),
1165a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber      mCurrentTimeUs(0),
1175a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber      mStarted(false),
1185a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber      mGroup(NULL) {
1195a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber}
1205a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber
1215a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas HuberAMRSource::~AMRSource() {
1225a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    if (mStarted) {
1235a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber        stop();
1245a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    }
1255a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber}
1265a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber
1275a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huberstatus_t AMRSource::start(MetaData *params) {
1285a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    CHECK(!mStarted);
1295a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber
1305a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    mOffset = mIsWide ? 9 : 6;
1315a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    mCurrentTimeUs = 0;
1325a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    mGroup = new MediaBufferGroup;
1335a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    mGroup->add_buffer(new MediaBuffer(128));
1345a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    mStarted = true;
1355a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber
1365a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    return OK;
1375a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber}
1385a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber
1395a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huberstatus_t AMRSource::stop() {
1405a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    CHECK(mStarted);
1415a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber
1425a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    delete mGroup;
1435a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    mGroup = NULL;
1445a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber
1455a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    mStarted = false;
1465a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    return OK;
1475a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber}
1485a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber
1495a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Hubersp<MetaData> AMRSource::getFormat() {
1505a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    return AMRExtractor::makeAMRFormat(mIsWide);
1515a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber}
1525a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber
1535a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huberstatus_t AMRSource::read(
1545a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber        MediaBuffer **out, const ReadOptions *options) {
1555a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    *out = NULL;
1565a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber
1575a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    uint8_t header;
1585a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    ssize_t n = mDataSource->read_at(mOffset, &header, 1);
1595a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber
1605a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    if (n < 1) {
1615a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber        return ERROR_IO;
1625a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    }
1635a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber
1645a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    MediaBuffer *buffer;
1655a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    status_t err = mGroup->acquire_buffer(&buffer);
1665a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    if (err != OK) {
1675a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber        return err;
1685a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    }
1695a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber
1705a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    if (header & 0x83) {
1715a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber        // Padding bits must be 0.
1725a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber
1735a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber        return ERROR_MALFORMED;
1745a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    }
1755a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber
1765a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    unsigned FT = (header >> 3) & 0x0f;
1775a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber
1785a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    if (FT > 8 || (!mIsWide && FT > 7)) {
1795a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber        return ERROR_MALFORMED;
1805a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    }
1815a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber
1825a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    static const size_t kFrameSizeNB[8] = {
1835a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber        95, 103, 118, 134, 148, 159, 204, 244
1845a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    };
1855a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    static const size_t kFrameSizeWB[9] = {
1865a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber        132, 177, 253, 285, 317, 365, 397, 461, 477
1875a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    };
1885a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber
1895a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    size_t frameSize = mIsWide ? kFrameSizeWB[FT] : kFrameSizeNB[FT];
1905a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber
1915a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    // Round up bits to bytes and add 1 for the header byte.
1925a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    frameSize = (frameSize + 7) / 8 + 1;
1935a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber
1945a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    n = mDataSource->read_at(mOffset, buffer->data(), frameSize);
1955a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber
1965a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    if (n != (ssize_t)frameSize) {
1975a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber        buffer->release();
1985a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber        buffer = NULL;
1995a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber
2005a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber        return ERROR_IO;
2015a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    }
2025a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber
2035a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    buffer->set_range(0, frameSize);
204fa8de752507feaca695123911915070c1ce463b2Andreas Huber    buffer->meta_data()->setInt64(kKeyTime, mCurrentTimeUs);
2055a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber
2065a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    mOffset += frameSize;
2075a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    mCurrentTimeUs += 20000;  // Each frame is 20ms
2085a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber
2095a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    *out = buffer;
2105a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber
2115a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    return OK;
2125a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber}
2135a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber
2145a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber////////////////////////////////////////////////////////////////////////////////
2155a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber
2165a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huberbool SniffAMR(
2175a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber        const sp<DataSource> &source, String8 *mimeType, float *confidence) {
2185a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    char header[9];
2195a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber
2205a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    if (source->read_at(0, header, sizeof(header)) != sizeof(header)) {
2215a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber        return false;
2225a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    }
2235a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber
2245a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    if (!memcmp(header, "#!AMR\n", 6)) {
225e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber        *mimeType = MEDIA_MIMETYPE_AUDIO_AMR_NB;
2265a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber        *confidence = 0.5;
2275a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber
2285a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber        return true;
2295a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    } else if (!memcmp(header, "#!AMR-WB\n", 9)) {
230e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber        *mimeType = MEDIA_MIMETYPE_AUDIO_AMR_WB;
2315a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber        *confidence = 0.5;
2325a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber
2335a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber        return true;
2345a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    }
2355a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber
2365a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber    return false;
2375a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber}
2385a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber
2395a65a6e22017e51ebcebb0f41510c54f1085f82cAndreas Huber}  // namespace android
240