1010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten/*
2010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten * Copyright (C) 2012 The Android Open Source Project
3010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten *
4010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten * Licensed under the Apache License, Version 2.0 (the "License");
5010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten * you may not use this file except in compliance with the License.
6010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten * You may obtain a copy of the License at
7010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten *
8010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten *      http://www.apache.org/licenses/LICENSE-2.0
9010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten *
10010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten * Unless required by applicable law or agreed to in writing, software
11010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten * distributed under the License is distributed on an "AS IS" BASIS,
12010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten * See the License for the specific language governing permissions and
14010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten * limitations under the License.
15010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten */
16010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten
17010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten#define LOG_TAG "SourceAudioBufferProvider"
18010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten//#define LOG_NDEBUG 0
19010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten
20010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten#include <utils/Log.h>
212dd4bdd715f586d4d30cf90cc6fc2bbfbce60fe0Glenn Kasten#include <media/nbaio/SourceAudioBufferProvider.h>
22010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten
23010662326b9c43c703725f933e95e0897f8a6bddGlenn Kastennamespace android {
24010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten
25010662326b9c43c703725f933e95e0897f8a6bddGlenn KastenSourceAudioBufferProvider::SourceAudioBufferProvider(const sp<NBAIO_Source>& source) :
26010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten    mSource(source),
27010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten    // mFrameBitShiftFormat below
28010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten    mAllocated(NULL), mSize(0), mOffset(0), mRemaining(0), mGetCount(0)
29010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten{
30010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten    ALOG_ASSERT(source != 0);
31010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten
32010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten    // negotiate with source
33010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten    NBAIO_Format counterOffers[1];
34010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten    size_t numCounterOffers = 1;
35010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten    ssize_t index = source->negotiate(NULL, 0, counterOffers, numCounterOffers);
36010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten    ALOG_ASSERT(index == (ssize_t) NEGOTIATE && numCounterOffers > 0);
37010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten    numCounterOffers = 0;
38010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten    index = source->negotiate(counterOffers, 1, NULL, numCounterOffers);
39010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten    ALOG_ASSERT(index == 0);
40010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten    mFrameBitShift = Format_frameBitShift(source->format());
41010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten}
42010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten
43010662326b9c43c703725f933e95e0897f8a6bddGlenn KastenSourceAudioBufferProvider::~SourceAudioBufferProvider()
44010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten{
45010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten    free(mAllocated);
46010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten}
47010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten
48010662326b9c43c703725f933e95e0897f8a6bddGlenn Kastenstatus_t SourceAudioBufferProvider::getNextBuffer(Buffer *buffer, int64_t pts)
49010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten{
50010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten    ALOG_ASSERT(buffer != NULL && buffer->frameCount > 0 && mGetCount == 0);
51010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten    // any leftover data available?
52010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten    if (mRemaining > 0) {
53010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten        ALOG_ASSERT(mOffset + mRemaining <= mSize);
54010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten        if (mRemaining < buffer->frameCount) {
55010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten            buffer->frameCount = mRemaining;
56010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten        }
57010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten        buffer->raw = (char *) mAllocated + (mOffset << mFrameBitShift);
58010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten        mGetCount = buffer->frameCount;
59010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten        return OK;
60010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten    }
61010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten    // do we need to reallocate?
62010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten    if (buffer->frameCount > mSize) {
63010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten        free(mAllocated);
64010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten        mAllocated = malloc(buffer->frameCount << mFrameBitShift);
65010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten        mSize = buffer->frameCount;
66010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten    }
67010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten    // read from source
682c3b2da3049627264b7c6b449a1622f002210f03John Grossman    ssize_t actual = mSource->read(mAllocated, buffer->frameCount, pts);
69010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten    if (actual > 0) {
70010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten        ALOG_ASSERT((size_t) actual <= buffer->frameCount);
71010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten        mOffset = 0;
72010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten        mRemaining = actual;
73010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten        buffer->raw = mAllocated;
74010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten        buffer->frameCount = actual;
75010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten        mGetCount = actual;
76010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten        return OK;
77010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten    }
78010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten    buffer->raw = NULL;
79010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten    buffer->frameCount = 0;
80010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten    mGetCount = 0;
81010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten    return NOT_ENOUGH_DATA;
82010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten}
83010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten
84010662326b9c43c703725f933e95e0897f8a6bddGlenn Kastenvoid SourceAudioBufferProvider::releaseBuffer(Buffer *buffer)
85010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten{
86010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten    ALOG_ASSERT((buffer != NULL) &&
87010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten            (buffer->raw == (char *) mAllocated + (mOffset << mFrameBitShift)) &&
88010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten            (buffer->frameCount <= mGetCount) &&
89010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten            (mGetCount <= mRemaining) &&
90010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten            (mOffset + mRemaining <= mSize));
91010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten    mOffset += buffer->frameCount;
92010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten    mRemaining -= buffer->frameCount;
93010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten    buffer->raw = NULL;
94010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten    buffer->frameCount = 0;
95010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten    mGetCount = 0;
96010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten}
97010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten
98288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kastensize_t SourceAudioBufferProvider::framesReady() const
99288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten{
100288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    ssize_t avail = mSource->availableToRead();
101288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    return avail < 0 ? 0 : (size_t) avail;
102288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten}
103288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten
104010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten}   // namespace android
105