WAVExtractor.cpp revision 7be6407f2ad7f2b0782d195d9f792072c084d6f5
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 857be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Hubersp<MetaData> WAVExtractor::getMetaData() { 867be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber sp<MetaData> meta = new MetaData; 877be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 887be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber if (mInitCheck != OK) { 897be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber return meta; 907be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber } 917be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 927be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber meta->setCString(kKeyMIMEType, "audio/x-wav"); 937be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 947be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber return meta; 957be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber} 967be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 970dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Hubersize_t WAVExtractor::countTracks() { 980dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return mInitCheck == OK ? 1 : 0; 990dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 1000dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1010dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Hubersp<MediaSource> WAVExtractor::getTrack(size_t index) { 1020dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (mInitCheck != OK || index > 0) { 1030dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return NULL; 1040dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 1050dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1060dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return new WAVSource( 1070dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mDataSource, mSampleRate, mNumChannels, mDataOffset, mDataSize); 1080dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 1090dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1100dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Hubersp<MetaData> WAVExtractor::getTrackMetaData( 1110dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber size_t index, uint32_t flags) { 1120dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (mInitCheck != OK || index > 0) { 1130dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return NULL; 1140dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 1150dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1160dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber sp<MetaData> meta = new MetaData; 1170dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW); 1180dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber meta->setInt32(kKeyChannelCount, mNumChannels); 1190dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber meta->setInt32(kKeySampleRate, mSampleRate); 1200dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1210dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber int64_t durationUs = 1220dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1000000LL * (mDataSize / (mNumChannels * 2)) / mSampleRate; 1230dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1240dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber meta->setInt64(kKeyDuration, durationUs); 1250dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1260dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return meta; 1270dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 1280dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1290dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberstatus_t WAVExtractor::init() { 1300dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber uint8_t header[12]; 1310dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (mDataSource->readAt( 1320dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 0, header, sizeof(header)) < (ssize_t)sizeof(header)) { 1330dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return NO_INIT; 1340dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 1350dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1360dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (memcmp(header, "RIFF", 4) || memcmp(&header[8], "WAVE", 4)) { 1370dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return NO_INIT; 1380dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 1390dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1400dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber size_t totalSize = U32_LE_AT(&header[4]); 1410dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1420dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber off_t offset = 12; 1430dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber size_t remainingSize = totalSize; 1440dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber while (remainingSize >= 8) { 1450dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber uint8_t chunkHeader[8]; 1460dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (mDataSource->readAt(offset, chunkHeader, 8) < 8) { 1470dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return NO_INIT; 1480dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 1490dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1500dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber remainingSize -= 8; 1510dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber offset += 8; 1520dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1530dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber uint32_t chunkSize = U32_LE_AT(&chunkHeader[4]); 1540dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1550dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (chunkSize > remainingSize) { 1560dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return NO_INIT; 1570dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 1580dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1590dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (!memcmp(chunkHeader, "fmt ", 4)) { 1600dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (chunkSize < 16) { 1610dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return NO_INIT; 1620dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 1630dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1640dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber uint8_t formatSpec[16]; 1650dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (mDataSource->readAt(offset, formatSpec, 16) < 16) { 1660dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return NO_INIT; 1670dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 1680dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1690dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber uint16_t format = U16_LE_AT(formatSpec); 1700dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (format != WAVE_FORMAT_PCM) { 1710dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return ERROR_UNSUPPORTED; 1720dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 1730dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1740dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mNumChannels = U16_LE_AT(&formatSpec[2]); 1750dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (mNumChannels != 1 && mNumChannels != 2) { 1760dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return ERROR_UNSUPPORTED; 1770dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 1780dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1790dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mSampleRate = U32_LE_AT(&formatSpec[4]); 1800dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1810dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (U16_LE_AT(&formatSpec[14]) != 16) { 1820dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return ERROR_UNSUPPORTED; 1830dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 1840dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1850dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mValidFormat = true; 1860dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } else if (!memcmp(chunkHeader, "data", 4)) { 1870dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (mValidFormat) { 1880dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mDataOffset = offset; 1890dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mDataSize = chunkSize; 1900dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1910dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return OK; 1920dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 1930dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 1940dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1950dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber offset += chunkSize; 1960dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 1970dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1980dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return NO_INIT; 1990dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 2000dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2010dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberconst size_t WAVSource::kMaxFrameSize = 32768; 2020dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2030dba73763a04d39faf999dcc5ef12af3c99535a7Andreas HuberWAVSource::WAVSource( 2040dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber const sp<DataSource> &dataSource, 2050dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber int32_t sampleRate, int32_t numChannels, 2060dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber off_t offset, size_t size) 2070dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber : mDataSource(dataSource), 2080dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mSampleRate(sampleRate), 2090dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mNumChannels(numChannels), 2100dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mOffset(offset), 2110dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mSize(size), 2120dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mStarted(false), 2130dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mGroup(NULL) { 2140dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 2150dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2160dba73763a04d39faf999dcc5ef12af3c99535a7Andreas HuberWAVSource::~WAVSource() { 2170dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (mStarted) { 2180dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber stop(); 2190dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 2200dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 2210dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2220dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberstatus_t WAVSource::start(MetaData *params) { 2230dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber LOGV("WAVSource::start"); 2240dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2250dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber CHECK(!mStarted); 2260dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2270dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mGroup = new MediaBufferGroup; 2280dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mGroup->add_buffer(new MediaBuffer(kMaxFrameSize)); 2290dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2300dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mCurrentPos = mOffset; 2310dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2320dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mStarted = true; 2330dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2340dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return OK; 2350dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 2360dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2370dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberstatus_t WAVSource::stop() { 2380dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber LOGV("WAVSource::stop"); 2390dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2400dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber CHECK(mStarted); 2410dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2420dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber delete mGroup; 2430dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mGroup = NULL; 2440dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2450dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mStarted = false; 2460dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2470dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return OK; 2480dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 2490dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2500dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Hubersp<MetaData> WAVSource::getFormat() { 2510dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber LOGV("WAVSource::getFormat"); 2520dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2530dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber sp<MetaData> meta = new MetaData; 2540dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW); 2550dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber meta->setInt32(kKeyChannelCount, mNumChannels); 2560dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber meta->setInt32(kKeySampleRate, mSampleRate); 2570dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2580dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber int64_t durationUs = 2590dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1000000LL * (mSize / (mNumChannels * 2)) / mSampleRate; 2600dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2610dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber meta->setInt64(kKeyDuration, durationUs); 2620dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2630dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return meta; 2640dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 2650dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2660dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberstatus_t WAVSource::read( 2670dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber MediaBuffer **out, const ReadOptions *options) { 2680dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber *out = NULL; 2690dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2700dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber int64_t seekTimeUs; 2710dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (options != NULL && options->getSeekTo(&seekTimeUs)) { 2720dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber int64_t pos = (seekTimeUs * mSampleRate) / 1000000 * mNumChannels * 2; 2730dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (pos > mSize) { 2740dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber pos = mSize; 2750dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 2760dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mCurrentPos = pos + mOffset; 2770dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 2780dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2790dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber MediaBuffer *buffer; 2800dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber status_t err = mGroup->acquire_buffer(&buffer); 2810dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (err != OK) { 2820dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return err; 2830dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 2840dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2850dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber ssize_t n = mDataSource->readAt( 2860dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mCurrentPos, buffer->data(), kMaxFrameSize); 2870dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2880dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (n <= 0) { 2890dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber buffer->release(); 2900dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber buffer = NULL; 2910dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2920dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return ERROR_END_OF_STREAM; 2930dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 2940dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2950dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mCurrentPos += n; 2960dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2970dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber buffer->set_range(0, n); 2980dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber buffer->meta_data()->setInt64( 2990dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber kKeyTime, 3000dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1000000LL * (mCurrentPos - mOffset) 3010dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber / (mNumChannels * 2) / mSampleRate); 3020dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3030dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3040dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber *out = buffer; 3050dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3060dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return OK; 3070dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 3080dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3090dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber//////////////////////////////////////////////////////////////////////////////// 3100dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3110dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberbool SniffWAV( 3120dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence) { 3130dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber char header[12]; 3140dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (source->readAt(0, header, sizeof(header)) < (ssize_t)sizeof(header)) { 3150dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return false; 3160dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 3170dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3180dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (memcmp(header, "RIFF", 4) || memcmp(&header[8], "WAVE", 4)) { 3190dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return false; 3200dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 3210dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3220dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber *mimeType = MEDIA_MIMETYPE_CONTAINER_WAV; 3230dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber *confidence = 0.3f; 3240dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3250dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return true; 3260dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 3270dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3280dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} // namespace android 3290dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 330