diff options
Diffstat (limited to 'media/libnbaio')
-rw-r--r-- | media/libnbaio/Android.mk | 7 | ||||
-rw-r--r-- | media/libnbaio/AudioBufferProviderSource.cpp | 8 | ||||
-rw-r--r-- | media/libnbaio/AudioStreamInSource.cpp | 20 | ||||
-rw-r--r-- | media/libnbaio/AudioStreamOutSink.cpp | 20 | ||||
-rw-r--r-- | media/libnbaio/MonoPipe.cpp | 36 | ||||
-rw-r--r-- | media/libnbaio/MonoPipeReader.cpp | 4 | ||||
-rw-r--r-- | media/libnbaio/NBAIO.cpp | 132 | ||||
-rw-r--r-- | media/libnbaio/NBLog.cpp | 6 | ||||
-rw-r--r-- | media/libnbaio/Pipe.cpp | 6 | ||||
-rw-r--r-- | media/libnbaio/PipeReader.cpp | 6 | ||||
-rw-r--r-- | media/libnbaio/SourceAudioBufferProvider.cpp | 10 |
11 files changed, 101 insertions, 154 deletions
diff --git a/media/libnbaio/Android.mk b/media/libnbaio/Android.mk index 69c75b8..9707c4a 100644 --- a/media/libnbaio/Android.mk +++ b/media/libnbaio/Android.mk @@ -31,9 +31,8 @@ LOCAL_SHARED_LIBRARIES := \ libcommon_time_client \ libcutils \ libutils \ - liblog \ - libmedia -# This dependency on libmedia is for SingleStateQueueInstantiations. -# Consider a separate a library for SingleStateQueueInstantiations. + liblog + +LOCAL_STATIC_LIBRARIES += libinstantssq include $(BUILD_SHARED_LIBRARY) diff --git a/media/libnbaio/AudioBufferProviderSource.cpp b/media/libnbaio/AudioBufferProviderSource.cpp index 74a6fdb..551f516 100644 --- a/media/libnbaio/AudioBufferProviderSource.cpp +++ b/media/libnbaio/AudioBufferProviderSource.cpp @@ -24,11 +24,11 @@ namespace android { AudioBufferProviderSource::AudioBufferProviderSource(AudioBufferProvider *provider, - NBAIO_Format format) : + const NBAIO_Format& format) : NBAIO_Source(format), mProvider(provider), mConsumed(0) { ALOG_ASSERT(provider != NULL); - ALOG_ASSERT(format != Format_Invalid); + ALOG_ASSERT(Format_isValid(format)); } AudioBufferProviderSource::~AudioBufferProviderSource() @@ -68,7 +68,7 @@ ssize_t AudioBufferProviderSource::read(void *buffer, } // count could be zero, either because count was zero on entry or // available is zero, but both are unlikely so don't check for that - memcpy(buffer, (char *) mBuffer.raw + (mConsumed << mBitShift), count << mBitShift); + memcpy(buffer, (char *) mBuffer.raw + (mConsumed * mFrameSize), count * mFrameSize); if (CC_UNLIKELY((mConsumed += count) >= mBuffer.frameCount)) { mProvider->releaseBuffer(&mBuffer); mBuffer.raw = NULL; @@ -120,7 +120,7 @@ ssize_t AudioBufferProviderSource::readVia(readVia_t via, size_t total, void *us count = available; } if (CC_LIKELY(count > 0)) { - char* readTgt = (char *) mBuffer.raw + (mConsumed << mBitShift); + char* readTgt = (char *) mBuffer.raw + (mConsumed * mFrameSize); ssize_t ret = via(user, readTgt, count, readPTS); if (CC_UNLIKELY(ret <= 0)) { if (CC_LIKELY(accumulator > 0)) { diff --git a/media/libnbaio/AudioStreamInSource.cpp b/media/libnbaio/AudioStreamInSource.cpp index 05273f6..80bf61a 100644 --- a/media/libnbaio/AudioStreamInSource.cpp +++ b/media/libnbaio/AudioStreamInSource.cpp @@ -40,16 +40,14 @@ AudioStreamInSource::~AudioStreamInSource() ssize_t AudioStreamInSource::negotiate(const NBAIO_Format offers[], size_t numOffers, NBAIO_Format counterOffers[], size_t& numCounterOffers) { - if (mFormat == Format_Invalid) { + if (!Format_isValid(mFormat)) { 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); - } + 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), streamFormat); + mFrameSize = Format_frameSize(mFormat); } return NBAIO_Source::negotiate(offers, numOffers, counterOffers, numCounterOffers); } @@ -67,12 +65,12 @@ size_t AudioStreamInSource::framesOverrun() ssize_t AudioStreamInSource::read(void *buffer, size_t count) { - if (CC_UNLIKELY(mFormat == Format_Invalid)) { + if (CC_UNLIKELY(!Format_isValid(mFormat))) { return NEGOTIATE; } - ssize_t bytesRead = mStream->read(mStream, buffer, count << mBitShift); + ssize_t bytesRead = mStream->read(mStream, buffer, count * mFrameSize); if (bytesRead > 0) { - size_t framesRead = bytesRead >> mBitShift; + size_t framesRead = bytesRead / mFrameSize; mFramesRead += framesRead; return framesRead; } else { diff --git a/media/libnbaio/AudioStreamOutSink.cpp b/media/libnbaio/AudioStreamOutSink.cpp index e4341d7..c28d34d 100644 --- a/media/libnbaio/AudioStreamOutSink.cpp +++ b/media/libnbaio/AudioStreamOutSink.cpp @@ -37,16 +37,14 @@ AudioStreamOutSink::~AudioStreamOutSink() ssize_t AudioStreamOutSink::negotiate(const NBAIO_Format offers[], size_t numOffers, NBAIO_Format counterOffers[], size_t& numCounterOffers) { - if (mFormat == Format_Invalid) { + if (!Format_isValid(mFormat)) { 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); - } + 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), streamFormat); + mFrameSize = Format_frameSize(mFormat); } return NBAIO_Sink::negotiate(offers, numOffers, counterOffers, numCounterOffers); } @@ -56,10 +54,10 @@ ssize_t AudioStreamOutSink::write(const void *buffer, size_t count) if (!mNegotiated) { return NEGOTIATE; } - ALOG_ASSERT(mFormat != Format_Invalid); - ssize_t ret = mStream->write(mStream, buffer, count << mBitShift); + ALOG_ASSERT(Format_isValid(mFormat)); + ssize_t ret = mStream->write(mStream, buffer, count * mFrameSize); if (ret > 0) { - ret >>= mBitShift; + ret /= mFrameSize; mFramesWritten += ret; } else { // FIXME verify HAL implementations are returning the correct error codes e.g. WOULD_BLOCK diff --git a/media/libnbaio/MonoPipe.cpp b/media/libnbaio/MonoPipe.cpp index 3c61b60..4adf018 100644 --- a/media/libnbaio/MonoPipe.cpp +++ b/media/libnbaio/MonoPipe.cpp @@ -30,7 +30,24 @@ namespace android { -MonoPipe::MonoPipe(size_t reqFrames, NBAIO_Format format, bool writeCanBlock) : +static uint64_t cacheN; // output of CCHelper::getLocalFreq() +static bool cacheValid; // whether cacheN is valid +static pthread_once_t cacheOnceControl = PTHREAD_ONCE_INIT; + +static void cacheOnceInit() +{ + CCHelper tmpHelper; + status_t res; + if (OK != (res = tmpHelper.getLocalFreq(&cacheN))) { + ALOGE("Failed to fetch local time frequency when constructing a" + " MonoPipe (res = %d). getNextWriteTimestamp calls will be" + " non-functional", res); + return; + } + cacheValid = true; +} + +MonoPipe::MonoPipe(size_t reqFrames, const NBAIO_Format& format, bool writeCanBlock) : NBAIO_Sink(format), mUpdateSeq(0), mReqFrames(reqFrames), @@ -47,8 +64,6 @@ MonoPipe::MonoPipe(size_t reqFrames, NBAIO_Format format, bool writeCanBlock) : mTimestampMutator(&mTimestampShared), mTimestampObserver(&mTimestampShared) { - CCHelper tmpHelper; - status_t res; uint64_t N, D; mNextRdPTS = AudioBufferProvider::kInvalidPTS; @@ -59,12 +74,13 @@ MonoPipe::MonoPipe(size_t reqFrames, NBAIO_Format format, bool writeCanBlock) : mSamplesToLocalTime.a_to_b_denom = 0; D = Format_sampleRate(format); - if (OK != (res = tmpHelper.getLocalFreq(&N))) { - ALOGE("Failed to fetch local time frequency when constructing a" - " MonoPipe (res = %d). getNextWriteTimestamp calls will be" - " non-functional", res); + + (void) pthread_once(&cacheOnceControl, cacheOnceInit); + if (!cacheValid) { + // log has already been done return; } + N = cacheN; LinearTransform::reduce(&N, &D); static const uint64_t kSignedHiBitsMask = ~(0x7FFFFFFFull); @@ -115,11 +131,11 @@ ssize_t MonoPipe::write(const void *buffer, size_t count) part1 = written; } if (CC_LIKELY(part1 > 0)) { - memcpy((char *) mBuffer + (rear << mBitShift), buffer, part1 << mBitShift); + memcpy((char *) mBuffer + (rear * mFrameSize), buffer, part1 * mFrameSize); if (CC_UNLIKELY(rear + part1 == mMaxFrames)) { size_t part2 = written - part1; if (CC_LIKELY(part2 > 0)) { - memcpy(mBuffer, (char *) buffer + (part1 << mBitShift), part2 << mBitShift); + memcpy(mBuffer, (char *) buffer + (part1 * mFrameSize), part2 * mFrameSize); } } android_atomic_release_store(written + mRear, &mRear); @@ -129,7 +145,7 @@ ssize_t MonoPipe::write(const void *buffer, size_t count) break; } count -= written; - buffer = (char *) buffer + (written << mBitShift); + buffer = (char *) buffer + (written * mFrameSize); // Simulate blocking I/O by sleeping at different rates, depending on a throttle. // The throttle tries to keep the mean pipe depth near the setpoint, with a slight jitter. uint32_t ns; diff --git a/media/libnbaio/MonoPipeReader.cpp b/media/libnbaio/MonoPipeReader.cpp index 851341a..de82229 100644 --- a/media/libnbaio/MonoPipeReader.cpp +++ b/media/libnbaio/MonoPipeReader.cpp @@ -73,11 +73,11 @@ ssize_t MonoPipeReader::read(void *buffer, size_t count, int64_t readPTS) part1 = red; } if (CC_LIKELY(part1 > 0)) { - memcpy(buffer, (char *) mPipe->mBuffer + (front << mBitShift), part1 << mBitShift); + memcpy(buffer, (char *) mPipe->mBuffer + (front * mFrameSize), part1 * mFrameSize); if (CC_UNLIKELY(front + part1 == mPipe->mMaxFrames)) { size_t part2 = red - part1; if (CC_LIKELY(part2 > 0)) { - memcpy((char *) buffer + (part1 << mBitShift), mPipe->mBuffer, part2 << mBitShift); + memcpy((char *) buffer + (part1 * mFrameSize), mPipe->mBuffer, part2 * mFrameSize); } } mPipe->updateFrontAndNRPTS(red + mPipe->mFront, nextReadPTS); diff --git a/media/libnbaio/NBAIO.cpp b/media/libnbaio/NBAIO.cpp index e0d2c21..ff3284c 100644 --- a/media/libnbaio/NBAIO.cpp +++ b/media/libnbaio/NBAIO.cpp @@ -22,119 +22,42 @@ namespace android { -size_t Format_frameSize(NBAIO_Format format) +size_t Format_frameSize(const NBAIO_Format& format) { - return Format_channelCount(format) * sizeof(short); + return format.mFrameSize; } -size_t Format_frameBitShift(NBAIO_Format format) -{ - // sizeof(short) == 2, so frame size == 1 << channels - return Format_channelCount(format); -} - -enum { - Format_SR_8000, - Format_SR_11025, - Format_SR_16000, - Format_SR_22050, - Format_SR_24000, - Format_SR_32000, - Format_SR_44100, - Format_SR_48000, - Format_SR_Mask = 7 -}; - -enum { - Format_C_1 = 0x08, - Format_C_2 = 0x10, - Format_C_Mask = 0x18 -}; +const NBAIO_Format Format_Invalid = { 0, 0, AUDIO_FORMAT_INVALID, 0 }; -unsigned Format_sampleRate(NBAIO_Format format) +unsigned Format_sampleRate(const NBAIO_Format& format) { - if (format == Format_Invalid) { - return 0; - } - switch (format & Format_SR_Mask) { - case Format_SR_8000: - return 8000; - case Format_SR_11025: - return 11025; - case Format_SR_16000: - return 16000; - case Format_SR_22050: - return 22050; - case Format_SR_24000: - return 24000; - case Format_SR_32000: - return 32000; - case Format_SR_44100: - return 44100; - case Format_SR_48000: - return 48000; - default: + if (!Format_isValid(format)) { return 0; } + return format.mSampleRate; } -unsigned Format_channelCount(NBAIO_Format format) +unsigned Format_channelCount(const NBAIO_Format& format) { - if (format == Format_Invalid) { - return 0; - } - switch (format & Format_C_Mask) { - case Format_C_1: - return 1; - case Format_C_2: - return 2; - default: + if (!Format_isValid(format)) { return 0; } + return format.mChannelCount; } -NBAIO_Format Format_from_SR_C(unsigned sampleRate, unsigned channelCount) +NBAIO_Format Format_from_SR_C(unsigned sampleRate, unsigned channelCount, + audio_format_t format) { - NBAIO_Format format; - switch (sampleRate) { - case 8000: - format = Format_SR_8000; - break; - case 11025: - format = Format_SR_11025; - break; - case 16000: - format = Format_SR_16000; - break; - case 22050: - format = Format_SR_22050; - break; - case 24000: - format = Format_SR_24000; - break; - case 32000: - format = Format_SR_32000; - break; - case 44100: - format = Format_SR_44100; - break; - case 48000: - format = Format_SR_48000; - break; - default: + if (sampleRate == 0 || channelCount == 0 || !audio_is_valid_format(format)) { return Format_Invalid; } - switch (channelCount) { - case 1: - format |= Format_C_1; - break; - case 2: - format |= Format_C_2; - break; - default: - return Format_Invalid; - } - return format; + NBAIO_Format ret; + ret.mSampleRate = sampleRate; + ret.mChannelCount = channelCount; + ret.mFormat = format; + ret.mFrameSize = audio_is_linear_pcm(format) ? + channelCount * audio_bytes_per_sample(format) : sizeof(uint8_t); + return ret; } // This is a default implementation; it is expected that subclasses will optimize this. @@ -216,9 +139,9 @@ ssize_t NBAIO_Port::negotiate(const NBAIO_Format offers[], size_t numOffers, { ALOGV("negotiate offers=%p numOffers=%u countersOffers=%p numCounterOffers=%u", offers, numOffers, counterOffers, numCounterOffers); - if (mFormat != Format_Invalid) { + if (Format_isValid(mFormat)) { for (size_t i = 0; i < numOffers; ++i) { - if (offers[i] == mFormat) { + if (Format_isEqual(offers[i], mFormat)) { mNegotiated = true; return i; } @@ -233,4 +156,17 @@ ssize_t NBAIO_Port::negotiate(const NBAIO_Format offers[], size_t numOffers, return (ssize_t) NEGOTIATE; } +bool Format_isValid(const NBAIO_Format& format) +{ + return format.mSampleRate != 0 && format.mChannelCount != 0 && + format.mFormat != AUDIO_FORMAT_INVALID && format.mFrameSize != 0; +} + +bool Format_isEqual(const NBAIO_Format& format1, const NBAIO_Format& format2) +{ + return format1.mSampleRate == format2.mSampleRate && + format1.mChannelCount == format2.mChannelCount && format1.mFormat == format2.mFormat && + format1.mFrameSize == format2.mFrameSize; +} + } // namespace android diff --git a/media/libnbaio/NBLog.cpp b/media/libnbaio/NBLog.cpp index 8dfb4f0..4d9a1fa 100644 --- a/media/libnbaio/NBLog.cpp +++ b/media/libnbaio/NBLog.cpp @@ -341,8 +341,8 @@ void NBLog::Reader::dump(int fd, size_t indent) mFd = fd; mIndent = indent; String8 timestamp, body; - if (i > 0) { - lost += i; + lost += i; + if (lost > 0) { body.appendFormat("warning: lost %zu bytes worth of events", lost); // TODO timestamp empty here, only other choice to wait for the first timestamp event in the // log to push it out. Consider keeping the timestamp/body between calls to readAt(). @@ -447,7 +447,7 @@ void NBLog::Reader::dumpLine(const String8& timestamp, String8& body) bool NBLog::Reader::isIMemory(const sp<IMemory>& iMemory) const { - return iMemory.get() == mIMemory.get(); + return iMemory != 0 && mIMemory != 0 && iMemory->pointer() == mIMemory->pointer(); } } // namespace android diff --git a/media/libnbaio/Pipe.cpp b/media/libnbaio/Pipe.cpp index 1c21f9c..28a034c 100644 --- a/media/libnbaio/Pipe.cpp +++ b/media/libnbaio/Pipe.cpp @@ -25,7 +25,7 @@ namespace android { -Pipe::Pipe(size_t maxFrames, NBAIO_Format format) : +Pipe::Pipe(size_t maxFrames, const NBAIO_Format& format) : NBAIO_Sink(format), mMaxFrames(roundup(maxFrames)), mBuffer(malloc(mMaxFrames * Format_frameSize(format))), @@ -52,13 +52,13 @@ ssize_t Pipe::write(const void *buffer, size_t count) if (CC_LIKELY(written > count)) { written = count; } - memcpy((char *) mBuffer + (rear << mBitShift), buffer, written << mBitShift); + memcpy((char *) mBuffer + (rear * mFrameSize), buffer, written * mFrameSize); if (CC_UNLIKELY(rear + written == mMaxFrames)) { if (CC_UNLIKELY((count -= written) > rear)) { count = rear; } if (CC_LIKELY(count > 0)) { - memcpy(mBuffer, (char *) buffer + (written << mBitShift), count << mBitShift); + memcpy(mBuffer, (char *) buffer + (written * mFrameSize), count * mFrameSize); written += count; } } diff --git a/media/libnbaio/PipeReader.cpp b/media/libnbaio/PipeReader.cpp index d786b84..c8e4953 100644 --- a/media/libnbaio/PipeReader.cpp +++ b/media/libnbaio/PipeReader.cpp @@ -59,7 +59,7 @@ ssize_t PipeReader::availableToRead() return avail; } -ssize_t PipeReader::read(void *buffer, size_t count, int64_t readPTS) +ssize_t PipeReader::read(void *buffer, size_t count, int64_t readPTS __unused) { ssize_t avail = availableToRead(); if (CC_UNLIKELY(avail <= 0)) { @@ -76,14 +76,14 @@ ssize_t PipeReader::read(void *buffer, size_t count, int64_t readPTS) red = count; } // In particular, an overrun during the memcpy will result in reading corrupt data - memcpy(buffer, (char *) mPipe.mBuffer + (front << mBitShift), red << mBitShift); + memcpy(buffer, (char *) mPipe.mBuffer + (front * mFrameSize), red * mFrameSize); // We could re-read the rear pointer here to detect the corruption, but why bother? if (CC_UNLIKELY(front + red == mPipe.mMaxFrames)) { if (CC_UNLIKELY((count -= red) > front)) { count = front; } if (CC_LIKELY(count > 0)) { - memcpy((char *) buffer + (red << mBitShift), mPipe.mBuffer, count << mBitShift); + memcpy((char *) buffer + (red * mFrameSize), mPipe.mBuffer, count * mFrameSize); red += count; } } diff --git a/media/libnbaio/SourceAudioBufferProvider.cpp b/media/libnbaio/SourceAudioBufferProvider.cpp index 062fa0f..e21ef48 100644 --- a/media/libnbaio/SourceAudioBufferProvider.cpp +++ b/media/libnbaio/SourceAudioBufferProvider.cpp @@ -24,7 +24,7 @@ namespace android { SourceAudioBufferProvider::SourceAudioBufferProvider(const sp<NBAIO_Source>& source) : mSource(source), - // mFrameBitShiftFormat below + // mFrameSize below mAllocated(NULL), mSize(0), mOffset(0), mRemaining(0), mGetCount(0), mFramesReleased(0) { ALOG_ASSERT(source != 0); @@ -37,7 +37,7 @@ SourceAudioBufferProvider::SourceAudioBufferProvider(const sp<NBAIO_Source>& sou numCounterOffers = 0; index = source->negotiate(counterOffers, 1, NULL, numCounterOffers); ALOG_ASSERT(index == 0); - mFrameBitShift = Format_frameBitShift(source->format()); + mFrameSize = Format_frameSize(source->format()); } SourceAudioBufferProvider::~SourceAudioBufferProvider() @@ -54,14 +54,14 @@ status_t SourceAudioBufferProvider::getNextBuffer(Buffer *buffer, int64_t pts) if (mRemaining < buffer->frameCount) { buffer->frameCount = mRemaining; } - buffer->raw = (char *) mAllocated + (mOffset << mFrameBitShift); + buffer->raw = (char *) mAllocated + (mOffset * mFrameSize); mGetCount = buffer->frameCount; return OK; } // do we need to reallocate? if (buffer->frameCount > mSize) { free(mAllocated); - mAllocated = malloc(buffer->frameCount << mFrameBitShift); + mAllocated = malloc(buffer->frameCount * mFrameSize); mSize = buffer->frameCount; } // read from source @@ -84,7 +84,7 @@ status_t SourceAudioBufferProvider::getNextBuffer(Buffer *buffer, int64_t pts) void SourceAudioBufferProvider::releaseBuffer(Buffer *buffer) { ALOG_ASSERT((buffer != NULL) && - (buffer->raw == (char *) mAllocated + (mOffset << mFrameBitShift)) && + (buffer->raw == (char *) mAllocated + (mOffset * mFrameSize)) && (buffer->frameCount <= mGetCount) && (mGetCount <= mRemaining) && (mOffset + mRemaining <= mSize)); |