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 off64_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 off64_t mOffset; 76 size_t mSize; 77 bool mStarted; 78 MediaBufferGroup *mGroup; 79 off64_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 off64_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 off64_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 mMeta->setInt32(kKeyMaxInputSize, kMaxFrameSize); 269 } 270 271 WAVSource::~WAVSource() { 272 if (mStarted) { 273 stop(); 274 } 275 } 276 277 status_t WAVSource::start(MetaData *params) { 278 LOGV("WAVSource::start"); 279 280 CHECK(!mStarted); 281 282 mGroup = new MediaBufferGroup; 283 mGroup->add_buffer(new MediaBuffer(kMaxFrameSize)); 284 285 if (mBitsPerSample == 8) { 286 // As a temporary buffer for 8->16 bit conversion. 287 mGroup->add_buffer(new MediaBuffer(kMaxFrameSize)); 288 } 289 290 mCurrentPos = mOffset; 291 292 mStarted = true; 293 294 return OK; 295 } 296 297 status_t WAVSource::stop() { 298 LOGV("WAVSource::stop"); 299 300 CHECK(mStarted); 301 302 delete mGroup; 303 mGroup = NULL; 304 305 mStarted = false; 306 307 return OK; 308 } 309 310 sp<MetaData> WAVSource::getFormat() { 311 LOGV("WAVSource::getFormat"); 312 313 return mMeta; 314 } 315 316 status_t WAVSource::read( 317 MediaBuffer **out, const ReadOptions *options) { 318 *out = NULL; 319 320 int64_t seekTimeUs; 321 ReadOptions::SeekMode mode; 322 if (options != NULL && options->getSeekTo(&seekTimeUs, &mode)) { 323 int64_t pos = (seekTimeUs * mSampleRate) / 1000000 * mNumChannels * (mBitsPerSample >> 3); 324 if (pos > mSize) { 325 pos = mSize; 326 } 327 mCurrentPos = pos + mOffset; 328 } 329 330 MediaBuffer *buffer; 331 status_t err = mGroup->acquire_buffer(&buffer); 332 if (err != OK) { 333 return err; 334 } 335 336 size_t maxBytesToRead = 337 mBitsPerSample == 8 ? kMaxFrameSize / 2 : kMaxFrameSize; 338 339 size_t maxBytesAvailable = 340 (mCurrentPos - mOffset >= (off64_t)mSize) 341 ? 0 : mSize - (mCurrentPos - mOffset); 342 343 if (maxBytesToRead > maxBytesAvailable) { 344 maxBytesToRead = maxBytesAvailable; 345 } 346 347 ssize_t n = mDataSource->readAt( 348 mCurrentPos, buffer->data(), 349 maxBytesToRead); 350 351 if (n <= 0) { 352 buffer->release(); 353 buffer = NULL; 354 355 return ERROR_END_OF_STREAM; 356 } 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 ssize_t numBytes = n; 374 375 while (numBytes-- > 0) { 376 *dst++ = ((int16_t)(*src) - 128) * 256; 377 ++src; 378 } 379 380 buffer->release(); 381 buffer = tmp; 382 } else if (mBitsPerSample == 24) { 383 // Convert 24-bit signed samples to 16-bit signed. 384 385 const uint8_t *src = 386 (const uint8_t *)buffer->data() + buffer->range_offset(); 387 int16_t *dst = (int16_t *)src; 388 389 size_t numSamples = buffer->range_length() / 3; 390 for (size_t i = 0; i < numSamples; ++i) { 391 int32_t x = (int32_t)(src[0] | src[1] << 8 | src[2] << 16); 392 x = (x << 8) >> 8; // sign extension 393 394 x = x >> 8; 395 *dst++ = (int16_t)x; 396 src += 3; 397 } 398 399 buffer->set_range(buffer->range_offset(), 2 * numSamples); 400 } 401 } 402 403 size_t bytesPerSample = mBitsPerSample >> 3; 404 405 buffer->meta_data()->setInt64( 406 kKeyTime, 407 1000000LL * (mCurrentPos - mOffset) 408 / (mNumChannels * bytesPerSample) / mSampleRate); 409 410 buffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); 411 mCurrentPos += n; 412 413 *out = buffer; 414 415 return OK; 416 } 417 418 //////////////////////////////////////////////////////////////////////////////// 419 420 bool SniffWAV( 421 const sp<DataSource> &source, String8 *mimeType, float *confidence, 422 sp<AMessage> *) { 423 char header[12]; 424 if (source->readAt(0, header, sizeof(header)) < (ssize_t)sizeof(header)) { 425 return false; 426 } 427 428 if (memcmp(header, "RIFF", 4) || memcmp(&header[8], "WAVE", 4)) { 429 return false; 430 } 431 432 sp<MediaExtractor> extractor = new WAVExtractor(source); 433 if (extractor->countTracks() == 0) { 434 return false; 435 } 436 437 *mimeType = MEDIA_MIMETYPE_CONTAINER_WAV; 438 *confidence = 0.3f; 439 440 return true; 441 } 442 443 } // namespace android 444 445