1 /* 2 * Copyright 2023 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 CODEC2_COMMON_MULTI_ACCESSUNIT_HELPER_H 18 #define CODEC2_COMMON_MULTI_ACCESSUNIT_HELPER_H 19 20 #include <hidl/Status.h> 21 #include <hwbinder/IBinder.h> 22 23 #include <C2Config.h> 24 #include <util/C2InterfaceHelper.h> 25 #include <C2Buffer.h> 26 #include <C2.h> 27 28 #include <set> 29 #include <memory> 30 #include <mutex> 31 32 namespace android { 33 34 struct MultiAccessUnitHelper; 35 36 struct MultiAccessUnitInterface : public C2InterfaceHelper { 37 explicit MultiAccessUnitInterface( 38 const std::shared_ptr<C2ComponentInterface>& interface, 39 std::shared_ptr<C2ReflectorHelper> helper); 40 41 bool isParamSupported(C2Param::Index index); 42 C2LargeFrame::output getLargeFrameParam() const; 43 C2Component::kind_t kind() const; 44 bool isValidField(const C2ParamField &field) const; 45 46 protected: 47 bool getDecoderSampleRateAndChannelCount( 48 uint32_t * const sampleRate_, uint32_t * const channelCount_) const; 49 bool getMaxInputSize(C2StreamMaxBufferSizeInfo::input* const maxInputSize) const; 50 const std::shared_ptr<C2ComponentInterface> mC2ComponentIntf; 51 std::shared_ptr<C2LargeFrame::output> mLargeFrameParams; 52 C2ComponentKindSetting mKind; 53 std::set<C2Param::Index> mSupportedParamIndexSet; 54 std::vector<C2ParamField> mParamFields; 55 56 friend struct MultiAccessUnitHelper; 57 }; 58 59 struct MultiAccessUnitHelper { 60 public: 61 MultiAccessUnitHelper( 62 const std::shared_ptr<MultiAccessUnitInterface>& intf, 63 std::shared_ptr<C2BlockPool> &linearPool); 64 65 virtual ~MultiAccessUnitHelper(); 66 67 static bool isEnabledOnPlatform(); 68 69 /* 70 * Scatters the incoming linear buffer into access-unit sized buffers 71 * based on the access-unit info. 72 */ 73 c2_status_t scatter( 74 std::list<std::unique_ptr<C2Work>> &c2workItems, 75 std::list<std::list<std::unique_ptr<C2Work>>> * const processedWork); 76 77 /* 78 * Gathers different access-units into a single buffer based on the scatter list 79 * and the configured max and threshold sizes. This also generates the associated 80 * access-unit information and attach it with the final result. 81 */ 82 c2_status_t gather( 83 std::list<std::unique_ptr<C2Work>> &c2workItems, 84 std::list<std::unique_ptr<C2Work>> * const processedWork); 85 86 /* 87 * Flushes the codec and generated the list of flushed buffers. 88 */ 89 c2_status_t flush( 90 std::list<std::unique_ptr<C2Work>> * const c2flushedWorks); 91 92 /* 93 * Gets all the pending buffers under generation in c2workItems. 94 */ 95 c2_status_t error(std::list<std::unique_ptr<C2Work>> * const c2workItems); 96 97 /* 98 * Get the interface object of this handler. 99 */ 100 std::shared_ptr<MultiAccessUnitInterface> getInterface(); 101 102 /* 103 * Gets the status of the object. This really is to make sure that 104 * all the allocators are configured properly within the handler. 105 */ 106 bool getStatus(); 107 108 /* 109 * Resets the structures inside the handler. 110 */ 111 void reset(); 112 113 protected: 114 115 struct MultiAccessUnitInfo { 116 /* 117 * From the input 118 * Ordinal of the input frame 119 */ 120 C2WorkOrdinalStruct inOrdinal; 121 122 /* 123 * Frame indexes of the scattered buffers 124 */ 125 std::set<uint64_t> mComponentFrameIds; 126 127 /* 128 * For the output 129 * Current output block. 130 */ 131 std::shared_ptr<C2LinearBlock> mBlock; 132 133 /* 134 * Write view of current block 135 */ 136 std::shared_ptr<C2WriteView> mWview; 137 138 /* 139 * C2Info related to the current mBlock 140 */ 141 std::vector<std::shared_ptr<const C2Info>> mInfos; 142 143 /* 144 * Vector for holding config updates from the wrapper 145 */ 146 std::vector<std::unique_ptr<C2Param>> mConfigUpdate; 147 148 /* 149 * C2AccessUnitInfos for the current buffer 150 */ 151 std::vector<C2AccessUnitInfosStruct> mAccessUnitInfos; 152 153 /* 154 * Current tuning used to process this input work 155 */ 156 C2LargeFrame::output mLargeFrameTuning; 157 158 /* 159 * Current output C2Work being processed 160 */ 161 std::unique_ptr<C2Work> mLargeWork; 162 163 /* 164 * For holding a reference to the incoming buffer 165 */ 166 std::vector<std::shared_ptr<C2Buffer>> mInputC2Ref; 167 MultiAccessUnitInfoMultiAccessUnitHelper::MultiAccessUnitInfo168 MultiAccessUnitInfo(C2WorkOrdinalStruct ordinal):inOrdinal(ordinal) { 169 170 } 171 172 /* 173 * Resets this frame 174 */ 175 void reset(); 176 }; 177 178 /* 179 * Reconfigure helper 180 */ 181 bool tryReconfigure(const std::unique_ptr<C2Param> &p); 182 183 /* 184 * Creates a linear block to be used with work 185 */ 186 c2_status_t createLinearBlock(MultiAccessUnitInfo &frame); 187 188 /* 189 * Processes worklets from the component 190 */ 191 c2_status_t processWorklets(MultiAccessUnitInfo &frame, 192 std::unique_ptr<C2Work> &work, 193 const std::function <void(std::unique_ptr<C2Work>&)> &addWork); 194 195 /* 196 * Finalizes the work to be send out. 197 */ 198 c2_status_t finalizeWork(MultiAccessUnitInfo &frame, 199 uint32_t flags = 0, bool forceComplete = false); 200 201 /* 202 * Merges different access unit infos if possible 203 */ 204 void mergeAccessUnitInfo(MultiAccessUnitInfo &frame, 205 uint32_t flags, 206 uint32_t size, 207 int64_t timestamp); 208 209 // Flag to allow dynamic on/off settings on this helper. 210 // Once enabled and buffers in transit, it is not possible 211 // to turn this module off by setting the max output value 212 // to 0. This is because the skip cut buffer expects the 213 // metadata to be always present along with a valid buffer. 214 // This flag is used to monitor that state of this module. 215 bool mMultiAccessOnOffAllowed; 216 217 bool mInit; 218 219 // Interface of this module 220 std::shared_ptr<MultiAccessUnitInterface> mInterface; 221 // Local pool id used for output buffer allocation 222 C2BlockPool::local_id_t mBlockPoolId; 223 // C2Blockpool for output buffer allocation 224 std::shared_ptr<C2BlockPool> mLinearPool; 225 // FrameIndex for the current outgoing work 226 std::atomic_uint64_t mFrameIndex; 227 // Mutex to protect mFrameHolder 228 std::mutex mLock; 229 // List of Infos that contains the input and 230 // output work and buffer objects 231 std::list<MultiAccessUnitInfo> mFrameHolder; 232 }; 233 234 } // namespace android 235 236 #endif // CODEC2_COMMON_MULTI_ACCESSUNIT_HELPER_H 237