ssize_t AudioStreamOutSink::negotiate(const NBAIO_Format offers[], size_t numOffers,
                                      NBAIO_Format counterOffers[], size_t& numCounterOffers)
{
    if (mFormat == Format_Invalid) {
        mStreamBufferSizeBytes = mStream->common.get_buffer_size(&mStream->common);
        audio_format_t streamFormat = mStream->common.get_format(&mStream->common);
        if (streamFormat == AUDIO_FORMAT_PCM_16_BIT) {
            uint32_t sampleRate = mStream->common.get_sample_rate(&mStream->common);
            audio_channel_mask_t channelMask =
                    (audio_channel_mask_t) mStream->common.get_channels(&mStream->common);
            mFormat = Format_from_SR_C(sampleRate, popcount(channelMask));
            mBitShift = Format_frameBitShift(mFormat);
        }
    }
    return NBAIO_Sink::negotiate(offers, numOffers, counterOffers, numCounterOffers);
}
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());
}