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#include "MP3Decoder.h" 18 19#include "include/pvmp3decoder_api.h" 20 21#include <media/stagefright/MediaBufferGroup.h> 22#include <media/stagefright/MediaDebug.h> 23#include <media/stagefright/MediaDefs.h> 24#include <media/stagefright/MetaData.h> 25 26namespace android { 27 28MP3Decoder::MP3Decoder(const sp<MediaSource> &source) 29 : mSource(source), 30 mStarted(false), 31 mBufferGroup(NULL), 32 mConfig(new tPVMP3DecoderExternal), 33 mDecoderBuf(NULL), 34 mAnchorTimeUs(0), 35 mNumSamplesOutput(0), 36 mInputBuffer(NULL) { 37} 38 39MP3Decoder::~MP3Decoder() { 40 if (mStarted) { 41 stop(); 42 } 43 44 delete mConfig; 45 mConfig = NULL; 46} 47 48status_t MP3Decoder::start(MetaData *params) { 49 CHECK(!mStarted); 50 51 mBufferGroup = new MediaBufferGroup; 52 mBufferGroup->add_buffer(new MediaBuffer(4608 * 2)); 53 54 mConfig->equalizerType = flat; 55 mConfig->crcEnabled = false; 56 57 uint32_t memRequirements = pvmp3_decoderMemRequirements(); 58 mDecoderBuf = malloc(memRequirements); 59 60 pvmp3_InitDecoder(mConfig, mDecoderBuf); 61 62 mSource->start(); 63 64 mAnchorTimeUs = 0; 65 mNumSamplesOutput = 0; 66 mStarted = true; 67 68 return OK; 69} 70 71status_t MP3Decoder::stop() { 72 CHECK(mStarted); 73 74 if (mInputBuffer) { 75 mInputBuffer->release(); 76 mInputBuffer = NULL; 77 } 78 79 free(mDecoderBuf); 80 mDecoderBuf = NULL; 81 82 delete mBufferGroup; 83 mBufferGroup = NULL; 84 85 mSource->stop(); 86 87 mStarted = false; 88 89 return OK; 90} 91 92sp<MetaData> MP3Decoder::getFormat() { 93 sp<MetaData> srcFormat = mSource->getFormat(); 94 95 int32_t numChannels; 96 int32_t sampleRate; 97 CHECK(srcFormat->findInt32(kKeyChannelCount, &numChannels)); 98 CHECK(srcFormat->findInt32(kKeySampleRate, &sampleRate)); 99 100 sp<MetaData> meta = new MetaData; 101 meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW); 102 meta->setInt32(kKeyChannelCount, numChannels); 103 meta->setInt32(kKeySampleRate, sampleRate); 104 105 int64_t durationUs; 106 if (srcFormat->findInt64(kKeyDuration, &durationUs)) { 107 meta->setInt64(kKeyDuration, durationUs); 108 } 109 110 meta->setCString(kKeyDecoderComponent, "MP3Decoder"); 111 112 return meta; 113} 114 115status_t MP3Decoder::read( 116 MediaBuffer **out, const ReadOptions *options) { 117 status_t err; 118 119 *out = NULL; 120 121 int64_t seekTimeUs; 122 if (options && options->getSeekTo(&seekTimeUs)) { 123 CHECK(seekTimeUs >= 0); 124 125 mNumSamplesOutput = 0; 126 127 if (mInputBuffer) { 128 mInputBuffer->release(); 129 mInputBuffer = NULL; 130 } 131 } else { 132 seekTimeUs = -1; 133 } 134 135 if (mInputBuffer == NULL) { 136 err = mSource->read(&mInputBuffer, options); 137 138 if (err != OK) { 139 return err; 140 } 141 142 int64_t timeUs; 143 if (mInputBuffer->meta_data()->findInt64(kKeyTime, &timeUs)) { 144 mAnchorTimeUs = timeUs; 145 mNumSamplesOutput = 0; 146 } else { 147 // We must have a new timestamp after seeking. 148 CHECK(seekTimeUs < 0); 149 } 150 } 151 152 MediaBuffer *buffer; 153 CHECK_EQ(mBufferGroup->acquire_buffer(&buffer), OK); 154 155 mConfig->pInputBuffer = 156 (uint8_t *)mInputBuffer->data() + mInputBuffer->range_offset(); 157 158 mConfig->inputBufferCurrentLength = mInputBuffer->range_length(); 159 mConfig->inputBufferMaxLength = 0; 160 mConfig->inputBufferUsedLength = 0; 161 162 mConfig->outputFrameSize = buffer->size() / sizeof(int16_t); 163 mConfig->pOutputBuffer = static_cast<int16_t *>(buffer->data()); 164 165 ERROR_CODE decoderErr; 166 if ((decoderErr = pvmp3_framedecoder(mConfig, mDecoderBuf)) 167 != NO_DECODING_ERROR) { 168 LOGV("mp3 decoder returned error %d", decoderErr); 169 170 if (decoderErr != NO_ENOUGH_MAIN_DATA_ERROR) { 171 buffer->release(); 172 buffer = NULL; 173 174 mInputBuffer->release(); 175 mInputBuffer = NULL; 176 177 return UNKNOWN_ERROR; 178 } 179 180 // This is recoverable, just ignore the current frame and 181 // play silence instead. 182 memset(buffer->data(), 0, mConfig->outputFrameSize); 183 mConfig->inputBufferUsedLength = mInputBuffer->range_length(); 184 } 185 186 buffer->set_range( 187 0, mConfig->outputFrameSize * sizeof(int16_t)); 188 189 mInputBuffer->set_range( 190 mInputBuffer->range_offset() + mConfig->inputBufferUsedLength, 191 mInputBuffer->range_length() - mConfig->inputBufferUsedLength); 192 193 if (mInputBuffer->range_length() == 0) { 194 mInputBuffer->release(); 195 mInputBuffer = NULL; 196 } 197 198 buffer->meta_data()->setInt64( 199 kKeyTime, 200 mAnchorTimeUs 201 + (mNumSamplesOutput * 1000000) / mConfig->samplingRate); 202 203 mNumSamplesOutput += mConfig->outputFrameSize / sizeof(int16_t); 204 205 *out = buffer; 206 207 return OK; 208} 209 210} // namespace android 211