VideoEditorSRC.cpp revision e6815bf8b4eaf9cc861e389cbebe3d7412698e9f
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 <media/stagefright/MediaBuffer.h>
27#include <media/stagefright/MediaDefs.h>
28#include "AudioMixer.h"
29
30
31namespace android {
32
33VideoEditorSRC::VideoEditorSRC(
34        const sp<MediaSource> &source) {
35
36    LOGV("VideoEditorSRC::Create");
37    mSource = source;
38    mResampler = NULL;
39    mBitDepth = 16;
40    mChannelCnt = 0;
41    mSampleRate = 0;
42    mOutputSampleRate = DEFAULT_SAMPLING_FREQ;
43    mStarted = false;
44    mIsResamplingRequired = false;
45    mIsChannelConvertionRequired = false;
46    mInitialTimeStampUs = -1;
47    mAccuOutBufferSize  = 0;
48    mSeekTimeUs = -1;
49    mLeftover = 0;
50    mLastReadSize = 0;
51    mReSampledBuffer = NULL;
52    mSeekMode =  ReadOptions::SEEK_PREVIOUS_SYNC;
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    mInterframeBuffer = 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 (mInterframeBuffer != NULL){
91        delete mInterframeBuffer;
92        mInterframeBuffer = 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    if(mSampleRate != mOutputSampleRate) {
127        LOGV("Resampling required (%d != %d)", mSampleRate, mOutputSampleRate);
128        mIsResamplingRequired = true;
129        LOGV("Create resampler %d %d %d", mBitDepth, mChannelCnt, mOutputSampleRate);
130
131        mResampler = AudioResampler::create(
132                        mBitDepth, mChannelCnt, mOutputSampleRate, AudioResampler::DEFAULT);
133
134        if(mResampler == NULL) {
135            return NO_MEMORY;
136        }
137        LOGV("Set input rate %d", mSampleRate);
138        mResampler->setSampleRate(mSampleRate);
139        mResampler->setVolume(UNITY_GAIN, UNITY_GAIN);
140
141    } else {
142        if(mChannelCnt != 2) { //we always make sure to provide stereo
143            LOGV("Only Channel convertion required");
144            mIsChannelConvertionRequired = true;
145        }
146    }
147    mSeekTimeUs = -1;
148    mSeekMode =  ReadOptions::SEEK_PREVIOUS_SYNC;
149    mStarted = true;
150    mSource->start();
151
152    return OK;
153}
154
155status_t VideoEditorSRC::stop() {
156
157    Mutex::Autolock autoLock(mLock);
158    LOGV("VideoEditorSRC::stop()");
159    mSource->stop();
160    if(mResampler != NULL) {
161        delete mResampler;
162        mResampler = NULL;
163    }
164    mStarted = false;
165    mInitialTimeStampUs = -1;
166    mAccuOutBufferSize  = 0;
167    mLeftover = 0;
168    mLastReadSize = 0;
169    if (mReSampledBuffer != NULL) {
170        free(mReSampledBuffer);
171        mReSampledBuffer = NULL;
172    }
173
174    return OK;
175}
176
177sp<MetaData> VideoEditorSRC::getFormat() {
178    LOGV("AudioSRC getFormat");
179    //Mutex::Autolock autoLock(mLock);
180    return mOutputFormat;
181}
182
183status_t VideoEditorSRC::read (
184        MediaBuffer **buffer_out, const ReadOptions *options) {
185    Mutex::Autolock autoLock(mLock);
186    *buffer_out = NULL;
187    int32_t leftover = 0;
188
189    LOGV("VideoEditorSRC::read");
190
191    if (!mStarted) {
192        return ERROR_END_OF_STREAM;
193    }
194
195    if(mIsResamplingRequired == true) {
196
197        LOGV("mIsResamplingRequired = true");
198
199        // Store the seek parameters
200        int64_t seekTimeUs;
201        ReadOptions::SeekMode mode = ReadOptions::SEEK_PREVIOUS_SYNC;
202        if (options && options->getSeekTo(&seekTimeUs, &mode)) {
203            LOGV("read Seek %lld", seekTimeUs);
204            mInitialTimeStampUs = -1;
205            mSeekTimeUs = seekTimeUs;
206            mSeekMode = mode;
207        }
208
209        // We ask for 1024 frames in output
210        size_t outFrameCnt = 1024;
211        int32_t outBufferSize = (outFrameCnt) * 2 * sizeof(int16_t); //out is always 2 channels & 16 bits
212        int64_t outDurationUs = (outBufferSize * 1000000) /(mOutputSampleRate * 2 * sizeof(int16_t)); //2 channels out * 2 bytes per sample
213        LOGV("outBufferSize            %d", outBufferSize);
214        LOGV("outFrameCnt              %d", outFrameCnt);
215
216        int32_t *pTmpBuffer = (int32_t*)malloc(outFrameCnt * 2 * sizeof(int32_t)); //out is always 2 channels and resampler out is 32 bits
217        memset(pTmpBuffer, 0x00, outFrameCnt * 2 * sizeof(int32_t));
218        // Resample to target quality
219        mResampler->resample(pTmpBuffer, outFrameCnt, this);
220
221        // Free previous allocation
222        if (mReSampledBuffer != NULL) {
223            free(mReSampledBuffer);
224            mReSampledBuffer = NULL;
225        }
226        mReSampledBuffer = (int16_t*)malloc(outBufferSize);
227        memset(mReSampledBuffer, 0x00, outBufferSize);
228
229        // Convert back to 16 bits
230        AudioMixer::ditherAndClamp((int32_t*)mReSampledBuffer, pTmpBuffer, outFrameCnt);
231        LOGV("Resampled buffer size %d", outFrameCnt* 2 * sizeof(int16_t));
232
233        // Create new MediaBuffer
234        mCopyBuffer = new MediaBuffer((void*)mReSampledBuffer, outBufferSize);
235
236        // Compute and set the new timestamp
237        sp<MetaData> to = mCopyBuffer->meta_data();
238        int64_t totalOutDurationUs = (mAccuOutBufferSize * 1000000) /(mOutputSampleRate * 2 * 2); //2 channels out * 2 bytes per sample
239        int64_t timeUs = mInitialTimeStampUs + totalOutDurationUs;
240        to->setInt64(kKeyTime, timeUs);
241        LOGV("buffer duration %lld   timestamp %lld   init %lld", outDurationUs, timeUs, mInitialTimeStampUs);
242
243        // update the accumulate size
244        mAccuOutBufferSize += outBufferSize;
245
246        mCopyBuffer->set_range(0, outBufferSize);
247        *buffer_out = mCopyBuffer;
248
249        free(pTmpBuffer);
250
251    } else if(mIsChannelConvertionRequired == true) {
252        //TODO convert to stereo here.
253    } else {
254        //LOGI("Resampling not required");
255        MediaBuffer *aBuffer;
256        status_t err = mSource->read(&aBuffer, options);
257        LOGV("mSource->read returned %d", err);
258        if(err != OK) {
259            *buffer_out = NULL;
260            mStarted = false;
261            return err;
262        }
263        *buffer_out = aBuffer;
264    }
265
266    return OK;
267}
268
269status_t VideoEditorSRC::getNextBuffer(AudioBufferProvider::Buffer *pBuffer) {
270    LOGV("Requesting        %d", pBuffer->frameCount);
271    uint32_t availableFrames;
272    bool lastBuffer = false;
273    MediaBuffer *aBuffer;
274
275
276    //update the internal buffer
277    // Store the leftover at the beginning of the local buffer
278    if (mLeftover > 0) {
279        LOGV("Moving mLeftover =%d  from  %d", mLeftover, mLastReadSize);
280        if (mLastReadSize > 0) {
281            memcpy(mInterframeBuffer, (uint8_t*) (mInterframeBuffer + mLastReadSize), mLeftover);
282        }
283        mInterframeBufferPosition = mLeftover;
284    }
285    else {
286        mInterframeBufferPosition = 0;
287    }
288
289    availableFrames = mInterframeBufferPosition / (mChannelCnt*2);
290
291    while ((availableFrames < pBuffer->frameCount)&&(mStarted)) {
292        // if we seek, reset the initial time stamp and accumulated time
293        ReadOptions options;
294        if (mSeekTimeUs >= 0) {
295            LOGV("%p cacheMore_l Seek requested = %lld", this, mSeekTimeUs);
296            ReadOptions::SeekMode mode = mSeekMode;
297            options.setSeekTo(mSeekTimeUs, mode);
298            mSeekTimeUs = -1;
299        }
300        /* The first call to read() will require to buffer twice as much data */
301        /* This will be needed by the resampler */
302        status_t err = mSource->read(&aBuffer, &options);
303        LOGV("mSource->read returned %d", err);
304        if(err != OK) {
305            if (mInterframeBufferPosition == 0) {
306                mStarted = false;
307            }
308            //Empty the internal buffer if there is no more data left in the source
309            else {
310                lastBuffer = true;
311                //clear the end of the buffer, just in case
312                memset(mInterframeBuffer+mInterframeBufferPosition, 0x00, DEFAULT_SAMPLING_FREQ * 2 * 2 - mInterframeBufferPosition);
313                mStarted = false;
314            }
315        }
316        else {
317            //copy the buffer
318            memcpy(((uint8_t*) mInterframeBuffer) + mInterframeBufferPosition,
319                    ((uint8_t*) aBuffer->data()) + aBuffer->range_offset(),
320                    aBuffer->range_length());
321            LOGV("Read from buffer  %d", aBuffer->range_length());
322
323            mInterframeBufferPosition += aBuffer->range_length();
324            LOGV("Stored            %d", mInterframeBufferPosition);
325
326            // Get the time stamp of the first buffer
327            if (mInitialTimeStampUs == -1) {
328                int64_t curTS;
329                sp<MetaData> from = aBuffer->meta_data();
330                from->findInt64(kKeyTime, &curTS);
331                LOGV("setting mInitialTimeStampUs to %lld", mInitialTimeStampUs);
332                mInitialTimeStampUs = curTS;
333            }
334
335            // release the buffer
336            aBuffer->release();
337        }
338        availableFrames = mInterframeBufferPosition / (mChannelCnt*2);
339        LOGV("availableFrames   %d", availableFrames);
340    }
341
342    if (lastBuffer) {
343        pBuffer->frameCount = availableFrames;
344    }
345
346    //update the input buffer
347    pBuffer->raw        = (void*)(mInterframeBuffer);
348
349    // Update how many bytes are left
350    // (actualReadSize is updated in getNextBuffer() called from resample())
351    int32_t actualReadSize = pBuffer->frameCount * mChannelCnt * 2;
352    mLeftover = mInterframeBufferPosition - actualReadSize;
353    LOGV("mLeftover         %d", mLeftover);
354
355    mLastReadSize = actualReadSize;
356
357    LOGV("inFrameCount     %d", pBuffer->frameCount);
358
359    return OK;
360}
361
362
363void VideoEditorSRC::releaseBuffer(AudioBufferProvider::Buffer *pBuffer) {
364    if(pBuffer->raw != NULL) {
365        pBuffer->raw = NULL;
366    }
367    pBuffer->frameCount = 0;
368}
369
370} //namespce android
371