NBAIO.cpp revision fc7992bd8220824f1404c0c54ac516d9e28b58c2
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 "NBAIO" 18//#define LOG_NDEBUG 0 19 20#include <utils/Log.h> 21#include <media/nbaio/NBAIO.h> 22 23namespace android { 24 25size_t Format_frameSize(NBAIO_Format format) 26{ 27 switch (format) { 28 case Format_SR44_1_C2_I16: 29 case Format_SR48_C2_I16: 30 return 2 * sizeof(short); 31 case Format_SR44_1_C1_I16: 32 case Format_SR48_C1_I16: 33 return 1 * sizeof(short); 34 case Format_Invalid: 35 default: 36 return 0; 37 } 38} 39 40size_t Format_frameBitShift(NBAIO_Format format) 41{ 42 switch (format) { 43 case Format_SR44_1_C2_I16: 44 case Format_SR48_C2_I16: 45 return 2; // 1 << 2 == 2 * sizeof(short) 46 case Format_SR44_1_C1_I16: 47 case Format_SR48_C1_I16: 48 return 1; // 1 << 1 == 1 * sizeof(short) 49 case Format_Invalid: 50 default: 51 return 0; 52 } 53} 54 55unsigned Format_sampleRate(NBAIO_Format format) 56{ 57 switch (format) { 58 case Format_SR44_1_C1_I16: 59 case Format_SR44_1_C2_I16: 60 return 44100; 61 case Format_SR48_C1_I16: 62 case Format_SR48_C2_I16: 63 return 48000; 64 case Format_Invalid: 65 default: 66 return 0; 67 } 68} 69 70unsigned Format_channelCount(NBAIO_Format format) 71{ 72 switch (format) { 73 case Format_SR44_1_C1_I16: 74 case Format_SR48_C1_I16: 75 return 1; 76 case Format_SR44_1_C2_I16: 77 case Format_SR48_C2_I16: 78 return 2; 79 case Format_Invalid: 80 default: 81 return 0; 82 } 83} 84 85NBAIO_Format Format_from_SR_C(unsigned sampleRate, unsigned channelCount) 86{ 87 if (sampleRate == 44100 && channelCount == 2) return Format_SR44_1_C2_I16; 88 if (sampleRate == 48000 && channelCount == 2) return Format_SR48_C2_I16; 89 if (sampleRate == 44100 && channelCount == 1) return Format_SR44_1_C1_I16; 90 if (sampleRate == 48000 && channelCount == 1) return Format_SR48_C1_I16; 91 return Format_Invalid; 92} 93 94// This is a default implementation; it is expected that subclasses will optimize this. 95ssize_t NBAIO_Sink::writeVia(writeVia_t via, size_t total, void *user, size_t block) 96{ 97 if (!mNegotiated) { 98 return (ssize_t) NEGOTIATE; 99 } 100 static const size_t maxBlock = 32; 101 size_t frameSize = Format_frameSize(mFormat); 102 ALOG_ASSERT(frameSize > 0 && frameSize <= 8); 103 // double guarantees alignment for stack similar to what malloc() gives for heap 104 if (block == 0 || block > maxBlock) { 105 block = maxBlock; 106 } 107 double buffer[((frameSize * block) + sizeof(double) - 1) / sizeof(double)]; 108 size_t accumulator = 0; 109 while (accumulator < total) { 110 size_t count = total - accumulator; 111 if (count > block) { 112 count = block; 113 } 114 ssize_t ret = via(user, buffer, count); 115 if (ret > 0) { 116 ALOG_ASSERT((size_t) ret <= count); 117 size_t maxRet = ret; 118 ret = write(buffer, maxRet); 119 if (ret > 0) { 120 ALOG_ASSERT((size_t) ret <= maxRet); 121 accumulator += ret; 122 continue; 123 } 124 } 125 return accumulator > 0 ? accumulator : ret; 126 } 127 return accumulator; 128} 129 130// This is a default implementation; it is expected that subclasses will optimize this. 131ssize_t NBAIO_Source::readVia(readVia_t via, size_t total, void *user, 132 int64_t readPTS, size_t block) 133{ 134 if (!mNegotiated) { 135 return (ssize_t) NEGOTIATE; 136 } 137 static const size_t maxBlock = 32; 138 size_t frameSize = Format_frameSize(mFormat); 139 ALOG_ASSERT(frameSize > 0 && frameSize <= 8); 140 // double guarantees alignment for stack similar to what malloc() gives for heap 141 if (block == 0 || block > maxBlock) { 142 block = maxBlock; 143 } 144 double buffer[((frameSize * block) + sizeof(double) - 1) / sizeof(double)]; 145 size_t accumulator = 0; 146 while (accumulator < total) { 147 size_t count = total - accumulator; 148 if (count > block) { 149 count = block; 150 } 151 ssize_t ret = read(buffer, count, readPTS); 152 if (ret > 0) { 153 ALOG_ASSERT((size_t) ret <= count); 154 size_t maxRet = ret; 155 ret = via(user, buffer, maxRet, readPTS); 156 if (ret > 0) { 157 ALOG_ASSERT((size_t) ret <= maxRet); 158 accumulator += ret; 159 continue; 160 } 161 } 162 return accumulator > 0 ? accumulator : ret; 163 } 164 return accumulator; 165} 166 167// Default implementation that only accepts my mFormat 168ssize_t NBAIO_Port::negotiate(const NBAIO_Format offers[], size_t numOffers, 169 NBAIO_Format counterOffers[], size_t& numCounterOffers) 170{ 171 ALOGV("negotiate offers=%p numOffers=%u countersOffers=%p numCounterOffers=%u", 172 offers, numOffers, counterOffers, numCounterOffers); 173 if (mFormat != Format_Invalid) { 174 for (size_t i = 0; i < numOffers; ++i) { 175 if (offers[i] == mFormat) { 176 mNegotiated = true; 177 return i; 178 } 179 } 180 if (numCounterOffers > 0) { 181 counterOffers[0] = mFormat; 182 } 183 numCounterOffers = 1; 184 } else { 185 numCounterOffers = 0; 186 } 187 return (ssize_t) NEGOTIATE; 188} 189 190} // namespace android 191