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