WAVExtractor.cpp revision b2487f03f12dcafdb801fc0007c8df8412397f44
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
23f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong#include <media/stagefright/foundation/ADebug.h>
240dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber#include <media/stagefright/DataSource.h>
250dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber#include <media/stagefright/MediaBufferGroup.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>
313bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi#include <cutils/bitops.h>
323bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi
333bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi#define CHANNEL_MASK_USE_CHANNEL_ORDER 0
340dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
350dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Hubernamespace android {
360dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
3742d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huberenum {
383bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi    WAVE_FORMAT_PCM        = 0x0001,
393bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi    WAVE_FORMAT_ALAW       = 0x0006,
403bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi    WAVE_FORMAT_MULAW      = 0x0007,
41ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen    WAVE_FORMAT_MSGSM      = 0x0031,
423bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi    WAVE_FORMAT_EXTENSIBLE = 0xFFFE
4342d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber};
440dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
453bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivistatic const char* WAVEEXT_SUBFORMAT = "\x00\x00\x00\x00\x10\x00\x80\x00\x00\xAA\x00\x38\x9B\x71";
463bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi
473bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi
480dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberstatic uint32_t U32_LE_AT(const uint8_t *ptr) {
490dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    return ptr[3] << 24 | ptr[2] << 16 | ptr[1] << 8 | ptr[0];
500dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}
510dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
520dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberstatic uint16_t U16_LE_AT(const uint8_t *ptr) {
530dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    return ptr[1] << 8 | ptr[0];
540dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}
550dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
560dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberstruct WAVSource : public MediaSource {
570dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    WAVSource(
580dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            const sp<DataSource> &dataSource,
59f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber            const sp<MetaData> &meta,
6042d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber            uint16_t waveFormat,
61f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber            int32_t bitsPerSample,
62c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong            off64_t offset, size_t size);
630dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
640dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    virtual status_t start(MetaData *params = NULL);
650dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    virtual status_t stop();
660dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    virtual sp<MetaData> getFormat();
670dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
680dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    virtual status_t read(
690dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            MediaBuffer **buffer, const ReadOptions *options = NULL);
700dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
710dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberprotected:
720dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    virtual ~WAVSource();
730dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
740dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberprivate:
750dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    static const size_t kMaxFrameSize;
760dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
770dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    sp<DataSource> mDataSource;
78f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber    sp<MetaData> mMeta;
7942d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber    uint16_t mWaveFormat;
800dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    int32_t mSampleRate;
810dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    int32_t mNumChannels;
82f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber    int32_t mBitsPerSample;
83c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong    off64_t mOffset;
840dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    size_t mSize;
850dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    bool mStarted;
860dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    MediaBufferGroup *mGroup;
87c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong    off64_t mCurrentPos;
880dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
890dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    WAVSource(const WAVSource &);
900dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    WAVSource &operator=(const WAVSource &);
910dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber};
920dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
930dba73763a04d39faf999dcc5ef12af3c99535a7Andreas HuberWAVExtractor::WAVExtractor(const sp<DataSource> &source)
940dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    : mDataSource(source),
953bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi      mValidFormat(false),
963bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi      mChannelMask(CHANNEL_MASK_USE_CHANNEL_ORDER) {
970dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    mInitCheck = init();
980dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}
990dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
1000dba73763a04d39faf999dcc5ef12af3c99535a7Andreas HuberWAVExtractor::~WAVExtractor() {
1010dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}
1020dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
1037be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Hubersp<MetaData> WAVExtractor::getMetaData() {
1047be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber    sp<MetaData> meta = new MetaData;
1057be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber
1067be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber    if (mInitCheck != OK) {
1077be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber        return meta;
1087be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber    }
1097be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber
11006096f955d486e229e19956052925f43f2f3f7c4Dongwon Kang    meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_WAV);
1117be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber
1127be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber    return meta;
1137be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber}
1147be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber
1150dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Hubersize_t WAVExtractor::countTracks() {
1160dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    return mInitCheck == OK ? 1 : 0;
1170dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}
1180dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
119b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissensp<IMediaSource> WAVExtractor::getTrack(size_t index) {
1200dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    if (mInitCheck != OK || index > 0) {
1210dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        return NULL;
1220dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    }
1230dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
1240dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    return new WAVSource(
125f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber            mDataSource, mTrackMeta,
12642d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber            mWaveFormat, mBitsPerSample, mDataOffset, mDataSize);
1270dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}
1280dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
1290dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Hubersp<MetaData> WAVExtractor::getTrackMetaData(
13084333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber        size_t index, uint32_t /* flags */) {
1310dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    if (mInitCheck != OK || index > 0) {
1320dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        return NULL;
1330dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    }
1340dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
135f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber    return mTrackMeta;
1360dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}
1370dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
1380dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberstatus_t WAVExtractor::init() {
1390dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    uint8_t header[12];
1400dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    if (mDataSource->readAt(
1410dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber                0, header, sizeof(header)) < (ssize_t)sizeof(header)) {
1420dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        return NO_INIT;
1430dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    }
1440dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
1450dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    if (memcmp(header, "RIFF", 4) || memcmp(&header[8], "WAVE", 4)) {
1460dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        return NO_INIT;
1470dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    }
1480dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
1490dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    size_t totalSize = U32_LE_AT(&header[4]);
1500dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
151c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong    off64_t offset = 12;
1520dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    size_t remainingSize = totalSize;
1530dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    while (remainingSize >= 8) {
1540dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        uint8_t chunkHeader[8];
1550dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        if (mDataSource->readAt(offset, chunkHeader, 8) < 8) {
1560dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            return NO_INIT;
1570dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        }
1580dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
1590dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        remainingSize -= 8;
1600dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        offset += 8;
161f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber
1620dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        uint32_t chunkSize = U32_LE_AT(&chunkHeader[4]);
1630dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
1640dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        if (chunkSize > remainingSize) {
1650dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            return NO_INIT;
1660dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        }
1670dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
1680dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        if (!memcmp(chunkHeader, "fmt ", 4)) {
1690dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            if (chunkSize < 16) {
1700dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber                return NO_INIT;
1710dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            }
1720dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
1733bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi            uint8_t formatSpec[40];
1743bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi            if (mDataSource->readAt(offset, formatSpec, 2) < 2) {
1750dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber                return NO_INIT;
1760dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            }
1770dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
17842d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber            mWaveFormat = U16_LE_AT(formatSpec);
17942d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber            if (mWaveFormat != WAVE_FORMAT_PCM
18042d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                    && mWaveFormat != WAVE_FORMAT_ALAW
1813bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                    && mWaveFormat != WAVE_FORMAT_MULAW
182ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen                    && mWaveFormat != WAVE_FORMAT_MSGSM
1833bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                    && mWaveFormat != WAVE_FORMAT_EXTENSIBLE) {
1840dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber                return ERROR_UNSUPPORTED;
1850dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            }
1860dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
1873bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi            uint8_t fmtSize = 16;
1883bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi            if (mWaveFormat == WAVE_FORMAT_EXTENSIBLE) {
1893bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                fmtSize = 40;
1903bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi            }
1913bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi            if (mDataSource->readAt(offset, formatSpec, fmtSize) < fmtSize) {
1923bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                return NO_INIT;
1933bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi            }
1943bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi
1950dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            mNumChannels = U16_LE_AT(&formatSpec[2]);
1963bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi            if (mWaveFormat != WAVE_FORMAT_EXTENSIBLE) {
1973bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                if (mNumChannels != 1 && mNumChannels != 2) {
1983bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                    ALOGW("More than 2 channels (%d) in non-WAVE_EXT, unknown channel mask",
1993bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                            mNumChannels);
2003bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                }
2013bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi            } else {
20218b7186ce7bc2df1f4f33b57fc323bf68feb2852Robert Shih                if (mNumChannels < 1 || mNumChannels > 8) {
2033bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                    return ERROR_UNSUPPORTED;
2043bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                }
2050dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            }
2060dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
2070dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            mSampleRate = U32_LE_AT(&formatSpec[4]);
2080dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
209f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber            if (mSampleRate == 0) {
210f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber                return ERROR_MALFORMED;
211f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber            }
212f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber
213f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber            mBitsPerSample = U16_LE_AT(&formatSpec[14]);
214f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber
2153bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi            if (mWaveFormat == WAVE_FORMAT_PCM
2163bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                    || mWaveFormat == WAVE_FORMAT_EXTENSIBLE) {
21742d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                if (mBitsPerSample != 8 && mBitsPerSample != 16
21842d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                    && mBitsPerSample != 24) {
21942d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                    return ERROR_UNSUPPORTED;
22042d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                }
221ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen            } else if (mWaveFormat == WAVE_FORMAT_MSGSM) {
222ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen                if (mBitsPerSample != 0) {
223ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen                    return ERROR_UNSUPPORTED;
224ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen                }
22542d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber            } else {
22642d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                CHECK(mWaveFormat == WAVE_FORMAT_MULAW
22742d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                        || mWaveFormat == WAVE_FORMAT_ALAW);
22842d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                if (mBitsPerSample != 8) {
22942d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                    return ERROR_UNSUPPORTED;
23042d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                }
2310dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            }
2320dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
2333bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi            if (mWaveFormat == WAVE_FORMAT_EXTENSIBLE) {
2343bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                uint16_t validBitsPerSample = U16_LE_AT(&formatSpec[18]);
2353bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                if (validBitsPerSample != mBitsPerSample) {
23606f6ae34c735640dccdaca6ab1567d8afc9d3938Jean-Michel Trivi                    if (validBitsPerSample != 0) {
23772b2b9ba68ee85a3054a0de3a8414b8dfb217aebJean-Michel Trivi                        ALOGE("validBits(%d) != bitsPerSample(%d) are not supported",
23872b2b9ba68ee85a3054a0de3a8414b8dfb217aebJean-Michel Trivi                                validBitsPerSample, mBitsPerSample);
23972b2b9ba68ee85a3054a0de3a8414b8dfb217aebJean-Michel Trivi                        return ERROR_UNSUPPORTED;
24072b2b9ba68ee85a3054a0de3a8414b8dfb217aebJean-Michel Trivi                    } else {
24172b2b9ba68ee85a3054a0de3a8414b8dfb217aebJean-Michel Trivi                        // we only support valitBitsPerSample == bitsPerSample but some WAV_EXT
24272b2b9ba68ee85a3054a0de3a8414b8dfb217aebJean-Michel Trivi                        // writers don't correctly set the valid bits value, and leave it at 0.
24372b2b9ba68ee85a3054a0de3a8414b8dfb217aebJean-Michel Trivi                        ALOGW("WAVE_EXT has 0 valid bits per sample, ignoring");
24472b2b9ba68ee85a3054a0de3a8414b8dfb217aebJean-Michel Trivi                    }
2453bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                }
2463bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi
2473bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                mChannelMask = U32_LE_AT(&formatSpec[20]);
2483bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                ALOGV("numChannels=%d channelMask=0x%x", mNumChannels, mChannelMask);
2493bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                if ((mChannelMask >> 18) != 0) {
2503bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                    ALOGE("invalid channel mask 0x%x", mChannelMask);
2513bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                    return ERROR_MALFORMED;
2523bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                }
2533bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi
2543bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                if ((mChannelMask != CHANNEL_MASK_USE_CHANNEL_ORDER)
2553bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                        && (popcount(mChannelMask) != mNumChannels)) {
2563bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                    ALOGE("invalid number of channels (%d) in channel mask (0x%x)",
2573bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                            popcount(mChannelMask), mChannelMask);
2583bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                    return ERROR_MALFORMED;
2593bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                }
2603bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi
2613bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                // In a WAVE_EXT header, the first two bytes of the GUID stored at byte 24 contain
2623bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                // the sample format, using the same definitions as a regular WAV header
2633bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                mWaveFormat = U16_LE_AT(&formatSpec[24]);
2643bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                if (mWaveFormat != WAVE_FORMAT_PCM
2653bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                        && mWaveFormat != WAVE_FORMAT_ALAW
2663bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                        && mWaveFormat != WAVE_FORMAT_MULAW) {
2673bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                    return ERROR_UNSUPPORTED;
2683bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                }
2693bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                if (memcmp(&formatSpec[26], WAVEEXT_SUBFORMAT, 14)) {
2703bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                    ALOGE("unsupported GUID");
2713bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                    return ERROR_UNSUPPORTED;
2723bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                }
2733bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi            }
2743bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi
2750dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            mValidFormat = true;
2760dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        } else if (!memcmp(chunkHeader, "data", 4)) {
2770dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            if (mValidFormat) {
2780dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber                mDataOffset = offset;
2790dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber                mDataSize = chunkSize;
2800dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
281f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber                mTrackMeta = new MetaData;
28242d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber
28342d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                switch (mWaveFormat) {
28442d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                    case WAVE_FORMAT_PCM:
28542d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                        mTrackMeta->setCString(
28642d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                                kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
28742d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                        break;
28842d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                    case WAVE_FORMAT_ALAW:
28942d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                        mTrackMeta->setCString(
29042d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                                kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_G711_ALAW);
29142d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                        break;
292ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen                    case WAVE_FORMAT_MSGSM:
293ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen                        mTrackMeta->setCString(
294ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen                                kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MSGSM);
295ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen                        break;
29642d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                    default:
297f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong                        CHECK_EQ(mWaveFormat, (uint16_t)WAVE_FORMAT_MULAW);
29842d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                        mTrackMeta->setCString(
29942d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                                kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_G711_MLAW);
30042d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                        break;
30142d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                }
30242d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber
303f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber                mTrackMeta->setInt32(kKeyChannelCount, mNumChannels);
3043bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                mTrackMeta->setInt32(kKeyChannelMask, mChannelMask);
305f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber                mTrackMeta->setInt32(kKeySampleRate, mSampleRate);
306f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber
307ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen                int64_t durationUs = 0;
308ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen                if (mWaveFormat == WAVE_FORMAT_MSGSM) {
309ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen                    // 65 bytes decode to 320 8kHz samples
310ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen                    durationUs =
311ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen                        1000000LL * (mDataSize / 65 * 320) / 8000;
312ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen                } else {
313ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen                    size_t bytesPerSample = mBitsPerSample >> 3;
314e52267adab4c89169aafd10a0fa2656ccb02c039Joshua J. Drake
315e52267adab4c89169aafd10a0fa2656ccb02c039Joshua J. Drake                    if (!bytesPerSample || !mNumChannels)
316e52267adab4c89169aafd10a0fa2656ccb02c039Joshua J. Drake                        return ERROR_MALFORMED;
317e52267adab4c89169aafd10a0fa2656ccb02c039Joshua J. Drake
318e52267adab4c89169aafd10a0fa2656ccb02c039Joshua J. Drake                    size_t num_samples = mDataSize / (mNumChannels * bytesPerSample);
319e52267adab4c89169aafd10a0fa2656ccb02c039Joshua J. Drake
320e52267adab4c89169aafd10a0fa2656ccb02c039Joshua J. Drake                    if (!mSampleRate)
321e52267adab4c89169aafd10a0fa2656ccb02c039Joshua J. Drake                        return ERROR_MALFORMED;
322e52267adab4c89169aafd10a0fa2656ccb02c039Joshua J. Drake
323ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen                    durationUs =
324e52267adab4c89169aafd10a0fa2656ccb02c039Joshua J. Drake                        1000000LL * num_samples / mSampleRate;
325ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen                }
326f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber
327f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber                mTrackMeta->setInt64(kKeyDuration, durationUs);
328f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber
3290dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber                return OK;
3300dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            }
3310dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        }
3320dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
3330dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        offset += chunkSize;
3340dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    }
3350dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
3360dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    return NO_INIT;
3370dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}
3380dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
3390dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberconst size_t WAVSource::kMaxFrameSize = 32768;
3400dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
3410dba73763a04d39faf999dcc5ef12af3c99535a7Andreas HuberWAVSource::WAVSource(
3420dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        const sp<DataSource> &dataSource,
343f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber        const sp<MetaData> &meta,
34442d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber        uint16_t waveFormat,
345f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber        int32_t bitsPerSample,
346c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong        off64_t offset, size_t size)
3470dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    : mDataSource(dataSource),
348f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber      mMeta(meta),
34942d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber      mWaveFormat(waveFormat),
350f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber      mSampleRate(0),
351f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber      mNumChannels(0),
352f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber      mBitsPerSample(bitsPerSample),
3530dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber      mOffset(offset),
3540dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber      mSize(size),
3550dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber      mStarted(false),
3560dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber      mGroup(NULL) {
357f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber    CHECK(mMeta->findInt32(kKeySampleRate, &mSampleRate));
358f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber    CHECK(mMeta->findInt32(kKeyChannelCount, &mNumChannels));
359bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
360bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    mMeta->setInt32(kKeyMaxInputSize, kMaxFrameSize);
3610dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}
3620dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
3630dba73763a04d39faf999dcc5ef12af3c99535a7Andreas HuberWAVSource::~WAVSource() {
3640dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    if (mStarted) {
3650dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        stop();
3660dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    }
3670dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}
3680dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
36984333e0475bc911adc16417f4ca327c975cf6c36Andreas Huberstatus_t WAVSource::start(MetaData * /* params */) {
3703856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("WAVSource::start");
3710dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
3720dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    CHECK(!mStarted);
3730dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
3740dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    mGroup = new MediaBufferGroup;
3750dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    mGroup->add_buffer(new MediaBuffer(kMaxFrameSize));
3760dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
377f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber    if (mBitsPerSample == 8) {
378f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber        // As a temporary buffer for 8->16 bit conversion.
379f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber        mGroup->add_buffer(new MediaBuffer(kMaxFrameSize));
380f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber    }
381f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber
3820dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    mCurrentPos = mOffset;
3830dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
3840dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    mStarted = true;
3850dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
3860dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    return OK;
3870dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}
3880dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
3890dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberstatus_t WAVSource::stop() {
3903856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("WAVSource::stop");
3910dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
3920dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    CHECK(mStarted);
3930dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
3940dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    delete mGroup;
3950dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    mGroup = NULL;
3960dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
3970dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    mStarted = false;
3980dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
3990dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    return OK;
4000dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}
4010dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
4020dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Hubersp<MetaData> WAVSource::getFormat() {
4033856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("WAVSource::getFormat");
4040dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
405f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber    return mMeta;
4060dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}
4070dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
4080dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberstatus_t WAVSource::read(
4090dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        MediaBuffer **out, const ReadOptions *options) {
4100dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    *out = NULL;
4110dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
4120dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    int64_t seekTimeUs;
413abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    ReadOptions::SeekMode mode;
414abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    if (options != NULL && options->getSeekTo(&seekTimeUs, &mode)) {
415ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen        int64_t pos = 0;
416ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen
417ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen        if (mWaveFormat == WAVE_FORMAT_MSGSM) {
418ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen            // 65 bytes decode to 320 8kHz samples
419ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen            int64_t samplenumber = (seekTimeUs * mSampleRate) / 1000000;
420ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen            int64_t framenumber = samplenumber / 320;
421ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen            pos = framenumber * 65;
422ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen        } else {
423ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen            pos = (seekTimeUs * mSampleRate) / 1000000 * mNumChannels * (mBitsPerSample >> 3);
424ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen        }
425a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn        if (pos > (off64_t)mSize) {
4260dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            pos = mSize;
4270dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        }
4280dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        mCurrentPos = pos + mOffset;
4290dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    }
4300dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
4310dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    MediaBuffer *buffer;
4320dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    status_t err = mGroup->acquire_buffer(&buffer);
4330dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    if (err != OK) {
4340dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        return err;
4350dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    }
4360dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
4379b1797fed7065be05f8fb7a36d1a27e0df3cb7abcong.zhou    // make sure that maxBytesToRead is multiple of 3, in 24-bit case
438104fcb88d4125caff74f63be4ce23537ca693ac7Andreas Huber    size_t maxBytesToRead =
4399b1797fed7065be05f8fb7a36d1a27e0df3cb7abcong.zhou        mBitsPerSample == 8 ? kMaxFrameSize / 2 :
4409b1797fed7065be05f8fb7a36d1a27e0df3cb7abcong.zhou        (mBitsPerSample == 24 ? 3*(kMaxFrameSize/3): kMaxFrameSize);
441104fcb88d4125caff74f63be4ce23537ca693ac7Andreas Huber
442104fcb88d4125caff74f63be4ce23537ca693ac7Andreas Huber    size_t maxBytesAvailable =
443c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong        (mCurrentPos - mOffset >= (off64_t)mSize)
444104fcb88d4125caff74f63be4ce23537ca693ac7Andreas Huber            ? 0 : mSize - (mCurrentPos - mOffset);
445104fcb88d4125caff74f63be4ce23537ca693ac7Andreas Huber
446104fcb88d4125caff74f63be4ce23537ca693ac7Andreas Huber    if (maxBytesToRead > maxBytesAvailable) {
447104fcb88d4125caff74f63be4ce23537ca693ac7Andreas Huber        maxBytesToRead = maxBytesAvailable;
448104fcb88d4125caff74f63be4ce23537ca693ac7Andreas Huber    }
449104fcb88d4125caff74f63be4ce23537ca693ac7Andreas Huber
450ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen    if (mWaveFormat == WAVE_FORMAT_MSGSM) {
451ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen        // Microsoft packs 2 frames into 65 bytes, rather than using separate 33-byte frames,
452ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen        // so read multiples of 65, and use smaller buffers to account for ~10:1 expansion ratio
453ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen        if (maxBytesToRead > 1024) {
454ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen            maxBytesToRead = 1024;
455ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen        }
456ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen        maxBytesToRead = (maxBytesToRead / 65) * 65;
45741d3f579d2c166984958263533284209b90c87d5Marco Nelissen    } else {
45841d3f579d2c166984958263533284209b90c87d5Marco Nelissen        // read only integral amounts of audio unit frames.
45941d3f579d2c166984958263533284209b90c87d5Marco Nelissen        const size_t inputUnitFrameSize = mNumChannels * mBitsPerSample / 8;
46041d3f579d2c166984958263533284209b90c87d5Marco Nelissen        maxBytesToRead -= maxBytesToRead % inputUnitFrameSize;
461ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen    }
462ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen
4630dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    ssize_t n = mDataSource->readAt(
464f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber            mCurrentPos, buffer->data(),
465104fcb88d4125caff74f63be4ce23537ca693ac7Andreas Huber            maxBytesToRead);
4660dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
4670dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    if (n <= 0) {
4680dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        buffer->release();
4690dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        buffer = NULL;
4700dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
4710dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        return ERROR_END_OF_STREAM;
4720dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    }
4730dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
4740dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    buffer->set_range(0, n);
475f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber
4769b1797fed7065be05f8fb7a36d1a27e0df3cb7abcong.zhou    if (mWaveFormat == WAVE_FORMAT_PCM || mWaveFormat == WAVE_FORMAT_EXTENSIBLE) {
47742d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber        if (mBitsPerSample == 8) {
47842d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber            // Convert 8-bit unsigned samples to 16-bit signed.
479f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber
48042d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber            MediaBuffer *tmp;
481f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong            CHECK_EQ(mGroup->acquire_buffer(&tmp), (status_t)OK);
482f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber
48342d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber            // The new buffer holds the sample number of samples, but each
48442d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber            // one is 2 bytes wide.
48542d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber            tmp->set_range(0, 2 * n);
486f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber
48742d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber            int16_t *dst = (int16_t *)tmp->data();
48842d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber            const uint8_t *src = (const uint8_t *)buffer->data();
4890b3f21761eae9b7d230ddd9b4be76ef02d4cec15Gloria Wang            ssize_t numBytes = n;
4900b3f21761eae9b7d230ddd9b4be76ef02d4cec15Gloria Wang
4910b3f21761eae9b7d230ddd9b4be76ef02d4cec15Gloria Wang            while (numBytes-- > 0) {
49242d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                *dst++ = ((int16_t)(*src) - 128) * 256;
49342d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                ++src;
49442d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber            }
495f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber
49642d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber            buffer->release();
49742d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber            buffer = tmp;
49842d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber        } else if (mBitsPerSample == 24) {
49942d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber            // Convert 24-bit signed samples to 16-bit signed.
50042d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber
50142d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber            const uint8_t *src =
50242d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                (const uint8_t *)buffer->data() + buffer->range_offset();
50342d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber            int16_t *dst = (int16_t *)src;
50442d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber
50542d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber            size_t numSamples = buffer->range_length() / 3;
50642d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber            for (size_t i = 0; i < numSamples; ++i) {
50742d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                int32_t x = (int32_t)(src[0] | src[1] << 8 | src[2] << 16);
50842d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                x = (x << 8) >> 8;  // sign extension
509984d8f40c15e7fd757a9fdc007aad75549aa0fceAndreas Huber
51042d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                x = x >> 8;
51142d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                *dst++ = (int16_t)x;
51242d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                src += 3;
51342d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber            }
51442d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber
51542d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber            buffer->set_range(buffer->range_offset(), 2 * numSamples);
51642d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber        }
517f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber    }
518f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber
519ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen    int64_t timeStampUs = 0;
520ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen
521ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen    if (mWaveFormat == WAVE_FORMAT_MSGSM) {
522ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen        timeStampUs = 1000000LL * (mCurrentPos - mOffset) * 320 / 65 / mSampleRate;
523ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen    } else {
524ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen        size_t bytesPerSample = mBitsPerSample >> 3;
525ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen        timeStampUs = 1000000LL * (mCurrentPos - mOffset)
526ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen                / (mNumChannels * bytesPerSample) / mSampleRate;
527ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen    }
528f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber
529ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen    buffer->meta_data()->setInt64(kKeyTime, timeStampUs);
5300dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
5318bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber    buffer->meta_data()->setInt32(kKeyIsSyncFrame, 1);
532f1e10e8ed74cac805d601139882378a1f450fe94James Dong    mCurrentPos += n;
5330dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
5340dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    *out = buffer;
5350dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
5360dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    return OK;
5370dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}
5380dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
5390dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber////////////////////////////////////////////////////////////////////////////////
5400dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
5410dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberbool SniffWAV(
5425a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber        const sp<DataSource> &source, String8 *mimeType, float *confidence,
5435a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber        sp<AMessage> *) {
5440dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    char header[12];
5450dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    if (source->readAt(0, header, sizeof(header)) < (ssize_t)sizeof(header)) {
5460dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        return false;
5470dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    }
5480dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
5490dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    if (memcmp(header, "RIFF", 4) || memcmp(&header[8], "WAVE", 4)) {
5500dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        return false;
5510dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    }
5520dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
55370d3e260edcd42972864bf501337f0b1a187657dJames Dong    sp<MediaExtractor> extractor = new WAVExtractor(source);
55470d3e260edcd42972864bf501337f0b1a187657dJames Dong    if (extractor->countTracks() == 0) {
55570d3e260edcd42972864bf501337f0b1a187657dJames Dong        return false;
55670d3e260edcd42972864bf501337f0b1a187657dJames Dong    }
55770d3e260edcd42972864bf501337f0b1a187657dJames Dong
5580dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    *mimeType = MEDIA_MIMETYPE_CONTAINER_WAV;
5590dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    *confidence = 0.3f;
5600dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
5610dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    return true;
5620dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}
5630dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
5640dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}  // namespace android
565