am 4edf85ab: Merge "Support for extracting G.711 a-law and mu-law audio from WAV files and a corresponding software decoder." into gingerbread
Merge commit '4edf85abc919b7d0e8db71c0c6166c7994269830' into gingerbread-plus-aosp * commit '4edf85abc919b7d0e8db71c0c6166c7994269830': Support for extracting G.711 a-law and mu-law audio from WAV files and a corresponding software decoder.
This commit is contained in:
@@ -34,6 +34,8 @@ extern const char *MEDIA_MIMETYPE_AUDIO_MPEG;
|
||||
extern const char *MEDIA_MIMETYPE_AUDIO_AAC;
|
||||
extern const char *MEDIA_MIMETYPE_AUDIO_QCELP;
|
||||
extern const char *MEDIA_MIMETYPE_AUDIO_VORBIS;
|
||||
extern const char *MEDIA_MIMETYPE_AUDIO_G711_ALAW;
|
||||
extern const char *MEDIA_MIMETYPE_AUDIO_G711_MLAW;
|
||||
extern const char *MEDIA_MIMETYPE_AUDIO_RAW;
|
||||
|
||||
extern const char *MEDIA_MIMETYPE_CONTAINER_MPEG4;
|
||||
|
||||
@@ -79,6 +79,7 @@ LOCAL_STATIC_LIBRARIES := \
|
||||
libstagefright_httplive \
|
||||
libstagefright_rtsp \
|
||||
libstagefright_id3 \
|
||||
libstagefright_g711dec \
|
||||
|
||||
LOCAL_SHARED_LIBRARIES += \
|
||||
libstagefright_amrnb_common \
|
||||
|
||||
@@ -32,6 +32,8 @@ const char *MEDIA_MIMETYPE_AUDIO_MPEG = "audio/mpeg";
|
||||
const char *MEDIA_MIMETYPE_AUDIO_AAC = "audio/mp4a-latm";
|
||||
const char *MEDIA_MIMETYPE_AUDIO_QCELP = "audio/qcelp";
|
||||
const char *MEDIA_MIMETYPE_AUDIO_VORBIS = "audio/vorbis";
|
||||
const char *MEDIA_MIMETYPE_AUDIO_G711_ALAW = "audio/g711-alaw";
|
||||
const char *MEDIA_MIMETYPE_AUDIO_G711_MLAW = "audio/g711-mlaw";
|
||||
const char *MEDIA_MIMETYPE_AUDIO_RAW = "audio/raw";
|
||||
|
||||
const char *MEDIA_MIMETYPE_CONTAINER_MPEG4 = "video/mpeg4";
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "include/AMRWBEncoder.h"
|
||||
#include "include/AVCDecoder.h"
|
||||
#include "include/AVCEncoder.h"
|
||||
#include "include/G711Decoder.h"
|
||||
#include "include/M4vH263Decoder.h"
|
||||
#include "include/M4vH263Encoder.h"
|
||||
#include "include/MP3Decoder.h"
|
||||
@@ -77,6 +78,7 @@ FACTORY_CREATE(AMRNBDecoder)
|
||||
FACTORY_CREATE(AMRWBDecoder)
|
||||
FACTORY_CREATE(AACDecoder)
|
||||
FACTORY_CREATE(AVCDecoder)
|
||||
FACTORY_CREATE(G711Decoder)
|
||||
FACTORY_CREATE(M4vH263Decoder)
|
||||
FACTORY_CREATE(VorbisDecoder)
|
||||
FACTORY_CREATE(VPXDecoder)
|
||||
@@ -124,6 +126,7 @@ static sp<MediaSource> InstantiateSoftwareCodec(
|
||||
FACTORY_REF(AMRWBDecoder)
|
||||
FACTORY_REF(AACDecoder)
|
||||
FACTORY_REF(AVCDecoder)
|
||||
FACTORY_REF(G711Decoder)
|
||||
FACTORY_REF(M4vH263Decoder)
|
||||
FACTORY_REF(VorbisDecoder)
|
||||
FACTORY_REF(VPXDecoder)
|
||||
@@ -155,6 +158,8 @@ static const CodecInfo kDecoderInfo[] = {
|
||||
{ MEDIA_MIMETYPE_AUDIO_AAC, "OMX.TI.AAC.decode" },
|
||||
{ MEDIA_MIMETYPE_AUDIO_AAC, "AACDecoder" },
|
||||
// { MEDIA_MIMETYPE_AUDIO_AAC, "OMX.PV.aacdec" },
|
||||
{ MEDIA_MIMETYPE_AUDIO_G711_ALAW, "G711Decoder" },
|
||||
{ MEDIA_MIMETYPE_AUDIO_G711_MLAW, "G711Decoder" },
|
||||
{ MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.qcom.7x30.video.decoder.mpeg4" },
|
||||
{ MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.qcom.video.decoder.mpeg4" },
|
||||
{ MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.TI.Video.Decoder" },
|
||||
|
||||
@@ -31,7 +31,11 @@
|
||||
|
||||
namespace android {
|
||||
|
||||
static uint16_t WAVE_FORMAT_PCM = 1;
|
||||
enum {
|
||||
WAVE_FORMAT_PCM = 1,
|
||||
WAVE_FORMAT_ALAW = 6,
|
||||
WAVE_FORMAT_MULAW = 7,
|
||||
};
|
||||
|
||||
static uint32_t U32_LE_AT(const uint8_t *ptr) {
|
||||
return ptr[3] << 24 | ptr[2] << 16 | ptr[1] << 8 | ptr[0];
|
||||
@@ -45,6 +49,7 @@ struct WAVSource : public MediaSource {
|
||||
WAVSource(
|
||||
const sp<DataSource> &dataSource,
|
||||
const sp<MetaData> &meta,
|
||||
uint16_t waveFormat,
|
||||
int32_t bitsPerSample,
|
||||
off_t offset, size_t size);
|
||||
|
||||
@@ -63,6 +68,7 @@ private:
|
||||
|
||||
sp<DataSource> mDataSource;
|
||||
sp<MetaData> mMeta;
|
||||
uint16_t mWaveFormat;
|
||||
int32_t mSampleRate;
|
||||
int32_t mNumChannels;
|
||||
int32_t mBitsPerSample;
|
||||
@@ -108,7 +114,7 @@ sp<MediaSource> WAVExtractor::getTrack(size_t index) {
|
||||
|
||||
return new WAVSource(
|
||||
mDataSource, mTrackMeta,
|
||||
mBitsPerSample, mDataOffset, mDataSize);
|
||||
mWaveFormat, mBitsPerSample, mDataOffset, mDataSize);
|
||||
}
|
||||
|
||||
sp<MetaData> WAVExtractor::getTrackMetaData(
|
||||
@@ -160,8 +166,10 @@ status_t WAVExtractor::init() {
|
||||
return NO_INIT;
|
||||
}
|
||||
|
||||
uint16_t format = U16_LE_AT(formatSpec);
|
||||
if (format != WAVE_FORMAT_PCM) {
|
||||
mWaveFormat = U16_LE_AT(formatSpec);
|
||||
if (mWaveFormat != WAVE_FORMAT_PCM
|
||||
&& mWaveFormat != WAVE_FORMAT_ALAW
|
||||
&& mWaveFormat != WAVE_FORMAT_MULAW) {
|
||||
return ERROR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
@@ -178,9 +186,17 @@ status_t WAVExtractor::init() {
|
||||
|
||||
mBitsPerSample = U16_LE_AT(&formatSpec[14]);
|
||||
|
||||
if (mBitsPerSample != 8 && mBitsPerSample != 16
|
||||
&& mBitsPerSample != 24) {
|
||||
return ERROR_UNSUPPORTED;
|
||||
if (mWaveFormat == WAVE_FORMAT_PCM) {
|
||||
if (mBitsPerSample != 8 && mBitsPerSample != 16
|
||||
&& mBitsPerSample != 24) {
|
||||
return ERROR_UNSUPPORTED;
|
||||
}
|
||||
} else {
|
||||
CHECK(mWaveFormat == WAVE_FORMAT_MULAW
|
||||
|| mWaveFormat == WAVE_FORMAT_ALAW);
|
||||
if (mBitsPerSample != 8) {
|
||||
return ERROR_UNSUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
mValidFormat = true;
|
||||
@@ -190,7 +206,23 @@ status_t WAVExtractor::init() {
|
||||
mDataSize = chunkSize;
|
||||
|
||||
mTrackMeta = new MetaData;
|
||||
mTrackMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
|
||||
|
||||
switch (mWaveFormat) {
|
||||
case WAVE_FORMAT_PCM:
|
||||
mTrackMeta->setCString(
|
||||
kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
|
||||
break;
|
||||
case WAVE_FORMAT_ALAW:
|
||||
mTrackMeta->setCString(
|
||||
kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_G711_ALAW);
|
||||
break;
|
||||
default:
|
||||
CHECK_EQ(mWaveFormat, WAVE_FORMAT_MULAW);
|
||||
mTrackMeta->setCString(
|
||||
kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_G711_MLAW);
|
||||
break;
|
||||
}
|
||||
|
||||
mTrackMeta->setInt32(kKeyChannelCount, mNumChannels);
|
||||
mTrackMeta->setInt32(kKeySampleRate, mSampleRate);
|
||||
|
||||
@@ -217,10 +249,12 @@ const size_t WAVSource::kMaxFrameSize = 32768;
|
||||
WAVSource::WAVSource(
|
||||
const sp<DataSource> &dataSource,
|
||||
const sp<MetaData> &meta,
|
||||
uint16_t waveFormat,
|
||||
int32_t bitsPerSample,
|
||||
off_t offset, size_t size)
|
||||
: mDataSource(dataSource),
|
||||
mMeta(meta),
|
||||
mWaveFormat(waveFormat),
|
||||
mSampleRate(0),
|
||||
mNumChannels(0),
|
||||
mBitsPerSample(bitsPerSample),
|
||||
@@ -312,43 +346,45 @@ status_t WAVSource::read(
|
||||
|
||||
buffer->set_range(0, n);
|
||||
|
||||
if (mBitsPerSample == 8) {
|
||||
// Convert 8-bit unsigned samples to 16-bit signed.
|
||||
if (mWaveFormat == WAVE_FORMAT_PCM) {
|
||||
if (mBitsPerSample == 8) {
|
||||
// Convert 8-bit unsigned samples to 16-bit signed.
|
||||
|
||||
MediaBuffer *tmp;
|
||||
CHECK_EQ(mGroup->acquire_buffer(&tmp), OK);
|
||||
MediaBuffer *tmp;
|
||||
CHECK_EQ(mGroup->acquire_buffer(&tmp), OK);
|
||||
|
||||
// The new buffer holds the sample number of samples, but each
|
||||
// one is 2 bytes wide.
|
||||
tmp->set_range(0, 2 * n);
|
||||
// The new buffer holds the sample number of samples, but each
|
||||
// one is 2 bytes wide.
|
||||
tmp->set_range(0, 2 * n);
|
||||
|
||||
int16_t *dst = (int16_t *)tmp->data();
|
||||
const uint8_t *src = (const uint8_t *)buffer->data();
|
||||
while (n-- > 0) {
|
||||
*dst++ = ((int16_t)(*src) - 128) * 256;
|
||||
++src;
|
||||
int16_t *dst = (int16_t *)tmp->data();
|
||||
const uint8_t *src = (const uint8_t *)buffer->data();
|
||||
while (n-- > 0) {
|
||||
*dst++ = ((int16_t)(*src) - 128) * 256;
|
||||
++src;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
buffer->set_range(buffer->range_offset(), 2 * numSamples);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
buffer->set_range(buffer->range_offset(), 2 * numSamples);
|
||||
}
|
||||
|
||||
size_t bytesPerSample = mBitsPerSample >> 3;
|
||||
|
||||
4
media/libstagefright/codecs/g711/Android.mk
Normal file
4
media/libstagefright/codecs/g711/Android.mk
Normal file
@@ -0,0 +1,4 @@
|
||||
LOCAL_PATH:= $(call my-dir)
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
include $(call all-makefiles-under,$(LOCAL_PATH))
|
||||
12
media/libstagefright/codecs/g711/dec/Android.mk
Normal file
12
media/libstagefright/codecs/g711/dec/Android.mk
Normal file
@@ -0,0 +1,12 @@
|
||||
LOCAL_PATH:= $(call my-dir)
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_SRC_FILES := \
|
||||
G711Decoder.cpp
|
||||
|
||||
LOCAL_C_INCLUDES := \
|
||||
frameworks/base/media/libstagefright/include \
|
||||
|
||||
LOCAL_MODULE := libstagefright_g711dec
|
||||
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
213
media/libstagefright/codecs/g711/dec/G711Decoder.cpp
Normal file
213
media/libstagefright/codecs/g711/dec/G711Decoder.cpp
Normal file
@@ -0,0 +1,213 @@
|
||||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
//#define LOG_NDEBUG 0
|
||||
#define LOG_TAG "G711Decoder"
|
||||
#include <utils/Log.h>
|
||||
|
||||
#include "G711Decoder.h"
|
||||
|
||||
#include <media/stagefright/MediaBufferGroup.h>
|
||||
#include <media/stagefright/MediaDebug.h>
|
||||
#include <media/stagefright/MediaDefs.h>
|
||||
#include <media/stagefright/MediaErrors.h>
|
||||
#include <media/stagefright/MetaData.h>
|
||||
|
||||
static const size_t kMaxNumSamplesPerFrame = 16384;
|
||||
|
||||
namespace android {
|
||||
|
||||
G711Decoder::G711Decoder(const sp<MediaSource> &source)
|
||||
: mSource(source),
|
||||
mStarted(false),
|
||||
mBufferGroup(NULL) {
|
||||
}
|
||||
|
||||
G711Decoder::~G711Decoder() {
|
||||
if (mStarted) {
|
||||
stop();
|
||||
}
|
||||
}
|
||||
|
||||
status_t G711Decoder::start(MetaData *params) {
|
||||
CHECK(!mStarted);
|
||||
|
||||
const char *mime;
|
||||
CHECK(mSource->getFormat()->findCString(kKeyMIMEType, &mime));
|
||||
|
||||
mIsMLaw = false;
|
||||
if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) {
|
||||
mIsMLaw = true;
|
||||
} else if (strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW)) {
|
||||
return ERROR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
mBufferGroup = new MediaBufferGroup;
|
||||
mBufferGroup->add_buffer(
|
||||
new MediaBuffer(kMaxNumSamplesPerFrame * sizeof(int16_t)));
|
||||
|
||||
mSource->start();
|
||||
|
||||
mStarted = true;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
status_t G711Decoder::stop() {
|
||||
CHECK(mStarted);
|
||||
|
||||
delete mBufferGroup;
|
||||
mBufferGroup = NULL;
|
||||
|
||||
mSource->stop();
|
||||
|
||||
mStarted = false;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
sp<MetaData> G711Decoder::getFormat() {
|
||||
sp<MetaData> srcFormat = mSource->getFormat();
|
||||
|
||||
int32_t numChannels;
|
||||
int32_t sampleRate;
|
||||
|
||||
CHECK(srcFormat->findInt32(kKeyChannelCount, &numChannels));
|
||||
CHECK(srcFormat->findInt32(kKeySampleRate, &sampleRate));
|
||||
|
||||
sp<MetaData> meta = new MetaData;
|
||||
meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
|
||||
meta->setInt32(kKeyChannelCount, numChannels);
|
||||
meta->setInt32(kKeySampleRate, sampleRate);
|
||||
|
||||
int64_t durationUs;
|
||||
if (srcFormat->findInt64(kKeyDuration, &durationUs)) {
|
||||
meta->setInt64(kKeyDuration, durationUs);
|
||||
}
|
||||
|
||||
meta->setCString(kKeyDecoderComponent, "G711Decoder");
|
||||
|
||||
return meta;
|
||||
}
|
||||
|
||||
status_t G711Decoder::read(
|
||||
MediaBuffer **out, const ReadOptions *options) {
|
||||
status_t err;
|
||||
|
||||
*out = NULL;
|
||||
|
||||
int64_t seekTimeUs;
|
||||
ReadOptions::SeekMode mode;
|
||||
if (options && options->getSeekTo(&seekTimeUs, &mode)) {
|
||||
CHECK(seekTimeUs >= 0);
|
||||
} else {
|
||||
seekTimeUs = -1;
|
||||
}
|
||||
|
||||
MediaBuffer *inBuffer;
|
||||
err = mSource->read(&inBuffer, options);
|
||||
|
||||
if (err != OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if (inBuffer->range_length() > kMaxNumSamplesPerFrame) {
|
||||
LOGE("input buffer too large (%d).", inBuffer->range_length());
|
||||
|
||||
inBuffer->release();
|
||||
inBuffer = NULL;
|
||||
|
||||
return ERROR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
int64_t timeUs;
|
||||
CHECK(inBuffer->meta_data()->findInt64(kKeyTime, &timeUs));
|
||||
|
||||
const uint8_t *inputPtr =
|
||||
(const uint8_t *)inBuffer->data() + inBuffer->range_offset();
|
||||
|
||||
MediaBuffer *outBuffer;
|
||||
CHECK_EQ(mBufferGroup->acquire_buffer(&outBuffer), OK);
|
||||
|
||||
if (mIsMLaw) {
|
||||
DecodeMLaw(
|
||||
static_cast<int16_t *>(outBuffer->data()),
|
||||
inputPtr, inBuffer->range_length());
|
||||
} else {
|
||||
DecodeALaw(
|
||||
static_cast<int16_t *>(outBuffer->data()),
|
||||
inputPtr, inBuffer->range_length());
|
||||
}
|
||||
|
||||
// Each 8-bit byte is converted into a 16-bit sample.
|
||||
outBuffer->set_range(0, inBuffer->range_length() * 2);
|
||||
|
||||
outBuffer->meta_data()->setInt64(kKeyTime, timeUs);
|
||||
|
||||
inBuffer->release();
|
||||
inBuffer = NULL;
|
||||
|
||||
*out = outBuffer;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
// static
|
||||
void G711Decoder::DecodeALaw(
|
||||
int16_t *out, const uint8_t *in, size_t inSize) {
|
||||
while (inSize-- > 0) {
|
||||
int32_t x = *in++;
|
||||
|
||||
int32_t ix = x ^ 0x55;
|
||||
ix &= 0x7f;
|
||||
|
||||
int32_t iexp = ix >> 4;
|
||||
int32_t mant = ix & 0x0f;
|
||||
|
||||
if (iexp > 0) {
|
||||
mant += 16;
|
||||
}
|
||||
|
||||
mant = (mant << 4) + 8;
|
||||
|
||||
if (iexp > 1) {
|
||||
mant = mant << (iexp - 1);
|
||||
}
|
||||
|
||||
*out++ = (x > 127) ? mant : -mant;
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void G711Decoder::DecodeMLaw(
|
||||
int16_t *out, const uint8_t *in, size_t inSize) {
|
||||
while (inSize-- > 0) {
|
||||
int32_t x = *in++;
|
||||
|
||||
int32_t mantissa = ~x;
|
||||
int32_t exponent = (mantissa >> 4) & 7;
|
||||
int32_t segment = exponent + 1;
|
||||
mantissa &= 0x0f;
|
||||
|
||||
int32_t step = 4 << segment;
|
||||
|
||||
int32_t abs = (0x80l << exponent) + step * mantissa + step / 2 - 4 * 33;
|
||||
|
||||
*out++ = (x < 0x80) ? -abs : abs;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace android
|
||||
57
media/libstagefright/include/G711Decoder.h
Normal file
57
media/libstagefright/include/G711Decoder.h
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef G711_DECODER_H_
|
||||
|
||||
#define G711_DECODER_H_
|
||||
|
||||
#include <media/stagefright/MediaSource.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
struct MediaBufferGroup;
|
||||
|
||||
struct G711Decoder : public MediaSource {
|
||||
G711Decoder(const sp<MediaSource> &source);
|
||||
|
||||
virtual status_t start(MetaData *params);
|
||||
virtual status_t stop();
|
||||
|
||||
virtual sp<MetaData> getFormat();
|
||||
|
||||
virtual status_t read(
|
||||
MediaBuffer **buffer, const ReadOptions *options);
|
||||
|
||||
protected:
|
||||
virtual ~G711Decoder();
|
||||
|
||||
private:
|
||||
sp<MediaSource> mSource;
|
||||
bool mStarted;
|
||||
bool mIsMLaw;
|
||||
|
||||
MediaBufferGroup *mBufferGroup;
|
||||
|
||||
static void DecodeALaw(int16_t *out, const uint8_t *in, size_t inSize);
|
||||
static void DecodeMLaw(int16_t *out, const uint8_t *in, size_t inSize);
|
||||
|
||||
G711Decoder(const G711Decoder &);
|
||||
G711Decoder &operator=(const G711Decoder &);
|
||||
};
|
||||
|
||||
} // namespace android
|
||||
|
||||
#endif // G711_DECODER_H_
|
||||
@@ -43,6 +43,7 @@ private:
|
||||
sp<DataSource> mDataSource;
|
||||
status_t mInitCheck;
|
||||
bool mValidFormat;
|
||||
uint16_t mWaveFormat;
|
||||
uint16_t mNumChannels;
|
||||
uint32_t mSampleRate;
|
||||
uint16_t mBitsPerSample;
|
||||
|
||||
Reference in New Issue
Block a user