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