1 /* 2 * Copyright (C) 2018 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 HARDWARE_GOOGLE_MEDIA_C2_V1_0_UTILS_TYPES_H 18 #define HARDWARE_GOOGLE_MEDIA_C2_V1_0_UTILS_TYPES_H 19 20 #include <chrono> 21 22 #include <bufferpool/ClientManager.h> 23 #include <android/hardware/media/bufferpool/1.0/IClientManager.h> 24 #include <android/hardware/media/bufferpool/1.0/types.h> 25 #include <hardware/google/media/c2/1.0/IComponentStore.h> 26 #include <hardware/google/media/c2/1.0/types.h> 27 #include <gui/IGraphicBufferProducer.h> 28 29 #include <C2Component.h> 30 #include <C2Param.h> 31 #include <C2ParamDef.h> 32 #include <C2Work.h> 33 34 using namespace std::chrono_literals; 35 36 namespace hardware { 37 namespace google { 38 namespace media { 39 namespace c2 { 40 namespace V1_0 { 41 namespace utils { 42 43 using ::android::hardware::hidl_bitfield; 44 using ::android::hardware::hidl_handle; 45 using ::android::hardware::hidl_string; 46 using ::android::hardware::hidl_vec; 47 using ::android::status_t; 48 using ::android::sp; 49 using ::android::hardware::media::bufferpool::V1_0::implementation:: 50 ConnectionId; 51 using ::android::IGraphicBufferProducer; 52 53 // Types of metadata for Blocks. 54 struct C2Hidl_Range { 55 uint32_t offset; 56 uint32_t length; // Do not use "size" because the name collides with C2Info::size(). 57 }; 58 typedef C2GlobalParam<C2Info, C2Hidl_Range, 0> C2Hidl_RangeInfo; 59 60 struct C2Hidl_Rect { 61 uint32_t left; 62 uint32_t top; 63 uint32_t width; 64 uint32_t height; 65 }; 66 typedef C2GlobalParam<C2Info, C2Hidl_Rect, 1> C2Hidl_RectInfo; 67 68 // C2SettingResult -> SettingResult 69 Status objcpy( 70 SettingResult* d, 71 const C2SettingResult& s); 72 73 // SettingResult -> std::unique_ptr<C2SettingResult> 74 c2_status_t objcpy( 75 std::unique_ptr<C2SettingResult>* d, 76 const SettingResult& s); 77 78 // C2ParamDescriptor -> ParamDescriptor 79 Status objcpy( 80 ParamDescriptor* d, 81 const C2ParamDescriptor& s); 82 83 // ParamDescriptor -> std::shared_ptr<C2ParamDescriptor> 84 c2_status_t objcpy( 85 std::shared_ptr<C2ParamDescriptor>* d, 86 const ParamDescriptor& s); 87 88 // C2FieldSupportedValuesQuery -> FieldSupportedValuesQuery 89 Status objcpy( 90 FieldSupportedValuesQuery* d, 91 const C2FieldSupportedValuesQuery& s); 92 93 // FieldSupportedValuesQuery -> C2FieldSupportedValuesQuery 94 c2_status_t objcpy( 95 C2FieldSupportedValuesQuery* d, 96 const FieldSupportedValuesQuery& s); 97 98 // C2FieldSupportedValuesQuery -> FieldSupportedValuesQueryResult 99 Status objcpy( 100 FieldSupportedValuesQueryResult* d, 101 const C2FieldSupportedValuesQuery& s); 102 103 // FieldSupportedValuesQuery, FieldSupportedValuesQueryResult -> C2FieldSupportedValuesQuery 104 c2_status_t objcpy( 105 C2FieldSupportedValuesQuery* d, 106 const FieldSupportedValuesQuery& sq, 107 const FieldSupportedValuesQueryResult& sr); 108 109 // C2Component::Traits -> ComponentTraits 110 Status objcpy( 111 IComponentStore::ComponentTraits* d, 112 const C2Component::Traits& s); 113 114 // ComponentTraits -> C2Component::Traits, std::unique_ptr<std::vector<std::string>> 115 // Note: The output d is only valid as long as aliasesBuffer remains alive. 116 c2_status_t objcpy( 117 C2Component::Traits* d, 118 std::unique_ptr<std::vector<std::string>>* aliasesBuffer, 119 const IComponentStore::ComponentTraits& s); 120 121 // C2StructDescriptor -> StructDescriptor 122 Status objcpy( 123 StructDescriptor* d, 124 const C2StructDescriptor& s); 125 126 // StructDescriptor -> C2StructDescriptor 127 c2_status_t objcpy( 128 std::unique_ptr<C2StructDescriptor>* d, 129 const StructDescriptor& s); 130 131 // Abstract class to be used in 132 // objcpy(std::list<std::unique_ptr<C2Work>> -> WorkBundle). 133 struct BufferPoolSender { 134 typedef ::android::hardware::media::bufferpool::V1_0:: 135 ResultStatus ResultStatus; 136 typedef ::android::hardware::media::bufferpool::V1_0:: 137 BufferStatusMessage BufferStatusMessage; 138 typedef ::android::hardware::media::bufferpool:: 139 BufferPoolData BufferPoolData; 140 141 /** 142 * Send bpData and return BufferStatusMessage that can be supplied to 143 * IClientManager::receive() in the receiving process. 144 * 145 * This function will be called from within the function 146 * objcpy(std::list<std::unique_ptr<C2Work>> -> WorkBundle). 147 * 148 * \param[in] bpData BufferPoolData identifying the buffer to send. 149 * \param[out] bpMessage BufferStatusMessage of the transaction. Information 150 * inside \p bpMessage should be passed to the receiving process by some 151 * other means so it can call receive() properly. 152 * \return ResultStatus value that determines the success of the operation. 153 * (See the possible values of ResultStatus in 154 * hardware/interfaces/media/bufferpool/1.0/types.hal.) 155 */ 156 virtual ResultStatus send( 157 const std::shared_ptr<BufferPoolData>& bpData, 158 BufferStatusMessage* bpMessage) = 0; 159 160 virtual ~BufferPoolSender() = default; 161 }; 162 163 // Default implementation of BufferPoolSender. 164 // 165 // To use DefaultBufferPoolSender, the IClientManager instance of the receiving 166 // process must be set before send() can operate. DefaultBufferPoolSender will 167 // hold a strong reference to the IClientManager instance and use it to call 168 // IClientManager::registerSender() to establish the bufferpool connection when 169 // send() is called. 170 struct DefaultBufferPoolSender : BufferPoolSender { 171 typedef ::android::hardware::media::bufferpool::V1_0::implementation:: 172 ClientManager ClientManager; 173 typedef ::android::hardware::media::bufferpool::V1_0:: 174 IClientManager IClientManager; 175 176 // Set the IClientManager instance of the receiving process and the refresh 177 // interval for the connection. The default interval is 4.5 seconds, which 178 // is slightly shorter than the amount of time the bufferpool will keep an 179 // inactive connection for. 180 DefaultBufferPoolSender( 181 const sp<IClientManager>& receiverManager = nullptr, 182 std::chrono::steady_clock::duration refreshInterval = 4500ms); 183 184 // Set the IClientManager instance of the receiving process and the refresh 185 // interval for the connection. The default interval is 4.5 seconds, which 186 // is slightly shorter than the amount of time the bufferpool will keep an 187 // inactive connection for. 188 void setReceiver( 189 const sp<IClientManager>& receiverManager, 190 std::chrono::steady_clock::duration refreshInterval = 4500ms); 191 192 // Implementation of BufferPoolSender::send(). send() will establish a 193 // bufferpool connection if needed, then send the bufferpool data over to 194 // the receiving process. 195 virtual ResultStatus send( 196 const std::shared_ptr<BufferPoolData>& bpData, 197 BufferStatusMessage* bpMessage) override; 198 199 private: 200 std::mutex mMutex; 201 sp<ClientManager> mSenderManager; 202 sp<IClientManager> mReceiverManager; 203 int64_t mReceiverConnectionId; 204 int64_t mSourceConnectionId; 205 std::chrono::steady_clock::time_point mLastSent; 206 std::chrono::steady_clock::duration mRefreshInterval; 207 }; 208 209 // std::list<std::unique_ptr<C2Work>> -> WorkBundle 210 // Note: If bufferpool will be used, bpSender must not be null. 211 Status objcpy( 212 WorkBundle* d, 213 const std::list<std::unique_ptr<C2Work>>& s, 214 BufferPoolSender* bpSender = nullptr); 215 216 // WorkBundle -> std::list<std::unique_ptr<C2Work>> 217 c2_status_t objcpy( 218 std::list<std::unique_ptr<C2Work>>* d, 219 const WorkBundle& s); 220 221 /** 222 * Parses a params blob and returns C2Param pointers to its params. 223 * \param[out] params target vector of C2Param pointers 224 * \param[in] blob parameter blob to parse 225 * \retval C2_OK if the full blob was parsed 226 * \retval C2_BAD_VALUE otherwise 227 */ 228 c2_status_t parseParamsBlob( 229 std::vector<C2Param*> *params, 230 const hidl_vec<uint8_t> &blob); 231 232 /** 233 * Concatenates a list of C2Params into a params blob. 234 * \param[out] blob target blob 235 * \param[in] params parameters to concatenate 236 * \retval C2_OK if the blob was successfully created 237 * \retval C2_BAD_VALUE if the blob was not successful (this only happens if the parameters were 238 * not const) 239 */ 240 Status createParamsBlob( 241 hidl_vec<uint8_t> *blob, 242 const std::vector<C2Param*> ¶ms); 243 Status createParamsBlob( 244 hidl_vec<uint8_t> *blob, 245 const std::vector<std::unique_ptr<C2Param>> ¶ms); 246 Status createParamsBlob( 247 hidl_vec<uint8_t> *blob, 248 const std::vector<std::shared_ptr<const C2Info>> ¶ms); 249 Status createParamsBlob( 250 hidl_vec<uint8_t> *blob, 251 const std::vector<std::unique_ptr<C2Tuning>> ¶ms); 252 253 /** 254 * Parses a params blob and create a vector of C2Params whose members are copies 255 * of the params in the blob. 256 * \param[out] params the resulting vector 257 * \param[in] blob parameter blob to parse 258 * \retval C2_OK if the full blob was parsed and params was constructed 259 * \retval C2_BAD_VALUE otherwise 260 */ 261 c2_status_t copyParamsFromBlob( 262 std::vector<std::unique_ptr<C2Param>>* params, 263 Params blob); 264 265 /** 266 * Parses a params blob and applies updates to params 267 * \param[in,out] params params to be updated 268 * \param[in] blob parameter blob containing updates 269 * \retval C2_OK if the full blob was parsed and params was updated 270 * \retval C2_BAD_VALUE otherwise 271 */ 272 c2_status_t updateParamsFromBlob( 273 const std::vector<C2Param*>& params, 274 const Params& blob); 275 276 /** 277 * Converts a BufferPool status value to c2_status_t. 278 * \param BufferPool status 279 * \return Corresponding c2_status_t 280 */ 281 c2_status_t toC2Status(::android::hardware::media::bufferpool::V1_0:: 282 ResultStatus rs); 283 284 // BufferQueue-Based Block Operations 285 // ================================== 286 287 // Create a GraphicBuffer object from a graphic block and attach it to an 288 // IGraphicBufferProducer. 289 status_t attachToBufferQueue(const C2ConstGraphicBlock& block, 290 const sp<IGraphicBufferProducer>& igbp, 291 uint32_t generation, 292 int32_t* bqSlot); 293 294 // Return false if block does not come from a bufferqueue-based blockpool. 295 // Otherwise, extract generation, bqId and bqSlot and return true. 296 bool getBufferQueueAssignment(const C2ConstGraphicBlock& block, 297 uint32_t* generation, 298 uint64_t* bqId, 299 int32_t* bqSlot); 300 301 // Disassociate the given block with its designated bufferqueue so that 302 // cancelBuffer() will not be called when the block is destroyed. If the block 303 // does not have a designated bufferqueue, the function returns false. 304 // Otherwise, it returns true. 305 // 306 // Note: This function should be called after attachBuffer() or queueBuffer() is 307 // called manually. 308 bool yieldBufferQueueBlock(const C2ConstGraphicBlock& block); 309 310 // Call yieldBufferQueueBlock() on blocks in the given workList. processInput 311 // determines whether input blocks are yielded. processOutput works similarly on 312 // output blocks. (The default value of processInput is false while the default 313 // value of processOutput is true. This implies that in most cases, only output 314 // buffers contain bufferqueue-based blocks.) 315 // 316 // Note: This function should be called after WorkBundle has been successfully 317 // sent over the Treble boundary to another process. 318 void yieldBufferQueueBlocks(const std::list<std::unique_ptr<C2Work>>& workList, 319 bool processInput = false, 320 bool processOutput = true); 321 322 // Assign the given block to a bufferqueue so that when the block is destroyed, 323 // cancelBuffer() will be called. 324 // 325 // If the block does not come from a bufferqueue-based blockpool, this function 326 // returns false. 327 // 328 // If the block already has a bufferqueue assignment that matches the given one, 329 // the function returns true. 330 // 331 // If the block already has a bufferqueue assignment that does not match the 332 // given one, the block will be reassigned to the given bufferqueue. This 333 // will call attachBuffer() on the given igbp. The function then returns true on 334 // success or false on any failure during the operation. 335 // 336 // Note: This function should be called after detachBuffer() or dequeueBuffer() 337 // is called manually. 338 bool holdBufferQueueBlock(const C2ConstGraphicBlock& block, 339 const sp<IGraphicBufferProducer>& igbp, 340 uint64_t bqId, 341 uint32_t generation); 342 343 // Call holdBufferQueueBlock() on input or output blocks in the given workList. 344 // Since the bufferqueue assignment for input and output buffers can be 345 // different, this function takes forInput to determine whether the given 346 // bufferqueue is for input buffers or output buffers. (The default value of 347 // forInput is false.) 348 // 349 // In the (rare) case that both input and output buffers are bufferqueue-based, 350 // this function must be called twice, once for the input buffers and once for 351 // the output buffers. 352 // 353 // Note: This function should be called after WorkBundle has been received from 354 // another process. 355 void holdBufferQueueBlocks(const std::list<std::unique_ptr<C2Work>>& workList, 356 const sp<IGraphicBufferProducer>& igbp, 357 uint64_t bqId, 358 uint32_t generation, 359 bool forInput = false); 360 361 } // namespace utils 362 } // namespace V1_0 363 } // namespace c2 364 } // namespace media 365 } // namespace google 366 } // namespace hardware 367 368 #endif // HARDWARE_GOOGLE_MEDIA_C2_V1_0_UTILS_TYPES_H 369