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