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