/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

//#define USE_LOG SLAndroidLogLevel_Verbose

#include "sles_allinclusive.h"
#include "android/android_AudioToCbRenderer.h"

#include <media/stagefright/foundation/ADebug.h>

namespace android {

//--------------------------------------------------------------------------------------------------
AudioToCbRenderer::AudioToCbRenderer(AudioPlayback_Parameters* params) : AudioSfDecoder(params),
        mDecodeCbf(NULL),
        mDecodeUser(NULL)
{
    SL_LOGD("AudioToCbRenderer::AudioToCbRenderer()");

}


AudioToCbRenderer::~AudioToCbRenderer() {
    SL_LOGD("AudioToCbRenderer::~AudioToCbRenderer()");

}

void AudioToCbRenderer::setDataPushListener(const data_push_cbf_t pushCbf, CAudioPlayer* pushUser) {
    mDecodeCbf = pushCbf;
    mDecodeUser = pushUser;
}

//--------------------------------------------------
// Event handlers

void AudioToCbRenderer::onRender() {
    SL_LOGV("AudioToCbRenderer::onRender");

    Mutex::Autolock _l(mBufferSourceLock);

    if (NULL == mDecodeBuffer) {
        // nothing to render, move along
        //SL_LOGV("AudioToCbRenderer::onRender NULL buffer, exiting");
        return;
    }

    if (mStateFlags & kFlagPlaying) {
        if (NULL != mDecodeCbf) {
            size_t full = mDecodeBuffer->range_length();
            size_t consumed = 0;
            size_t offset = 0;
            while (offset < full) {
                consumed = mDecodeCbf(
                        (const uint8_t *)mDecodeBuffer->data()
                                + offset + mDecodeBuffer->range_offset(),
                        mDecodeBuffer->range_length() - offset,
                        mDecodeUser);
                offset += consumed;
                //SL_LOGV("consumed=%u, offset=%u, full=%u", consumed, offset, full);
                if (consumed == 0) {
                    // decoded data is not being consumed, skip this buffer
                    break;
                }
            }
        }
        (new AMessage(kWhatDecode, id()))->post();
    }

    mDecodeBuffer->release();
    mDecodeBuffer = NULL;

    updateOneShot();
}


//--------------------------------------------------
// Audio output
void AudioToCbRenderer::createAudioSink() {
    SL_LOGD("AudioToCbRenderer::createAudioSink()");
}


void AudioToCbRenderer::updateAudioSink() {
    SL_LOGD("AudioToCbRenderer::updateAudioSink()");
}


void AudioToCbRenderer::startAudioSink() {
    SL_LOGD("AudioToCbRenderer::startAudioSink()");
}


void AudioToCbRenderer::pauseAudioSink() {
    SL_LOGD("AudioToCbRenderer::pauseAudioSink()");
}

} // namespace android
