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