VideoEditorSRC.cpp revision 9785cdf83214ce4d998e65ac0fce92cea3137f0b
1/*
2 * Copyright (C) 2011 NXP Software
3 * Copyright (C) 2011 The Android Open Source Project
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 *      http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18#define LOG_NDEBUG 1
19#define LOG_TAG "VEAudioSource"
20#include <utils/Log.h>
21
22
23#include "VideoEditorSRC.h"
24#include <media/stagefright/MetaData.h>
25#include <media/stagefright/MediaDebug.h>
26#include "AudioMixer.h"
27
28
29namespace android {
30
31VideoEditorSRC::VideoEditorSRC(
32        const sp<MediaSource> &source) {
33
34    LOGV("VideoEditorSRC::Create");
35    mSource = source;
36    mResampler = NULL;
37    mBitDepth = 16;
38    mChannelCnt = 0;
39    mSampleRate = 0;
40    mOutputSampleRate = DEFAULT_SAMPLING_FREQ;
41    mStarted = false;
42    mIsResamplingRequired = false;
43    mIsChannelConvertionRequired = false;
44    mInitialTimeStampUs = -1;
45    mAccuOutBufferSize  = 0;
46    mSeekTimeUs = -1;
47    mLeftover = 0;
48    mLastReadSize = 0;
49    mReSampledBuffer = NULL;
50#ifndef FROYO
51    mSeekMode =  ReadOptions::SEEK_PREVIOUS_SYNC;
52#endif
53
54    mOutputFormat = new MetaData;
55
56    // Input Source validation
57    sp<MetaData> format = mSource->getFormat();
58    const char *mime;
59    bool success = format->findCString(kKeyMIMEType, &mime);
60    CHECK(success);
61    CHECK(!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW));
62
63    //set the meta data of the output after convertion.
64    if(mOutputFormat != NULL) {
65        mOutputFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
66        mOutputFormat->setInt32(kKeySampleRate, DEFAULT_SAMPLING_FREQ);
67
68        //by default we convert all data to stereo
69        mOutputFormat->setInt32(kKeyChannelCount, 2);
70    } else {
71        LOGE("Meta data was not allocated.");
72    }
73
74    // Allocate a  1 sec buffer (test only, to be refined)
75    mInterframeBufferPosition = 0;
76    pInterframeBuffer = new uint8_t[DEFAULT_SAMPLING_FREQ * 2 * 2]; //stereo=2 * bytespersample=2
77
78
79}
80
81VideoEditorSRC::~VideoEditorSRC(){
82    if (mStarted == true)
83        stop();
84
85    if(mOutputFormat != NULL) {
86        mOutputFormat.clear();
87        mOutputFormat = NULL;
88    }
89
90    if (pInterframeBuffer != NULL){
91        delete pInterframeBuffer;
92        pInterframeBuffer = NULL;
93    }
94}
95
96void VideoEditorSRC::setResampling(int32_t sampleRate) {
97    Mutex::Autolock autoLock(mLock);
98    LOGV("VideoEditorSRC::setResampling called with samplreRate = %d", sampleRate);
99    if(sampleRate != DEFAULT_SAMPLING_FREQ) { //default case
100        LOGV("VideoEditor Audio resampler, freq set is other than default");
101        CHECK(mOutputFormat->setInt32(kKeySampleRate, DEFAULT_SAMPLING_FREQ));
102    }
103    mOutputSampleRate = sampleRate;
104    return;
105}
106
107status_t  VideoEditorSRC::start (MetaData *params) {
108    Mutex::Autolock autoLock(mLock);
109
110    CHECK(!mStarted);
111    LOGV(" VideoEditorSRC:start() called");
112
113    sp<MetaData> format = mSource->getFormat();
114    const char *mime;
115    bool success = format->findCString(kKeyMIMEType, &mime);
116    CHECK(success);
117    CHECK(!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW));
118
119    success = format->findInt32(kKeySampleRate, &mSampleRate);
120    CHECK(success);
121
122    int32_t numChannels;
123    success = format->findInt32(kKeyChannelCount, &mChannelCnt);
124    CHECK(success);
125
126    mInputFrameSize = mChannelCnt * 2; //2 is the byte depth
127    if(mSampleRate != mOutputSampleRate) {
128        LOGV("Resampling required (%d != %d)", mSampleRate, mOutputSampleRate);
129        mIsResamplingRequired = true;
130        LOGV("Create resampler %d %d %d", mBitDepth, mChannelCnt, mOutputSampleRate);
131
132        mResampler = AudioResampler::create(
133                        mBitDepth, mChannelCnt, mOutputSampleRate, AudioResampler::DEFAULT);
134
135        if(mResampler == NULL) {
136            return NO_MEMORY;
137        }
138        LOGV("Set input rate %d", mSampleRate);
139        mResampler->setSampleRate(mSampleRate);
140        mResampler->setVolume(UNITY_GAIN, UNITY_GAIN);
141
142    } else {
143        if(mChannelCnt != 2) { //we always make sure to provide stereo
144            LOGV("Only Channel convertion required");
145            mIsChannelConvertionRequired = true;
146        }
147    }
148    mSeekTimeUs = -1;
149#ifndef FROYO
150    mSeekMode =  ReadOptions::SEEK_PREVIOUS_SYNC;
151#endif
152    mStarted = true;
153    mSource->start();
154
155    return OK;
156}
157
158status_t VideoEditorSRC::stop() {
159
160    Mutex::Autolock autoLock(mLock);
161    LOGV("VideoEditorSRC::stop()");
162    mSource->stop();
163    if(mResampler != NULL) {
164        delete mResampler;
165        mResampler = NULL;
166    }
167    mStarted = false;
168    mInitialTimeStampUs = -1;
169    mAccuOutBufferSize  = 0;
170    mLeftover = 0;
171    mLastReadSize = 0;
172    if (mReSampledBuffer != NULL) {
173        free(mReSampledBuffer);
174        mReSampledBuffer = NULL;
175    }
176
177    return OK;
178}
179
180sp<MetaData> VideoEditorSRC::getFormat() {
181    LOGV("AudioSRC getFormat");
182    //Mutex::Autolock autoLock(mLock);
183    return mOutputFormat;
184}
185
186status_t VideoEditorSRC::read (
187        MediaBuffer **buffer_out, const ReadOptions *options) {
188    Mutex::Autolock autoLock(mLock);
189    *buffer_out = NULL;
190    int32_t leftover = 0;
191
192    LOGV("VideoEditorSRC::read");
193
194    if (!mStarted) {
195        return ERROR_END_OF_STREAM;
196    }
197
198    if(mIsResamplingRequired == true) {
199
200        LOGV("mIsResamplingRequired = true");
201
202        // Store the seek parameters
203        int64_t seekTimeUs;
204#ifndef FROYO
205        ReadOptions::SeekMode mode = ReadOptions::SEEK_PREVIOUS_SYNC;
206        if (options && options->getSeekTo(&seekTimeUs, &mode)) {
207#else
208        if (options && options->getSeekTo(&seekTimeUs)) {
209#endif
210            LOGV("read Seek %lld", seekTimeUs);
211            mInitialTimeStampUs = -1;
212            mSeekTimeUs = seekTimeUs;
213#ifndef FROYO
214            mSeekMode = mode;
215#else
216            mReadOptions = *options;
217#endif
218        }
219
220        // We ask for 1024 frames in output
221        size_t outFrameCnt = 1024;
222        int32_t outBufferSize = (outFrameCnt) * 2 * sizeof(int16_t); //out is always 2 channels & 16 bits
223        int64_t outDurationUs = (outBufferSize * 1000000) /(mOutputSampleRate * 2 * sizeof(int16_t)); //2 channels out * 2 bytes per sample
224        LOGV("outBufferSize            %d", outBufferSize);
225        LOGV("outFrameCnt              %d", outFrameCnt);
226
227        pTmpBuffer = (int32_t*)malloc(outFrameCnt * 2 * sizeof(int32_t)); //out is always 2 channels and resampler out is 32 bits
228        memset(pTmpBuffer, 0x00, outFrameCnt * 2 * sizeof(int32_t));
229        // Resample to target quality
230        mResampler->resample(pTmpBuffer, outFrameCnt, this);
231
232        // Free previous allocation
233        if (mReSampledBuffer != NULL) {
234            free(mReSampledBuffer);
235            mReSampledBuffer = NULL;
236        }
237        mReSampledBuffer = (int16_t*)malloc(outBufferSize);
238        memset(mReSampledBuffer, 0x00, outBufferSize);
239
240        // Convert back to 16 bits
241        AudioMixer::ditherAndClamp((int32_t*)mReSampledBuffer, pTmpBuffer, outFrameCnt);
242        LOGV("Resampled buffer size %d", outFrameCnt* 2 * sizeof(int16_t));
243
244        // Create new MediaBuffer
245        mCopyBuffer = new MediaBuffer((void*)mReSampledBuffer, outBufferSize);
246
247        // Compute and set the new timestamp
248        sp<MetaData> to = mCopyBuffer->meta_data();
249        int64_t totalOutDurationUs = (mAccuOutBufferSize * 1000000) /(mOutputSampleRate * 2 * 2); //2 channels out * 2 bytes per sample
250        int64_t timeUs = mInitialTimeStampUs + totalOutDurationUs;
251        to->setInt64(kKeyTime, timeUs);
252        LOGV("buffer duration %lld   timestamp %lld   init %lld", outDurationUs, timeUs, mInitialTimeStampUs);
253
254        // update the accumulate size
255        mAccuOutBufferSize += outBufferSize;
256
257        mCopyBuffer->set_range(0, outBufferSize);
258        *buffer_out = mCopyBuffer;
259
260        free(pTmpBuffer);
261
262    } else if(mIsChannelConvertionRequired == true) {
263        //TODO convert to stereo here.
264    } else {
265        //LOGI("Resampling not required");
266        MediaBuffer *aBuffer;
267        status_t err = mSource->read(&aBuffer, options);
268        LOGV("mSource->read returned %d", err);
269        if(err != OK) {
270            *buffer_out = NULL;
271            mStarted = false;
272            return err;
273        }
274        *buffer_out = aBuffer;
275    }
276
277    return OK;
278}
279
280status_t VideoEditorSRC::getNextBuffer(AudioBufferProvider::Buffer *pBuffer) {
281    LOGV("Requesting        %d", pBuffer->frameCount);
282    uint32_t availableFrames;
283    bool lastBuffer = false;
284    MediaBuffer *aBuffer;
285
286
287    //update the internal buffer
288    // Store the leftover at the beginning of the local buffer
289    if (mLeftover > 0) {
290        LOGV("Moving mLeftover =%d  from  %d", mLeftover, mLastReadSize);
291        if (mLastReadSize > 0) {
292            memcpy(pInterframeBuffer, (uint8_t*) (pInterframeBuffer + mLastReadSize), mLeftover);
293        }
294        mInterframeBufferPosition = mLeftover;
295    }
296    else {
297        mInterframeBufferPosition = 0;
298    }
299
300    availableFrames = mInterframeBufferPosition / (mChannelCnt*2);
301
302    while ((availableFrames < pBuffer->frameCount)&&(mStarted)) {
303        // if we seek, reset the initial time stamp and accumulated time
304#ifndef FROYO
305        ReadOptions options;
306        if (mSeekTimeUs >= 0) {
307            LOGV("%p cacheMore_l Seek requested = %lld", this, mSeekTimeUs);
308            ReadOptions::SeekMode mode = mSeekMode;
309            options.setSeekTo(mSeekTimeUs, mode);
310            mSeekTimeUs = -1;
311        }
312#else
313        ReadOptions options;
314        if (mSeekTimeUs >= 0) {
315            LOGV("%p cacheMore_l Seek requested = %lld", this, mSeekTimeUs);
316            options = mReadOptions;
317            mSeekTimeUs = -1;
318        }
319#endif
320        /* The first call to read() will require to buffer twice as much data */
321        /* This will be needed by the resampler */
322        status_t err = mSource->read(&aBuffer, &options);
323        LOGV("mSource->read returned %d", err);
324        if(err != OK) {
325            if (mInterframeBufferPosition == 0) {
326                mStarted = false;
327            }
328            //Empty the internal buffer if there is no more data left in the source
329            else {
330                lastBuffer = true;
331                mInputByteBuffer = pInterframeBuffer;
332                //clear the end of the buffer, just in case
333                memset(pInterframeBuffer+mInterframeBufferPosition, 0x00, DEFAULT_SAMPLING_FREQ * 2 * 2 - mInterframeBufferPosition);
334                mStarted = false;
335            }
336        }
337        else {
338            //copy the buffer
339            memcpy(((uint8_t*) pInterframeBuffer) + mInterframeBufferPosition,
340                    ((uint8_t*) aBuffer->data()) + aBuffer->range_offset(),
341                    aBuffer->range_length());
342            LOGV("Read from buffer  %d", aBuffer->range_length());
343
344            mInterframeBufferPosition += aBuffer->range_length();
345            LOGV("Stored            %d", mInterframeBufferPosition);
346
347            // Get the time stamp of the first buffer
348            if (mInitialTimeStampUs == -1) {
349                int64_t curTS;
350                sp<MetaData> from = aBuffer->meta_data();
351                from->findInt64(kKeyTime, &curTS);
352                LOGV("setting mInitialTimeStampUs to %lld", mInitialTimeStampUs);
353                mInitialTimeStampUs = curTS;
354            }
355
356            // release the buffer
357            aBuffer->release();
358        }
359        availableFrames = mInterframeBufferPosition / (mChannelCnt*2);
360        LOGV("availableFrames   %d", availableFrames);
361    }
362
363    if (lastBuffer) {
364        pBuffer->frameCount = availableFrames;
365    }
366
367    //update the input buffer
368    pBuffer->raw        = (void*)(pInterframeBuffer);
369
370    // Update how many bytes are left
371    // (actualReadSize is updated in getNextBuffer() called from resample())
372    int32_t actualReadSize = pBuffer->frameCount * mChannelCnt * 2;
373    mLeftover = mInterframeBufferPosition - actualReadSize;
374    LOGV("mLeftover         %d", mLeftover);
375
376    mLastReadSize = actualReadSize;
377
378    LOGV("inFrameCount     %d", pBuffer->frameCount);
379
380    return OK;
381}
382
383
384void VideoEditorSRC::releaseBuffer(AudioBufferProvider::Buffer *pBuffer) {
385    if(pBuffer->raw != NULL) {
386        pBuffer->raw = NULL;
387    }
388    pBuffer->frameCount = 0;
389}
390
391} //namespce android
392