• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 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 SIMPLE_C2_COMPONENT_H_
18 #define SIMPLE_C2_COMPONENT_H_
19 
20 #include <list>
21 #include <unordered_map>
22 
23 #include <C2Component.h>
24 
25 #include <media/stagefright/foundation/AHandler.h>
26 #include <media/stagefright/foundation/ALooper.h>
27 #include <media/stagefright/foundation/Mutexed.h>
28 
29 namespace android {
30 
31 class SimpleC2Component
32         : public C2Component, public std::enable_shared_from_this<SimpleC2Component> {
33 public:
34     explicit SimpleC2Component(
35             const std::shared_ptr<C2ComponentInterface> &intf);
36     virtual ~SimpleC2Component();
37 
38     // C2Component
39     // From C2Component
40     virtual c2_status_t setListener_vb(
41             const std::shared_ptr<Listener> &listener, c2_blocking_t mayBlock) override;
42     virtual c2_status_t queue_nb(std::list<std::unique_ptr<C2Work>>* const items) override;
43     virtual c2_status_t announce_nb(const std::vector<C2WorkOutline> &items) override;
44     virtual c2_status_t flush_sm(
45             flush_mode_t mode, std::list<std::unique_ptr<C2Work>>* const flushedWork) override;
46     virtual c2_status_t drain_nb(drain_mode_t mode) override;
47     virtual c2_status_t start() override;
48     virtual c2_status_t stop() override;
49     virtual c2_status_t reset() override;
50     virtual c2_status_t release() override;
51     virtual std::shared_ptr<C2ComponentInterface> intf() override;
52 
53     // for handler
54     bool processQueue();
55 
56 protected:
57     /**
58      * Initialize internal states of the component according to the config set
59      * in the interface.
60      *
61      * This method is called during start(), but only at the first invocation or
62      * after reset().
63      */
64     virtual c2_status_t onInit() = 0;
65 
66     /**
67      * Stop the component.
68      */
69     virtual c2_status_t onStop() = 0;
70 
71     /**
72      * Reset the component.
73      */
74     virtual void onReset() = 0;
75 
76     /**
77      * Release the component.
78      */
79     virtual void onRelease() = 0;
80 
81     /**
82      * Flush the component.
83      */
84     virtual c2_status_t onFlush_sm() = 0;
85 
86     /**
87      * Process the given work and finish pending work using finish().
88      *
89      * \param[in,out]   work    the work to process
90      * \param[in]       pool    the pool to use for allocating output blocks.
91      */
92     virtual void process(
93             const std::unique_ptr<C2Work> &work,
94             const std::shared_ptr<C2BlockPool> &pool) = 0;
95 
96     /**
97      * Drain the component and finish pending work using finish().
98      *
99      * \param[in]   drainMode   mode of drain.
100      * \param[in]   pool        the pool to use for allocating output blocks.
101      *
102      * \retval C2_OK            The component has drained all pending output
103      *                          work.
104      * \retval C2_OMITTED       Unsupported mode (e.g. DRAIN_CHAIN)
105      */
106     virtual c2_status_t drain(
107             uint32_t drainMode,
108             const std::shared_ptr<C2BlockPool> &pool) = 0;
109 
110     // for derived classes
111     /**
112      * Finish pending work.
113      *
114      * This method will retrieve the pending work according to |frameIndex| and
115      * feed the work into |fillWork| function. |fillWork| must be
116      * "non-blocking". Once |fillWork| returns the filled work will be returned
117      * to the client.
118      *
119      * \param[in]   frameIndex    the index of the pending work
120      * \param[in]   fillWork      the function to fill the retrieved work.
121      */
122     void finish(uint64_t frameIndex, std::function<void(const std::unique_ptr<C2Work> &)> fillWork);
123 
124     /**
125      * Clone pending or current work and send the work back to client.
126      *
127      * This method will retrieve and clone the pending or current work according
128      * to |frameIndex| and feed the work into |fillWork| function. |fillWork|
129      * must be "non-blocking". Once |fillWork| returns the filled work will be
130      * returned to the client.
131      *
132      * \param[in]   frameIndex    the index of the work
133      * \param[in]   currentWork   the current work under processing
134      * \param[in]   fillWork      the function to fill the retrieved work.
135      */
136     void cloneAndSend(
137             uint64_t frameIndex,
138             const std::unique_ptr<C2Work> &currentWork,
139             std::function<void(const std::unique_ptr<C2Work> &)> fillWork);
140 
141 
142     std::shared_ptr<C2Buffer> createLinearBuffer(
143             const std::shared_ptr<C2LinearBlock> &block, size_t offset, size_t size);
144 
145     std::shared_ptr<C2Buffer> createGraphicBuffer(
146             const std::shared_ptr<C2GraphicBlock> &block,
147             const C2Rect &crop);
148 
149     static constexpr uint32_t NO_DRAIN = ~0u;
150 
151     C2ReadView mDummyReadView;
152 
153 private:
154     const std::shared_ptr<C2ComponentInterface> mIntf;
155 
156     class WorkHandler : public AHandler {
157     public:
158         enum {
159             kWhatProcess,
160             kWhatInit,
161             kWhatStart,
162             kWhatStop,
163             kWhatReset,
164             kWhatRelease,
165         };
166 
167         WorkHandler();
168         ~WorkHandler() override = default;
169 
170         void setComponent(const std::shared_ptr<SimpleC2Component> &thiz);
171 
172     protected:
173         void onMessageReceived(const sp<AMessage> &msg) override;
174 
175     private:
176         std::weak_ptr<SimpleC2Component> mThiz;
177         bool mRunning;
178     };
179 
180     enum {
181         UNINITIALIZED,
182         STOPPED,
183         RUNNING,
184     };
185 
186     struct ExecState {
ExecStateExecState187         ExecState() : mState(UNINITIALIZED) {}
188 
189         int mState;
190         std::shared_ptr<C2Component::Listener> mListener;
191     };
192     Mutexed<ExecState> mExecState;
193 
194     sp<ALooper> mLooper;
195     sp<WorkHandler> mHandler;
196 
197     class WorkQueue {
198     public:
199         typedef std::unordered_map<uint64_t, std::unique_ptr<C2Work>> PendingWork;
200 
WorkQueue()201         inline WorkQueue() : mFlush(false), mGeneration(0ul) {}
202 
generation()203         inline uint64_t generation() const { return mGeneration; }
incGeneration()204         inline void incGeneration() { ++mGeneration; mFlush = true; }
205 
206         std::unique_ptr<C2Work> pop_front();
207         void push_back(std::unique_ptr<C2Work> work);
208         bool empty() const;
209         uint32_t drainMode() const;
210         void markDrain(uint32_t drainMode);
popPendingFlush()211         inline bool popPendingFlush() {
212             bool flush = mFlush;
213             mFlush = false;
214             return flush;
215         }
216         void clear();
pending()217         PendingWork &pending() { return mPendingWork; }
218 
219     private:
220         struct Entry {
221             std::unique_ptr<C2Work> work;
222             uint32_t drainMode;
223         };
224 
225         bool mFlush;
226         uint64_t mGeneration;
227         std::list<Entry> mQueue;
228         PendingWork mPendingWork;
229     };
230     Mutexed<WorkQueue> mWorkQueue;
231 
232     class BlockingBlockPool;
233     std::shared_ptr<BlockingBlockPool> mOutputBlockPool;
234 
235     SimpleC2Component() = delete;
236 };
237 
238 }  // namespace android
239 
240 #endif  // SIMPLE_C2_COMPONENT_H_
241