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