VideoEditorSRC.cpp revision c4689fae1bdb8d1c94eb28af1b2a1f30d2b1a3da
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 0 18#define LOG_TAG "VideoEditorSRC" 19 20#include <stdlib.h> 21#include <utils/Log.h> 22#include <audio_utils/primitives.h> 23#include <media/stagefright/foundation/ADebug.h> 24#include <media/stagefright/MetaData.h> 25#include <media/stagefright/MediaBuffer.h> 26#include <media/stagefright/MediaDefs.h> 27#include "AudioMixer.h" 28#include "VideoEditorSRC.h" 29 30 31namespace android { 32 33VideoEditorSRC::VideoEditorSRC(const sp<MediaSource> &source) { 34 ALOGV("VideoEditorSRC %p(%p)", this, source.get()); 35 static const int32_t kDefaultSamplingFreqencyHz = kFreq32000Hz; 36 mSource = source; 37 mResampler = NULL; 38 mChannelCnt = 0; 39 mSampleRate = 0; 40 mOutputSampleRate = kDefaultSamplingFreqencyHz; 41 mStarted = false; 42 mInitialTimeStampUs = -1; 43 mAccuOutBufferSize = 0; 44 mSeekTimeUs = -1; 45 mBuffer = NULL; 46 mLeftover = 0; 47 mFormatChanged = false; 48 mStopPending = false; 49 mSeekMode = ReadOptions::SEEK_PREVIOUS_SYNC; 50 51 // Input Source validation 52 sp<MetaData> format = mSource->getFormat(); 53 const char *mime; 54 CHECK(format->findCString(kKeyMIMEType, &mime)); 55 CHECK(!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)); 56 57 // Set the metadata of the output after resampling. 58 mOutputFormat = new MetaData; 59 mOutputFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW); 60 mOutputFormat->setInt32(kKeySampleRate, kDefaultSamplingFreqencyHz); 61 mOutputFormat->setInt32(kKeyChannelCount, 2); // always stereo 62} 63 64VideoEditorSRC::~VideoEditorSRC() { 65 ALOGV("~VideoEditorSRC %p(%p)", this, mSource.get()); 66 stop(); 67} 68 69status_t VideoEditorSRC::start(MetaData *params) { 70 ALOGV("start %p(%p)", this, mSource.get()); 71 CHECK(!mStarted); 72 73 // Set resampler if required 74 checkAndSetResampler(); 75 76 mSeekTimeUs = -1; 77 mSeekMode = ReadOptions::SEEK_PREVIOUS_SYNC; 78 mStarted = true; 79 mSource->start(); 80 81 return OK; 82} 83 84status_t VideoEditorSRC::stop() { 85 ALOGV("stop %p(%p)", this, mSource.get()); 86 if (!mStarted) { 87 return OK; 88 } 89 90 if (mBuffer) { 91 mBuffer->release(); 92 mBuffer = NULL; 93 } 94 mSource->stop(); 95 if (mResampler != NULL) { 96 delete mResampler; 97 mResampler = NULL; 98 } 99 100 mStarted = false; 101 mInitialTimeStampUs = -1; 102 mAccuOutBufferSize = 0; 103 mLeftover = 0; 104 105 return OK; 106} 107 108sp<MetaData> VideoEditorSRC::getFormat() { 109 ALOGV("getFormat"); 110 return mOutputFormat; 111} 112 113status_t VideoEditorSRC::read( 114 MediaBuffer **buffer_out, const ReadOptions *options) { 115 ALOGV("read %p(%p)", this, mSource.get()); 116 *buffer_out = NULL; 117 118 if (!mStarted) { 119 return ERROR_END_OF_STREAM; 120 } 121 122 if (mResampler) { 123 // Store the seek parameters 124 int64_t seekTimeUs; 125 ReadOptions::SeekMode mode = ReadOptions::SEEK_PREVIOUS_SYNC; 126 if (options && options->getSeekTo(&seekTimeUs, &mode)) { 127 ALOGV("read Seek %lld", seekTimeUs); 128 mSeekTimeUs = seekTimeUs; 129 mSeekMode = mode; 130 } 131 132 // We ask for 1024 frames in output 133 // resampler output is always 2 channels and 32 bits 134 const size_t kOutputFrameCount = 1024; 135 const size_t kBytes = kOutputFrameCount * 2 * sizeof(int32_t); 136 int32_t *pTmpBuffer = (int32_t *)calloc(1, kBytes); 137 if (!pTmpBuffer) { 138 ALOGE("calloc failed to allocate memory: %d bytes", kBytes); 139 return NO_MEMORY; 140 } 141 142 // Resample to target quality 143 mResampler->resample(pTmpBuffer, kOutputFrameCount, this); 144 145 if (mStopPending) { 146 stop(); 147 mStopPending = false; 148 } 149 150 // Change resampler and retry if format change happened 151 if (mFormatChanged) { 152 mFormatChanged = false; 153 checkAndSetResampler(); 154 free(pTmpBuffer); 155 return read(buffer_out, NULL); 156 } 157 158 // Create a new MediaBuffer 159 int32_t outBufferSize = kOutputFrameCount * 2 * sizeof(int16_t); 160 MediaBuffer* outBuffer = new MediaBuffer(outBufferSize); 161 162 // Convert back to 2 channels and 16 bits 163 ditherAndClamp( 164 (int32_t *)((uint8_t*)outBuffer->data() + outBuffer->range_offset()), 165 pTmpBuffer, kOutputFrameCount); 166 free(pTmpBuffer); 167 168 // Compute and set the new timestamp 169 sp<MetaData> to = outBuffer->meta_data(); 170 int64_t totalOutDurationUs = (mAccuOutBufferSize * 1000000) / (mOutputSampleRate * 2 * 2); 171 int64_t timeUs = mInitialTimeStampUs + totalOutDurationUs; 172 to->setInt64(kKeyTime, timeUs); 173 174 // update the accumulate size 175 mAccuOutBufferSize += outBufferSize; 176 *buffer_out = outBuffer; 177 } else { 178 // Resampling not required. Read and pass-through. 179 MediaBuffer *aBuffer; 180 status_t err = mSource->read(&aBuffer, options); 181 if (err != OK) { 182 ALOGV("read returns err = %d", err); 183 } 184 185 if (err == INFO_FORMAT_CHANGED) { 186 checkAndSetResampler(); 187 return read(buffer_out, NULL); 188 } 189 190 // EOS or some other error 191 if(err != OK) { 192 stop(); 193 *buffer_out = NULL; 194 return err; 195 } 196 *buffer_out = aBuffer; 197 } 198 199 return OK; 200} 201 202status_t VideoEditorSRC::getNextBuffer(AudioBufferProvider::Buffer *pBuffer) { 203 ALOGV("getNextBuffer %d, chan = %d", pBuffer->frameCount, mChannelCnt); 204 uint32_t done = 0; 205 uint32_t want = pBuffer->frameCount * mChannelCnt * 2; 206 pBuffer->raw = malloc(want); 207 208 while (mStarted && want > 0) { 209 // If we don't have any data left, read a new buffer. 210 if (!mBuffer) { 211 // if we seek, reset the initial time stamp and accumulated time 212 ReadOptions options; 213 if (mSeekTimeUs >= 0) { 214 ALOGV("%p cacheMore_l Seek requested = %lld", this, mSeekTimeUs); 215 ReadOptions::SeekMode mode = mSeekMode; 216 options.setSeekTo(mSeekTimeUs, mode); 217 mSeekTimeUs = -1; 218 mInitialTimeStampUs = -1; 219 mAccuOutBufferSize = 0; 220 } 221 222 status_t err = mSource->read(&mBuffer, &options); 223 224 if (err != OK) { 225 free(pBuffer->raw); 226 pBuffer->raw = NULL; 227 pBuffer->frameCount = 0; 228 } 229 230 if (err == INFO_FORMAT_CHANGED) { 231 ALOGV("getNextBuffer: source read returned INFO_FORMAT_CHANGED"); 232 // At this point we cannot switch to a new AudioResampler because 233 // we are in a callback called by the AudioResampler itself. So 234 // just remember the fact that the format has changed, and let 235 // read() handles this. 236 mFormatChanged = true; 237 return err; 238 } 239 240 // EOS or some other error 241 if (err != OK) { 242 ALOGV("EOS or some err: %d", err); 243 // We cannot call stop() here because stop() will release the 244 // AudioResampler, and we are in a callback of the AudioResampler. 245 // So just remember the fact and let read() call stop(). 246 mStopPending = true; 247 return err; 248 } 249 250 CHECK(mBuffer); 251 mLeftover = mBuffer->range_length(); 252 if (mInitialTimeStampUs == -1) { 253 int64_t curTS; 254 sp<MetaData> from = mBuffer->meta_data(); 255 from->findInt64(kKeyTime, &curTS); 256 ALOGV("setting mInitialTimeStampUs to %lld", mInitialTimeStampUs); 257 mInitialTimeStampUs = curTS; 258 } 259 } 260 261 // Now copy data to the destination 262 uint32_t todo = mLeftover; 263 if (todo > want) { 264 todo = want; 265 } 266 267 uint8_t* end = (uint8_t*)mBuffer->data() + mBuffer->range_offset() 268 + mBuffer->range_length(); 269 memcpy((uint8_t*)pBuffer->raw + done, end - mLeftover, todo); 270 done += todo; 271 want -= todo; 272 mLeftover -= todo; 273 274 // Release MediaBuffer as soon as possible. 275 if (mLeftover == 0) { 276 mBuffer->release(); 277 mBuffer = NULL; 278 } 279 } 280 281 pBuffer->frameCount = done / (mChannelCnt * 2); 282 ALOGV("getNextBuffer done %d", pBuffer->frameCount); 283 return OK; 284} 285 286 287void VideoEditorSRC::releaseBuffer(AudioBufferProvider::Buffer *pBuffer) { 288 ALOGV("releaseBuffer: %p", pBuffers); 289 free(pBuffer->raw); 290 pBuffer->raw = NULL; 291 pBuffer->frameCount = 0; 292} 293 294void VideoEditorSRC::checkAndSetResampler() { 295 ALOGV("checkAndSetResampler"); 296 297 static const uint16_t kUnityGain = 0x1000; 298 sp<MetaData> format = mSource->getFormat(); 299 const char *mime; 300 CHECK(format->findCString(kKeyMIMEType, &mime)); 301 CHECK(!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)); 302 303 CHECK(format->findInt32(kKeySampleRate, &mSampleRate)); 304 CHECK(format->findInt32(kKeyChannelCount, &mChannelCnt)); 305 306 // If a resampler exists, delete it first 307 if (mResampler != NULL) { 308 delete mResampler; 309 mResampler = NULL; 310 } 311 312 // Clear previous buffer 313 if (mBuffer) { 314 mBuffer->release(); 315 mBuffer = NULL; 316 } 317 318 if (mSampleRate != mOutputSampleRate || mChannelCnt != 2) { 319 ALOGV("Resampling required (%d => %d Hz, # channels = %d)", 320 mSampleRate, mOutputSampleRate, mChannelCnt); 321 322 mResampler = AudioResampler::create( 323 16 /* bit depth */, 324 mChannelCnt, 325 mOutputSampleRate, 326 AudioResampler::DEFAULT); 327 CHECK(mResampler); 328 mResampler->setSampleRate(mSampleRate); 329 mResampler->setVolume(kUnityGain, kUnityGain); 330 } else { 331 ALOGV("Resampling not required (%d => %d Hz, # channels = %d)", 332 mSampleRate, mOutputSampleRate, mChannelCnt); 333 } 334} 335 336} //namespce android 337