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),
27ac3e9db88ddb1f24bc6c8fb744a37dfdeec332bbGlenn Kasten    // mFrameSize below
286466c9e6e6278c740aed77f695f679be9f5db478Glenn Kasten    mAllocated(NULL), mSize(0), mOffset(0), mRemaining(0), mGetCount(0), mFramesReleased(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);
40ac3e9db88ddb1f24bc6c8fb744a37dfdeec332bbGlenn Kasten    mFrameSize = Format_frameSize(source->format());
41010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten}
42010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten
43010662326b9c43c703725f933e95e0897f8a6bddGlenn KastenSourceAudioBufferProvider::~SourceAudioBufferProvider()
44010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten{
45010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten    free(mAllocated);
46010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten}
47010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten
48d79072e9dff59f767cce2cda1caab80ce5a0815bGlenn Kastenstatus_t SourceAudioBufferProvider::getNextBuffer(Buffer *buffer)
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        }
574d693d6b8cc1283f92f5301daf19a07abc772a2bGlenn Kasten        buffer->raw = (char *) mAllocated + (mOffset * mFrameSize);
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);
6497f230b39bfedeea6ee1a2fc9be847dcbdcb163aGlenn Kasten        // Android convention is to _not_ check the return value of malloc and friends.
6597f230b39bfedeea6ee1a2fc9be847dcbdcb163aGlenn Kasten        // But in this case the calloc() can also fail due to integer overflow,
6697f230b39bfedeea6ee1a2fc9be847dcbdcb163aGlenn Kasten        // so we check and recover.
6797f230b39bfedeea6ee1a2fc9be847dcbdcb163aGlenn Kasten        mAllocated = calloc(buffer->frameCount, mFrameSize);
6897f230b39bfedeea6ee1a2fc9be847dcbdcb163aGlenn Kasten        if (mAllocated == NULL) {
6997f230b39bfedeea6ee1a2fc9be847dcbdcb163aGlenn Kasten            mSize = 0;
7097f230b39bfedeea6ee1a2fc9be847dcbdcb163aGlenn Kasten            goto fail;
7197f230b39bfedeea6ee1a2fc9be847dcbdcb163aGlenn Kasten        }
72010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten        mSize = buffer->frameCount;
73010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten    }
7497f230b39bfedeea6ee1a2fc9be847dcbdcb163aGlenn Kasten    {
7597f230b39bfedeea6ee1a2fc9be847dcbdcb163aGlenn Kasten        // read from source
76d79072e9dff59f767cce2cda1caab80ce5a0815bGlenn Kasten        ssize_t actual = mSource->read(mAllocated, buffer->frameCount);
7797f230b39bfedeea6ee1a2fc9be847dcbdcb163aGlenn Kasten        if (actual > 0) {
7897f230b39bfedeea6ee1a2fc9be847dcbdcb163aGlenn Kasten            ALOG_ASSERT((size_t) actual <= buffer->frameCount);
7997f230b39bfedeea6ee1a2fc9be847dcbdcb163aGlenn Kasten            mOffset = 0;
8097f230b39bfedeea6ee1a2fc9be847dcbdcb163aGlenn Kasten            mRemaining = actual;
8197f230b39bfedeea6ee1a2fc9be847dcbdcb163aGlenn Kasten            buffer->raw = mAllocated;
8297f230b39bfedeea6ee1a2fc9be847dcbdcb163aGlenn Kasten            buffer->frameCount = actual;
8397f230b39bfedeea6ee1a2fc9be847dcbdcb163aGlenn Kasten            mGetCount = actual;
8497f230b39bfedeea6ee1a2fc9be847dcbdcb163aGlenn Kasten            return OK;
8597f230b39bfedeea6ee1a2fc9be847dcbdcb163aGlenn Kasten        }
86010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten    }
8797f230b39bfedeea6ee1a2fc9be847dcbdcb163aGlenn Kastenfail:
88010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten    buffer->raw = NULL;
89010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten    buffer->frameCount = 0;
90010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten    mGetCount = 0;
91010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten    return NOT_ENOUGH_DATA;
92010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten}
93010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten
94010662326b9c43c703725f933e95e0897f8a6bddGlenn Kastenvoid SourceAudioBufferProvider::releaseBuffer(Buffer *buffer)
95010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten{
96010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten    ALOG_ASSERT((buffer != NULL) &&
974d693d6b8cc1283f92f5301daf19a07abc772a2bGlenn Kasten            (buffer->raw == (char *) mAllocated + (mOffset * mFrameSize)) &&
98010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten            (buffer->frameCount <= mGetCount) &&
99010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten            (mGetCount <= mRemaining) &&
100010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten            (mOffset + mRemaining <= mSize));
101010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten    mOffset += buffer->frameCount;
102010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten    mRemaining -= buffer->frameCount;
1036466c9e6e6278c740aed77f695f679be9f5db478Glenn Kasten    mFramesReleased += buffer->frameCount;
104010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten    buffer->raw = NULL;
105010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten    buffer->frameCount = 0;
106010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten    mGetCount = 0;
107010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten}
108010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten
109288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kastensize_t SourceAudioBufferProvider::framesReady() const
110288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten{
111288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    ssize_t avail = mSource->availableToRead();
112288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    return avail < 0 ? 0 : (size_t) avail;
113288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten}
114288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten
115818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hungint64_t SourceAudioBufferProvider::framesReleased() const
1166466c9e6e6278c740aed77f695f679be9f5db478Glenn Kasten{
1176466c9e6e6278c740aed77f695f679be9f5db478Glenn Kasten    return mFramesReleased;
1186466c9e6e6278c740aed77f695f679be9f5db478Glenn Kasten}
1196466c9e6e6278c740aed77f695f679be9f5db478Glenn Kasten
120818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hungvoid SourceAudioBufferProvider::onTimestamp(const ExtendedTimestamp &timestamp)
1216466c9e6e6278c740aed77f695f679be9f5db478Glenn Kasten{
1226466c9e6e6278c740aed77f695f679be9f5db478Glenn Kasten    mSource->onTimestamp(timestamp);
1236466c9e6e6278c740aed77f695f679be9f5db478Glenn Kasten}
1246466c9e6e6278c740aed77f695f679be9f5db478Glenn Kasten
125010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten}   // namespace android
126