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 "PipeReader" 18//#define LOG_NDEBUG 0 19 20#include <cutils/compiler.h> 21#include <cutils/atomic.h> 22#include <utils/Log.h> 23#include <media/nbaio/PipeReader.h> 24 25namespace android { 26 27PipeReader::PipeReader(Pipe& pipe) : 28 NBAIO_Source(pipe.mFormat), 29 mPipe(pipe), mFifoReader(mPipe.mFifo, false /*throttlesWriter*/, true /*flush*/), 30 mFramesOverrun(0), 31 mOverruns(0) 32{ 33 android_atomic_inc(&pipe.mReaders); 34} 35 36PipeReader::~PipeReader() 37{ 38#if !LOG_NDEBUG 39 int32_t readers = 40#else 41 (void) 42#endif 43 android_atomic_dec(&mPipe.mReaders); 44 ALOG_ASSERT(readers > 0); 45} 46 47ssize_t PipeReader::availableToRead() 48{ 49 if (CC_UNLIKELY(!mNegotiated)) { 50 return NEGOTIATE; 51 } 52 size_t lost; 53 ssize_t avail = mFifoReader.available(&lost); 54 if (avail == -EOVERFLOW || lost > 0) { 55 mFramesOverrun += lost; 56 ++mOverruns; 57 avail = OVERRUN; 58 } 59 return avail; 60} 61 62ssize_t PipeReader::read(void *buffer, size_t count) 63{ 64 size_t lost; 65 ssize_t actual = mFifoReader.read(buffer, count, NULL /*timeout*/, &lost); 66 ALOG_ASSERT(actual <= count); 67 if (actual == -EOVERFLOW || lost > 0) { 68 mFramesOverrun += lost; 69 ++mOverruns; 70 actual = OVERRUN; 71 } 72 if (actual <= 0) { 73 return actual; 74 } 75 mFramesRead += (size_t) actual; 76 return actual; 77} 78 79ssize_t PipeReader::flush() 80{ 81 if (CC_UNLIKELY(!mNegotiated)) { 82 return NEGOTIATE; 83 } 84 size_t lost; 85 ssize_t flushed = mFifoReader.flush(&lost); 86 if (flushed == -EOVERFLOW || lost > 0) { 87 mFramesOverrun += lost; 88 ++mOverruns; 89 flushed = OVERRUN; 90 } 91 if (flushed <= 0) { 92 return flushed; 93 } 94 mFramesRead += (size_t) flushed; // we consider flushed frames as read, but not lost frames 95 return flushed; 96} 97 98} // namespace android 99