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