1 /*
2  * Copyright 2015 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 #ifndef FIFO_FIFO_BUFFER_H
18 #define FIFO_FIFO_BUFFER_H
19 
20 #include <stdint.h>
21 
22 #include "FifoControllerBase.h"
23 
24 namespace android {
25 
26 /**
27  * Structure that represents a region in a circular buffer that might be at the
28  * end of the array and split in two.
29  */
30 struct WrappingBuffer {
31     enum {
32         SIZE = 2
33     };
34     void *data[SIZE];
35     int32_t numFrames[SIZE];
36 };
37 
38 class FifoBuffer {
39 public:
40     FifoBuffer(int32_t bytesPerFrame, fifo_frames_t capacityInFrames);
41 
42     FifoBuffer(int32_t bytesPerFrame,
43                fifo_frames_t capacityInFrames,
44                fifo_counter_t *readCounterAddress,
45                fifo_counter_t *writeCounterAddress,
46                void *dataStorageAddress);
47 
48     ~FifoBuffer();
49 
50     int32_t convertFramesToBytes(fifo_frames_t frames);
51 
52     fifo_frames_t read(void *destination, fifo_frames_t framesToRead);
53 
54     fifo_frames_t write(const void *source, fifo_frames_t framesToWrite);
55 
56     fifo_frames_t getThreshold();
57 
58     void setThreshold(fifo_frames_t threshold);
59 
60     fifo_frames_t getBufferCapacityInFrames();
61 
62     /**
63      * Return pointer to available full frames in data1 and set size in numFrames1.
64      * if the data is split across the end of the FIFO then set data2 and numFrames2.
65      * Other wise set them to null
66      * @param wrappingBuffer
67      */
68     void getFullDataAvailable(WrappingBuffer *wrappingBuffer);
69 
70     /**
71      * Return pointer to available empty frames in data1 and set size in numFrames1.
72      * if the room is split across the end of the FIFO then set data2 and numFrames2.
73      * Other wise set them to null
74      * @param wrappingBuffer
75      */
76     void getEmptyRoomAvailable(WrappingBuffer *wrappingBuffer);
77 
78     /**
79      * Copy data from the FIFO into the buffer.
80      * @param buffer
81      * @param numFrames
82      * @return
83      */
84     fifo_frames_t readNow(void *buffer, fifo_frames_t numFrames);
85 
86     int64_t getNextReadTime(int32_t frameRate);
87 
getUnderrunCount()88     int32_t getUnderrunCount() const { return mUnderrunCount; }
89 
getFifoControllerBase()90     FifoControllerBase *getFifoControllerBase() { return mFifo; }
91 
getBytesPerFrame()92     int32_t getBytesPerFrame() {
93         return mBytesPerFrame;
94     }
95 
getReadCounter()96     fifo_counter_t getReadCounter() {
97         return mFifo->getReadCounter();
98     }
99 
setReadCounter(fifo_counter_t n)100     void setReadCounter(fifo_counter_t n) {
101         mFifo->setReadCounter(n);
102     }
103 
getWriteCounter()104     fifo_counter_t getWriteCounter() {
105         return mFifo->getWriteCounter();
106     }
107 
setWriteCounter(fifo_counter_t n)108     void setWriteCounter(fifo_counter_t n) {
109         mFifo->setWriteCounter(n);
110     }
111 
112 private:
113 
114     void fillWrappingBuffer(WrappingBuffer *wrappingBuffer,
115                             int32_t framesAvailable, int32_t startIndex);
116 
117     const fifo_frames_t mFrameCapacity;
118     const int32_t mBytesPerFrame;
119     uint8_t *mStorage;
120     bool mStorageOwned; // did this object allocate the storage?
121     FifoControllerBase *mFifo;
122     fifo_counter_t mFramesReadCount;
123     fifo_counter_t mFramesUnderrunCount;
124     int32_t mUnderrunCount; // need? just use frames
125     int32_t mLastReadSize;
126 };
127 
128 }  // android
129 
130 #endif //FIFO_FIFO_BUFFER_H
131