AMRExtractor.cpp revision f75978f63a25e79c683e96611f95cb5cd49efd3d
1f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber/* 2f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber * Copyright (C) 2009 The Android Open Source Project 3f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber * 4f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 5f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber * you may not use this file except in compliance with the License. 6f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber * You may obtain a copy of the License at 7f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber * 8f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber * http://www.apache.org/licenses/LICENSE-2.0 9f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber * 10f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber * Unless required by applicable law or agreed to in writing, software 11f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 12f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber * See the License for the specific language governing permissions and 14f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber * limitations under the License. 15f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber */ 16f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber 17f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber//#define LOG_NDEBUG 0 18f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber#define LOG_TAG "AMRExtractor" 19f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber#include <utils/Log.h> 20f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber 21f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber#include <media/stagefright/AMRExtractor.h> 22f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber#include <media/stagefright/DataSource.h> 23f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber#include <media/stagefright/MediaBufferGroup.h> 24f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber#include <media/stagefright/MediaDebug.h> 25f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber#include <media/stagefright/MediaErrors.h> 26f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber#include <media/stagefright/MediaSource.h> 27f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber#include <media/stagefright/MetaData.h> 28f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber#include <utils/String8.h> 29f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber 30f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Hubernamespace android { 31f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber 32f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huberclass AMRSource : public MediaSource { 33f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huberpublic: 34f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber AMRSource(const sp<DataSource> &source, bool isWide); 35f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber 36f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber virtual status_t start(MetaData *params = NULL); 37f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber virtual status_t stop(); 38f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber 39f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber virtual sp<MetaData> getFormat(); 40f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber 41f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber virtual status_t read( 42f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber MediaBuffer **buffer, const ReadOptions *options = NULL); 43f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber 44f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huberprotected: 45f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber virtual ~AMRSource(); 46f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber 47f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huberprivate: 48f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber sp<DataSource> mDataSource; 49f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber bool mIsWide; 50f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber 51f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber off_t mOffset; 52f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber int64_t mCurrentTimeUs; 53f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber bool mStarted; 54f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber MediaBufferGroup *mGroup; 55f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber 56f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber AMRSource(const AMRSource &); 57f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber AMRSource &operator=(const AMRSource &); 58f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber}; 59f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber 60f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber//////////////////////////////////////////////////////////////////////////////// 61f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber 62f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas HuberAMRExtractor::AMRExtractor(const sp<DataSource> &source) 63f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber : mDataSource(source), 64f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber mInitCheck(NO_INIT) { 65f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber String8 mimeType; 66f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber float confidence; 67f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber if (SniffAMR(mDataSource, &mimeType, &confidence)) { 68f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber mInitCheck = OK; 69f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber mIsWide = (mimeType == "audio/amr-wb"); 70f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber } 71f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber} 72f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber 73f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas HuberAMRExtractor::~AMRExtractor() { 74f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber} 75f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber 76f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Hubersize_t AMRExtractor::countTracks() { 77f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber return mInitCheck == OK ? 1 : 0; 78f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber} 79f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber 80f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Hubersp<MediaSource> AMRExtractor::getTrack(size_t index) { 81f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber if (mInitCheck != OK || index != 0) { 82f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber return NULL; 83f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber } 84f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber 85f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber return new AMRSource(mDataSource, mIsWide); 86f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber} 87f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber 88f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Hubersp<MetaData> AMRExtractor::getTrackMetaData(size_t index) { 89f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber if (mInitCheck != OK || index != 0) { 90f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber return NULL; 91f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber } 92f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber 93f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber return makeAMRFormat(mIsWide); 94f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber} 95f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber 96f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber// static 97f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Hubersp<MetaData> AMRExtractor::makeAMRFormat(bool isWide) { 98f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber sp<MetaData> meta = new MetaData; 99f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber meta->setCString(kKeyMIMEType, isWide ? "audio/amr-wb" : "audio/3gpp"); 100f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber meta->setInt32(kKeyChannelCount, 1); 101f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber meta->setInt32(kKeySampleRate, isWide ? 16000 : 8000); 102f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber 103f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber return meta; 104f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber} 105f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber 106f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber//////////////////////////////////////////////////////////////////////////////// 107f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber 108f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas HuberAMRSource::AMRSource(const sp<DataSource> &source, bool isWide) 109f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber : mDataSource(source), 110f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber mIsWide(isWide), 111f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber mOffset(mIsWide ? 9 : 6), 112f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber mCurrentTimeUs(0), 113f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber mStarted(false), 114f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber mGroup(NULL) { 115f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber} 116f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber 117f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas HuberAMRSource::~AMRSource() { 118f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber if (mStarted) { 119f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber stop(); 120f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber } 121f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber} 122f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber 123f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huberstatus_t AMRSource::start(MetaData *params) { 124f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber CHECK(!mStarted); 125f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber 126f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber mOffset = mIsWide ? 9 : 6; 127f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber mCurrentTimeUs = 0; 128f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber mGroup = new MediaBufferGroup; 129f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber mGroup->add_buffer(new MediaBuffer(128)); 130f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber mStarted = true; 131f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber 132f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber return OK; 133f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber} 134f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber 135f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huberstatus_t AMRSource::stop() { 136f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber CHECK(mStarted); 137f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber 138f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber delete mGroup; 139f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber mGroup = NULL; 140f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber 141f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber mStarted = false; 142f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber return OK; 143f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber} 144f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber 145f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Hubersp<MetaData> AMRSource::getFormat() { 146f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber return AMRExtractor::makeAMRFormat(mIsWide); 147f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber} 148f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber 149f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huberstatus_t AMRSource::read( 150f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber MediaBuffer **out, const ReadOptions *options) { 151f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber *out = NULL; 152f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber 153f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber uint8_t header; 154f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber ssize_t n = mDataSource->read_at(mOffset, &header, 1); 155f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber 156f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber if (n < 1) { 157f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber return ERROR_IO; 158f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber } 159f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber 160f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber MediaBuffer *buffer; 161f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber status_t err = mGroup->acquire_buffer(&buffer); 162f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber if (err != OK) { 163f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber return err; 164f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber } 165f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber 166f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber if (header & 0x83) { 167f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber // Padding bits must be 0. 168f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber 169f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber return ERROR_MALFORMED; 170f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber } 171f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber 172f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber unsigned FT = (header >> 3) & 0x0f; 173f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber 174f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber if (FT > 8 || (!mIsWide && FT > 7)) { 175f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber return ERROR_MALFORMED; 176f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber } 177f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber 178f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber static const size_t kFrameSizeNB[8] = { 179f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber 95, 103, 118, 134, 148, 159, 204, 244 180f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber }; 181f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber static const size_t kFrameSizeWB[9] = { 182f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber 132, 177, 253, 285, 317, 365, 397, 461, 477 183f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber }; 184f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber 185f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber size_t frameSize = mIsWide ? kFrameSizeWB[FT] : kFrameSizeNB[FT]; 186f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber 187f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber // Round up bits to bytes and add 1 for the header byte. 188f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber frameSize = (frameSize + 7) / 8 + 1; 189f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber 190f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber n = mDataSource->read_at(mOffset, buffer->data(), frameSize); 191f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber 192f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber if (n != (ssize_t)frameSize) { 193f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber buffer->release(); 194f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber buffer = NULL; 195f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber 196f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber return ERROR_IO; 197f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber } 198f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber 199f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber buffer->set_range(0, frameSize); 200f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber buffer->meta_data()->setInt32( 201f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber kKeyTimeUnits, (mCurrentTimeUs + 500) / 1000); 202f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber buffer->meta_data()->setInt32( 203f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber kKeyTimeScale, 1000); 204f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber 205f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber mOffset += frameSize; 206f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber mCurrentTimeUs += 20000; // Each frame is 20ms 207f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber 208f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber *out = buffer; 209f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber 210f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber return OK; 211f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber} 212f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber 213f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber//////////////////////////////////////////////////////////////////////////////// 214f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber 215f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huberbool SniffAMR( 216f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence) { 217f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber char header[9]; 218f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber 219f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber if (source->read_at(0, header, sizeof(header)) != sizeof(header)) { 220f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber return false; 221f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber } 222f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber 223f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber if (!memcmp(header, "#!AMR\n", 6)) { 224f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber *mimeType = "audio/3gpp"; 225f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber *confidence = 0.5; 226f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber 227f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber return true; 228f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber } else if (!memcmp(header, "#!AMR-WB\n", 9)) { 229f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber *mimeType = "audio/amr-wb"; 230f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber *confidence = 0.5; 231f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber 232f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber return true; 233f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber } 234f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber 235f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber return false; 236f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber} 237f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber 238f75978f63a25e79c683e96611f95cb5cd49efd3dAndreas Huber} // namespace android 239