/*
 * Copyright (C) 2012 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 LOG_TAG "SourceAudioBufferProvider"
//#define LOG_NDEBUG 0

#include <utils/Log.h>
#include <media/nbaio/SourceAudioBufferProvider.h>

namespace android {

SourceAudioBufferProvider::SourceAudioBufferProvider(const sp<NBAIO_Source>& source) :
    mSource(source),
    // mFrameSize below
    mAllocated(NULL), mSize(0), mOffset(0), mRemaining(0), mGetCount(0), mFramesReleased(0)
{
    ALOG_ASSERT(source != 0);

    // negotiate with source
    NBAIO_Format counterOffers[1];
    size_t numCounterOffers = 1;
    ssize_t index = source->negotiate(NULL, 0, counterOffers, numCounterOffers);
    ALOG_ASSERT(index == (ssize_t) NEGOTIATE && numCounterOffers > 0);
    numCounterOffers = 0;
    index = source->negotiate(counterOffers, 1, NULL, numCounterOffers);
    ALOG_ASSERT(index == 0);
    mFrameSize = Format_frameSize(source->format());
}

SourceAudioBufferProvider::~SourceAudioBufferProvider()
{
    free(mAllocated);
}

status_t SourceAudioBufferProvider::getNextBuffer(Buffer *buffer, int64_t pts)
{
    ALOG_ASSERT(buffer != NULL && buffer->frameCount > 0 && mGetCount == 0);
    // any leftover data available?
    if (mRemaining > 0) {
        ALOG_ASSERT(mOffset + mRemaining <= mSize);
        if (mRemaining < buffer->frameCount) {
            buffer->frameCount = mRemaining;
        }
        buffer->raw = (char *) mAllocated + (mOffset * mFrameSize);
        mGetCount = buffer->frameCount;
        return OK;
    }
    // do we need to reallocate?
    if (buffer->frameCount > mSize) {
        free(mAllocated);
        mAllocated = malloc(buffer->frameCount * mFrameSize);
        mSize = buffer->frameCount;
    }
    // read from source
    ssize_t actual = mSource->read(mAllocated, buffer->frameCount, pts);
    if (actual > 0) {
        ALOG_ASSERT((size_t) actual <= buffer->frameCount);
        mOffset = 0;
        mRemaining = actual;
        buffer->raw = mAllocated;
        buffer->frameCount = actual;
        mGetCount = actual;
        return OK;
    }
    buffer->raw = NULL;
    buffer->frameCount = 0;
    mGetCount = 0;
    return NOT_ENOUGH_DATA;
}

void SourceAudioBufferProvider::releaseBuffer(Buffer *buffer)
{
    ALOG_ASSERT((buffer != NULL) &&
            (buffer->raw == (char *) mAllocated + (mOffset * mFrameSize)) &&
            (buffer->frameCount <= mGetCount) &&
            (mGetCount <= mRemaining) &&
            (mOffset + mRemaining <= mSize));
    mOffset += buffer->frameCount;
    mRemaining -= buffer->frameCount;
    mFramesReleased += buffer->frameCount;
    buffer->raw = NULL;
    buffer->frameCount = 0;
    mGetCount = 0;
}

size_t SourceAudioBufferProvider::framesReady() const
{
    ssize_t avail = mSource->availableToRead();
    return avail < 0 ? 0 : (size_t) avail;
}

size_t SourceAudioBufferProvider::framesReleased() const
{
    return mFramesReleased;
}

void SourceAudioBufferProvider::onTimestamp(const AudioTimestamp& timestamp)
{
    mSource->onTimestamp(timestamp);
}

}   // namespace android
