/*
 * 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),
    // mFrameBitShiftFormat below
    mAllocated(NULL), mSize(0), mOffset(0), mRemaining(0), mGetCount(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);
    mFrameBitShift = Format_frameBitShift(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 << mFrameBitShift);
        mGetCount = buffer->frameCount;
        return OK;
    }
    // do we need to reallocate?
    if (buffer->frameCount > mSize) {
        free(mAllocated);
        mAllocated = malloc(buffer->frameCount << mFrameBitShift);
        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 << mFrameBitShift)) &&
            (buffer->frameCount <= mGetCount) &&
            (mGetCount <= mRemaining) &&
            (mOffset + mRemaining <= mSize));
    mOffset += buffer->frameCount;
    mRemaining -= 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;
}

}   // namespace android
