Home | History | Annotate | Download | only in libstagefright
      1 /*
      2  * Copyright (C) 2009 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 //#define LOG_NDEBUG 0
     18 #define LOG_TAG "WAVExtractor"
     19 #include <utils/Log.h>
     20 
     21 #include "include/WAVExtractor.h"
     22 
     23 #include <media/stagefright/DataSource.h>
     24 #include <media/stagefright/MediaBufferGroup.h>
     25 #include <media/stagefright/MediaDebug.h>
     26 #include <media/stagefright/MediaDefs.h>
     27 #include <media/stagefright/MediaErrors.h>
     28 #include <media/stagefright/MediaSource.h>
     29 #include <media/stagefright/MetaData.h>
     30 #include <utils/String8.h>
     31 
     32 namespace android {
     33 
     34 enum {
     35     WAVE_FORMAT_PCM = 1,
     36     WAVE_FORMAT_ALAW = 6,
     37     WAVE_FORMAT_MULAW = 7,
     38 };
     39 
     40 static uint32_t U32_LE_AT(const uint8_t *ptr) {
     41     return ptr[3] << 24 | ptr[2] << 16 | ptr[1] << 8 | ptr[0];
     42 }
     43 
     44 static uint16_t U16_LE_AT(const uint8_t *ptr) {
     45     return ptr[1] << 8 | ptr[0];
     46 }
     47 
     48 struct WAVSource : public MediaSource {
     49     WAVSource(
     50             const sp<DataSource> &dataSource,
     51             const sp<MetaData> &meta,
     52             uint16_t waveFormat,
     53             int32_t bitsPerSample,
     54             off_t offset, size_t size);
     55 
     56     virtual status_t start(MetaData *params = NULL);
     57     virtual status_t stop();
     58     virtual sp<MetaData> getFormat();
     59 
     60     virtual status_t read(
     61             MediaBuffer **buffer, const ReadOptions *options = NULL);
     62 
     63 protected:
     64     virtual ~WAVSource();
     65 
     66 private:
     67     static const size_t kMaxFrameSize;
     68 
     69     sp<DataSource> mDataSource;
     70     sp<MetaData> mMeta;
     71     uint16_t mWaveFormat;
     72     int32_t mSampleRate;
     73     int32_t mNumChannels;
     74     int32_t mBitsPerSample;
     75     off_t mOffset;
     76     size_t mSize;
     77     bool mStarted;
     78     MediaBufferGroup *mGroup;
     79     off_t mCurrentPos;
     80 
     81     WAVSource(const WAVSource &);
     82     WAVSource &operator=(const WAVSource &);
     83 };
     84 
     85 WAVExtractor::WAVExtractor(const sp<DataSource> &source)
     86     : mDataSource(source),
     87       mValidFormat(false) {
     88     mInitCheck = init();
     89 }
     90 
     91 WAVExtractor::~WAVExtractor() {
     92 }
     93 
     94 sp<MetaData> WAVExtractor::getMetaData() {
     95     sp<MetaData> meta = new MetaData;
     96 
     97     if (mInitCheck != OK) {
     98         return meta;
     99     }
    100 
    101     meta->setCString(kKeyMIMEType, "audio/x-wav");
    102 
    103     return meta;
    104 }
    105 
    106 size_t WAVExtractor::countTracks() {
    107     return mInitCheck == OK ? 1 : 0;
    108 }
    109 
    110 sp<MediaSource> WAVExtractor::getTrack(size_t index) {
    111     if (mInitCheck != OK || index > 0) {
    112         return NULL;
    113     }
    114 
    115     return new WAVSource(
    116             mDataSource, mTrackMeta,
    117             mWaveFormat, mBitsPerSample, mDataOffset, mDataSize);
    118 }
    119 
    120 sp<MetaData> WAVExtractor::getTrackMetaData(
    121         size_t index, uint32_t flags) {
    122     if (mInitCheck != OK || index > 0) {
    123         return NULL;
    124     }
    125 
    126     return mTrackMeta;
    127 }
    128 
    129 status_t WAVExtractor::init() {
    130     uint8_t header[12];
    131     if (mDataSource->readAt(
    132                 0, header, sizeof(header)) < (ssize_t)sizeof(header)) {
    133         return NO_INIT;
    134     }
    135 
    136     if (memcmp(header, "RIFF", 4) || memcmp(&header[8], "WAVE", 4)) {
    137         return NO_INIT;
    138     }
    139 
    140     size_t totalSize = U32_LE_AT(&header[4]);
    141 
    142     off_t offset = 12;
    143     size_t remainingSize = totalSize;
    144     while (remainingSize >= 8) {
    145         uint8_t chunkHeader[8];
    146         if (mDataSource->readAt(offset, chunkHeader, 8) < 8) {
    147             return NO_INIT;
    148         }
    149 
    150         remainingSize -= 8;
    151         offset += 8;
    152 
    153         uint32_t chunkSize = U32_LE_AT(&chunkHeader[4]);
    154 
    155         if (chunkSize > remainingSize) {
    156             return NO_INIT;
    157         }
    158 
    159         if (!memcmp(chunkHeader, "fmt ", 4)) {
    160             if (chunkSize < 16) {
    161                 return NO_INIT;
    162             }
    163 
    164             uint8_t formatSpec[16];
    165             if (mDataSource->readAt(offset, formatSpec, 16) < 16) {
    166                 return NO_INIT;
    167             }
    168 
    169             mWaveFormat = U16_LE_AT(formatSpec);
    170             if (mWaveFormat != WAVE_FORMAT_PCM
    171                     && mWaveFormat != WAVE_FORMAT_ALAW
    172                     && mWaveFormat != WAVE_FORMAT_MULAW) {
    173                 return ERROR_UNSUPPORTED;
    174             }
    175 
    176             mNumChannels = U16_LE_AT(&formatSpec[2]);
    177             if (mNumChannels != 1 && mNumChannels != 2) {
    178                 return ERROR_UNSUPPORTED;
    179             }
    180 
    181             mSampleRate = U32_LE_AT(&formatSpec[4]);
    182 
    183             if (mSampleRate == 0) {
    184                 return ERROR_MALFORMED;
    185             }
    186 
    187             mBitsPerSample = U16_LE_AT(&formatSpec[14]);
    188 
    189             if (mWaveFormat == WAVE_FORMAT_PCM) {
    190                 if (mBitsPerSample != 8 && mBitsPerSample != 16
    191                     && mBitsPerSample != 24) {
    192                     return ERROR_UNSUPPORTED;
    193                 }
    194             } else {
    195                 CHECK(mWaveFormat == WAVE_FORMAT_MULAW
    196                         || mWaveFormat == WAVE_FORMAT_ALAW);
    197                 if (mBitsPerSample != 8) {
    198                     return ERROR_UNSUPPORTED;
    199                 }
    200             }
    201 
    202             mValidFormat = true;
    203         } else if (!memcmp(chunkHeader, "data", 4)) {
    204             if (mValidFormat) {
    205                 mDataOffset = offset;
    206                 mDataSize = chunkSize;
    207 
    208                 mTrackMeta = new MetaData;
    209 
    210                 switch (mWaveFormat) {
    211                     case WAVE_FORMAT_PCM:
    212                         mTrackMeta->setCString(
    213                                 kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
    214                         break;
    215                     case WAVE_FORMAT_ALAW:
    216                         mTrackMeta->setCString(
    217                                 kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_G711_ALAW);
    218                         break;
    219                     default:
    220                         CHECK_EQ(mWaveFormat, WAVE_FORMAT_MULAW);
    221                         mTrackMeta->setCString(
    222                                 kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_G711_MLAW);
    223                         break;
    224                 }
    225 
    226                 mTrackMeta->setInt32(kKeyChannelCount, mNumChannels);
    227                 mTrackMeta->setInt32(kKeySampleRate, mSampleRate);
    228 
    229                 size_t bytesPerSample = mBitsPerSample >> 3;
    230 
    231                 int64_t durationUs =
    232                     1000000LL * (mDataSize / (mNumChannels * bytesPerSample))
    233                         / mSampleRate;
    234 
    235                 mTrackMeta->setInt64(kKeyDuration, durationUs);
    236 
    237                 return OK;
    238             }
    239         }
    240 
    241         offset += chunkSize;
    242     }
    243 
    244     return NO_INIT;
    245 }
    246 
    247 const size_t WAVSource::kMaxFrameSize = 32768;
    248 
    249 WAVSource::WAVSource(
    250         const sp<DataSource> &dataSource,
    251         const sp<MetaData> &meta,
    252         uint16_t waveFormat,
    253         int32_t bitsPerSample,
    254         off_t offset, size_t size)
    255     : mDataSource(dataSource),
    256       mMeta(meta),
    257       mWaveFormat(waveFormat),
    258       mSampleRate(0),
    259       mNumChannels(0),
    260       mBitsPerSample(bitsPerSample),
    261       mOffset(offset),
    262       mSize(size),
    263       mStarted(false),
    264       mGroup(NULL) {
    265     CHECK(mMeta->findInt32(kKeySampleRate, &mSampleRate));
    266     CHECK(mMeta->findInt32(kKeyChannelCount, &mNumChannels));
    267 }
    268 
    269 WAVSource::~WAVSource() {
    270     if (mStarted) {
    271         stop();
    272     }
    273 }
    274 
    275 status_t WAVSource::start(MetaData *params) {
    276     LOGV("WAVSource::start");
    277 
    278     CHECK(!mStarted);
    279 
    280     mGroup = new MediaBufferGroup;
    281     mGroup->add_buffer(new MediaBuffer(kMaxFrameSize));
    282 
    283     if (mBitsPerSample == 8) {
    284         // As a temporary buffer for 8->16 bit conversion.
    285         mGroup->add_buffer(new MediaBuffer(kMaxFrameSize));
    286     }
    287 
    288     mCurrentPos = mOffset;
    289 
    290     mStarted = true;
    291 
    292     return OK;
    293 }
    294 
    295 status_t WAVSource::stop() {
    296     LOGV("WAVSource::stop");
    297 
    298     CHECK(mStarted);
    299 
    300     delete mGroup;
    301     mGroup = NULL;
    302 
    303     mStarted = false;
    304 
    305     return OK;
    306 }
    307 
    308 sp<MetaData> WAVSource::getFormat() {
    309     LOGV("WAVSource::getFormat");
    310 
    311     return mMeta;
    312 }
    313 
    314 status_t WAVSource::read(
    315         MediaBuffer **out, const ReadOptions *options) {
    316     *out = NULL;
    317 
    318     int64_t seekTimeUs;
    319     ReadOptions::SeekMode mode;
    320     if (options != NULL && options->getSeekTo(&seekTimeUs, &mode)) {
    321         int64_t pos = (seekTimeUs * mSampleRate) / 1000000 * mNumChannels * 2;
    322         if (pos > mSize) {
    323             pos = mSize;
    324         }
    325         mCurrentPos = pos + mOffset;
    326     }
    327 
    328     MediaBuffer *buffer;
    329     status_t err = mGroup->acquire_buffer(&buffer);
    330     if (err != OK) {
    331         return err;
    332     }
    333 
    334     size_t maxBytesToRead =
    335         mBitsPerSample == 8 ? kMaxFrameSize / 2 : kMaxFrameSize;
    336 
    337     size_t maxBytesAvailable =
    338         (mCurrentPos - mOffset >= (off_t)mSize)
    339             ? 0 : mSize - (mCurrentPos - mOffset);
    340 
    341     if (maxBytesToRead > maxBytesAvailable) {
    342         maxBytesToRead = maxBytesAvailable;
    343     }
    344 
    345     ssize_t n = mDataSource->readAt(
    346             mCurrentPos, buffer->data(),
    347             maxBytesToRead);
    348 
    349     if (n <= 0) {
    350         buffer->release();
    351         buffer = NULL;
    352 
    353         return ERROR_END_OF_STREAM;
    354     }
    355 
    356     mCurrentPos += n;
    357 
    358     buffer->set_range(0, n);
    359 
    360     if (mWaveFormat == WAVE_FORMAT_PCM) {
    361         if (mBitsPerSample == 8) {
    362             // Convert 8-bit unsigned samples to 16-bit signed.
    363 
    364             MediaBuffer *tmp;
    365             CHECK_EQ(mGroup->acquire_buffer(&tmp), OK);
    366 
    367             // The new buffer holds the sample number of samples, but each
    368             // one is 2 bytes wide.
    369             tmp->set_range(0, 2 * n);
    370 
    371             int16_t *dst = (int16_t *)tmp->data();
    372             const uint8_t *src = (const uint8_t *)buffer->data();
    373             while (n-- > 0) {
    374                 *dst++ = ((int16_t)(*src) - 128) * 256;
    375                 ++src;
    376             }
    377 
    378             buffer->release();
    379             buffer = tmp;
    380         } else if (mBitsPerSample == 24) {
    381             // Convert 24-bit signed samples to 16-bit signed.
    382 
    383             const uint8_t *src =
    384                 (const uint8_t *)buffer->data() + buffer->range_offset();
    385             int16_t *dst = (int16_t *)src;
    386 
    387             size_t numSamples = buffer->range_length() / 3;
    388             for (size_t i = 0; i < numSamples; ++i) {
    389                 int32_t x = (int32_t)(src[0] | src[1] << 8 | src[2] << 16);
    390                 x = (x << 8) >> 8;  // sign extension
    391 
    392                 x = x >> 8;
    393                 *dst++ = (int16_t)x;
    394                 src += 3;
    395             }
    396 
    397             buffer->set_range(buffer->range_offset(), 2 * numSamples);
    398         }
    399     }
    400 
    401     size_t bytesPerSample = mBitsPerSample >> 3;
    402 
    403     buffer->meta_data()->setInt64(
    404             kKeyTime,
    405             1000000LL * (mCurrentPos - mOffset)
    406                 / (mNumChannels * bytesPerSample) / mSampleRate);
    407 
    408     buffer->meta_data()->setInt32(kKeyIsSyncFrame, 1);
    409 
    410     *out = buffer;
    411 
    412     return OK;
    413 }
    414 
    415 ////////////////////////////////////////////////////////////////////////////////
    416 
    417 bool SniffWAV(
    418         const sp<DataSource> &source, String8 *mimeType, float *confidence,
    419         sp<AMessage> *) {
    420     char header[12];
    421     if (source->readAt(0, header, sizeof(header)) < (ssize_t)sizeof(header)) {
    422         return false;
    423     }
    424 
    425     if (memcmp(header, "RIFF", 4) || memcmp(&header[8], "WAVE", 4)) {
    426         return false;
    427     }
    428 
    429     *mimeType = MEDIA_MIMETYPE_CONTAINER_WAV;
    430     *confidence = 0.3f;
    431 
    432     return true;
    433 }
    434 
    435 }  // namespace android
    436 
    437