summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/WAVExtractor.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'media/libstagefright/WAVExtractor.cpp')
-rw-r--r--media/libstagefright/WAVExtractor.cpp78
1 files changed, 49 insertions, 29 deletions
diff --git a/media/libstagefright/WAVExtractor.cpp b/media/libstagefright/WAVExtractor.cpp
index 335ac84..62bb416 100644
--- a/media/libstagefright/WAVExtractor.cpp
+++ b/media/libstagefright/WAVExtractor.cpp
@@ -29,6 +29,7 @@
#include <media/stagefright/MetaData.h>
#include <utils/String8.h>
#include <cutils/bitops.h>
+#include <system/audio.h>
#define CHANNEL_MASK_USE_CHANNEL_ORDER 0
@@ -193,15 +194,17 @@ status_t WAVExtractor::init() {
}
mNumChannels = U16_LE_AT(&formatSpec[2]);
+
+ if (mNumChannels < 1 || mNumChannels > 8) {
+ ALOGE("Unsupported number of channels (%d)", mNumChannels);
+ return ERROR_UNSUPPORTED;
+ }
+
if (mWaveFormat != WAVE_FORMAT_EXTENSIBLE) {
if (mNumChannels != 1 && mNumChannels != 2) {
ALOGW("More than 2 channels (%d) in non-WAVE_EXT, unknown channel mask",
mNumChannels);
}
- } else {
- if (mNumChannels < 1 && mNumChannels > 8) {
- return ERROR_UNSUPPORTED;
- }
}
mSampleRate = U32_LE_AT(&formatSpec[4]);
@@ -284,6 +287,7 @@ status_t WAVExtractor::init() {
case WAVE_FORMAT_PCM:
mTrackMeta->setCString(
kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
+ mTrackMeta->setInt32(kKeyBitsPerSample, mBitsPerSample);
break;
case WAVE_FORMAT_ALAW:
mTrackMeta->setCString(
@@ -311,9 +315,17 @@ status_t WAVExtractor::init() {
1000000LL * (mDataSize / 65 * 320) / 8000;
} else {
size_t bytesPerSample = mBitsPerSample >> 3;
+
+ if (!bytesPerSample || !mNumChannels)
+ return ERROR_MALFORMED;
+
+ size_t num_samples = mDataSize / (mNumChannels * bytesPerSample);
+
+ if (!mSampleRate)
+ return ERROR_MALFORMED;
+
durationUs =
- 1000000LL * (mDataSize / (mNumChannels * bytesPerSample))
- / mSampleRate;
+ 1000000LL * num_samples / mSampleRate;
}
mTrackMeta->setInt64(kKeyDuration, durationUs);
@@ -359,15 +371,16 @@ WAVSource::~WAVSource() {
}
status_t WAVSource::start(MetaData * /* params */) {
- ALOGV("WAVSource::start");
- CHECK(!mStarted);
+ if (mStarted) {
+ return OK;
+ }
mGroup = new MediaBufferGroup;
mGroup->add_buffer(new MediaBuffer(kMaxFrameSize));
- if (mBitsPerSample == 8) {
- // As a temporary buffer for 8->16 bit conversion.
+ if (mBitsPerSample == 8 || mBitsPerSample == 24) {
+ // As a temporary buffer for 8->16/24->32 bit conversion.
mGroup->add_buffer(new MediaBuffer(kMaxFrameSize));
}
@@ -427,9 +440,15 @@ status_t WAVSource::read(
}
// make sure that maxBytesToRead is multiple of 3, in 24-bit case
- size_t maxBytesToRead =
- mBitsPerSample == 8 ? kMaxFrameSize / 2 :
- (mBitsPerSample == 24 ? 3*(kMaxFrameSize/3): kMaxFrameSize);
+ size_t maxBytesToRead;
+ if(8 == mBitsPerSample)
+ maxBytesToRead = kMaxFrameSize / 2;
+ else if (24 == mBitsPerSample) {
+ maxBytesToRead = 3*(kMaxFrameSize/4);
+ } else
+ maxBytesToRead = kMaxFrameSize;
+ ALOGV("%s mBitsPerSample %d, kMaxFrameSize %zu, ",
+ __func__, mBitsPerSample, kMaxFrameSize);
size_t maxBytesAvailable =
(mCurrentPos - mOffset >= (off64_t)mSize)
@@ -488,23 +507,24 @@ status_t WAVSource::read(
buffer->release();
buffer = tmp;
} else if (mBitsPerSample == 24) {
- // Convert 24-bit signed samples to 16-bit signed.
-
- const uint8_t *src =
- (const uint8_t *)buffer->data() + buffer->range_offset();
- int16_t *dst = (int16_t *)src;
-
- size_t numSamples = buffer->range_length() / 3;
- for (size_t i = 0; i < numSamples; ++i) {
- int32_t x = (int32_t)(src[0] | src[1] << 8 | src[2] << 16);
- x = (x << 8) >> 8; // sign extension
-
- x = x >> 8;
- *dst++ = (int16_t)x;
- src += 3;
+ // Padding done here to convert to 32-bit samples
+ MediaBuffer *tmp;
+ CHECK_EQ(mGroup->acquire_buffer(&tmp), (status_t)OK);
+ ssize_t numBytes = buffer->range_length() / 3;
+ tmp->set_range(0, 4 * numBytes);
+ int8_t *dst = (int8_t *)tmp->data();
+ const uint8_t *src = (const uint8_t *)buffer->data();
+ ALOGV("numBytes = %zd", numBytes);
+ while(numBytes-- > 0) {
+ *dst++ = 0x0;
+ *dst++ = src[0];
+ *dst++ = src[1];
+ *dst++ = src[2];
+ src += 3;
}
-
- buffer->set_range(buffer->range_offset(), 2 * numSamples);
+ buffer->release();
+ buffer = tmp;
+ ALOGV("length = %zu", buffer->range_length());
}
}