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