WAVExtractor.cpp revision 0dba73763a04d39faf999dcc5ef12af3c99535a7
10dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber/* 20dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber * Copyright (C) 2009 The Android Open Source Project 30dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber * 40dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 50dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber * you may not use this file except in compliance with the License. 60dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber * You may obtain a copy of the License at 70dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber * 80dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber * http://www.apache.org/licenses/LICENSE-2.0 90dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber * 100dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber * Unless required by applicable law or agreed to in writing, software 110dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 120dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 130dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber * See the License for the specific language governing permissions and 140dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber * limitations under the License. 150dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber */ 160dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 170dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber//#define LOG_NDEBUG 0 180dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber#define LOG_TAG "WAVExtractor" 190dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber#include <utils/Log.h> 200dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 210dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber#include "include/WAVExtractor.h" 220dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 230dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber#include <media/stagefright/DataSource.h> 240dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber#include <media/stagefright/MediaBufferGroup.h> 250dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber#include <media/stagefright/MediaDebug.h> 260dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber#include <media/stagefright/MediaDefs.h> 270dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber#include <media/stagefright/MediaErrors.h> 280dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber#include <media/stagefright/MediaSource.h> 290dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber#include <media/stagefright/MetaData.h> 300dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber#include <utils/String8.h> 310dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 320dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Hubernamespace android { 330dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 340dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberstatic uint16_t WAVE_FORMAT_PCM = 1; 350dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 360dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberstatic uint32_t U32_LE_AT(const uint8_t *ptr) { 370dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return ptr[3] << 24 | ptr[2] << 16 | ptr[1] << 8 | ptr[0]; 380dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 390dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 400dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberstatic uint16_t U16_LE_AT(const uint8_t *ptr) { 410dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return ptr[1] << 8 | ptr[0]; 420dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 430dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 440dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberstruct WAVSource : public MediaSource { 450dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber WAVSource( 460dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber const sp<DataSource> &dataSource, 470dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber int32_t sampleRate, int32_t numChannels, 480dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber off_t offset, size_t size); 490dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 500dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber virtual status_t start(MetaData *params = NULL); 510dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber virtual status_t stop(); 520dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber virtual sp<MetaData> getFormat(); 530dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 540dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber virtual status_t read( 550dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber MediaBuffer **buffer, const ReadOptions *options = NULL); 560dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 570dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberprotected: 580dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber virtual ~WAVSource(); 590dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 600dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberprivate: 610dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber static const size_t kMaxFrameSize; 620dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 630dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber sp<DataSource> mDataSource; 640dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber int32_t mSampleRate; 650dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber int32_t mNumChannels; 660dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber off_t mOffset; 670dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber size_t mSize; 680dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber bool mStarted; 690dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber MediaBufferGroup *mGroup; 700dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber off_t mCurrentPos; 710dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 720dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber WAVSource(const WAVSource &); 730dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber WAVSource &operator=(const WAVSource &); 740dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}; 750dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 760dba73763a04d39faf999dcc5ef12af3c99535a7Andreas HuberWAVExtractor::WAVExtractor(const sp<DataSource> &source) 770dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber : mDataSource(source), 780dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mValidFormat(false) { 790dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mInitCheck = init(); 800dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 810dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 820dba73763a04d39faf999dcc5ef12af3c99535a7Andreas HuberWAVExtractor::~WAVExtractor() { 830dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 840dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 850dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Hubersize_t WAVExtractor::countTracks() { 860dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return mInitCheck == OK ? 1 : 0; 870dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 880dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 890dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Hubersp<MediaSource> WAVExtractor::getTrack(size_t index) { 900dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (mInitCheck != OK || index > 0) { 910dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return NULL; 920dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 930dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 940dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return new WAVSource( 950dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mDataSource, mSampleRate, mNumChannels, mDataOffset, mDataSize); 960dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 970dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 980dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Hubersp<MetaData> WAVExtractor::getTrackMetaData( 990dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber size_t index, uint32_t flags) { 1000dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (mInitCheck != OK || index > 0) { 1010dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return NULL; 1020dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 1030dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1040dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber sp<MetaData> meta = new MetaData; 1050dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW); 1060dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber meta->setInt32(kKeyChannelCount, mNumChannels); 1070dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber meta->setInt32(kKeySampleRate, mSampleRate); 1080dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1090dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber int64_t durationUs = 1100dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1000000LL * (mDataSize / (mNumChannels * 2)) / mSampleRate; 1110dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1120dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber meta->setInt64(kKeyDuration, durationUs); 1130dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1140dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return meta; 1150dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 1160dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1170dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberstatus_t WAVExtractor::init() { 1180dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber uint8_t header[12]; 1190dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (mDataSource->readAt( 1200dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 0, header, sizeof(header)) < (ssize_t)sizeof(header)) { 1210dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return NO_INIT; 1220dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 1230dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1240dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (memcmp(header, "RIFF", 4) || memcmp(&header[8], "WAVE", 4)) { 1250dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return NO_INIT; 1260dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 1270dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1280dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber size_t totalSize = U32_LE_AT(&header[4]); 1290dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1300dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber off_t offset = 12; 1310dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber size_t remainingSize = totalSize; 1320dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber while (remainingSize >= 8) { 1330dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber uint8_t chunkHeader[8]; 1340dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (mDataSource->readAt(offset, chunkHeader, 8) < 8) { 1350dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return NO_INIT; 1360dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 1370dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1380dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber remainingSize -= 8; 1390dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber offset += 8; 1400dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1410dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber uint32_t chunkSize = U32_LE_AT(&chunkHeader[4]); 1420dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1430dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (chunkSize > remainingSize) { 1440dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return NO_INIT; 1450dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 1460dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1470dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (!memcmp(chunkHeader, "fmt ", 4)) { 1480dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (chunkSize < 16) { 1490dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return NO_INIT; 1500dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 1510dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1520dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber uint8_t formatSpec[16]; 1530dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (mDataSource->readAt(offset, formatSpec, 16) < 16) { 1540dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return NO_INIT; 1550dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 1560dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1570dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber uint16_t format = U16_LE_AT(formatSpec); 1580dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (format != WAVE_FORMAT_PCM) { 1590dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return ERROR_UNSUPPORTED; 1600dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 1610dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1620dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mNumChannels = U16_LE_AT(&formatSpec[2]); 1630dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (mNumChannels != 1 && mNumChannels != 2) { 1640dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return ERROR_UNSUPPORTED; 1650dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 1660dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1670dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mSampleRate = U32_LE_AT(&formatSpec[4]); 1680dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1690dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (U16_LE_AT(&formatSpec[14]) != 16) { 1700dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return ERROR_UNSUPPORTED; 1710dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 1720dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1730dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mValidFormat = true; 1740dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } else if (!memcmp(chunkHeader, "data", 4)) { 1750dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (mValidFormat) { 1760dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mDataOffset = offset; 1770dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mDataSize = chunkSize; 1780dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1790dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return OK; 1800dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 1810dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 1820dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1830dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber offset += chunkSize; 1840dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 1850dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1860dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return NO_INIT; 1870dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 1880dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1890dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberconst size_t WAVSource::kMaxFrameSize = 32768; 1900dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1910dba73763a04d39faf999dcc5ef12af3c99535a7Andreas HuberWAVSource::WAVSource( 1920dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber const sp<DataSource> &dataSource, 1930dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber int32_t sampleRate, int32_t numChannels, 1940dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber off_t offset, size_t size) 1950dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber : mDataSource(dataSource), 1960dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mSampleRate(sampleRate), 1970dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mNumChannels(numChannels), 1980dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mOffset(offset), 1990dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mSize(size), 2000dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mStarted(false), 2010dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mGroup(NULL) { 2020dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 2030dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2040dba73763a04d39faf999dcc5ef12af3c99535a7Andreas HuberWAVSource::~WAVSource() { 2050dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (mStarted) { 2060dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber stop(); 2070dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 2080dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 2090dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2100dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberstatus_t WAVSource::start(MetaData *params) { 2110dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber LOGV("WAVSource::start"); 2120dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2130dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber CHECK(!mStarted); 2140dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2150dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mGroup = new MediaBufferGroup; 2160dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mGroup->add_buffer(new MediaBuffer(kMaxFrameSize)); 2170dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2180dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mCurrentPos = mOffset; 2190dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2200dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mStarted = true; 2210dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2220dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return OK; 2230dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 2240dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2250dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberstatus_t WAVSource::stop() { 2260dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber LOGV("WAVSource::stop"); 2270dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2280dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber CHECK(mStarted); 2290dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2300dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber delete mGroup; 2310dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mGroup = NULL; 2320dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2330dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mStarted = false; 2340dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2350dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return OK; 2360dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 2370dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2380dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Hubersp<MetaData> WAVSource::getFormat() { 2390dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber LOGV("WAVSource::getFormat"); 2400dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2410dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber sp<MetaData> meta = new MetaData; 2420dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW); 2430dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber meta->setInt32(kKeyChannelCount, mNumChannels); 2440dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber meta->setInt32(kKeySampleRate, mSampleRate); 2450dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2460dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber int64_t durationUs = 2470dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1000000LL * (mSize / (mNumChannels * 2)) / mSampleRate; 2480dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2490dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber meta->setInt64(kKeyDuration, durationUs); 2500dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2510dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return meta; 2520dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 2530dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2540dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberstatus_t WAVSource::read( 2550dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber MediaBuffer **out, const ReadOptions *options) { 2560dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber *out = NULL; 2570dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2580dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber int64_t seekTimeUs; 2590dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (options != NULL && options->getSeekTo(&seekTimeUs)) { 2600dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber int64_t pos = (seekTimeUs * mSampleRate) / 1000000 * mNumChannels * 2; 2610dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (pos > mSize) { 2620dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber pos = mSize; 2630dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 2640dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mCurrentPos = pos + mOffset; 2650dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 2660dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2670dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber MediaBuffer *buffer; 2680dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber status_t err = mGroup->acquire_buffer(&buffer); 2690dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (err != OK) { 2700dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return err; 2710dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 2720dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2730dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber ssize_t n = mDataSource->readAt( 2740dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mCurrentPos, buffer->data(), kMaxFrameSize); 2750dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2760dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (n <= 0) { 2770dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber buffer->release(); 2780dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber buffer = NULL; 2790dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2800dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return ERROR_END_OF_STREAM; 2810dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 2820dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2830dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mCurrentPos += n; 2840dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2850dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber buffer->set_range(0, n); 2860dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber buffer->meta_data()->setInt64( 2870dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber kKeyTime, 2880dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1000000LL * (mCurrentPos - mOffset) 2890dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber / (mNumChannels * 2) / mSampleRate); 2900dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2910dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2920dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber *out = buffer; 2930dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2940dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return OK; 2950dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 2960dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2970dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber//////////////////////////////////////////////////////////////////////////////// 2980dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2990dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberbool SniffWAV( 3000dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence) { 3010dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber char header[12]; 3020dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (source->readAt(0, header, sizeof(header)) < (ssize_t)sizeof(header)) { 3030dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return false; 3040dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 3050dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3060dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (memcmp(header, "RIFF", 4) || memcmp(&header[8], "WAVE", 4)) { 3070dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return false; 3080dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 3090dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3100dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber *mimeType = MEDIA_MIMETYPE_CONTAINER_WAV; 3110dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber *confidence = 0.3f; 3120dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3130dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return true; 3140dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 3150dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3160dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} // namespace android 3170dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 318