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