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