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 <thread> 22 #include <unordered_map> 23 24 #include <C2Component.h> 25 26 #include <media/stagefright/foundation/Mutexed.h> 27 28 namespace android { 29 30 class SimpleC2Component 31 : public C2Component, public std::enable_shared_from_this<SimpleC2Component> { 32 public: 33 explicit SimpleC2Component( 34 const std::shared_ptr<C2ComponentInterface> &intf); 35 virtual ~SimpleC2Component() = default; 36 37 // C2Component 38 // From C2Component 39 virtual c2_status_t setListener_vb( 40 const std::shared_ptr<Listener> &listener, c2_blocking_t mayBlock) override; 41 virtual c2_status_t queue_nb(std::list<std::unique_ptr<C2Work>>* const items) override; 42 virtual c2_status_t announce_nb(const std::vector<C2WorkOutline> &items) override; 43 virtual c2_status_t flush_sm( 44 flush_mode_t mode, std::list<std::unique_ptr<C2Work>>* const flushedWork) override; 45 virtual c2_status_t drain_nb(drain_mode_t mode) override; 46 virtual c2_status_t start() override; 47 virtual c2_status_t stop() override; 48 virtual c2_status_t reset() override; 49 virtual c2_status_t release() override; 50 virtual std::shared_ptr<C2ComponentInterface> intf() override; 51 52 // for thread exitRequested()53 inline bool exitRequested() { return mExitRequested; } 54 void processQueue(); 55 void signalExit(); 56 57 protected: 58 /** 59 * Initialize internal states of the component according to the config set 60 * in the interface. 61 * 62 * This method is called during start(), but only at the first invocation or 63 * after reset(). 64 */ 65 virtual c2_status_t onInit() = 0; 66 67 /** 68 * Stop the component. 69 */ 70 virtual c2_status_t onStop() = 0; 71 72 /** 73 * Reset the component. 74 */ 75 virtual void onReset() = 0; 76 77 /** 78 * Release the component. 79 */ 80 virtual void onRelease() = 0; 81 82 /** 83 * Flush the component. 84 */ 85 virtual c2_status_t onFlush_sm() = 0; 86 87 /** 88 * Process the given work and finish pending work using finish(). 89 * 90 * \param[in,out] work the work to process 91 * \param[in] pool the pool to use for allocating output blocks. 92 */ 93 virtual void process( 94 const std::unique_ptr<C2Work> &work, 95 const std::shared_ptr<C2BlockPool> &pool) = 0; 96 97 /** 98 * Drain the component and finish pending work using finish(). 99 * 100 * \param[in] drainMode mode of drain. 101 * \param[in] pool the pool to use for allocating output blocks. 102 * 103 * \retval C2_OK The component has drained all pending output 104 * work. 105 * \retval C2_OMITTED Unsupported mode (e.g. DRAIN_CHAIN) 106 */ 107 virtual c2_status_t drain( 108 uint32_t drainMode, 109 const std::shared_ptr<C2BlockPool> &pool) = 0; 110 111 // for derived classes 112 /** 113 * Finish pending work. 114 * 115 * This method will retrieve the pending work according to |frameIndex| and 116 * feed the work into |fillWork| function. |fillWork| must be 117 * "non-blocking". Once |fillWork| returns the filled work will be returned 118 * to the client. 119 * 120 * \param[in] frameIndex the index of the pending work 121 * \param[in] fillWork the function to fill the retrieved work. 122 */ 123 void finish(uint64_t frameIndex, std::function<void(const std::unique_ptr<C2Work> &)> fillWork); 124 125 std::shared_ptr<C2Buffer> createLinearBuffer( 126 const std::shared_ptr<C2LinearBlock> &block); 127 128 std::shared_ptr<C2Buffer> createLinearBuffer( 129 const std::shared_ptr<C2LinearBlock> &block, size_t offset, size_t size); 130 131 std::shared_ptr<C2Buffer> createGraphicBuffer( 132 const std::shared_ptr<C2GraphicBlock> &block); 133 134 std::shared_ptr<C2Buffer> createGraphicBuffer( 135 const std::shared_ptr<C2GraphicBlock> &block, 136 const C2Rect &crop); 137 138 static constexpr uint32_t NO_DRAIN = ~0u; 139 140 C2ReadView mDummyReadView; 141 142 private: 143 const std::shared_ptr<C2ComponentInterface> mIntf; 144 std::atomic_bool mExitRequested; 145 146 enum { 147 UNINITIALIZED, 148 STOPPED, 149 RUNNING, 150 }; 151 152 struct ExecState { ExecStateExecState153 ExecState() : mState(UNINITIALIZED) {} 154 155 int mState; 156 std::thread mThread; 157 std::shared_ptr<C2Component::Listener> mListener; 158 }; 159 Mutexed<ExecState> mExecState; 160 161 class WorkQueue { 162 public: WorkQueue()163 inline WorkQueue() : mFlush(false), mGeneration(0ul) {} 164 generation()165 inline uint64_t generation() const { return mGeneration; } incGeneration()166 inline void incGeneration() { ++mGeneration; mFlush = true; } 167 168 std::unique_ptr<C2Work> pop_front(); 169 void push_back(std::unique_ptr<C2Work> work); 170 bool empty() const; 171 uint32_t drainMode() const; 172 void markDrain(uint32_t drainMode); popPendingFlush()173 inline bool popPendingFlush() { 174 bool flush = mFlush; 175 mFlush = false; 176 return flush; 177 } 178 void clear(); 179 180 Condition mCondition; 181 182 private: 183 struct Entry { 184 std::unique_ptr<C2Work> work; 185 uint32_t drainMode; 186 }; 187 188 bool mFlush; 189 uint64_t mGeneration; 190 std::list<Entry> mQueue; 191 }; 192 Mutexed<WorkQueue> mWorkQueue; 193 194 typedef std::unordered_map<uint64_t, std::unique_ptr<C2Work>> PendingWork; 195 Mutexed<PendingWork> mPendingWork; 196 197 struct ExitMonitor { ExitMonitorExitMonitor198 inline ExitMonitor() : mExited(false) {} 199 Condition mCondition; 200 bool mExited; 201 }; 202 Mutexed<ExitMonitor> mExitMonitor; 203 204 std::shared_ptr<C2BlockPool> mOutputBlockPool; 205 206 SimpleC2Component() = delete; 207 208 void requestExitAndWait(std::function<void()> job); 209 }; 210 211 } // namespace android 212 213 #endif // SIMPLE_C2_COMPONENT_H_ 214