Exemplo n.º 1
0
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;
}
Exemplo n.º 2
0
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;
}