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
25 namespace android {
26
PipeReader(Pipe & pipe)27 PipeReader::PipeReader(Pipe& pipe) :
28 NBAIO_Source(pipe.mFormat),
29 mPipe(pipe), mFifoReader(mPipe.mFifo, false /*throttlesWriter*/, false /*flush*/),
30 mFramesOverrun(0),
31 mOverruns(0)
32 {
33 android_atomic_inc(&pipe.mReaders);
34 }
35
~PipeReader()36 PipeReader::~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
availableToRead()47 ssize_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
read(void * buffer,size_t count)62 ssize_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
flush()79 ssize_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