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_CLIENT_H 18 #define CODEC2_HIDL_CLIENT_H 19 20 #include <C2PlatformSupport.h> 21 #include <C2Component.h> 22 #include <C2Buffer.h> 23 #include <C2Param.h> 24 #include <C2.h> 25 26 #include <gui/FrameTimestamps.h> 27 #include <gui/IGraphicBufferProducer.h> 28 #include <hidl/HidlSupport.h> 29 #include <utils/StrongPointer.h> 30 31 #include <functional> 32 #include <map> 33 #include <memory> 34 #include <mutex> 35 36 /** 37 * This file contains minimal interfaces for the framework to access Codec2.0. 38 * 39 * Codec2Client is the main class that contains the following inner classes: 40 * - Listener 41 * - Configurable 42 * - Interface 43 * - Component 44 * 45 * Classes in Codec2Client, interfaces in Codec2.0, and HIDL interfaces are 46 * related as follows: 47 * - Codec2Client <==> C2ComponentStore <==> IComponentStore 48 * - Codec2Client::Listener <==> C2Component::Listener <==> IComponentListener 49 * - Codec2Client::Configurable <==> [No equivalent] <==> IConfigurable 50 * - Codec2Client::Interface <==> C2ComponentInterface <==> IComponentInterface 51 * - Codec2Client::Component <==> C2Component <==> IComponent 52 * 53 * The entry point is Codec2Client::CreateFromService(), which creates a 54 * Codec2Client object. From Codec2Client, Interface and Component objects can 55 * be created by calling createComponent() and createInterface(). 56 * 57 * createComponent() takes a Listener object, which must be implemented by the 58 * user. 59 * 60 * At the present, createBlockPool() is the only method that yields a 61 * Configurable object. Note, however, that Interface, Component and 62 * Codec2Client are all subclasses of Configurable. 63 */ 64 65 // Forward declaration of relevant HIDL interfaces 66 67 namespace android::hardware::media::c2::V1_0 { 68 struct IConfigurable; 69 struct IComponent; 70 struct IComponentInterface; 71 struct IComponentStore; 72 struct IInputSink; 73 struct IInputSurface; 74 struct IInputSurfaceConnection; 75 } // namespace android::hardware::media::c2::V1_0 76 77 namespace android::hardware::media::c2::V1_1 { 78 struct IComponent; 79 struct IComponentStore; 80 } // namespace android::hardware::media::c2::V1_1 81 82 namespace android::hardware::media::c2::V1_2 { 83 struct IComponent; 84 struct IComponentStore; 85 } // namespace android::hardware::media::c2::V1_2 86 87 namespace aidl::android::hardware::media::c2 { 88 class IComponent; 89 class IComponentInterface; 90 class IComponentStore; 91 class IConfigurable; 92 } // namespace aidl::android::hardware::media::c2 93 94 namespace android::hardware::media::bufferpool::V2_0 { 95 struct IClientManager; 96 } // namespace android::hardware::media::bufferpool::V2_0 97 98 namespace aidl::android::hardware::media::bufferpool2 { 99 class IClientManager; 100 } // namespace aidl::android::hardware::media::c2 101 102 103 namespace android::hardware::graphics::bufferqueue::V1_0 { 104 struct IGraphicBufferProducer; 105 } // android::hardware::graphics::bufferqueue::V1_0 106 107 namespace android::hardware::graphics::bufferqueue::V2_0 { 108 struct IGraphicBufferProducer; 109 } // android::hardware::graphics::bufferqueue::V2_0 110 111 namespace android::hardware::media::omx::V1_0 { 112 struct IGraphicBufferSource; 113 } // namespace android::hardware::media::omx::V1_0 114 115 namespace android { 116 117 // This class is supposed to be called Codec2Client::Configurable, but forward 118 // declaration of an inner class is not possible. 119 struct Codec2ConfigurableClient { 120 121 typedef ::android::hardware::media::c2::V1_0::IConfigurable HidlBase; 122 typedef ::aidl::android::hardware::media::c2::IConfigurable AidlBase; 123 124 struct ImplBase { 125 virtual ~ImplBase() = default; 126 127 virtual const C2String& getName() const = 0; 128 129 virtual c2_status_t query( 130 const std::vector<C2Param*>& stackParams, 131 const std::vector<C2Param::Index> &heapParamIndices, 132 c2_blocking_t mayBlock, 133 std::vector<std::unique_ptr<C2Param>>* const heapParams) const = 0; 134 135 virtual c2_status_t config( 136 const std::vector<C2Param*> ¶ms, 137 c2_blocking_t mayBlock, 138 std::vector<std::unique_ptr<C2SettingResult>>* const failures) = 0; 139 140 virtual c2_status_t querySupportedParams( 141 std::vector<std::shared_ptr<C2ParamDescriptor>>* const params 142 ) const = 0; 143 144 virtual c2_status_t querySupportedValues( 145 std::vector<C2FieldSupportedValuesQuery>& fields, 146 c2_blocking_t mayBlock) const = 0; 147 }; 148 149 explicit Codec2ConfigurableClient(const sp<HidlBase> &hidlBase); 150 explicit Codec2ConfigurableClient(const std::shared_ptr<AidlBase> &aidlBase); 151 152 const C2String& getName() const; 153 154 c2_status_t query( 155 const std::vector<C2Param*>& stackParams, 156 const std::vector<C2Param::Index> &heapParamIndices, 157 c2_blocking_t mayBlock, 158 std::vector<std::unique_ptr<C2Param>>* const heapParams) const; 159 160 c2_status_t config( 161 const std::vector<C2Param*> ¶ms, 162 c2_blocking_t mayBlock, 163 std::vector<std::unique_ptr<C2SettingResult>>* const failures); 164 165 c2_status_t querySupportedParams( 166 std::vector<std::shared_ptr<C2ParamDescriptor>>* const params 167 ) const; 168 169 c2_status_t querySupportedValues( 170 std::vector<C2FieldSupportedValuesQuery>& fields, 171 c2_blocking_t mayBlock) const; 172 private: 173 struct HidlImpl; 174 struct AidlImpl; 175 176 const std::unique_ptr<ImplBase> mImpl; 177 }; 178 179 struct Codec2Client : public Codec2ConfigurableClient { 180 181 typedef ::android::hardware::media::c2::V1_0::IComponentStore HidlBase1_0; 182 typedef ::android::hardware::media::c2::V1_1::IComponentStore HidlBase1_1; 183 typedef ::android::hardware::media::c2::V1_2::IComponentStore HidlBase1_2; 184 typedef HidlBase1_0 HidlBase; 185 186 typedef ::aidl::android::hardware::media::c2::IComponentStore AidlBase; 187 188 struct Listener; 189 190 typedef Codec2ConfigurableClient Configurable; 191 192 struct Component; 193 194 struct Interface; 195 196 struct InputSurface; 197 198 struct InputSurfaceConnection; 199 200 typedef Codec2Client Store; 201 202 sp<HidlBase> const& getHidlBase() const; 203 sp<HidlBase1_0> const& getHidlBase1_0() const; 204 sp<HidlBase1_1> const& getHidlBase1_1() const; 205 sp<HidlBase1_2> const& getHidlBase1_2() const; 206 ::ndk::SpAIBinder getAidlBase() const; 207 208 std::string const& getServiceName() const; 209 210 c2_status_t createComponent( 211 C2String const& name, 212 std::shared_ptr<Listener> const& listener, 213 std::shared_ptr<Component>* const component); 214 215 c2_status_t createInterface( 216 C2String const& name, 217 std::shared_ptr<Interface>* const interface); 218 219 c2_status_t createInputSurface( 220 std::shared_ptr<InputSurface>* const inputSurface); 221 222 std::vector<C2Component::Traits> const& listComponents() const; 223 224 c2_status_t copyBuffer( 225 std::shared_ptr<C2Buffer> const& src, 226 std::shared_ptr<C2Buffer> const& dst); 227 228 std::shared_ptr<C2ParamReflector> getParamReflector(); 229 230 // Returns the list of IComponentStore service names that are available on 231 // the device. This list is specified at the build time in manifest files. 232 // Note: A software service will have "_software" as a suffix. 233 static std::vector<std::string> const& GetServiceNames(); 234 235 // Create a client to a service with a given name. 236 // 237 // After a client to the service is successfully created, if 238 // setAsPreferredCodec2ComponentStore is true, the component store that the 239 // service hosts will be set as the preferred C2ComponentStore for this 240 // process. (See SetPreferredCodec2ComponentStore() for more information.) 241 static std::shared_ptr<Codec2Client> CreateFromService( 242 char const* name, 243 bool setAsPreferredCodec2ComponentStore = false); 244 245 // Get clients to all services. 246 static std::vector<std::shared_ptr<Codec2Client>> CreateFromAllServices(); 247 248 // Try to create a component with a given name from all known 249 // IComponentStore services. numberOfAttempts determines the number of times 250 // to retry the HIDL call if the transaction fails. 251 static c2_status_t CreateComponentByName( 252 char const* componentName, 253 std::shared_ptr<Listener> const& listener, 254 std::shared_ptr<Component>* component, 255 std::shared_ptr<Codec2Client>* owner = nullptr, 256 size_t numberOfAttempts = 10); 257 258 // Try to create a component interface with a given name from all known 259 // IComponentStore services. numberOfAttempts determines the number of times 260 // to retry the HIDL call if the transaction fails. 261 static std::shared_ptr<Interface> CreateInterfaceByName( 262 char const* interfaceName, 263 std::shared_ptr<Codec2Client>* owner = nullptr, 264 size_t numberOfAttempts = 10); 265 266 // List traits from all known IComponentStore services. 267 static std::vector<C2Component::Traits> const& ListComponents(); 268 269 // Create an input surface. 270 static std::shared_ptr<InputSurface> CreateInputSurface( 271 char const* serviceName = nullptr); 272 273 // Whether AIDL is selected. 274 static bool IsAidlSelected(); 275 276 // base and/or configurable cannot be null. 277 Codec2Client( 278 sp<HidlBase> const& base, 279 sp<Codec2ConfigurableClient::HidlBase> const& configurable, 280 size_t serviceIndex); 281 Codec2Client( 282 std::shared_ptr<AidlBase> const& base, 283 std::shared_ptr<Codec2ConfigurableClient::AidlBase> const& configurable, 284 size_t serviceIndex); 285 286 protected: 287 sp<HidlBase1_0> mHidlBase1_0; 288 sp<HidlBase1_1> mHidlBase1_1; 289 sp<HidlBase1_2> mHidlBase1_2; 290 std::shared_ptr<AidlBase> mAidlBase; 291 292 // Finds the first store where the predicate returns C2_OK and returns the 293 // last predicate result. The predicate will be tried on all stores. The 294 // function will return C2_OK the first time the predicate returns C2_OK, 295 // or it will return the value from the last time that predicate is tried. 296 // (The latter case corresponds to a failure on every store.) The order of 297 // the stores to try is the same as the return value of GetServiceNames(). 298 // 299 // key is used to remember the last store with which the predicate last 300 // succeeded. If the last successful store is cached, it will be tried 301 // first before all the stores are tried. Note that the last successful 302 // store will be tried twice---first before all the stores, and another time 303 // with all the stores. 304 // 305 // If an attempt to evaluate the predicate results in a transaction failure, 306 // repeated attempts will be made until the predicate returns without a 307 // transaction failure or numberOfAttempts attempts have been made. 308 static c2_status_t ForAllServices( 309 const std::string& key, 310 size_t numberOfAttempts, 311 std::function<c2_status_t(std::shared_ptr<Codec2Client> const&)> 312 predicate); 313 314 size_t mServiceIndex; 315 mutable std::vector<C2Component::Traits> mTraitsList; 316 317 sp<::android::hardware::media::bufferpool::V2_0::IClientManager> 318 mHidlHostPoolManager; 319 std::shared_ptr<::aidl::android::hardware::media::bufferpool2::IClientManager> 320 mAidlHostPoolManager; 321 322 static std::vector<std::string> CacheServiceNames(); 323 static std::shared_ptr<Codec2Client> _CreateFromIndex(size_t index); 324 325 std::vector<C2Component::Traits> _listComponents(bool* success) const; 326 327 class Cache; 328 }; 329 330 struct Codec2Client::Interface : public Codec2Client::Configurable { 331 332 typedef ::android::hardware::media::c2::V1_0::IComponentInterface HidlBase; 333 typedef ::aidl::android::hardware::media::c2::IComponentInterface AidlBase; 334 335 Interface(const sp<HidlBase>& base); 336 Interface(const std::shared_ptr<AidlBase>& base); 337 338 protected: 339 sp<HidlBase> mHidlBase; 340 std::shared_ptr<AidlBase> mAidlBase; 341 }; 342 343 struct Codec2Client::Listener { 344 345 // This is called when the component produces some output. 346 virtual void onWorkDone( 347 const std::weak_ptr<Component>& comp, 348 std::list<std::unique_ptr<C2Work>>& workItems) = 0; 349 350 // This is called when the component goes into a tripped state. 351 virtual void onTripped( 352 const std::weak_ptr<Component>& comp, 353 const std::vector<std::shared_ptr<C2SettingResult>>& settingResults 354 ) = 0; 355 356 // This is called when the component encounters an error. 357 virtual void onError( 358 const std::weak_ptr<Component>& comp, 359 uint32_t errorCode) = 0; 360 361 // This is called when the process that hosts the component shuts down 362 // unexpectedly. 363 virtual void onDeath( 364 const std::weak_ptr<Component>& comp) = 0; 365 366 // This is called when an input buffer is no longer in use by the codec. 367 // Input buffers that have been returned by onWorkDone() or flush() will not 368 // trigger a call to this function. 369 virtual void onInputBufferDone( 370 uint64_t frameIndex, size_t arrayIndex) = 0; 371 372 // This is called when the component becomes aware of a frame being 373 // rendered. 374 virtual void onFrameRendered( 375 uint64_t bufferQueueId, 376 int32_t slotId, 377 int64_t timestampNs) = 0; 378 379 virtual ~Listener() = default; 380 }; 381 382 struct Codec2Client::Component : public Codec2Client::Configurable { 383 384 typedef ::android::hardware::media::c2::V1_0::IComponent HidlBase1_0; 385 typedef ::android::hardware::media::c2::V1_1::IComponent HidlBase1_1; 386 typedef ::android::hardware::media::c2::V1_2::IComponent HidlBase1_2; 387 typedef HidlBase1_0 HidlBase; 388 389 typedef ::aidl::android::hardware::media::c2::IComponent AidlBase; 390 391 c2_status_t createBlockPool( 392 C2Allocator::id_t id, 393 C2BlockPool::local_id_t* blockPoolId, 394 std::shared_ptr<Configurable>* configurable); 395 396 c2_status_t destroyBlockPool( 397 C2BlockPool::local_id_t localId); 398 399 c2_status_t queue( 400 std::list<std::unique_ptr<C2Work>>* const items); 401 402 c2_status_t flush( 403 C2Component::flush_mode_t mode, 404 std::list<std::unique_ptr<C2Work>>* const flushedWork); 405 406 c2_status_t drain(C2Component::drain_mode_t mode); 407 408 c2_status_t start(); 409 410 c2_status_t stop(); 411 412 c2_status_t reset(); 413 414 c2_status_t release(); 415 416 /** 417 * Use tunneling. 418 * 419 * On success, @p sidebandHandle will be a newly allocated native handle. 420 * File descriptors in @p sidebandHandle must be closed and 421 * @p sidebandHandle itself must be deleted afterwards. 422 */ 423 c2_status_t configureVideoTunnel( 424 uint32_t avSyncHwId, 425 native_handle_t** sidebandHandle); 426 427 typedef ::android:: 428 IGraphicBufferProducer IGraphicBufferProducer; 429 typedef IGraphicBufferProducer:: 430 QueueBufferInput QueueBufferInput; 431 typedef IGraphicBufferProducer:: 432 QueueBufferOutput QueueBufferOutput; 433 434 typedef ::android::hardware::graphics::bufferqueue::V1_0:: 435 IGraphicBufferProducer HGraphicBufferProducer1; 436 typedef ::android::hardware::graphics::bufferqueue::V2_0:: 437 IGraphicBufferProducer HGraphicBufferProducer2; 438 typedef ::android::hardware::media::omx::V1_0:: 439 IGraphicBufferSource HGraphicBufferSource; 440 441 // Set the output surface to be used with a blockpool previously created by 442 // createBlockPool(). 443 c2_status_t setOutputSurface( 444 C2BlockPool::local_id_t blockPoolId, 445 const sp<IGraphicBufferProducer>& surface, 446 uint32_t generation, 447 int maxDequeueBufferCount); 448 449 // Extract a slot number from of the block, then call 450 // IGraphicBufferProducer::queueBuffer(). 451 // 452 // If the output surface has not been set, NO_INIT will be returned. 453 // 454 // If the block does not come from a bufferqueue-based blockpool, 455 // attachBuffer() will be called, followed by queueBuffer(). 456 // 457 // If the block has a bqId that does not match the id of the output surface, 458 // DEAD_OBJECT will be returned. 459 // 460 // If the call to queueBuffer() is successful but the block cannot be 461 // associated to the output surface for automatic cancellation upon 462 // destruction, UNKNOWN_ERROR will be returned. 463 // 464 // Otherwise, the return value from queueBuffer() will be returned. 465 status_t queueToOutputSurface( 466 const C2ConstGraphicBlock& block, 467 const QueueBufferInput& input, 468 QueueBufferOutput* output); 469 470 // Retrieve frame event history from the output surface. 471 void pollForRenderedFrames(FrameEventHistoryDelta* delta); 472 473 // Set max dequeue count for output surface. 474 void setOutputSurfaceMaxDequeueCount(int maxDequeueCount); 475 476 // Stop using the current output surface. 477 void stopUsingOutputSurface( 478 C2BlockPool::local_id_t blockPoolId); 479 480 // Notify a buffer is released from output surface. 481 void onBufferReleasedFromOutputSurface( 482 uint32_t generation); 483 484 // When the client received \p workList and the blocks inside 485 // \p workList are IGBA based graphic blocks, specify the owner 486 // as the current IGBA for the future operations. 487 // Future operations could be rendering the blocks to the surface 488 // or deallocating blocks to the surface. 489 void holdIgbaBlocks( 490 const std::list<std::unique_ptr<C2Work>>& workList); 491 492 // Connect to a given InputSurface. 493 c2_status_t connectToInputSurface( 494 const std::shared_ptr<InputSurface>& inputSurface, 495 std::shared_ptr<InputSurfaceConnection>* connection); 496 497 c2_status_t connectToOmxInputSurface( 498 const sp<HGraphicBufferProducer1>& producer, 499 const sp<HGraphicBufferSource>& source, 500 std::shared_ptr<InputSurfaceConnection>* connection); 501 502 c2_status_t disconnectFromInputSurface(); 503 504 // base cannot be null. 505 Component(const sp<HidlBase>& base); 506 Component(const sp<HidlBase1_1>& base); 507 Component(const sp<HidlBase1_2>& base); 508 Component(const std::shared_ptr<AidlBase>& base); 509 510 ~Component(); 511 512 protected: 513 sp<HidlBase1_0> mHidlBase1_0; 514 sp<HidlBase1_1> mHidlBase1_1; 515 sp<HidlBase1_2> mHidlBase1_2; 516 std::shared_ptr<AidlBase> mAidlBase; 517 518 struct HidlBufferPoolSender; 519 struct AidlBufferPoolSender; 520 std::unique_ptr<HidlBufferPoolSender> mHidlBufferPoolSender; 521 std::unique_ptr<AidlBufferPoolSender> mAidlBufferPoolSender; 522 523 struct OutputBufferQueue; 524 std::unique_ptr<OutputBufferQueue> mOutputBufferQueue; 525 526 // (b/202903117) Sometimes MediaCodec::setSurface races between normal 527 // setSurface and setSurface with ReleaseSurface due to timing issues. 528 // In order to prevent the race condition mutex is added. 529 std::mutex mOutputMutex; 530 531 struct GraphicBufferAllocators; 532 std::unique_ptr<GraphicBufferAllocators> mGraphicBufferAllocators; 533 534 class AidlDeathManager; 535 static AidlDeathManager *GetAidlDeathManager(); 536 std::optional<size_t> mAidlDeathSeq; 537 538 static c2_status_t setDeathListener( 539 const std::shared_ptr<Component>& component, 540 const std::shared_ptr<Listener>& listener); 541 sp<::android::hardware::hidl_death_recipient> mDeathRecipient; 542 543 friend struct Codec2Client; 544 545 struct HidlListener; 546 struct AidlListener; 547 void handleOnWorkDone(const std::list<std::unique_ptr<C2Work>> &workItems); 548 }; 549 550 struct Codec2Client::InputSurface : public Codec2Client::Configurable { 551 public: 552 typedef ::android::hardware::media::c2::V1_0::IInputSurface Base; 553 554 typedef ::android::hardware::media::c2::V1_0::IInputSurfaceConnection ConnectionBase; 555 556 typedef Codec2Client::InputSurfaceConnection Connection; 557 558 typedef ::android::IGraphicBufferProducer IGraphicBufferProducer; 559 560 sp<IGraphicBufferProducer> getGraphicBufferProducer() const; 561 562 // Return the underlying IInputSurface. 563 sp<Base> getHalInterface() const; 564 565 // base cannot be null. 566 InputSurface(const sp<Base>& base); 567 568 protected: 569 sp<Base> mBase; 570 571 sp<IGraphicBufferProducer> mGraphicBufferProducer; 572 573 friend struct Codec2Client; 574 friend struct Component; 575 }; 576 577 struct Codec2Client::InputSurfaceConnection : public Codec2Client::Configurable { 578 579 typedef ::android::hardware::media::c2::V1_0::IInputSurfaceConnection Base; 580 581 c2_status_t disconnect(); 582 583 // base cannot be null. 584 InputSurfaceConnection(const sp<Base>& base); 585 586 protected: 587 sp<Base> mBase; 588 589 friend struct Codec2Client::InputSurface; 590 }; 591 592 } // namespace android 593 594 #endif // CODEC2_HIDL_CLIENT_H 595