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