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