• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 YUV 422 10-10-10 layout.
103  */
104 bool IsYUV422_10bit(const C2GraphicView &view);
105 
106 /**
107  * Returns true iff a view has a NV12 layout.
108  */
109 bool IsNV12(const C2GraphicView &view);
110 
111 /**
112  * Returns true iff a view has a P010 layout.
113  */
114 bool IsP010(const C2GraphicView &view);
115 
116 /**
117  * Returns true iff a view has a P210 layout.
118  */
119 bool IsP210(const C2GraphicView &view);
120 
121 /**
122  * Returns true iff a view has a NV21 layout.
123  */
124 bool IsNV21(const C2GraphicView &view);
125 
126 /**
127  * Returns true iff a view has a I420 layout.
128  */
129 bool IsI420(const C2GraphicView &view);
130 
131 /**
132  * Returns true iff a MediaImage2 has a YUV 420 888 layout.
133  */
134 bool IsYUV420(const MediaImage2 *img);
135 
136 /**
137  * Returns true iff a MediaImage2 has a NV12 layout.
138  */
139 bool IsNV12(const MediaImage2 *img);
140 
141 /**
142  * Returns true iff a MediaImage2 has a NV21 layout.
143  */
144 bool IsNV21(const MediaImage2 *img);
145 
146 /**
147  * Returns true iff a MediaImage2 has a I420 layout.
148  */
149 bool IsI420(const MediaImage2 *img);
150 
151 enum FlexLayout {
152     FLEX_LAYOUT_UNKNOWN,
153     FLEX_LAYOUT_PLANAR,
154     FLEX_LAYOUT_SEMIPLANAR_UV,
155     FLEX_LAYOUT_SEMIPLANAR_VU,
156 };
157 /**
158  * Returns layout of YCBCR_420_888 pixel format.
159  */
160 FlexLayout GetYuv420FlexibleLayout();
161 
162 /**
163  * A raw memory block to use for internal buffers.
164  *
165  * TODO: replace this with C2LinearBlocks from a private C2BlockPool
166  */
167 struct MemoryBlock : public C2MemoryBlock<uint8_t> {
168     virtual const uint8_t* data() const override;
169     virtual size_t size() const override;
170 
dataMemoryBlock171     inline uint8_t *data() {
172         return const_cast<uint8_t*>(const_cast<const MemoryBlock*>(this)->data());
173     }
174 
175     // allocates an unmanaged block (not in a pool)
176     static MemoryBlock Allocate(size_t);
177 
178     // memory block with no actual memory (size is 0, data is null)
179     MemoryBlock();
180 
181     struct Impl;
182     MemoryBlock(std::shared_ptr<Impl> impl);
183     virtual ~MemoryBlock();
184 
185 private:
186     std::shared_ptr<Impl> mImpl;
187 };
188 
189 /**
190  * A raw memory mini-pool.
191  */
192 struct MemoryBlockPool {
193     /**
194      * Fetches a block with a given size.
195      *
196      * \param size size in bytes
197      */
198     MemoryBlock fetch(size_t size);
199 
200     MemoryBlockPool();
201     ~MemoryBlockPool() = default;
202 
203 private:
204     struct Impl;
205     std::shared_ptr<Impl> mImpl;
206 };
207 
208 struct ABuffer;
209 struct AMessage;
210 
211 class GraphicView2MediaImageConverter {
212 public:
213     /**
214      * Creates a C2GraphicView <=> MediaImage converter
215      *
216      * \param view C2GraphicView object
217      * \param format buffer format
218      * \param copy whether the converter is used for copy or not
219      */
220     GraphicView2MediaImageConverter(
221             const C2GraphicView &view, const sp<AMessage> &format, bool copy);
222 
223     status_t initCheck() const;
224 
225     uint32_t backBufferSize() const;
226 
227     /**
228      * Wrap C2GraphicView using a MediaImage2. Note that if not wrapped, the content is not mapped
229      * in this function --- the caller should use CopyGraphicView2MediaImage() function to copy the
230      * data into a backing buffer explicitly.
231      *
232      * \return media buffer. This is null if wrapping failed.
233      */
234     sp<ABuffer> wrap() const;
235 
236     bool setBackBuffer(const sp<ABuffer> &backBuffer);
237 
238     /**
239      * Copy C2GraphicView to MediaImage2.
240      */
241     status_t copyToMediaImage();
242 
243     const sp<ABuffer> &imageData() const;
244 
245 private:
246     status_t mInitCheck;
247 
248     const C2GraphicView mView;
249     uint32_t mWidth;
250     uint32_t mHeight;
251     int32_t mClientColorFormat;  ///< SDK color format for MediaImage
252     int32_t mComponentColorFormat;  ///< SDK color format from component
253     sp<ABuffer> mWrapped;  ///< wrapped buffer (if we can map C2Buffer to an ABuffer)
254     uint32_t mAllocatedDepth;
255     uint32_t mBackBufferSize;
256     sp<ABuffer> mMediaImage;
257 
258     sp<ABuffer> mBackBuffer;    ///< backing buffer if we have to copy C2Buffer <=> ABuffer
259 
260     MediaImage2 *getMediaImage();
261 };
262 
263 } // namespace android
264 
265 #endif  // CODEC2_BUFFER_UTILS_H_
266