xref: /aosp_15_r20/frameworks/av/media/codec2/sfplugin/utils/Codec2BufferUtils.h (revision ec779b8e0859a360c3d303172224686826e6e0e1)
1 /*
2  * Copyright 2018, 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 CODEC2_BUFFER_UTILS_H_
18 #define CODEC2_BUFFER_UTILS_H_
19 
20 #include <C2Buffer.h>
21 #include <C2Config.h>
22 #include <C2ParamDef.h>
23 
24 #include <media/hardware/VideoAPI.h>
25 #include <utils/StrongPointer.h>
26 #include <utils/Errors.h>
27 
28 namespace android {
29 
30 /**
31  * Converts an RGB view to planar YUV 420 media image.
32  *
33  * \param dstY       pointer to media image buffer
34  * \param dstStride  stride in bytes
35  * \param dstVStride vertical stride in pixels
36  * \param bufferSize media image buffer size
37  * \param src source image
38  *
39  * \retval NO_MEMORY media image is too small
40  * \retval OK on success
41  */
42 status_t ConvertRGBToPlanarYUV(
43         uint8_t *dstY, size_t dstStride, size_t dstVStride, size_t bufferSize,
44         const C2GraphicView &src, C2Color::matrix_t colorMatrix = C2Color::MATRIX_BT601,
45         C2Color::range_t colorRange = C2Color::RANGE_LIMITED);
46 
47 /**
48  * Returns a planar YUV 420 8-bit media image descriptor.
49  *
50  * \param width width of image in pixels
51  * \param height height of image in pixels
52  * \param stride stride of image in pixels
53  * \param vstride vertical stride of image in pixels
54  */
55 MediaImage2 CreateYUV420PlanarMediaImage2(
56         uint32_t width, uint32_t height, uint32_t stride, uint32_t vstride);
57 
58 /**
59  * Returns a semiplanar YUV 420 8-bit media image descriptor.
60  *
61  * \param width width of image in pixels
62  * \param height height of image in pixels
63  * \param stride stride of image in pixels
64  * \param vstride vertical stride of image in pixels
65  */
66 MediaImage2 CreateYUV420SemiPlanarMediaImage2(
67         uint32_t width, uint32_t height, uint32_t stride, uint32_t vstride);
68 
69 /**
70  * Copies a graphic view into a media image.
71  *
72  * \param imgBase base of MediaImage
73  * \param img MediaImage data
74  * \param view graphic view
75  *
76  * \return OK on success
77  */
78 status_t ImageCopy(uint8_t *imgBase, const MediaImage2 *img, const C2GraphicView &view);
79 
80 /**
81  * Copies a media image into a graphic view.
82  *
83  * \param view graphic view
84  * \param imgBase base of MediaImage
85  * \param img MediaImage data
86  *
87  * \return OK on success
88  */
89 status_t ImageCopy(C2GraphicView &view, const uint8_t *imgBase, const MediaImage2 *img);
90 
91 /**
92  * Returns true iff a view has a YUV 420 888 layout.
93  */
94 bool IsYUV420(const C2GraphicView &view);
95 
96 /**
97  * Returns true iff a view has a YUV 420 10-10-10 layout.
98  */
99 bool IsYUV420_10bit(const C2GraphicView &view);
100 
101 /**
102  * Returns true iff a view has a NV12 layout.
103  */
104 bool IsNV12(const C2GraphicView &view);
105 
106 /**
107  * Returns true iff a view has a P010 layout.
108  */
109 bool IsP010(const C2GraphicView &view);
110 
111 /**
112  * Returns true iff a view has a NV21 layout.
113  */
114 bool IsNV21(const C2GraphicView &view);
115 
116 /**
117  * Returns true iff a view has a I420 layout.
118  */
119 bool IsI420(const C2GraphicView &view);
120 
121 /**
122  * Returns true iff a MediaImage2 has a YUV 420 888 layout.
123  */
124 bool IsYUV420(const MediaImage2 *img);
125 
126 /**
127  * Returns true iff a MediaImage2 has a NV12 layout.
128  */
129 bool IsNV12(const MediaImage2 *img);
130 
131 /**
132  * Returns true iff a MediaImage2 has a NV21 layout.
133  */
134 bool IsNV21(const MediaImage2 *img);
135 
136 /**
137  * Returns true iff a MediaImage2 has a I420 layout.
138  */
139 bool IsI420(const MediaImage2 *img);
140 
141 enum FlexLayout {
142     FLEX_LAYOUT_UNKNOWN,
143     FLEX_LAYOUT_PLANAR,
144     FLEX_LAYOUT_SEMIPLANAR_UV,
145     FLEX_LAYOUT_SEMIPLANAR_VU,
146 };
147 /**
148  * Returns layout of YCBCR_420_888 pixel format.
149  */
150 FlexLayout GetYuv420FlexibleLayout();
151 
152 /**
153  * A raw memory block to use for internal buffers.
154  *
155  * TODO: replace this with C2LinearBlocks from a private C2BlockPool
156  */
157 struct MemoryBlock : public C2MemoryBlock<uint8_t> {
158     virtual const uint8_t* data() const override;
159     virtual size_t size() const override;
160 
dataMemoryBlock161     inline uint8_t *data() {
162         return const_cast<uint8_t*>(const_cast<const MemoryBlock*>(this)->data());
163     }
164 
165     // allocates an unmanaged block (not in a pool)
166     static MemoryBlock Allocate(size_t);
167 
168     // memory block with no actual memory (size is 0, data is null)
169     MemoryBlock();
170 
171     struct Impl;
172     MemoryBlock(std::shared_ptr<Impl> impl);
173     virtual ~MemoryBlock();
174 
175 private:
176     std::shared_ptr<Impl> mImpl;
177 };
178 
179 /**
180  * A raw memory mini-pool.
181  */
182 struct MemoryBlockPool {
183     /**
184      * Fetches a block with a given size.
185      *
186      * \param size size in bytes
187      */
188     MemoryBlock fetch(size_t size);
189 
190     MemoryBlockPool();
191     ~MemoryBlockPool() = default;
192 
193 private:
194     struct Impl;
195     std::shared_ptr<Impl> mImpl;
196 };
197 
198 struct ABuffer;
199 struct AMessage;
200 
201 class GraphicView2MediaImageConverter {
202 public:
203     /**
204      * Creates a C2GraphicView <=> MediaImage converter
205      *
206      * \param view C2GraphicView object
207      * \param format buffer format
208      * \param copy whether the converter is used for copy or not
209      */
210     GraphicView2MediaImageConverter(
211             const C2GraphicView &view, const sp<AMessage> &format, bool copy);
212 
213     status_t initCheck() const;
214 
215     uint32_t backBufferSize() const;
216 
217     /**
218      * Wrap C2GraphicView using a MediaImage2. Note that if not wrapped, the content is not mapped
219      * in this function --- the caller should use CopyGraphicView2MediaImage() function to copy the
220      * data into a backing buffer explicitly.
221      *
222      * \return media buffer. This is null if wrapping failed.
223      */
224     sp<ABuffer> wrap() const;
225 
226     bool setBackBuffer(const sp<ABuffer> &backBuffer);
227 
228     /**
229      * Copy C2GraphicView to MediaImage2.
230      */
231     status_t copyToMediaImage();
232 
233     const sp<ABuffer> &imageData() const;
234 
235 private:
236     status_t mInitCheck;
237 
238     const C2GraphicView mView;
239     uint32_t mWidth;
240     uint32_t mHeight;
241     int32_t mClientColorFormat;  ///< SDK color format for MediaImage
242     int32_t mComponentColorFormat;  ///< SDK color format from component
243     sp<ABuffer> mWrapped;  ///< wrapped buffer (if we can map C2Buffer to an ABuffer)
244     uint32_t mAllocatedDepth;
245     uint32_t mBackBufferSize;
246     sp<ABuffer> mMediaImage;
247 
248     sp<ABuffer> mBackBuffer;    ///< backing buffer if we have to copy C2Buffer <=> ABuffer
249 
250     MediaImage2 *getMediaImage();
251 };
252 
253 } // namespace android
254 
255 #endif  // CODEC2_BUFFER_UTILS_H_
256