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