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