1 /* 2 * Copyright 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 CODEC2_HIDL_V1_0_UTILS_TYPES_H 18 #define CODEC2_HIDL_V1_0_UTILS_TYPES_H 19 20 #include <bufferpool/ClientManager.h> 21 #include <android/hardware/media/bufferpool/2.0/IClientManager.h> 22 #include <android/hardware/media/bufferpool/2.0/types.h> 23 #include <android/hardware/media/c2/1.0/IComponentStore.h> 24 #include <android/hardware/media/c2/1.0/types.h> 25 #include <android/hidl/safe_union/1.0/types.h> 26 27 #include <C2Component.h> 28 #include <C2Param.h> 29 #include <C2ParamDef.h> 30 #include <C2Work.h> 31 #include <util/C2Debug-base.h> 32 33 #include <chrono> 34 35 using namespace std::chrono_literals; 36 37 namespace android { 38 namespace hardware { 39 namespace media { 40 namespace c2 { 41 namespace V1_0 { 42 namespace utils { 43 44 using ::android::hardware::hidl_bitfield; 45 using ::android::hardware::hidl_handle; 46 using ::android::hardware::hidl_string; 47 using ::android::hardware::hidl_vec; 48 using ::android::status_t; 49 using ::android::sp; 50 using ::android::hardware::media::bufferpool::V2_0::implementation:: 51 ConnectionId; 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 // Make asString() and operator<< work with Status as well as c2_status_t. 69 C2_DECLARE_AS_STRING_AND_DEFINE_STREAM_OUT(Status); 70 71 /** 72 * All objcpy() functions will return a boolean value indicating whether the 73 * conversion succeeds or not. 74 */ 75 76 // C2SettingResult -> SettingResult 77 bool objcpy( 78 SettingResult* d, 79 const C2SettingResult& s); 80 81 // SettingResult -> std::unique_ptr<C2SettingResult> 82 bool objcpy( 83 std::unique_ptr<C2SettingResult>* d, 84 const SettingResult& s); 85 86 // C2ParamDescriptor -> ParamDescriptor 87 bool objcpy( 88 ParamDescriptor* d, 89 const C2ParamDescriptor& s); 90 91 // ParamDescriptor -> std::shared_ptr<C2ParamDescriptor> 92 bool objcpy( 93 std::shared_ptr<C2ParamDescriptor>* d, 94 const ParamDescriptor& s); 95 96 // C2FieldSupportedValuesQuery -> FieldSupportedValuesQuery 97 bool objcpy( 98 FieldSupportedValuesQuery* d, 99 const C2FieldSupportedValuesQuery& s); 100 101 // FieldSupportedValuesQuery -> C2FieldSupportedValuesQuery 102 bool objcpy( 103 C2FieldSupportedValuesQuery* d, 104 const FieldSupportedValuesQuery& s); 105 106 // C2FieldSupportedValuesQuery -> FieldSupportedValuesQueryResult 107 bool objcpy( 108 FieldSupportedValuesQueryResult* d, 109 const C2FieldSupportedValuesQuery& s); 110 111 // FieldSupportedValuesQuery, FieldSupportedValuesQueryResult -> C2FieldSupportedValuesQuery 112 bool objcpy( 113 C2FieldSupportedValuesQuery* d, 114 const FieldSupportedValuesQuery& sq, 115 const FieldSupportedValuesQueryResult& sr); 116 117 // C2Component::Traits -> ComponentTraits 118 bool objcpy( 119 IComponentStore::ComponentTraits* d, 120 const C2Component::Traits& s); 121 122 // ComponentTraits -> C2Component::Traits 123 bool objcpy( 124 C2Component::Traits* d, 125 const IComponentStore::ComponentTraits& s); 126 127 // C2StructDescriptor -> StructDescriptor 128 bool objcpy( 129 StructDescriptor* d, 130 const C2StructDescriptor& s); 131 132 // StructDescriptor -> C2StructDescriptor 133 bool objcpy( 134 std::unique_ptr<C2StructDescriptor>* d, 135 const StructDescriptor& s); 136 137 // Abstract class to be used in 138 // objcpy(std::list<std::unique_ptr<C2Work>> -> WorkBundle). 139 struct BufferPoolSender { 140 typedef ::android::hardware::media::bufferpool::V2_0:: 141 ResultStatus ResultStatus; 142 typedef ::android::hardware::media::bufferpool::V2_0:: 143 BufferStatusMessage BufferStatusMessage; 144 typedef ::android::hardware::media::bufferpool:: 145 BufferPoolData BufferPoolData; 146 147 /** 148 * Send bpData and return BufferStatusMessage that can be supplied to 149 * IClientManager::receive() in the receiving process. 150 * 151 * This function will be called from within the function 152 * objcpy(std::list<std::unique_ptr<C2Work>> -> WorkBundle). 153 * 154 * \param[in] bpData BufferPoolData identifying the buffer to send. 155 * \param[out] bpMessage BufferStatusMessage of the transaction. Information 156 * inside \p bpMessage should be passed to the receiving process by some 157 * other means so it can call receive() properly. 158 * \return ResultStatus value that determines the success of the operation. 159 * (See the possible values of ResultStatus in 160 * hardware/interfaces/media/bufferpool/2.0/types.hal.) 161 */ 162 virtual ResultStatus send( 163 const std::shared_ptr<BufferPoolData>& bpData, 164 BufferStatusMessage* bpMessage) = 0; 165 166 virtual ~BufferPoolSender() = default; 167 }; 168 169 // Default implementation of BufferPoolSender. 170 // 171 // To use DefaultBufferPoolSender, the IClientManager instance of the receiving 172 // process must be set before send() can operate. DefaultBufferPoolSender will 173 // hold a strong reference to the IClientManager instance and use it to call 174 // IClientManager::registerSender() to establish the bufferpool connection when 175 // send() is called. 176 struct DefaultBufferPoolSender : BufferPoolSender { 177 typedef ::android::hardware::media::bufferpool::V2_0::implementation:: 178 ClientManager ClientManager; 179 typedef ::android::hardware::media::bufferpool::V2_0:: 180 IClientManager IClientManager; 181 182 // Set the IClientManager instance of the receiving process and the refresh 183 // interval for the connection. The default interval is 4.5 seconds, which 184 // is slightly shorter than the amount of time the bufferpool will keep an 185 // inactive connection for. 186 DefaultBufferPoolSender( 187 const sp<IClientManager>& receiverManager = nullptr, 188 std::chrono::steady_clock::duration refreshInterval = 4500ms); 189 190 // Set the IClientManager instance of the receiving process and the refresh 191 // interval for the connection. The default interval is 4.5 seconds, which 192 // is slightly shorter than the amount of time the bufferpool will keep an 193 // inactive connection for. 194 void setReceiver( 195 const sp<IClientManager>& receiverManager, 196 std::chrono::steady_clock::duration refreshInterval = 4500ms); 197 198 // Implementation of BufferPoolSender::send(). send() will establish a 199 // bufferpool connection if needed, then send the bufferpool data over to 200 // the receiving process. 201 virtual ResultStatus send( 202 const std::shared_ptr<BufferPoolData>& bpData, 203 BufferStatusMessage* bpMessage) override; 204 205 private: 206 std::mutex mMutex; 207 sp<ClientManager> mSenderManager; 208 sp<IClientManager> mReceiverManager; 209 std::chrono::steady_clock::duration mRefreshInterval; 210 211 struct Connection { 212 int64_t receiverConnectionId; 213 std::chrono::steady_clock::time_point lastSent; ConnectionDefaultBufferPoolSender::Connection214 Connection(int64_t receiverConnectionId, 215 std::chrono::steady_clock::time_point lastSent) 216 : receiverConnectionId(receiverConnectionId), 217 lastSent(lastSent) { 218 } 219 }; 220 221 // Map of connections. 222 // 223 // The key is the connection id. One sender-receiver pair may have multiple 224 // connections. 225 std::map<int64_t, Connection> mConnections; 226 }; 227 228 // std::list<std::unique_ptr<C2Work>> -> WorkBundle 229 // Note: If bufferpool will be used, bpSender must not be null. 230 bool objcpy( 231 WorkBundle* d, 232 const std::list<std::unique_ptr<C2Work>>& s, 233 BufferPoolSender* bpSender = nullptr); 234 235 // WorkBundle -> std::list<std::unique_ptr<C2Work>> 236 bool objcpy( 237 std::list<std::unique_ptr<C2Work>>* d, 238 const WorkBundle& s); 239 240 /** 241 * Parses a params blob and returns C2Param pointers to its params. The pointers 242 * point to locations inside the underlying buffer of \p blob. If \p blob is 243 * destroyed, the pointers become invalid. 244 * 245 * \param[out] params target vector of C2Param pointers 246 * \param[in] blob parameter blob to parse 247 * \retval true if the full blob was parsed 248 * \retval false otherwise 249 */ 250 bool parseParamsBlob( 251 std::vector<C2Param*> *params, 252 const hidl_vec<uint8_t> &blob); 253 254 /** 255 * Concatenates a list of C2Params into a params blob. 256 * 257 * \param[out] blob target blob 258 * \param[in] params parameters to concatenate 259 * \retval true if the blob was successfully created 260 * \retval false if the blob was not successful (this only happens if the 261 * parameters were not const) 262 */ 263 bool createParamsBlob( 264 hidl_vec<uint8_t> *blob, 265 const std::vector<C2Param*> ¶ms); 266 bool createParamsBlob( 267 hidl_vec<uint8_t> *blob, 268 const std::vector<std::unique_ptr<C2Param>> ¶ms); 269 bool createParamsBlob( 270 hidl_vec<uint8_t> *blob, 271 const std::vector<std::shared_ptr<const C2Info>> ¶ms); 272 bool createParamsBlob( 273 hidl_vec<uint8_t> *blob, 274 const std::vector<std::unique_ptr<C2Tuning>> ¶ms); 275 276 /** 277 * Parses a params blob and create a vector of C2Params whose members are copies 278 * of the params in the blob. 279 * 280 * \param[out] params the resulting vector 281 * \param[in] blob parameter blob to parse 282 * \retval true if the full blob was parsed and params was constructed 283 * \retval false otherwise 284 */ 285 bool copyParamsFromBlob( 286 std::vector<std::unique_ptr<C2Param>>* params, 287 Params blob); 288 bool copyParamsFromBlob( 289 std::vector<std::unique_ptr<C2Tuning>>* params, 290 Params blob); 291 292 /** 293 * Parses a params blob and applies updates to params. 294 * 295 * \param[in,out] params params to be updated 296 * \param[in] blob parameter blob containing updates 297 * \retval true if the full blob was parsed and params was updated 298 * \retval false otherwise 299 */ 300 bool updateParamsFromBlob( 301 const std::vector<C2Param*>& params, 302 const Params& blob); 303 304 /** 305 * Converts a BufferPool status value to c2_status_t. 306 * \param BufferPool status 307 * \return Corresponding c2_status_t 308 */ 309 c2_status_t toC2Status(::android::hardware::media::bufferpool::V2_0:: 310 ResultStatus rs); 311 312 // BufferQueue-Based Block Operations 313 // ================================== 314 315 // Call before transferring block to other processes. 316 // 317 // The given block is ready to transfer to other processes. This will guarantee 318 // the given block data is not mutated by bufferqueue migration. 319 bool beginTransferBufferQueueBlock(const C2ConstGraphicBlock& block); 320 321 // Call beginTransferBufferQueueBlock() on blocks in the given workList. 322 // processInput determines whether input blocks are yielded. processOutput 323 // works similarly on output blocks. (The default value of processInput is 324 // false while the default value of processOutput is true. This implies that in 325 // most cases, only output buffers contain bufferqueue-based blocks.) 326 void beginTransferBufferQueueBlocks( 327 const std::list<std::unique_ptr<C2Work>>& workList, 328 bool processInput = false, 329 bool processOutput = true); 330 331 // Call after transferring block is finished and make sure that 332 // beginTransferBufferQueueBlock() is called before. 333 // 334 // The transfer of given block is finished. If transfer is successful the given 335 // block is not owned by process anymore. Since transfer is finished the given 336 // block data is OK to mutate by bufferqueue migration after this call. 337 bool endTransferBufferQueueBlock(const C2ConstGraphicBlock& block, 338 bool transfer); 339 340 // Call endTransferBufferQueueBlock() on blocks in the given workList. 341 // processInput determines whether input blocks are yielded. processOutput 342 // works similarly on output blocks. (The default value of processInput is 343 // false while the default value of processOutput is true. This implies that in 344 // most cases, only output buffers contain bufferqueue-based blocks.) 345 void endTransferBufferQueueBlocks( 346 const std::list<std::unique_ptr<C2Work>>& workList, 347 bool transfer, 348 bool processInput = false, 349 bool processOutput = true); 350 351 // The given block is ready to be rendered. the given block is not owned by 352 // process anymore. If migration is in progress, this returns false in order 353 // not to render. 354 bool displayBufferQueueBlock(const C2ConstGraphicBlock& block); 355 356 } // namespace utils 357 } // namespace V1_0 358 } // namespace c2 359 } // namespace media 360 } // namespace hardware 361 } // namespace android 362 363 #endif // CODEC2_HIDL_V1_0_UTILS_TYPES_H 364