1010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten/*
2010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten * Copyright (C) 2012 The Android Open Source Project
3010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten *
4010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten * Licensed under the Apache License, Version 2.0 (the "License");
5010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten * you may not use this file except in compliance with the License.
6010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten * You may obtain a copy of the License at
7010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten *
8010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten *      http://www.apache.org/licenses/LICENSE-2.0
9010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten *
10010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten * Unless required by applicable law or agreed to in writing, software
11010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten * distributed under the License is distributed on an "AS IS" BASIS,
12010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten * See the License for the specific language governing permissions and
14010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten * limitations under the License.
15010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten */
16010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten
17010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten#define LOG_TAG "PipeReader"
18010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten//#define LOG_NDEBUG 0
19010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten
20010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten#include <cutils/compiler.h>
2105d19b08f3affa6fa8407e779f67e7ad1c1ca84fMathias Agopian#include <cutils/atomic.h>
22010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten#include <utils/Log.h>
232dd4bdd715f586d4d30cf90cc6fc2bbfbce60fe0Glenn Kasten#include <media/nbaio/PipeReader.h>
24010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten
25010662326b9c43c703725f933e95e0897f8a6bddGlenn Kastennamespace android {
26010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten
27010662326b9c43c703725f933e95e0897f8a6bddGlenn KastenPipeReader::PipeReader(Pipe& pipe) :
28010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten        NBAIO_Source(pipe.mFormat),
2903539407b0208fadba3d3f3a9b8c3cd899228b67Glenn Kasten        mPipe(pipe), mFifoReader(mPipe.mFifo, false /*throttlesWriter*/, true /*flush*/),
30010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten        mFramesOverrun(0),
31010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten        mOverruns(0)
32010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten{
33010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten    android_atomic_inc(&pipe.mReaders);
34010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten}
35010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten
36010662326b9c43c703725f933e95e0897f8a6bddGlenn KastenPipeReader::~PipeReader()
37010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten{
3857c4e6f7464d458eb52d209c2a63524913d6406dGlenn Kasten#if !LOG_NDEBUG
3957c4e6f7464d458eb52d209c2a63524913d6406dGlenn Kasten    int32_t readers =
4057c4e6f7464d458eb52d209c2a63524913d6406dGlenn Kasten#else
4157c4e6f7464d458eb52d209c2a63524913d6406dGlenn Kasten    (void)
4257c4e6f7464d458eb52d209c2a63524913d6406dGlenn Kasten#endif
4357c4e6f7464d458eb52d209c2a63524913d6406dGlenn Kasten            android_atomic_dec(&mPipe.mReaders);
44010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten    ALOG_ASSERT(readers > 0);
45010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten}
46010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten
47010662326b9c43c703725f933e95e0897f8a6bddGlenn Kastenssize_t PipeReader::availableToRead()
48010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten{
49010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten    if (CC_UNLIKELY(!mNegotiated)) {
50010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten        return NEGOTIATE;
51010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten    }
52ed99c2b5a99a8bfc163a6ffa0b767c82032b09b5Glenn Kasten    size_t lost;
53ed99c2b5a99a8bfc163a6ffa0b767c82032b09b5Glenn Kasten    ssize_t avail = mFifoReader.available(&lost);
54ed99c2b5a99a8bfc163a6ffa0b767c82032b09b5Glenn Kasten    if (avail == -EOVERFLOW || lost > 0) {
55ed99c2b5a99a8bfc163a6ffa0b767c82032b09b5Glenn Kasten        mFramesOverrun += lost;
56010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten        ++mOverruns;
57ed99c2b5a99a8bfc163a6ffa0b767c82032b09b5Glenn Kasten        avail = OVERRUN;
58010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten    }
59010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten    return avail;
60010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten}
61010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten
62d79072e9dff59f767cce2cda1caab80ce5a0815bGlenn Kastenssize_t PipeReader::read(void *buffer, size_t count)
63010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten{
64ed99c2b5a99a8bfc163a6ffa0b767c82032b09b5Glenn Kasten    size_t lost;
65ed99c2b5a99a8bfc163a6ffa0b767c82032b09b5Glenn Kasten    ssize_t actual = mFifoReader.read(buffer, count, NULL /*timeout*/, &lost);
66ed99c2b5a99a8bfc163a6ffa0b767c82032b09b5Glenn Kasten    ALOG_ASSERT(actual <= count);
67ed99c2b5a99a8bfc163a6ffa0b767c82032b09b5Glenn Kasten    if (actual == -EOVERFLOW || lost > 0) {
68ed99c2b5a99a8bfc163a6ffa0b767c82032b09b5Glenn Kasten        mFramesOverrun += lost;
69ed99c2b5a99a8bfc163a6ffa0b767c82032b09b5Glenn Kasten        ++mOverruns;
70ed99c2b5a99a8bfc163a6ffa0b767c82032b09b5Glenn Kasten        actual = OVERRUN;
71010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten    }
72ed99c2b5a99a8bfc163a6ffa0b767c82032b09b5Glenn Kasten    if (actual <= 0) {
73ed99c2b5a99a8bfc163a6ffa0b767c82032b09b5Glenn Kasten        return actual;
74010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten    }
75ed99c2b5a99a8bfc163a6ffa0b767c82032b09b5Glenn Kasten    mFramesRead += (size_t) actual;
76ed99c2b5a99a8bfc163a6ffa0b767c82032b09b5Glenn Kasten    return actual;
77010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten}
78010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten
79ad6d52d38917069e3d8e68cec1625855b9d96200Andy Hungssize_t PipeReader::flush()
80ad6d52d38917069e3d8e68cec1625855b9d96200Andy Hung{
81ad6d52d38917069e3d8e68cec1625855b9d96200Andy Hung    if (CC_UNLIKELY(!mNegotiated)) {
82ad6d52d38917069e3d8e68cec1625855b9d96200Andy Hung        return NEGOTIATE;
83ad6d52d38917069e3d8e68cec1625855b9d96200Andy Hung    }
84ed99c2b5a99a8bfc163a6ffa0b767c82032b09b5Glenn Kasten    size_t lost;
85ed99c2b5a99a8bfc163a6ffa0b767c82032b09b5Glenn Kasten    ssize_t flushed = mFifoReader.flush(&lost);
86ed99c2b5a99a8bfc163a6ffa0b767c82032b09b5Glenn Kasten    if (flushed == -EOVERFLOW || lost > 0) {
87ed99c2b5a99a8bfc163a6ffa0b767c82032b09b5Glenn Kasten        mFramesOverrun += lost;
88ed99c2b5a99a8bfc163a6ffa0b767c82032b09b5Glenn Kasten        ++mOverruns;
89ed99c2b5a99a8bfc163a6ffa0b767c82032b09b5Glenn Kasten        flushed = OVERRUN;
90ed99c2b5a99a8bfc163a6ffa0b767c82032b09b5Glenn Kasten    }
91ed99c2b5a99a8bfc163a6ffa0b767c82032b09b5Glenn Kasten    if (flushed <= 0) {
92ed99c2b5a99a8bfc163a6ffa0b767c82032b09b5Glenn Kasten        return flushed;
93ed99c2b5a99a8bfc163a6ffa0b767c82032b09b5Glenn Kasten    }
94ed99c2b5a99a8bfc163a6ffa0b767c82032b09b5Glenn Kasten    mFramesRead += (size_t) flushed;  // we consider flushed frames as read, but not lost frames
95ad6d52d38917069e3d8e68cec1625855b9d96200Andy Hung    return flushed;
96ad6d52d38917069e3d8e68cec1625855b9d96200Andy Hung}
97ad6d52d38917069e3d8e68cec1625855b9d96200Andy Hung
98010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten}   // namespace android
99