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,
413bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi    WAVE_FORMAT_EXTENSIBLE = 0xFFFE
4242d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber};
430dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
443bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivistatic const char* WAVEEXT_SUBFORMAT = "\x00\x00\x00\x00\x10\x00\x80\x00\x00\xAA\x00\x38\x9B\x71";
453bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi
463bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi
470dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberstatic uint32_t U32_LE_AT(const uint8_t *ptr) {
480dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    return ptr[3] << 24 | ptr[2] << 16 | ptr[1] << 8 | ptr[0];
490dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}
500dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
510dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberstatic uint16_t U16_LE_AT(const uint8_t *ptr) {
520dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    return ptr[1] << 8 | ptr[0];
530dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}
540dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
550dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberstruct WAVSource : public MediaSource {
560dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    WAVSource(
570dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            const sp<DataSource> &dataSource,
58f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber            const sp<MetaData> &meta,
5942d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber            uint16_t waveFormat,
60f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber            int32_t bitsPerSample,
61c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong            off64_t offset, size_t size);
620dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
630dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    virtual status_t start(MetaData *params = NULL);
640dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    virtual status_t stop();
650dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    virtual sp<MetaData> getFormat();
660dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
670dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    virtual status_t read(
680dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            MediaBuffer **buffer, const ReadOptions *options = NULL);
690dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
700dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberprotected:
710dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    virtual ~WAVSource();
720dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
730dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberprivate:
740dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    static const size_t kMaxFrameSize;
750dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
760dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    sp<DataSource> mDataSource;
77f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber    sp<MetaData> mMeta;
7842d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber    uint16_t mWaveFormat;
790dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    int32_t mSampleRate;
800dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    int32_t mNumChannels;
81f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber    int32_t mBitsPerSample;
82c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong    off64_t mOffset;
830dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    size_t mSize;
840dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    bool mStarted;
850dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    MediaBufferGroup *mGroup;
86c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong    off64_t mCurrentPos;
870dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
880dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    WAVSource(const WAVSource &);
890dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    WAVSource &operator=(const WAVSource &);
900dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber};
910dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
920dba73763a04d39faf999dcc5ef12af3c99535a7Andreas HuberWAVExtractor::WAVExtractor(const sp<DataSource> &source)
930dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    : mDataSource(source),
943bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi      mValidFormat(false),
953bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi      mChannelMask(CHANNEL_MASK_USE_CHANNEL_ORDER) {
960dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    mInitCheck = init();
970dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}
980dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
990dba73763a04d39faf999dcc5ef12af3c99535a7Andreas HuberWAVExtractor::~WAVExtractor() {
1000dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}
1010dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
1027be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Hubersp<MetaData> WAVExtractor::getMetaData() {
1037be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber    sp<MetaData> meta = new MetaData;
1047be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber
1057be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber    if (mInitCheck != OK) {
1067be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber        return meta;
1077be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber    }
1087be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber
10906096f955d486e229e19956052925f43f2f3f7c4Dongwon Kang    meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_WAV);
1107be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber
1117be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber    return meta;
1127be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber}
1137be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber
1140dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Hubersize_t WAVExtractor::countTracks() {
1150dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    return mInitCheck == OK ? 1 : 0;
1160dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}
1170dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
1180dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Hubersp<MediaSource> WAVExtractor::getTrack(size_t index) {
1190dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    if (mInitCheck != OK || index > 0) {
1200dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        return NULL;
1210dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    }
1220dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
1230dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    return new WAVSource(
124f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber            mDataSource, mTrackMeta,
12542d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber            mWaveFormat, mBitsPerSample, mDataOffset, mDataSize);
1260dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}
1270dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
1280dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Hubersp<MetaData> WAVExtractor::getTrackMetaData(
1290dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        size_t index, uint32_t flags) {
1300dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    if (mInitCheck != OK || index > 0) {
1310dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        return NULL;
1320dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    }
1330dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
134f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber    return mTrackMeta;
1350dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}
1360dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
1370dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberstatus_t WAVExtractor::init() {
1380dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    uint8_t header[12];
1390dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    if (mDataSource->readAt(
1400dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber                0, header, sizeof(header)) < (ssize_t)sizeof(header)) {
1410dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        return NO_INIT;
1420dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    }
1430dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
1440dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    if (memcmp(header, "RIFF", 4) || memcmp(&header[8], "WAVE", 4)) {
1450dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        return NO_INIT;
1460dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    }
1470dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
1480dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    size_t totalSize = U32_LE_AT(&header[4]);
1490dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
150c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong    off64_t offset = 12;
1510dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    size_t remainingSize = totalSize;
1520dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    while (remainingSize >= 8) {
1530dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        uint8_t chunkHeader[8];
1540dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        if (mDataSource->readAt(offset, chunkHeader, 8) < 8) {
1550dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            return NO_INIT;
1560dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        }
1570dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
1580dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        remainingSize -= 8;
1590dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        offset += 8;
160f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber
1610dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        uint32_t chunkSize = U32_LE_AT(&chunkHeader[4]);
1620dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
1630dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        if (chunkSize > remainingSize) {
1640dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            return NO_INIT;
1650dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        }
1660dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
1670dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        if (!memcmp(chunkHeader, "fmt ", 4)) {
1680dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            if (chunkSize < 16) {
1690dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber                return NO_INIT;
1700dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            }
1710dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
1723bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi            uint8_t formatSpec[40];
1733bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi            if (mDataSource->readAt(offset, formatSpec, 2) < 2) {
1740dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber                return NO_INIT;
1750dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            }
1760dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
17742d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber            mWaveFormat = U16_LE_AT(formatSpec);
17842d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber            if (mWaveFormat != WAVE_FORMAT_PCM
17942d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                    && mWaveFormat != WAVE_FORMAT_ALAW
1803bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                    && mWaveFormat != WAVE_FORMAT_MULAW
1813bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                    && mWaveFormat != WAVE_FORMAT_EXTENSIBLE) {
1820dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber                return ERROR_UNSUPPORTED;
1830dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            }
1840dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
1853bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi            uint8_t fmtSize = 16;
1863bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi            if (mWaveFormat == WAVE_FORMAT_EXTENSIBLE) {
1873bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                fmtSize = 40;
1883bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi            }
1893bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi            if (mDataSource->readAt(offset, formatSpec, fmtSize) < fmtSize) {
1903bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                return NO_INIT;
1913bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi            }
1923bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi
1930dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            mNumChannels = U16_LE_AT(&formatSpec[2]);
1943bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi            if (mWaveFormat != WAVE_FORMAT_EXTENSIBLE) {
1953bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                if (mNumChannels != 1 && mNumChannels != 2) {
1963bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                    ALOGW("More than 2 channels (%d) in non-WAVE_EXT, unknown channel mask",
1973bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                            mNumChannels);
1983bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                }
1993bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi            } else {
2003bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                if (mNumChannels < 1 && mNumChannels > 8) {
2013bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                    return ERROR_UNSUPPORTED;
2023bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                }
2030dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            }
2040dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
2050dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            mSampleRate = U32_LE_AT(&formatSpec[4]);
2060dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
207f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber            if (mSampleRate == 0) {
208f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber                return ERROR_MALFORMED;
209f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber            }
210f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber
211f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber            mBitsPerSample = U16_LE_AT(&formatSpec[14]);
212f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber
2133bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi            if (mWaveFormat == WAVE_FORMAT_PCM
2143bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                    || mWaveFormat == WAVE_FORMAT_EXTENSIBLE) {
21542d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                if (mBitsPerSample != 8 && mBitsPerSample != 16
21642d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                    && mBitsPerSample != 24) {
21742d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                    return ERROR_UNSUPPORTED;
21842d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                }
21942d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber            } else {
22042d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                CHECK(mWaveFormat == WAVE_FORMAT_MULAW
22142d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                        || mWaveFormat == WAVE_FORMAT_ALAW);
22242d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                if (mBitsPerSample != 8) {
22342d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                    return ERROR_UNSUPPORTED;
22442d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                }
2250dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            }
2260dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
2273bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi            if (mWaveFormat == WAVE_FORMAT_EXTENSIBLE) {
2283bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                uint16_t validBitsPerSample = U16_LE_AT(&formatSpec[18]);
2293bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                if (validBitsPerSample != mBitsPerSample) {
23006f6ae34c735640dccdaca6ab1567d8afc9d3938Jean-Michel Trivi                    if (validBitsPerSample != 0) {
23172b2b9ba68ee85a3054a0de3a8414b8dfb217aebJean-Michel Trivi                        ALOGE("validBits(%d) != bitsPerSample(%d) are not supported",
23272b2b9ba68ee85a3054a0de3a8414b8dfb217aebJean-Michel Trivi                                validBitsPerSample, mBitsPerSample);
23372b2b9ba68ee85a3054a0de3a8414b8dfb217aebJean-Michel Trivi                        return ERROR_UNSUPPORTED;
23472b2b9ba68ee85a3054a0de3a8414b8dfb217aebJean-Michel Trivi                    } else {
23572b2b9ba68ee85a3054a0de3a8414b8dfb217aebJean-Michel Trivi                        // we only support valitBitsPerSample == bitsPerSample but some WAV_EXT
23672b2b9ba68ee85a3054a0de3a8414b8dfb217aebJean-Michel Trivi                        // writers don't correctly set the valid bits value, and leave it at 0.
23772b2b9ba68ee85a3054a0de3a8414b8dfb217aebJean-Michel Trivi                        ALOGW("WAVE_EXT has 0 valid bits per sample, ignoring");
23872b2b9ba68ee85a3054a0de3a8414b8dfb217aebJean-Michel Trivi                    }
2393bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                }
2403bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi
2413bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                mChannelMask = U32_LE_AT(&formatSpec[20]);
2423bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                ALOGV("numChannels=%d channelMask=0x%x", mNumChannels, mChannelMask);
2433bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                if ((mChannelMask >> 18) != 0) {
2443bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                    ALOGE("invalid channel mask 0x%x", mChannelMask);
2453bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                    return ERROR_MALFORMED;
2463bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                }
2473bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi
2483bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                if ((mChannelMask != CHANNEL_MASK_USE_CHANNEL_ORDER)
2493bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                        && (popcount(mChannelMask) != mNumChannels)) {
2503bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                    ALOGE("invalid number of channels (%d) in channel mask (0x%x)",
2513bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                            popcount(mChannelMask), mChannelMask);
2523bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                    return ERROR_MALFORMED;
2533bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                }
2543bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi
2553bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                // In a WAVE_EXT header, the first two bytes of the GUID stored at byte 24 contain
2563bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                // the sample format, using the same definitions as a regular WAV header
2573bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                mWaveFormat = U16_LE_AT(&formatSpec[24]);
2583bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                if (mWaveFormat != WAVE_FORMAT_PCM
2593bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                        && mWaveFormat != WAVE_FORMAT_ALAW
2603bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                        && mWaveFormat != WAVE_FORMAT_MULAW) {
2613bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                    return ERROR_UNSUPPORTED;
2623bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                }
2633bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                if (memcmp(&formatSpec[26], WAVEEXT_SUBFORMAT, 14)) {
2643bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                    ALOGE("unsupported GUID");
2653bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                    return ERROR_UNSUPPORTED;
2663bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                }
2673bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi            }
2683bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi
2690dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            mValidFormat = true;
2700dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        } else if (!memcmp(chunkHeader, "data", 4)) {
2710dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            if (mValidFormat) {
2720dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber                mDataOffset = offset;
2730dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber                mDataSize = chunkSize;
2740dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
275f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber                mTrackMeta = new MetaData;
27642d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber
27742d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                switch (mWaveFormat) {
27842d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                    case WAVE_FORMAT_PCM:
27942d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                        mTrackMeta->setCString(
28042d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                                kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
28142d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                        break;
28242d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                    case WAVE_FORMAT_ALAW:
28342d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                        mTrackMeta->setCString(
28442d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                                kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_G711_ALAW);
28542d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                        break;
28642d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                    default:
287f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong                        CHECK_EQ(mWaveFormat, (uint16_t)WAVE_FORMAT_MULAW);
28842d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                        mTrackMeta->setCString(
28942d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                                kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_G711_MLAW);
29042d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                        break;
29142d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                }
29242d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber
293f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber                mTrackMeta->setInt32(kKeyChannelCount, mNumChannels);
2943bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                mTrackMeta->setInt32(kKeyChannelMask, mChannelMask);
295f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber                mTrackMeta->setInt32(kKeySampleRate, mSampleRate);
296f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber
297f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber                size_t bytesPerSample = mBitsPerSample >> 3;
298f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber
299f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber                int64_t durationUs =
300f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber                    1000000LL * (mDataSize / (mNumChannels * bytesPerSample))
301f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber                        / mSampleRate;
302f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber
303f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber                mTrackMeta->setInt64(kKeyDuration, durationUs);
304f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber
3050dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber                return OK;
3060dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            }
3070dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        }
3080dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
3090dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        offset += chunkSize;
3100dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    }
3110dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
3120dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    return NO_INIT;
3130dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}
3140dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
3150dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberconst size_t WAVSource::kMaxFrameSize = 32768;
3160dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
3170dba73763a04d39faf999dcc5ef12af3c99535a7Andreas HuberWAVSource::WAVSource(
3180dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        const sp<DataSource> &dataSource,
319f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber        const sp<MetaData> &meta,
32042d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber        uint16_t waveFormat,
321f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber        int32_t bitsPerSample,
322c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong        off64_t offset, size_t size)
3230dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    : mDataSource(dataSource),
324f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber      mMeta(meta),
32542d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber      mWaveFormat(waveFormat),
326f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber      mSampleRate(0),
327f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber      mNumChannels(0),
328f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber      mBitsPerSample(bitsPerSample),
3290dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber      mOffset(offset),
3300dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber      mSize(size),
3310dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber      mStarted(false),
3320dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber      mGroup(NULL) {
333f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber    CHECK(mMeta->findInt32(kKeySampleRate, &mSampleRate));
334f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber    CHECK(mMeta->findInt32(kKeyChannelCount, &mNumChannels));
335bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
336bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    mMeta->setInt32(kKeyMaxInputSize, kMaxFrameSize);
3370dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}
3380dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
3390dba73763a04d39faf999dcc5ef12af3c99535a7Andreas HuberWAVSource::~WAVSource() {
3400dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    if (mStarted) {
3410dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        stop();
3420dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    }
3430dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}
3440dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
3450dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberstatus_t WAVSource::start(MetaData *params) {
3463856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("WAVSource::start");
3470dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
3480dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    CHECK(!mStarted);
3490dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
3500dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    mGroup = new MediaBufferGroup;
3510dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    mGroup->add_buffer(new MediaBuffer(kMaxFrameSize));
3520dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
353f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber    if (mBitsPerSample == 8) {
354f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber        // As a temporary buffer for 8->16 bit conversion.
355f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber        mGroup->add_buffer(new MediaBuffer(kMaxFrameSize));
356f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber    }
357f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber
3580dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    mCurrentPos = mOffset;
3590dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
3600dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    mStarted = true;
3610dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
3620dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    return OK;
3630dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}
3640dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
3650dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberstatus_t WAVSource::stop() {
3663856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("WAVSource::stop");
3670dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
3680dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    CHECK(mStarted);
3690dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
3700dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    delete mGroup;
3710dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    mGroup = NULL;
3720dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
3730dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    mStarted = false;
3740dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
3750dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    return OK;
3760dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}
3770dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
3780dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Hubersp<MetaData> WAVSource::getFormat() {
3793856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("WAVSource::getFormat");
3800dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
381f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber    return mMeta;
3820dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}
3830dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
3840dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberstatus_t WAVSource::read(
3850dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        MediaBuffer **out, const ReadOptions *options) {
3860dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    *out = NULL;
3870dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
3880dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    int64_t seekTimeUs;
389abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    ReadOptions::SeekMode mode;
390abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    if (options != NULL && options->getSeekTo(&seekTimeUs, &mode)) {
39136fb2077764093a0a19ed65770078b9987bd82b1James Dong        int64_t pos = (seekTimeUs * mSampleRate) / 1000000 * mNumChannels * (mBitsPerSample >> 3);
3920dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        if (pos > mSize) {
3930dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            pos = mSize;
3940dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        }
3950dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        mCurrentPos = pos + mOffset;
3960dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    }
3970dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
3980dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    MediaBuffer *buffer;
3990dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    status_t err = mGroup->acquire_buffer(&buffer);
4000dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    if (err != OK) {
4010dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        return err;
4020dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    }
4030dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
404104fcb88d4125caff74f63be4ce23537ca693ac7Andreas Huber    size_t maxBytesToRead =
405104fcb88d4125caff74f63be4ce23537ca693ac7Andreas Huber        mBitsPerSample == 8 ? kMaxFrameSize / 2 : kMaxFrameSize;
406104fcb88d4125caff74f63be4ce23537ca693ac7Andreas Huber
407104fcb88d4125caff74f63be4ce23537ca693ac7Andreas Huber    size_t maxBytesAvailable =
408c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong        (mCurrentPos - mOffset >= (off64_t)mSize)
409104fcb88d4125caff74f63be4ce23537ca693ac7Andreas Huber            ? 0 : mSize - (mCurrentPos - mOffset);
410104fcb88d4125caff74f63be4ce23537ca693ac7Andreas Huber
411104fcb88d4125caff74f63be4ce23537ca693ac7Andreas Huber    if (maxBytesToRead > maxBytesAvailable) {
412104fcb88d4125caff74f63be4ce23537ca693ac7Andreas Huber        maxBytesToRead = maxBytesAvailable;
413104fcb88d4125caff74f63be4ce23537ca693ac7Andreas Huber    }
414104fcb88d4125caff74f63be4ce23537ca693ac7Andreas Huber
4150dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    ssize_t n = mDataSource->readAt(
416f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber            mCurrentPos, buffer->data(),
417104fcb88d4125caff74f63be4ce23537ca693ac7Andreas Huber            maxBytesToRead);
4180dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
4190dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    if (n <= 0) {
4200dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        buffer->release();
4210dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        buffer = NULL;
4220dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
4230dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        return ERROR_END_OF_STREAM;
4240dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    }
4250dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
4260dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    buffer->set_range(0, n);
427f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber
42842d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber    if (mWaveFormat == WAVE_FORMAT_PCM) {
42942d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber        if (mBitsPerSample == 8) {
43042d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber            // Convert 8-bit unsigned samples to 16-bit signed.
431f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber
43242d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber            MediaBuffer *tmp;
433f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong            CHECK_EQ(mGroup->acquire_buffer(&tmp), (status_t)OK);
434f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber
43542d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber            // The new buffer holds the sample number of samples, but each
43642d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber            // one is 2 bytes wide.
43742d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber            tmp->set_range(0, 2 * n);
438f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber
43942d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber            int16_t *dst = (int16_t *)tmp->data();
44042d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber            const uint8_t *src = (const uint8_t *)buffer->data();
4410b3f21761eae9b7d230ddd9b4be76ef02d4cec15Gloria Wang            ssize_t numBytes = n;
4420b3f21761eae9b7d230ddd9b4be76ef02d4cec15Gloria Wang
4430b3f21761eae9b7d230ddd9b4be76ef02d4cec15Gloria Wang            while (numBytes-- > 0) {
44442d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                *dst++ = ((int16_t)(*src) - 128) * 256;
44542d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                ++src;
44642d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber            }
447f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber
44842d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber            buffer->release();
44942d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber            buffer = tmp;
45042d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber        } else if (mBitsPerSample == 24) {
45142d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber            // Convert 24-bit signed samples to 16-bit signed.
45242d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber
45342d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber            const uint8_t *src =
45442d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                (const uint8_t *)buffer->data() + buffer->range_offset();
45542d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber            int16_t *dst = (int16_t *)src;
45642d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber
45742d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber            size_t numSamples = buffer->range_length() / 3;
45842d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber            for (size_t i = 0; i < numSamples; ++i) {
45942d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                int32_t x = (int32_t)(src[0] | src[1] << 8 | src[2] << 16);
46042d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                x = (x << 8) >> 8;  // sign extension
461984d8f40c15e7fd757a9fdc007aad75549aa0fceAndreas Huber
46242d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                x = x >> 8;
46342d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                *dst++ = (int16_t)x;
46442d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                src += 3;
46542d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber            }
46642d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber
46742d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber            buffer->set_range(buffer->range_offset(), 2 * numSamples);
46842d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber        }
469f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber    }
470f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber
471f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber    size_t bytesPerSample = mBitsPerSample >> 3;
472f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber
4730dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    buffer->meta_data()->setInt64(
4740dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            kKeyTime,
4750dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            1000000LL * (mCurrentPos - mOffset)
476f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber                / (mNumChannels * bytesPerSample) / mSampleRate);
4770dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
4788bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber    buffer->meta_data()->setInt32(kKeyIsSyncFrame, 1);
479f1e10e8ed74cac805d601139882378a1f450fe94James Dong    mCurrentPos += n;
4800dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
4810dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    *out = buffer;
4820dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
4830dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    return OK;
4840dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}
4850dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
4860dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber////////////////////////////////////////////////////////////////////////////////
4870dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
4880dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberbool SniffWAV(
4895a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber        const sp<DataSource> &source, String8 *mimeType, float *confidence,
4905a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber        sp<AMessage> *) {
4910dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    char header[12];
4920dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    if (source->readAt(0, header, sizeof(header)) < (ssize_t)sizeof(header)) {
4930dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        return false;
4940dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    }
4950dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
4960dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    if (memcmp(header, "RIFF", 4) || memcmp(&header[8], "WAVE", 4)) {
4970dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        return false;
4980dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    }
4990dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
50070d3e260edcd42972864bf501337f0b1a187657dJames Dong    sp<MediaExtractor> extractor = new WAVExtractor(source);
50170d3e260edcd42972864bf501337f0b1a187657dJames Dong    if (extractor->countTracks() == 0) {
50270d3e260edcd42972864bf501337f0b1a187657dJames Dong        return false;
50370d3e260edcd42972864bf501337f0b1a187657dJames Dong    }
50470d3e260edcd42972864bf501337f0b1a187657dJames Dong
5050dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    *mimeType = MEDIA_MIMETYPE_CONTAINER_WAV;
5060dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    *confidence = 0.3f;
5070dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
5080dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    return true;
5090dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}
5100dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
5110dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}  // namespace android
512