WAVExtractor.cpp revision c7fc37a3dab9bd1f96713649f351b5990e6316ff
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
3442d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huberenum {
3542d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber    WAVE_FORMAT_PCM = 1,
3642d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber    WAVE_FORMAT_ALAW = 6,
3742d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber    WAVE_FORMAT_MULAW = 7,
3842d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber};
390dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
400dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberstatic uint32_t U32_LE_AT(const uint8_t *ptr) {
410dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    return ptr[3] << 24 | ptr[2] << 16 | ptr[1] << 8 | ptr[0];
420dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}
430dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
440dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberstatic uint16_t U16_LE_AT(const uint8_t *ptr) {
450dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    return ptr[1] << 8 | ptr[0];
460dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}
470dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
480dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberstruct WAVSource : public MediaSource {
490dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    WAVSource(
500dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            const sp<DataSource> &dataSource,
51f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber            const sp<MetaData> &meta,
5242d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber            uint16_t waveFormat,
53f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber            int32_t bitsPerSample,
54c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong            off64_t offset, size_t size);
550dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
560dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    virtual status_t start(MetaData *params = NULL);
570dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    virtual status_t stop();
580dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    virtual sp<MetaData> getFormat();
590dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
600dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    virtual status_t read(
610dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            MediaBuffer **buffer, const ReadOptions *options = NULL);
620dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
630dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberprotected:
640dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    virtual ~WAVSource();
650dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
660dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberprivate:
670dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    static const size_t kMaxFrameSize;
680dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
690dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    sp<DataSource> mDataSource;
70f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber    sp<MetaData> mMeta;
7142d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber    uint16_t mWaveFormat;
720dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    int32_t mSampleRate;
730dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    int32_t mNumChannels;
74f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber    int32_t mBitsPerSample;
75c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong    off64_t mOffset;
760dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    size_t mSize;
770dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    bool mStarted;
780dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    MediaBufferGroup *mGroup;
79c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong    off64_t mCurrentPos;
800dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
810dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    WAVSource(const WAVSource &);
820dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    WAVSource &operator=(const WAVSource &);
830dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber};
840dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
850dba73763a04d39faf999dcc5ef12af3c99535a7Andreas HuberWAVExtractor::WAVExtractor(const sp<DataSource> &source)
860dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    : mDataSource(source),
870dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber      mValidFormat(false) {
880dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    mInitCheck = init();
890dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}
900dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
910dba73763a04d39faf999dcc5ef12af3c99535a7Andreas HuberWAVExtractor::~WAVExtractor() {
920dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}
930dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
947be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Hubersp<MetaData> WAVExtractor::getMetaData() {
957be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber    sp<MetaData> meta = new MetaData;
967be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber
977be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber    if (mInitCheck != OK) {
987be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber        return meta;
997be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber    }
1007be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber
1017be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber    meta->setCString(kKeyMIMEType, "audio/x-wav");
1027be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber
1037be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber    return meta;
1047be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber}
1057be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber
1060dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Hubersize_t WAVExtractor::countTracks() {
1070dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    return mInitCheck == OK ? 1 : 0;
1080dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}
1090dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
1100dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Hubersp<MediaSource> WAVExtractor::getTrack(size_t index) {
1110dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    if (mInitCheck != OK || index > 0) {
1120dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        return NULL;
1130dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    }
1140dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
1150dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    return new WAVSource(
116f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber            mDataSource, mTrackMeta,
11742d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber            mWaveFormat, mBitsPerSample, mDataOffset, mDataSize);
1180dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}
1190dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
1200dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Hubersp<MetaData> WAVExtractor::getTrackMetaData(
1210dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        size_t index, uint32_t flags) {
1220dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    if (mInitCheck != OK || index > 0) {
1230dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        return NULL;
1240dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    }
1250dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
126f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber    return mTrackMeta;
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
142c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong    off64_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;
152f99f049dd228333e3d6f886efe373f8e461ff2daAndreas 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
16942d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber            mWaveFormat = U16_LE_AT(formatSpec);
17042d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber            if (mWaveFormat != WAVE_FORMAT_PCM
17142d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                    && mWaveFormat != WAVE_FORMAT_ALAW
17242d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                    && mWaveFormat != WAVE_FORMAT_MULAW) {
1730dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber                return ERROR_UNSUPPORTED;
1740dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            }
1750dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
1760dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            mNumChannels = U16_LE_AT(&formatSpec[2]);
1770dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            if (mNumChannels != 1 && mNumChannels != 2) {
1780dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber                return ERROR_UNSUPPORTED;
1790dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            }
1800dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
1810dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            mSampleRate = U32_LE_AT(&formatSpec[4]);
1820dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
183f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber            if (mSampleRate == 0) {
184f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber                return ERROR_MALFORMED;
185f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber            }
186f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber
187f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber            mBitsPerSample = U16_LE_AT(&formatSpec[14]);
188f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber
18942d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber            if (mWaveFormat == WAVE_FORMAT_PCM) {
19042d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                if (mBitsPerSample != 8 && mBitsPerSample != 16
19142d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                    && mBitsPerSample != 24) {
19242d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                    return ERROR_UNSUPPORTED;
19342d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                }
19442d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber            } else {
19542d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                CHECK(mWaveFormat == WAVE_FORMAT_MULAW
19642d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                        || mWaveFormat == WAVE_FORMAT_ALAW);
19742d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                if (mBitsPerSample != 8) {
19842d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                    return ERROR_UNSUPPORTED;
19942d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                }
2000dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            }
2010dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
2020dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            mValidFormat = true;
2030dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        } else if (!memcmp(chunkHeader, "data", 4)) {
2040dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            if (mValidFormat) {
2050dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber                mDataOffset = offset;
2060dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber                mDataSize = chunkSize;
2070dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
208f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber                mTrackMeta = new MetaData;
20942d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber
21042d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                switch (mWaveFormat) {
21142d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                    case WAVE_FORMAT_PCM:
21242d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                        mTrackMeta->setCString(
21342d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                                kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
21442d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                        break;
21542d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                    case WAVE_FORMAT_ALAW:
21642d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                        mTrackMeta->setCString(
21742d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                                kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_G711_ALAW);
21842d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                        break;
21942d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                    default:
22042d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                        CHECK_EQ(mWaveFormat, WAVE_FORMAT_MULAW);
22142d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                        mTrackMeta->setCString(
22242d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                                kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_G711_MLAW);
22342d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                        break;
22442d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                }
22542d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber
226f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber                mTrackMeta->setInt32(kKeyChannelCount, mNumChannels);
227f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber                mTrackMeta->setInt32(kKeySampleRate, mSampleRate);
228f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber
229f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber                size_t bytesPerSample = mBitsPerSample >> 3;
230f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber
231f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber                int64_t durationUs =
232f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber                    1000000LL * (mDataSize / (mNumChannels * bytesPerSample))
233f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber                        / mSampleRate;
234f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber
235f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber                mTrackMeta->setInt64(kKeyDuration, durationUs);
236f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber
2370dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber                return OK;
2380dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            }
2390dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        }
2400dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
2410dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        offset += chunkSize;
2420dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    }
2430dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
2440dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    return NO_INIT;
2450dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}
2460dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
2470dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberconst size_t WAVSource::kMaxFrameSize = 32768;
2480dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
2490dba73763a04d39faf999dcc5ef12af3c99535a7Andreas HuberWAVSource::WAVSource(
2500dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        const sp<DataSource> &dataSource,
251f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber        const sp<MetaData> &meta,
25242d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber        uint16_t waveFormat,
253f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber        int32_t bitsPerSample,
254c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong        off64_t offset, size_t size)
2550dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    : mDataSource(dataSource),
256f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber      mMeta(meta),
25742d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber      mWaveFormat(waveFormat),
258f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber      mSampleRate(0),
259f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber      mNumChannels(0),
260f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber      mBitsPerSample(bitsPerSample),
2610dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber      mOffset(offset),
2620dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber      mSize(size),
2630dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber      mStarted(false),
2640dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber      mGroup(NULL) {
265f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber    CHECK(mMeta->findInt32(kKeySampleRate, &mSampleRate));
266f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber    CHECK(mMeta->findInt32(kKeyChannelCount, &mNumChannels));
2670dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}
2680dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
2690dba73763a04d39faf999dcc5ef12af3c99535a7Andreas HuberWAVSource::~WAVSource() {
2700dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    if (mStarted) {
2710dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        stop();
2720dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    }
2730dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}
2740dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
2750dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberstatus_t WAVSource::start(MetaData *params) {
2760dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    LOGV("WAVSource::start");
2770dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
2780dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    CHECK(!mStarted);
2790dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
2800dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    mGroup = new MediaBufferGroup;
2810dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    mGroup->add_buffer(new MediaBuffer(kMaxFrameSize));
2820dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
283f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber    if (mBitsPerSample == 8) {
284f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber        // As a temporary buffer for 8->16 bit conversion.
285f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber        mGroup->add_buffer(new MediaBuffer(kMaxFrameSize));
286f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber    }
287f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber
2880dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    mCurrentPos = mOffset;
2890dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
2900dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    mStarted = true;
2910dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
2920dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    return OK;
2930dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}
2940dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
2950dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberstatus_t WAVSource::stop() {
2960dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    LOGV("WAVSource::stop");
2970dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
2980dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    CHECK(mStarted);
2990dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
3000dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    delete mGroup;
3010dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    mGroup = NULL;
3020dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
3030dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    mStarted = false;
3040dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
3050dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    return OK;
3060dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}
3070dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
3080dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Hubersp<MetaData> WAVSource::getFormat() {
3090dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    LOGV("WAVSource::getFormat");
3100dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
311f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber    return mMeta;
3120dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}
3130dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
3140dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberstatus_t WAVSource::read(
3150dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        MediaBuffer **out, const ReadOptions *options) {
3160dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    *out = NULL;
3170dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
3180dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    int64_t seekTimeUs;
319abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    ReadOptions::SeekMode mode;
320abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    if (options != NULL && options->getSeekTo(&seekTimeUs, &mode)) {
3210dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        int64_t pos = (seekTimeUs * mSampleRate) / 1000000 * mNumChannels * 2;
3220dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        if (pos > mSize) {
3230dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            pos = mSize;
3240dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        }
3250dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        mCurrentPos = pos + mOffset;
3260dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    }
3270dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
3280dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    MediaBuffer *buffer;
3290dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    status_t err = mGroup->acquire_buffer(&buffer);
3300dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    if (err != OK) {
3310dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        return err;
3320dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    }
3330dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
334104fcb88d4125caff74f63be4ce23537ca693ac7Andreas Huber    size_t maxBytesToRead =
335104fcb88d4125caff74f63be4ce23537ca693ac7Andreas Huber        mBitsPerSample == 8 ? kMaxFrameSize / 2 : kMaxFrameSize;
336104fcb88d4125caff74f63be4ce23537ca693ac7Andreas Huber
337104fcb88d4125caff74f63be4ce23537ca693ac7Andreas Huber    size_t maxBytesAvailable =
338c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong        (mCurrentPos - mOffset >= (off64_t)mSize)
339104fcb88d4125caff74f63be4ce23537ca693ac7Andreas Huber            ? 0 : mSize - (mCurrentPos - mOffset);
340104fcb88d4125caff74f63be4ce23537ca693ac7Andreas Huber
341104fcb88d4125caff74f63be4ce23537ca693ac7Andreas Huber    if (maxBytesToRead > maxBytesAvailable) {
342104fcb88d4125caff74f63be4ce23537ca693ac7Andreas Huber        maxBytesToRead = maxBytesAvailable;
343104fcb88d4125caff74f63be4ce23537ca693ac7Andreas Huber    }
344104fcb88d4125caff74f63be4ce23537ca693ac7Andreas Huber
3450dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    ssize_t n = mDataSource->readAt(
346f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber            mCurrentPos, buffer->data(),
347104fcb88d4125caff74f63be4ce23537ca693ac7Andreas Huber            maxBytesToRead);
3480dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
3490dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    if (n <= 0) {
3500dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        buffer->release();
3510dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        buffer = NULL;
3520dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
3530dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        return ERROR_END_OF_STREAM;
3540dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    }
3550dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
3560dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    mCurrentPos += n;
3570dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
3580dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    buffer->set_range(0, n);
359f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber
36042d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber    if (mWaveFormat == WAVE_FORMAT_PCM) {
36142d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber        if (mBitsPerSample == 8) {
36242d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber            // Convert 8-bit unsigned samples to 16-bit signed.
363f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber
36442d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber            MediaBuffer *tmp;
36542d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber            CHECK_EQ(mGroup->acquire_buffer(&tmp), OK);
366f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber
36742d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber            // The new buffer holds the sample number of samples, but each
36842d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber            // one is 2 bytes wide.
36942d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber            tmp->set_range(0, 2 * n);
370f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber
37142d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber            int16_t *dst = (int16_t *)tmp->data();
37242d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber            const uint8_t *src = (const uint8_t *)buffer->data();
37342d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber            while (n-- > 0) {
37442d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                *dst++ = ((int16_t)(*src) - 128) * 256;
37542d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                ++src;
37642d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber            }
377f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber
37842d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber            buffer->release();
37942d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber            buffer = tmp;
38042d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber        } else if (mBitsPerSample == 24) {
38142d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber            // Convert 24-bit signed samples to 16-bit signed.
38242d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber
38342d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber            const uint8_t *src =
38442d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                (const uint8_t *)buffer->data() + buffer->range_offset();
38542d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber            int16_t *dst = (int16_t *)src;
38642d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber
38742d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber            size_t numSamples = buffer->range_length() / 3;
38842d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber            for (size_t i = 0; i < numSamples; ++i) {
38942d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                int32_t x = (int32_t)(src[0] | src[1] << 8 | src[2] << 16);
39042d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                x = (x << 8) >> 8;  // sign extension
391984d8f40c15e7fd757a9fdc007aad75549aa0fceAndreas Huber
39242d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                x = x >> 8;
39342d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                *dst++ = (int16_t)x;
39442d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                src += 3;
39542d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber            }
39642d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber
39742d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber            buffer->set_range(buffer->range_offset(), 2 * numSamples);
39842d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber        }
399f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber    }
400f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber
401f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber    size_t bytesPerSample = mBitsPerSample >> 3;
402f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber
4030dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    buffer->meta_data()->setInt64(
4040dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            kKeyTime,
4050dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            1000000LL * (mCurrentPos - mOffset)
406f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber                / (mNumChannels * bytesPerSample) / mSampleRate);
4070dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
4088bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber    buffer->meta_data()->setInt32(kKeyIsSyncFrame, 1);
4090dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
4100dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    *out = buffer;
4110dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
4120dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    return OK;
4130dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}
4140dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
4150dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber////////////////////////////////////////////////////////////////////////////////
4160dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
4170dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberbool SniffWAV(
4185a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber        const sp<DataSource> &source, String8 *mimeType, float *confidence,
4195a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber        sp<AMessage> *) {
4200dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    char header[12];
4210dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    if (source->readAt(0, header, sizeof(header)) < (ssize_t)sizeof(header)) {
4220dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        return false;
4230dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    }
4240dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
4250dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    if (memcmp(header, "RIFF", 4) || memcmp(&header[8], "WAVE", 4)) {
4260dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        return false;
4270dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    }
4280dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
4290dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    *mimeType = MEDIA_MIMETYPE_CONTAINER_WAV;
4300dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    *confidence = 0.3f;
4310dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
4320dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    return true;
4330dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}
4340dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
4350dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}  // namespace android
4360dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
437