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