1520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber/* 2520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber * Copyright (C) 2010 The Android Open Source Project 3520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber * 4520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 5520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber * you may not use this file except in compliance with the License. 6520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber * You may obtain a copy of the License at 7520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber * 8520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber * http://www.apache.org/licenses/LICENSE-2.0 9520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber * 10520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber * Unless required by applicable law or agreed to in writing, software 11520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 12520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber * See the License for the specific language governing permissions and 14520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber * limitations under the License. 15520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber */ 16520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber 17520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber//#define LOG_NDEBUG 0 18520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber#define LOG_TAG "G711Decoder" 19520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber#include <utils/Log.h> 20520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber 21520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber#include "G711Decoder.h" 22520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber 23520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber#include <media/stagefright/MediaBufferGroup.h> 24520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber#include <media/stagefright/MediaDebug.h> 25520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber#include <media/stagefright/MediaDefs.h> 26520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber#include <media/stagefright/MediaErrors.h> 27520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber#include <media/stagefright/MetaData.h> 28520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber 29520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huberstatic const size_t kMaxNumSamplesPerFrame = 16384; 30520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber 31520b2a7039792f03da11a8d54344f10175cebfbcAndreas Hubernamespace android { 32520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber 33520b2a7039792f03da11a8d54344f10175cebfbcAndreas HuberG711Decoder::G711Decoder(const sp<MediaSource> &source) 34520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber : mSource(source), 35520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber mStarted(false), 36520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber mBufferGroup(NULL) { 37520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber} 38520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber 39520b2a7039792f03da11a8d54344f10175cebfbcAndreas HuberG711Decoder::~G711Decoder() { 40520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber if (mStarted) { 41520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber stop(); 42520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber } 43520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber} 44520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber 45520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huberstatus_t G711Decoder::start(MetaData *params) { 46520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber CHECK(!mStarted); 47520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber 48520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber const char *mime; 49520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber CHECK(mSource->getFormat()->findCString(kKeyMIMEType, &mime)); 50520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber 51520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber mIsMLaw = false; 52520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) { 53520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber mIsMLaw = true; 54520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber } else if (strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW)) { 55520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber return ERROR_UNSUPPORTED; 56520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber } 57520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber 58520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber mBufferGroup = new MediaBufferGroup; 59520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber mBufferGroup->add_buffer( 60520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber new MediaBuffer(kMaxNumSamplesPerFrame * sizeof(int16_t))); 61520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber 62520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber mSource->start(); 63520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber 64520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber mStarted = true; 65520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber 66520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber return OK; 67520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber} 68520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber 69520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huberstatus_t G711Decoder::stop() { 70520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber CHECK(mStarted); 71520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber 72520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber delete mBufferGroup; 73520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber mBufferGroup = NULL; 74520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber 75520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber mSource->stop(); 76520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber 77520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber mStarted = false; 78520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber 79520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber return OK; 80520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber} 81520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber 82520b2a7039792f03da11a8d54344f10175cebfbcAndreas Hubersp<MetaData> G711Decoder::getFormat() { 83520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber sp<MetaData> srcFormat = mSource->getFormat(); 84520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber 85520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber int32_t numChannels; 86520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber int32_t sampleRate; 87520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber 88520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber CHECK(srcFormat->findInt32(kKeyChannelCount, &numChannels)); 89520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber CHECK(srcFormat->findInt32(kKeySampleRate, &sampleRate)); 90520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber 91520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber sp<MetaData> meta = new MetaData; 92520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW); 93520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber meta->setInt32(kKeyChannelCount, numChannels); 94520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber meta->setInt32(kKeySampleRate, sampleRate); 95520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber 96520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber int64_t durationUs; 97520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber if (srcFormat->findInt64(kKeyDuration, &durationUs)) { 98520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber meta->setInt64(kKeyDuration, durationUs); 99520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber } 100520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber 101520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber meta->setCString(kKeyDecoderComponent, "G711Decoder"); 102520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber 103520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber return meta; 104520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber} 105520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber 106520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huberstatus_t G711Decoder::read( 107520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber MediaBuffer **out, const ReadOptions *options) { 108520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber status_t err; 109520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber 110520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber *out = NULL; 111520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber 112520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber int64_t seekTimeUs; 113520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber ReadOptions::SeekMode mode; 114520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber if (options && options->getSeekTo(&seekTimeUs, &mode)) { 115520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber CHECK(seekTimeUs >= 0); 116520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber } else { 117520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber seekTimeUs = -1; 118520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber } 119520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber 120520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber MediaBuffer *inBuffer; 121520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber err = mSource->read(&inBuffer, options); 122520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber 123520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber if (err != OK) { 124520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber return err; 125520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber } 126520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber 127520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber if (inBuffer->range_length() > kMaxNumSamplesPerFrame) { 128520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber LOGE("input buffer too large (%d).", inBuffer->range_length()); 129520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber 130520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber inBuffer->release(); 131520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber inBuffer = NULL; 132520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber 133520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber return ERROR_UNSUPPORTED; 134520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber } 135520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber 136520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber int64_t timeUs; 137520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber CHECK(inBuffer->meta_data()->findInt64(kKeyTime, &timeUs)); 138520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber 139520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber const uint8_t *inputPtr = 140520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber (const uint8_t *)inBuffer->data() + inBuffer->range_offset(); 141520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber 142520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber MediaBuffer *outBuffer; 143520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber CHECK_EQ(mBufferGroup->acquire_buffer(&outBuffer), OK); 144520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber 145520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber if (mIsMLaw) { 146520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber DecodeMLaw( 147520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber static_cast<int16_t *>(outBuffer->data()), 148520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber inputPtr, inBuffer->range_length()); 149520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber } else { 150520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber DecodeALaw( 151520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber static_cast<int16_t *>(outBuffer->data()), 152520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber inputPtr, inBuffer->range_length()); 153520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber } 154520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber 155520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber // Each 8-bit byte is converted into a 16-bit sample. 156520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber outBuffer->set_range(0, inBuffer->range_length() * 2); 157520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber 158520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber outBuffer->meta_data()->setInt64(kKeyTime, timeUs); 159520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber 160520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber inBuffer->release(); 161520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber inBuffer = NULL; 162520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber 163520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber *out = outBuffer; 164520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber 165520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber return OK; 166520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber} 167520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber 168520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber// static 169520b2a7039792f03da11a8d54344f10175cebfbcAndreas Hubervoid G711Decoder::DecodeALaw( 170520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber int16_t *out, const uint8_t *in, size_t inSize) { 171520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber while (inSize-- > 0) { 172520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber int32_t x = *in++; 173520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber 174520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber int32_t ix = x ^ 0x55; 175520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber ix &= 0x7f; 176520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber 177520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber int32_t iexp = ix >> 4; 178520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber int32_t mant = ix & 0x0f; 179520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber 180520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber if (iexp > 0) { 181520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber mant += 16; 182520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber } 183520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber 184520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber mant = (mant << 4) + 8; 185520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber 186520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber if (iexp > 1) { 187520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber mant = mant << (iexp - 1); 188520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber } 189520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber 190520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber *out++ = (x > 127) ? mant : -mant; 191520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber } 192520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber} 193520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber 194520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber// static 195520b2a7039792f03da11a8d54344f10175cebfbcAndreas Hubervoid G711Decoder::DecodeMLaw( 196520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber int16_t *out, const uint8_t *in, size_t inSize) { 197520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber while (inSize-- > 0) { 198520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber int32_t x = *in++; 199520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber 200520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber int32_t mantissa = ~x; 201520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber int32_t exponent = (mantissa >> 4) & 7; 202520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber int32_t segment = exponent + 1; 203520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber mantissa &= 0x0f; 204520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber 205520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber int32_t step = 4 << segment; 206520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber 207520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber int32_t abs = (0x80l << exponent) + step * mantissa + step / 2 - 4 * 33; 208520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber 209520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber *out++ = (x < 0x80) ? -abs : abs; 210520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber } 211520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber} 212520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber 213520b2a7039792f03da11a8d54344f10175cebfbcAndreas Huber} // namespace android 214