VideoEditorSRC.cpp revision c4689fae1bdb8d1c94eb28af1b2a1f30d2b1a3da
1/*
2 * Copyright (C) 2011 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//#define LOG_NDEBUG 0
18#define LOG_TAG "VideoEditorSRC"
19
20#include <stdlib.h>
21#include <utils/Log.h>
22#include <audio_utils/primitives.h>
23#include <media/stagefright/foundation/ADebug.h>
24#include <media/stagefright/MetaData.h>
25#include <media/stagefright/MediaBuffer.h>
26#include <media/stagefright/MediaDefs.h>
27#include "AudioMixer.h"
28#include "VideoEditorSRC.h"
29
30
31namespace android {
32
33VideoEditorSRC::VideoEditorSRC(const sp<MediaSource> &source) {
34    ALOGV("VideoEditorSRC %p(%p)", this, source.get());
35    static const int32_t kDefaultSamplingFreqencyHz = kFreq32000Hz;
36    mSource = source;
37    mResampler = NULL;
38    mChannelCnt = 0;
39    mSampleRate = 0;
40    mOutputSampleRate = kDefaultSamplingFreqencyHz;
41    mStarted = false;
42    mInitialTimeStampUs = -1;
43    mAccuOutBufferSize  = 0;
44    mSeekTimeUs = -1;
45    mBuffer = NULL;
46    mLeftover = 0;
47    mFormatChanged = false;
48    mStopPending = false;
49    mSeekMode = ReadOptions::SEEK_PREVIOUS_SYNC;
50
51    // Input Source validation
52    sp<MetaData> format = mSource->getFormat();
53    const char *mime;
54    CHECK(format->findCString(kKeyMIMEType, &mime));
55    CHECK(!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW));
56
57    // Set the metadata of the output after resampling.
58    mOutputFormat = new MetaData;
59    mOutputFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
60    mOutputFormat->setInt32(kKeySampleRate, kDefaultSamplingFreqencyHz);
61    mOutputFormat->setInt32(kKeyChannelCount, 2);  // always stereo
62}
63
64VideoEditorSRC::~VideoEditorSRC() {
65    ALOGV("~VideoEditorSRC %p(%p)", this, mSource.get());
66    stop();
67}
68
69status_t VideoEditorSRC::start(MetaData *params) {
70    ALOGV("start %p(%p)", this, mSource.get());
71    CHECK(!mStarted);
72
73    // Set resampler if required
74    checkAndSetResampler();
75
76    mSeekTimeUs = -1;
77    mSeekMode = ReadOptions::SEEK_PREVIOUS_SYNC;
78    mStarted = true;
79    mSource->start();
80
81    return OK;
82}
83
84status_t VideoEditorSRC::stop() {
85    ALOGV("stop %p(%p)", this, mSource.get());
86    if (!mStarted) {
87        return OK;
88    }
89
90    if (mBuffer) {
91        mBuffer->release();
92        mBuffer = NULL;
93    }
94    mSource->stop();
95    if (mResampler != NULL) {
96        delete mResampler;
97        mResampler = NULL;
98    }
99
100    mStarted = false;
101    mInitialTimeStampUs = -1;
102    mAccuOutBufferSize = 0;
103    mLeftover = 0;
104
105    return OK;
106}
107
108sp<MetaData> VideoEditorSRC::getFormat() {
109    ALOGV("getFormat");
110    return mOutputFormat;
111}
112
113status_t VideoEditorSRC::read(
114        MediaBuffer **buffer_out, const ReadOptions *options) {
115    ALOGV("read %p(%p)", this, mSource.get());
116    *buffer_out = NULL;
117
118    if (!mStarted) {
119        return ERROR_END_OF_STREAM;
120    }
121
122    if (mResampler) {
123        // Store the seek parameters
124        int64_t seekTimeUs;
125        ReadOptions::SeekMode mode = ReadOptions::SEEK_PREVIOUS_SYNC;
126        if (options && options->getSeekTo(&seekTimeUs, &mode)) {
127            ALOGV("read Seek %lld", seekTimeUs);
128            mSeekTimeUs = seekTimeUs;
129            mSeekMode = mode;
130        }
131
132        // We ask for 1024 frames in output
133        // resampler output is always 2 channels and 32 bits
134        const size_t kOutputFrameCount = 1024;
135        const size_t kBytes = kOutputFrameCount * 2 * sizeof(int32_t);
136        int32_t *pTmpBuffer = (int32_t *)calloc(1, kBytes);
137        if (!pTmpBuffer) {
138            ALOGE("calloc failed to allocate memory: %d bytes", kBytes);
139            return NO_MEMORY;
140        }
141
142        // Resample to target quality
143        mResampler->resample(pTmpBuffer, kOutputFrameCount, this);
144
145        if (mStopPending) {
146            stop();
147            mStopPending = false;
148        }
149
150        // Change resampler and retry if format change happened
151        if (mFormatChanged) {
152            mFormatChanged = false;
153            checkAndSetResampler();
154            free(pTmpBuffer);
155            return read(buffer_out, NULL);
156        }
157
158        // Create a new MediaBuffer
159        int32_t outBufferSize = kOutputFrameCount * 2 * sizeof(int16_t);
160        MediaBuffer* outBuffer = new MediaBuffer(outBufferSize);
161
162        // Convert back to 2 channels and 16 bits
163        ditherAndClamp(
164                (int32_t *)((uint8_t*)outBuffer->data() + outBuffer->range_offset()),
165                pTmpBuffer, kOutputFrameCount);
166        free(pTmpBuffer);
167
168        // Compute and set the new timestamp
169        sp<MetaData> to = outBuffer->meta_data();
170        int64_t totalOutDurationUs = (mAccuOutBufferSize * 1000000) / (mOutputSampleRate * 2 * 2);
171        int64_t timeUs = mInitialTimeStampUs + totalOutDurationUs;
172        to->setInt64(kKeyTime, timeUs);
173
174        // update the accumulate size
175        mAccuOutBufferSize += outBufferSize;
176        *buffer_out = outBuffer;
177    } else {
178        // Resampling not required. Read and pass-through.
179        MediaBuffer *aBuffer;
180        status_t err = mSource->read(&aBuffer, options);
181        if (err != OK) {
182            ALOGV("read returns err = %d", err);
183        }
184
185        if (err == INFO_FORMAT_CHANGED) {
186            checkAndSetResampler();
187            return read(buffer_out, NULL);
188        }
189
190        // EOS or some other error
191        if(err != OK) {
192            stop();
193            *buffer_out = NULL;
194            return err;
195        }
196        *buffer_out = aBuffer;
197    }
198
199    return OK;
200}
201
202status_t VideoEditorSRC::getNextBuffer(AudioBufferProvider::Buffer *pBuffer) {
203    ALOGV("getNextBuffer %d, chan = %d", pBuffer->frameCount, mChannelCnt);
204    uint32_t done = 0;
205    uint32_t want = pBuffer->frameCount * mChannelCnt * 2;
206    pBuffer->raw = malloc(want);
207
208    while (mStarted && want > 0) {
209        // If we don't have any data left, read a new buffer.
210        if (!mBuffer) {
211            // if we seek, reset the initial time stamp and accumulated time
212            ReadOptions options;
213            if (mSeekTimeUs >= 0) {
214                ALOGV("%p cacheMore_l Seek requested = %lld", this, mSeekTimeUs);
215                ReadOptions::SeekMode mode = mSeekMode;
216                options.setSeekTo(mSeekTimeUs, mode);
217                mSeekTimeUs = -1;
218                mInitialTimeStampUs = -1;
219                mAccuOutBufferSize = 0;
220            }
221
222            status_t err = mSource->read(&mBuffer, &options);
223
224            if (err != OK) {
225                free(pBuffer->raw);
226                pBuffer->raw = NULL;
227                pBuffer->frameCount = 0;
228            }
229
230            if (err == INFO_FORMAT_CHANGED) {
231                ALOGV("getNextBuffer: source read returned INFO_FORMAT_CHANGED");
232                // At this point we cannot switch to a new AudioResampler because
233                // we are in a callback called by the AudioResampler itself. So
234                // just remember the fact that the format has changed, and let
235                // read() handles this.
236                mFormatChanged = true;
237                return err;
238            }
239
240            // EOS or some other error
241            if (err != OK) {
242                ALOGV("EOS or some err: %d", err);
243                // We cannot call stop() here because stop() will release the
244                // AudioResampler, and we are in a callback of the AudioResampler.
245                // So just remember the fact and let read() call stop().
246                mStopPending = true;
247                return err;
248            }
249
250            CHECK(mBuffer);
251            mLeftover = mBuffer->range_length();
252            if (mInitialTimeStampUs == -1) {
253                int64_t curTS;
254                sp<MetaData> from = mBuffer->meta_data();
255                from->findInt64(kKeyTime, &curTS);
256                ALOGV("setting mInitialTimeStampUs to %lld", mInitialTimeStampUs);
257                mInitialTimeStampUs = curTS;
258            }
259        }
260
261        // Now copy data to the destination
262        uint32_t todo = mLeftover;
263        if (todo > want) {
264            todo = want;
265        }
266
267        uint8_t* end = (uint8_t*)mBuffer->data() + mBuffer->range_offset()
268                + mBuffer->range_length();
269        memcpy((uint8_t*)pBuffer->raw + done, end - mLeftover, todo);
270        done += todo;
271        want -= todo;
272        mLeftover -= todo;
273
274        // Release MediaBuffer as soon as possible.
275        if (mLeftover == 0) {
276            mBuffer->release();
277            mBuffer = NULL;
278        }
279    }
280
281    pBuffer->frameCount = done / (mChannelCnt * 2);
282    ALOGV("getNextBuffer done %d", pBuffer->frameCount);
283    return OK;
284}
285
286
287void VideoEditorSRC::releaseBuffer(AudioBufferProvider::Buffer *pBuffer) {
288    ALOGV("releaseBuffer: %p", pBuffers);
289    free(pBuffer->raw);
290    pBuffer->raw = NULL;
291    pBuffer->frameCount = 0;
292}
293
294void VideoEditorSRC::checkAndSetResampler() {
295    ALOGV("checkAndSetResampler");
296
297    static const uint16_t kUnityGain = 0x1000;
298    sp<MetaData> format = mSource->getFormat();
299    const char *mime;
300    CHECK(format->findCString(kKeyMIMEType, &mime));
301    CHECK(!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW));
302
303    CHECK(format->findInt32(kKeySampleRate, &mSampleRate));
304    CHECK(format->findInt32(kKeyChannelCount, &mChannelCnt));
305
306    // If a resampler exists, delete it first
307    if (mResampler != NULL) {
308        delete mResampler;
309        mResampler = NULL;
310    }
311
312    // Clear previous buffer
313    if (mBuffer) {
314        mBuffer->release();
315        mBuffer = NULL;
316    }
317
318    if (mSampleRate != mOutputSampleRate || mChannelCnt != 2) {
319        ALOGV("Resampling required (%d => %d Hz, # channels = %d)",
320            mSampleRate, mOutputSampleRate, mChannelCnt);
321
322        mResampler = AudioResampler::create(
323                        16 /* bit depth */,
324                        mChannelCnt,
325                        mOutputSampleRate,
326                        AudioResampler::DEFAULT);
327        CHECK(mResampler);
328        mResampler->setSampleRate(mSampleRate);
329        mResampler->setVolume(kUnityGain, kUnityGain);
330    } else {
331        ALOGV("Resampling not required (%d => %d Hz, # channels = %d)",
332            mSampleRate, mOutputSampleRate, mChannelCnt);
333    }
334}
335
336} //namespce android
337