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