| Chih-Chung Chang | 9969866 | 2011-06-30 14:21:38 +0800 | [diff] [blame^] | 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 |  | 
 | 30 | namespace android { | 
 | 31 |  | 
 | 32 | VideoEditorSRC::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 |  | 
 | 80 | VideoEditorSRC::~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 |  | 
 | 95 | void 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 | status_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 |  | 
 | 154 | status_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 |  | 
 | 176 | sp<MetaData> VideoEditorSRC::getFormat() { | 
 | 177 |     LOGV("AudioSRC getFormat"); | 
 | 178 |     //Mutex::Autolock autoLock(mLock); | 
 | 179 |     return mOutputFormat; | 
 | 180 | } | 
 | 181 |  | 
 | 182 | status_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 |  | 
 | 268 | status_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 |  | 
 | 362 | void VideoEditorSRC::releaseBuffer(AudioBufferProvider::Buffer *pBuffer) { | 
 | 363 |     if(pBuffer->raw != NULL) { | 
 | 364 |         pBuffer->raw = NULL; | 
 | 365 |     } | 
 | 366 |     pBuffer->frameCount = 0; | 
 | 367 | } | 
 | 368 |  | 
 | 369 | } //namespce android |