Home | History | Annotate | Download | only in audioflinger
      1 /*
      2  * Copyright (C) 2012 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #define LOG_TAG "SourceAudioBufferProvider"
     18 //#define LOG_NDEBUG 0
     19 
     20 #include <utils/Log.h>
     21 #include "SourceAudioBufferProvider.h"
     22 
     23 namespace android {
     24 
     25 SourceAudioBufferProvider::SourceAudioBufferProvider(const sp<NBAIO_Source>& source) :
     26     mSource(source),
     27     // mFrameBitShiftFormat below
     28     mAllocated(NULL), mSize(0), mOffset(0), mRemaining(0), mGetCount(0)
     29 {
     30     ALOG_ASSERT(source != 0);
     31 
     32     // negotiate with source
     33     NBAIO_Format counterOffers[1];
     34     size_t numCounterOffers = 1;
     35     ssize_t index = source->negotiate(NULL, 0, counterOffers, numCounterOffers);
     36     ALOG_ASSERT(index == (ssize_t) NEGOTIATE && numCounterOffers > 0);
     37     numCounterOffers = 0;
     38     index = source->negotiate(counterOffers, 1, NULL, numCounterOffers);
     39     ALOG_ASSERT(index == 0);
     40     mFrameBitShift = Format_frameBitShift(source->format());
     41 }
     42 
     43 SourceAudioBufferProvider::~SourceAudioBufferProvider()
     44 {
     45     free(mAllocated);
     46 }
     47 
     48 status_t SourceAudioBufferProvider::getNextBuffer(Buffer *buffer, int64_t pts)
     49 {
     50     ALOG_ASSERT(buffer != NULL && buffer->frameCount > 0 && mGetCount == 0);
     51     // any leftover data available?
     52     if (mRemaining > 0) {
     53         ALOG_ASSERT(mOffset + mRemaining <= mSize);
     54         if (mRemaining < buffer->frameCount) {
     55             buffer->frameCount = mRemaining;
     56         }
     57         buffer->raw = (char *) mAllocated + (mOffset << mFrameBitShift);
     58         mGetCount = buffer->frameCount;
     59         return OK;
     60     }
     61     // do we need to reallocate?
     62     if (buffer->frameCount > mSize) {
     63         free(mAllocated);
     64         mAllocated = malloc(buffer->frameCount << mFrameBitShift);
     65         mSize = buffer->frameCount;
     66     }
     67     // read from source
     68     ssize_t actual = mSource->read(mAllocated, buffer->frameCount);
     69     if (actual > 0) {
     70         ALOG_ASSERT((size_t) actual <= buffer->frameCount);
     71         mOffset = 0;
     72         mRemaining = actual;
     73         buffer->raw = mAllocated;
     74         buffer->frameCount = actual;
     75         mGetCount = actual;
     76         return OK;
     77     }
     78     buffer->raw = NULL;
     79     buffer->frameCount = 0;
     80     mGetCount = 0;
     81     return NOT_ENOUGH_DATA;
     82 }
     83 
     84 void SourceAudioBufferProvider::releaseBuffer(Buffer *buffer)
     85 {
     86     ALOG_ASSERT((buffer != NULL) &&
     87             (buffer->raw == (char *) mAllocated + (mOffset << mFrameBitShift)) &&
     88             (buffer->frameCount <= mGetCount) &&
     89             (mGetCount <= mRemaining) &&
     90             (mOffset + mRemaining <= mSize));
     91     mOffset += buffer->frameCount;
     92     mRemaining -= buffer->frameCount;
     93     buffer->raw = NULL;
     94     buffer->frameCount = 0;
     95     mGetCount = 0;
     96 }
     97 
     98 size_t SourceAudioBufferProvider::framesReady() const
     99 {
    100     ssize_t avail = mSource->availableToRead();
    101     return avail < 0 ? 0 : (size_t) avail;
    102 }
    103 
    104 }   // namespace android
    105