void LVAudioresample_LowQuality(M4OSA_Int16* out, M4OSA_Int16* input, M4OSA_Int32 outFrameCount, M4OSA_Context resamplerContext) { VideoEditorResampler *context = (VideoEditorResampler *)resamplerContext; int32_t *pTmpBuffer = NULL; context->nbSamples = (context->inSamplingRate * outFrameCount) / context->outSamplingRate; memcpy(context->mInput,input,(context->nbSamples * context->nbChannels * sizeof(int16_t))); /* SRC module always gives stereo output, hence 2 for stereo audio */ pTmpBuffer = (int32_t*)malloc(outFrameCount * 2 * sizeof(int32_t)); memset(pTmpBuffer, 0x00, outFrameCount * 2 * sizeof(int32_t)); context->mResampler->resample((int32_t *)pTmpBuffer, (size_t)outFrameCount, (VideoEditorResampler *)resamplerContext); // Convert back to 16 bits ditherAndClamp((int32_t*)out, pTmpBuffer, outFrameCount); free(pTmpBuffer); pTmpBuffer = NULL; }
status_t VideoEditorSRC::read( MediaBuffer **buffer_out, const ReadOptions *options) { ALOGV("read %p(%p)", this, mSource.get()); *buffer_out = NULL; if (!mStarted) { return ERROR_END_OF_STREAM; } if (mResampler) { // Store the seek parameters int64_t seekTimeUs; ReadOptions::SeekMode mode = ReadOptions::SEEK_PREVIOUS_SYNC; if (options && options->getSeekTo(&seekTimeUs, &mode)) { ALOGV("read Seek %lld", seekTimeUs); mSeekTimeUs = seekTimeUs; mSeekMode = mode; } // We ask for 1024 frames in output // resampler output is always 2 channels and 32 bits const size_t kOutputFrameCount = 1024; const size_t kBytes = kOutputFrameCount * 2 * sizeof(int32_t); int32_t *pTmpBuffer = (int32_t *)calloc(1, kBytes); if (!pTmpBuffer) { ALOGE("calloc failed to allocate memory: %d bytes", kBytes); return NO_MEMORY; } // Resample to target quality mResampler->resample(pTmpBuffer, kOutputFrameCount, this); if (mStopPending) { stop(); mStopPending = false; } // Change resampler and retry if format change happened if (mFormatChanged) { mFormatChanged = false; checkAndSetResampler(); free(pTmpBuffer); return read(buffer_out, NULL); } // Create a new MediaBuffer int32_t outBufferSize = kOutputFrameCount * 2 * sizeof(int16_t); MediaBuffer* outBuffer = new MediaBuffer(outBufferSize); // Convert back to 2 channels and 16 bits ditherAndClamp( (int32_t *)((uint8_t*)outBuffer->data() + outBuffer->range_offset()), pTmpBuffer, kOutputFrameCount); free(pTmpBuffer); // Compute and set the new timestamp sp<MetaData> to = outBuffer->meta_data(); int64_t totalOutDurationUs = (mAccuOutBufferSize * 1000000) / (mOutputSampleRate * 2 * 2); int64_t timeUs = mInitialTimeStampUs + totalOutDurationUs; to->setInt64(kKeyTime, timeUs); // update the accumulate size mAccuOutBufferSize += outBufferSize; *buffer_out = outBuffer; } else { // Resampling not required. Read and pass-through. MediaBuffer *aBuffer; status_t err = mSource->read(&aBuffer, options); if (err != OK) { ALOGV("read returns err = %d", err); } if (err == INFO_FORMAT_CHANGED) { checkAndSetResampler(); return read(buffer_out, NULL); } // EOS or some other error if(err != OK) { stop(); *buffer_out = NULL; return err; } *buffer_out = aBuffer; } return OK; }