1 /*
2  * Copyright 2019 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 PIPELINE_WATCHER_H_
18 #define PIPELINE_WATCHER_H_
19 
20 #include <chrono>
21 #include <map>
22 #include <memory>
23 
24 #include <C2Work.h>
25 
26 namespace android {
27 
28 /**
29  * PipelineWatcher watches the pipeline and infers the status of work items from
30  * events.
31  */
32 class PipelineWatcher {
33 public:
34     typedef std::chrono::steady_clock Clock;
35 
PipelineWatcher()36     PipelineWatcher()
37         : mInputDelay(0),
38           mPipelineDelay(0),
39           mOutputDelay(0),
40           mSmoothnessFactor(0),
41           mTunneled(false) {}
42     ~PipelineWatcher() = default;
43 
44     /**
45      * \param value the new input delay value
46      * \return  this object
47      */
48     PipelineWatcher &inputDelay(uint32_t value);
49 
50     /**
51      * \param value the new pipeline delay value
52      * \return  this object
53      */
54     PipelineWatcher &pipelineDelay(uint32_t value);
55 
56     /**
57      * \param value the new output delay value
58      * \return  this object
59      */
60     PipelineWatcher &outputDelay(uint32_t value);
61 
62     /**
63      * \param value the new smoothness factor value
64      * \return  this object
65      */
66     PipelineWatcher &smoothnessFactor(uint32_t value);
67 
68     /**
69      * \param value the new tunneled value
70      * \return  this object
71      */
72     PipelineWatcher &tunneled(bool value);
73 
74     /**
75      * Client queued a work item to the component.
76      *
77      * \param frameIndex  input frame index of this work
78      * \param buffers     input buffers of the queued work item
79      * \param queuedAt    time when the client queued the buffer
80      */
81     void onWorkQueued(
82             uint64_t frameIndex,
83             std::vector<std::shared_ptr<C2Buffer>> &&buffers,
84             const Clock::time_point &queuedAt);
85 
86     /**
87      * The component released input buffers from a work item.
88      *
89      * \param frameIndex  input frame index
90      * \param arrayIndex  index of the buffer at the original |buffers| in
91      *                    onWorkQueued().
92      * \return  buffers[arrayIndex]
93      */
94     std::shared_ptr<C2Buffer> onInputBufferReleased(
95             uint64_t frameIndex, size_t arrayIndex);
96 
97     /**
98      * The component finished processing a work item.
99      *
100      * \param frameIndex  input frame index
101      */
102     void onWorkDone(uint64_t frameIndex);
103 
104     /**
105      * Flush the pipeline.
106      */
107     void flush();
108 
109     /**
110      * \return  true  if pipeline does not need more work items to proceed
111      *                smoothly, considering delays and smoothness factor;
112      *          false otherwise.
113      */
114     bool pipelineFull() const;
115 
116     /**
117      * Return elapsed processing time of a work item, nth from the longest
118      * processing time to the shortest.
119      *
120      * \param now current timestamp
121      * \param n   nth work item, from the longest processing time to the
122      *            shortest. It's a 0-based index.
123      * \return  elapsed processing time of nth work item.
124      */
125     Clock::duration elapsed(const Clock::time_point &now, size_t n) const;
126 
127 private:
128     uint32_t mInputDelay;
129     uint32_t mPipelineDelay;
130     uint32_t mOutputDelay;
131     uint32_t mSmoothnessFactor;
132     bool mTunneled;
133 
134     struct Frame {
FrameFrame135         Frame(std::vector<std::shared_ptr<C2Buffer>> &&b,
136               const Clock::time_point &q)
137             : buffers(b),
138               queuedAt(q) {}
139         std::vector<std::shared_ptr<C2Buffer>> buffers;
140         const Clock::time_point queuedAt;
141     };
142     std::map<uint64_t, Frame> mFramesInPipeline;
143 };
144 
145 }  // namespace android
146 
147 #endif  // PIPELINE_WATCHER_H_
148