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