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