1efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang/* 2efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang * Copyright (C) 2011 The Android Open Source Project 3efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang * 4efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang * Licensed under the Apache License, Version 2.0 (the "License"); 5efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang * you may not use this file except in compliance with the License. 6efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang * You may obtain a copy of the License at 7efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang * 8efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang * http://www.apache.org/licenses/LICENSE-2.0 9efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang * 10efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang * Unless required by applicable law or agreed to in writing, software 11efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang * distributed under the License is distributed on an "AS IS" BASIS, 12efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang * See the License for the specific language governing permissions and 14efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang * limitations under the License. 15efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang */ 16efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang 17e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang//#define LOG_NDEBUG 0 18e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang#define LOG_TAG "VideoEditorSRC" 19efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang 20efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang#include "VideoEditorSRC.h" 21efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang#include <media/stagefright/MetaData.h> 22efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang#include <media/stagefright/MediaDebug.h> 23efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang#include <media/stagefright/MediaBuffer.h> 24efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang#include <media/stagefright/MediaDefs.h> 25efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang#include "AudioMixer.h" 26e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang#include <utils/Log.h> 27efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang 28efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Changnamespace android { 29efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang 30e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung ChangVideoEditorSRC::VideoEditorSRC(const sp<MediaSource> &source) { 31e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang LOGV("VideoEditorSRC::VideoEditorSRC %p(%p)", this, source.get()); 32efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang mSource = source; 33efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang mResampler = NULL; 34efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang mChannelCnt = 0; 35efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang mSampleRate = 0; 36efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang mOutputSampleRate = DEFAULT_SAMPLING_FREQ; 37efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang mStarted = false; 38efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang mInitialTimeStampUs = -1; 39efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang mAccuOutBufferSize = 0; 40efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang mSeekTimeUs = -1; 41e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang mBuffer = NULL; 42efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang mLeftover = 0; 43e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang mFormatChanged = false; 440d2c710a293d68fb729eff148d40002f5deacf17Chih-Chung Chang mStopPending = false; 45e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang mSeekMode = ReadOptions::SEEK_PREVIOUS_SYNC; 46efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang 47efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang // Input Source validation 48efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang sp<MetaData> format = mSource->getFormat(); 49efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang const char *mime; 50e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang CHECK(format->findCString(kKeyMIMEType, &mime)); 51efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang CHECK(!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)); 52efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang 53e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang // Set the metadata of the output after resampling. 54e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang mOutputFormat = new MetaData; 55e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang mOutputFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW); 56e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang mOutputFormat->setInt32(kKeySampleRate, DEFAULT_SAMPLING_FREQ); 57e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang mOutputFormat->setInt32(kKeyChannelCount, 2); 58efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang} 59efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang 60e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung ChangVideoEditorSRC::~VideoEditorSRC() { 61e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang LOGV("VideoEditorSRC::~VideoEditorSRC %p(%p)", this, mSource.get()); 62e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang stop(); 63efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang} 64efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang 65e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Changstatus_t VideoEditorSRC::start(MetaData *params) { 66efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang CHECK(!mStarted); 67e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang LOGV("VideoEditorSRC:start %p(%p)", this, mSource.get()); 68efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang 6984161acd0c02718b47f82ced3123e9d9eac7b9b9Rajneesh Chowdury // Set resampler if required 70e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang checkAndSetResampler(); 7184161acd0c02718b47f82ced3123e9d9eac7b9b9Rajneesh Chowdury 72efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang mSeekTimeUs = -1; 73e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang mSeekMode = ReadOptions::SEEK_PREVIOUS_SYNC; 74efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang mStarted = true; 75efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang mSource->start(); 76efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang 77efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang return OK; 78efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang} 79efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang 80efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Changstatus_t VideoEditorSRC::stop() { 81e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang LOGV("VideoEditorSRC::stop %p(%p)", this, mSource.get()); 82e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang if (!mStarted) return OK; 83e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang if (mBuffer) { 84e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang mBuffer->release(); 85e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang mBuffer = NULL; 86e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang } 87efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang mSource->stop(); 88efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang if(mResampler != NULL) { 89efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang delete mResampler; 90efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang mResampler = NULL; 91efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang } 92efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang mStarted = false; 93efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang mInitialTimeStampUs = -1; 94e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang mAccuOutBufferSize = 0; 95efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang mLeftover = 0; 96efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang 97efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang return OK; 98efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang} 99efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang 100efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Changsp<MetaData> VideoEditorSRC::getFormat() { 101e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang LOGV("VideoEditorSRC::getFormat"); 102efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang return mOutputFormat; 103efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang} 104efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang 105e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Changstatus_t VideoEditorSRC::read( 106efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang MediaBuffer **buffer_out, const ReadOptions *options) { 107e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang LOGV("VideoEditorSRC::read %p(%p)", this, mSource.get()); 108efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang *buffer_out = NULL; 109efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang 110efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang if (!mStarted) { 111efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang return ERROR_END_OF_STREAM; 112efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang } 113efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang 114e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang if (mResampler) { 115efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang // Store the seek parameters 116efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang int64_t seekTimeUs; 117efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang ReadOptions::SeekMode mode = ReadOptions::SEEK_PREVIOUS_SYNC; 118efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang if (options && options->getSeekTo(&seekTimeUs, &mode)) { 119efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang LOGV("read Seek %lld", seekTimeUs); 120efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang mSeekTimeUs = seekTimeUs; 121efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang mSeekMode = mode; 122efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang } 123efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang 124efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang // We ask for 1024 frames in output 125e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang const size_t outFrameCnt = 1024; 126e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang // resampler output is always 2 channels and 32 bits 127e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang int32_t *pTmpBuffer = (int32_t *)calloc(1, outFrameCnt * 2 * sizeof(int32_t)); 128efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang // Resample to target quality 129efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang mResampler->resample(pTmpBuffer, outFrameCnt, this); 130efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang 1310d2c710a293d68fb729eff148d40002f5deacf17Chih-Chung Chang if (mStopPending) { 1320d2c710a293d68fb729eff148d40002f5deacf17Chih-Chung Chang stop(); 1330d2c710a293d68fb729eff148d40002f5deacf17Chih-Chung Chang mStopPending = false; 1340d2c710a293d68fb729eff148d40002f5deacf17Chih-Chung Chang } 1350d2c710a293d68fb729eff148d40002f5deacf17Chih-Chung Chang 136e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang // Change resampler and retry if format change happened 137e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang if (mFormatChanged) { 138e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang mFormatChanged = false; 139e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang checkAndSetResampler(); 140e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang free(pTmpBuffer); 141e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang return read(buffer_out, NULL); 142efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang } 143efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang 144e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang // Create a new MediaBuffer 145e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang int32_t outBufferSize = outFrameCnt * 2 * sizeof(int16_t); 146e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang MediaBuffer* outBuffer = new MediaBuffer(outBufferSize); 147efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang 148e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang // Convert back to 2 channels and 16 bits 149e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang AudioMixer::ditherAndClamp( 150e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang (int32_t *)((uint8_t*)outBuffer->data() + outBuffer->range_offset()), 151e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang pTmpBuffer, outFrameCnt); 152e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang free(pTmpBuffer); 153efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang 154efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang // Compute and set the new timestamp 155e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang sp<MetaData> to = outBuffer->meta_data(); 156e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang int64_t totalOutDurationUs = (mAccuOutBufferSize * 1000000) / (mOutputSampleRate * 2 * 2); 157efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang int64_t timeUs = mInitialTimeStampUs + totalOutDurationUs; 158efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang to->setInt64(kKeyTime, timeUs); 159efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang 160efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang // update the accumulate size 161efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang mAccuOutBufferSize += outBufferSize; 162e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang *buffer_out = outBuffer; 163efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang } else { 164e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang // Resampling not required. Read and pass-through. 165efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang MediaBuffer *aBuffer; 166efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang status_t err = mSource->read(&aBuffer, options); 167e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang if (err != OK) { 168e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang LOGV("read returns err = %d", err); 169e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang } 170e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang 171e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang if (err == INFO_FORMAT_CHANGED) { 172e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang checkAndSetResampler(); 173e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang return read(buffer_out, NULL); 174e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang } 175e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang 176e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang // EOS or some other error 177efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang if(err != OK) { 178e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang stop(); 179efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang *buffer_out = NULL; 180efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang return err; 181efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang } 182efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang *buffer_out = aBuffer; 183efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang } 184efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang 185efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang return OK; 186efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang} 187efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang 188efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Changstatus_t VideoEditorSRC::getNextBuffer(AudioBufferProvider::Buffer *pBuffer) { 189e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang LOGV("Requesting %d, chan = %d", pBuffer->frameCount, mChannelCnt); 190e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang uint32_t done = 0; 191e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang uint32_t want = pBuffer->frameCount * mChannelCnt * 2; 192e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang pBuffer->raw = malloc(want); 193e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang 194e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang while (mStarted && want > 0) { 195e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang // If we don't have any data left, read a new buffer. 196e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang if (!mBuffer) { 197e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang // if we seek, reset the initial time stamp and accumulated time 198e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang ReadOptions options; 199e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang if (mSeekTimeUs >= 0) { 200e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang LOGV("%p cacheMore_l Seek requested = %lld", this, mSeekTimeUs); 201e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang ReadOptions::SeekMode mode = mSeekMode; 202e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang options.setSeekTo(mSeekTimeUs, mode); 203e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang mSeekTimeUs = -1; 204e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang mInitialTimeStampUs = -1; 205e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang mAccuOutBufferSize = 0; 206e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang } 207efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang 208e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang status_t err = mSource->read(&mBuffer, &options); 209efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang 210e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang if (err != OK) { 211e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang free(pBuffer->raw); 212e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang pBuffer->raw = NULL; 213e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang pBuffer->frameCount = 0; 21484161acd0c02718b47f82ced3123e9d9eac7b9b9Rajneesh Chowdury } 215e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang 216e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang if (err == INFO_FORMAT_CHANGED) { 217e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang LOGV("getNextBuffer: source read returned INFO_FORMAT_CHANGED"); 218e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang // At this point we cannot switch to a new AudioResampler because 219e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang // we are in a callback called by the AudioResampler itself. So 220e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang // just remember the fact that the format has changed, and let 221e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang // read() handles this. 222e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang mFormatChanged = true; 223e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang return err; 224efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang } 225efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang 226e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang // EOS or some other error 227e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang if (err != OK) { 228e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang LOGV("EOS or some err: %d", err); 2290d2c710a293d68fb729eff148d40002f5deacf17Chih-Chung Chang // We cannot call stop() here because stop() will release the 2300d2c710a293d68fb729eff148d40002f5deacf17Chih-Chung Chang // AudioResampler, and we are in a callback of the AudioResampler. 2310d2c710a293d68fb729eff148d40002f5deacf17Chih-Chung Chang // So just remember the fact and let read() call stop(). 2320d2c710a293d68fb729eff148d40002f5deacf17Chih-Chung Chang mStopPending = true; 233e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang return err; 234e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang } 235efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang 236e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang CHECK(mBuffer); 237e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang mLeftover = mBuffer->range_length(); 238efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang if (mInitialTimeStampUs == -1) { 239efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang int64_t curTS; 240e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang sp<MetaData> from = mBuffer->meta_data(); 241efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang from->findInt64(kKeyTime, &curTS); 242efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang LOGV("setting mInitialTimeStampUs to %lld", mInitialTimeStampUs); 243efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang mInitialTimeStampUs = curTS; 244efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang } 245e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang } 246efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang 247e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang // Now copy data to the destination 248e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang uint32_t todo = mLeftover; 249e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang if (todo > want) { 250e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang todo = want; 251efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang } 252efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang 253e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang uint8_t* end = (uint8_t*)mBuffer->data() + mBuffer->range_offset() 254e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang + mBuffer->range_length(); 255e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang memcpy((uint8_t*)pBuffer->raw + done, end - mLeftover, todo); 256e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang done += todo; 257e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang want -= todo; 258e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang mLeftover -= todo; 259e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang 260e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang // Release MediaBuffer as soon as possible. 261e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang if (mLeftover == 0) { 262e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang mBuffer->release(); 263e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang mBuffer = NULL; 264e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang } 265efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang } 266efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang 267e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang pBuffer->frameCount = done / (mChannelCnt * 2); 268e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang LOGV("getNextBuffer done %d", pBuffer->frameCount); 269efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang return OK; 270efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang} 271efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang 272efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang 273efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Changvoid VideoEditorSRC::releaseBuffer(AudioBufferProvider::Buffer *pBuffer) { 274e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang free(pBuffer->raw); 275e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang pBuffer->raw = NULL; 276efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang pBuffer->frameCount = 0; 277efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang} 278efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang 279e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Changvoid VideoEditorSRC::checkAndSetResampler() { 28084161acd0c02718b47f82ced3123e9d9eac7b9b9Rajneesh Chowdury LOGV("checkAndSetResampler"); 28184161acd0c02718b47f82ced3123e9d9eac7b9b9Rajneesh Chowdury 28284161acd0c02718b47f82ced3123e9d9eac7b9b9Rajneesh Chowdury sp<MetaData> format = mSource->getFormat(); 28384161acd0c02718b47f82ced3123e9d9eac7b9b9Rajneesh Chowdury const char *mime; 284e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang CHECK(format->findCString(kKeyMIMEType, &mime)); 28584161acd0c02718b47f82ced3123e9d9eac7b9b9Rajneesh Chowdury CHECK(!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)); 28684161acd0c02718b47f82ced3123e9d9eac7b9b9Rajneesh Chowdury 287e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang CHECK(format->findInt32(kKeySampleRate, &mSampleRate)); 288e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang CHECK(format->findInt32(kKeyChannelCount, &mChannelCnt)); 28984161acd0c02718b47f82ced3123e9d9eac7b9b9Rajneesh Chowdury 290e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang // If a resampler exists, delete it first 29184161acd0c02718b47f82ced3123e9d9eac7b9b9Rajneesh Chowdury if (mResampler != NULL) { 29284161acd0c02718b47f82ced3123e9d9eac7b9b9Rajneesh Chowdury delete mResampler; 29384161acd0c02718b47f82ced3123e9d9eac7b9b9Rajneesh Chowdury mResampler = NULL; 29484161acd0c02718b47f82ced3123e9d9eac7b9b9Rajneesh Chowdury } 29584161acd0c02718b47f82ced3123e9d9eac7b9b9Rajneesh Chowdury 296e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang // Clear previous buffer 297e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang if (mBuffer) { 298e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang mBuffer->release(); 299e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang mBuffer = NULL; 300e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang } 30184161acd0c02718b47f82ced3123e9d9eac7b9b9Rajneesh Chowdury 302e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang if (mSampleRate != mOutputSampleRate || mChannelCnt != 2) { 303e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang LOGV("Resampling required (in rate %d, out rate %d, in channel %d)", 304e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang mSampleRate, mOutputSampleRate, mChannelCnt); 30584161acd0c02718b47f82ced3123e9d9eac7b9b9Rajneesh Chowdury 306e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang mResampler = AudioResampler::create( 307e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang 16 /* bit depth */, 308e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang mChannelCnt, 309e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang mOutputSampleRate, 310e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang AudioResampler::DEFAULT); 311e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang CHECK(mResampler); 31284161acd0c02718b47f82ced3123e9d9eac7b9b9Rajneesh Chowdury mResampler->setSampleRate(mSampleRate); 31384161acd0c02718b47f82ced3123e9d9eac7b9b9Rajneesh Chowdury mResampler->setVolume(UNITY_GAIN, UNITY_GAIN); 31484161acd0c02718b47f82ced3123e9d9eac7b9b9Rajneesh Chowdury } else { 31584161acd0c02718b47f82ced3123e9d9eac7b9b9Rajneesh Chowdury LOGV("Resampling not required (%d = %d)", mSampleRate, mOutputSampleRate); 31684161acd0c02718b47f82ced3123e9d9eac7b9b9Rajneesh Chowdury } 31784161acd0c02718b47f82ced3123e9d9eac7b9b9Rajneesh Chowdury} 31884161acd0c02718b47f82ced3123e9d9eac7b9b9Rajneesh Chowdury 319efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang} //namespce android 320