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 android::hardware::media::bufferpool::V2_0 { 88 struct IClientManager; 89 } // namespace android::hardware::media::bufferpool::V2_0 90 91 namespace android::hardware::graphics::bufferqueue::V1_0 { 92 struct IGraphicBufferProducer; 93 } // android::hardware::graphics::bufferqueue::V1_0 94 95 namespace android::hardware::graphics::bufferqueue::V2_0 { 96 struct IGraphicBufferProducer; 97 } // android::hardware::graphics::bufferqueue::V2_0 98 99 namespace android::hardware::media::omx::V1_0 { 100 struct IGraphicBufferSource; 101 } // namespace android::hardware::media::omx::V1_0 102 103 namespace android { 104 105 // This class is supposed to be called Codec2Client::Configurable, but forward 106 // declaration of an inner class is not possible. 107 struct Codec2ConfigurableClient { 108 109 typedef ::android::hardware::media::c2::V1_0::IConfigurable Base; 110 111 const C2String& getName() const; 112 113 c2_status_t query( 114 const std::vector<C2Param*>& stackParams, 115 const std::vector<C2Param::Index> &heapParamIndices, 116 c2_blocking_t mayBlock, 117 std::vector<std::unique_ptr<C2Param>>* const heapParams) const; 118 119 c2_status_t config( 120 const std::vector<C2Param*> ¶ms, 121 c2_blocking_t mayBlock, 122 std::vector<std::unique_ptr<C2SettingResult>>* const failures); 123 124 c2_status_t querySupportedParams( 125 std::vector<std::shared_ptr<C2ParamDescriptor>>* const params 126 ) const; 127 128 c2_status_t querySupportedValues( 129 std::vector<C2FieldSupportedValuesQuery>& fields, 130 c2_blocking_t mayBlock) const; 131 132 // base cannot be null. 133 Codec2ConfigurableClient(const sp<Base>& base); 134 135 protected: 136 sp<Base> mBase; 137 C2String mName; 138 139 friend struct Codec2Client; 140 }; 141 142 struct Codec2Client : public Codec2ConfigurableClient { 143 144 typedef ::android::hardware::media::c2::V1_0::IComponentStore Base1_0; 145 typedef ::android::hardware::media::c2::V1_1::IComponentStore Base1_1; 146 typedef ::android::hardware::media::c2::V1_2::IComponentStore Base1_2; 147 typedef Base1_0 Base; 148 149 typedef ::android::hardware::media::c2::V1_0::IConfigurable IConfigurable; 150 151 struct Listener; 152 153 typedef Codec2ConfigurableClient Configurable; 154 155 struct Component; 156 157 struct Interface; 158 159 struct InputSurface; 160 161 struct InputSurfaceConnection; 162 163 typedef Codec2Client Store; 164 165 sp<Base> const& getBase() const; 166 sp<Base1_0> const& getBase1_0() const; 167 sp<Base1_1> const& getBase1_1() const; 168 sp<Base1_2> const& getBase1_2() const; 169 170 std::string const& getServiceName() const; 171 172 c2_status_t createComponent( 173 C2String const& name, 174 std::shared_ptr<Listener> const& listener, 175 std::shared_ptr<Component>* const component); 176 177 c2_status_t createInterface( 178 C2String const& name, 179 std::shared_ptr<Interface>* const interface); 180 181 c2_status_t createInputSurface( 182 std::shared_ptr<InputSurface>* const inputSurface); 183 184 std::vector<C2Component::Traits> const& listComponents() const; 185 186 c2_status_t copyBuffer( 187 std::shared_ptr<C2Buffer> const& src, 188 std::shared_ptr<C2Buffer> const& dst); 189 190 std::shared_ptr<C2ParamReflector> getParamReflector(); 191 192 // Returns the list of IComponentStore service names that are available on 193 // the device. This list is specified at the build time in manifest files. 194 // Note: A software service will have "_software" as a suffix. 195 static std::vector<std::string> const& GetServiceNames(); 196 197 // Create a client to a service with a given name. 198 // 199 // After a client to the service is successfully created, if 200 // setAsPreferredCodec2ComponentStore is true, the component store that the 201 // service hosts will be set as the preferred C2ComponentStore for this 202 // process. (See SetPreferredCodec2ComponentStore() for more information.) 203 static std::shared_ptr<Codec2Client> CreateFromService( 204 char const* name, 205 bool setAsPreferredCodec2ComponentStore = false); 206 207 // Get clients to all services. 208 static std::vector<std::shared_ptr<Codec2Client>> CreateFromAllServices(); 209 210 // Try to create a component with a given name from all known 211 // IComponentStore services. numberOfAttempts determines the number of times 212 // to retry the HIDL call if the transaction fails. 213 static c2_status_t CreateComponentByName( 214 char const* componentName, 215 std::shared_ptr<Listener> const& listener, 216 std::shared_ptr<Component>* component, 217 std::shared_ptr<Codec2Client>* owner = nullptr, 218 size_t numberOfAttempts = 10); 219 220 // Try to create a component interface with a given name from all known 221 // IComponentStore services. numberOfAttempts determines the number of times 222 // to retry the HIDL call if the transaction fails. 223 static std::shared_ptr<Interface> CreateInterfaceByName( 224 char const* interfaceName, 225 std::shared_ptr<Codec2Client>* owner = nullptr, 226 size_t numberOfAttempts = 10); 227 228 // List traits from all known IComponentStore services. 229 static std::vector<C2Component::Traits> const& ListComponents(); 230 231 // Create an input surface. 232 static std::shared_ptr<InputSurface> CreateInputSurface( 233 char const* serviceName = nullptr); 234 235 // base and/or configurable cannot be null. 236 Codec2Client( 237 sp<Base> const& base, 238 sp<IConfigurable> const& configurable, 239 size_t serviceIndex); 240 241 protected: 242 sp<Base1_0> mBase1_0; 243 sp<Base1_1> mBase1_1; 244 sp<Base1_2> mBase1_2; 245 246 // Finds the first store where the predicate returns C2_OK and returns the 247 // last predicate result. The predicate will be tried on all stores. The 248 // function will return C2_OK the first time the predicate returns C2_OK, 249 // or it will return the value from the last time that predicate is tried. 250 // (The latter case corresponds to a failure on every store.) The order of 251 // the stores to try is the same as the return value of GetServiceNames(). 252 // 253 // key is used to remember the last store with which the predicate last 254 // succeeded. If the last successful store is cached, it will be tried 255 // first before all the stores are tried. Note that the last successful 256 // store will be tried twice---first before all the stores, and another time 257 // with all the stores. 258 // 259 // If an attempt to evaluate the predicate results in a transaction failure, 260 // repeated attempts will be made until the predicate returns without a 261 // transaction failure or numberOfAttempts attempts have been made. 262 static c2_status_t ForAllServices( 263 const std::string& key, 264 size_t numberOfAttempts, 265 std::function<c2_status_t(std::shared_ptr<Codec2Client> const&)> 266 predicate); 267 268 size_t mServiceIndex; 269 mutable std::vector<C2Component::Traits> mTraitsList; 270 271 sp<::android::hardware::media::bufferpool::V2_0::IClientManager> 272 mHostPoolManager; 273 274 static std::shared_ptr<Codec2Client> _CreateFromIndex(size_t index); 275 276 std::vector<C2Component::Traits> _listComponents(bool* success) const; 277 278 class Cache; 279 }; 280 281 struct Codec2Client::Interface : public Codec2Client::Configurable { 282 283 typedef ::android::hardware::media::c2::V1_0::IComponentInterface Base; 284 285 Interface(const sp<Base>& base); 286 287 protected: 288 sp<Base> mBase; 289 }; 290 291 struct Codec2Client::Listener { 292 293 // This is called when the component produces some output. 294 virtual void onWorkDone( 295 const std::weak_ptr<Component>& comp, 296 std::list<std::unique_ptr<C2Work>>& workItems) = 0; 297 298 // This is called when the component goes into a tripped state. 299 virtual void onTripped( 300 const std::weak_ptr<Component>& comp, 301 const std::vector<std::shared_ptr<C2SettingResult>>& settingResults 302 ) = 0; 303 304 // This is called when the component encounters an error. 305 virtual void onError( 306 const std::weak_ptr<Component>& comp, 307 uint32_t errorCode) = 0; 308 309 // This is called when the process that hosts the component shuts down 310 // unexpectedly. 311 virtual void onDeath( 312 const std::weak_ptr<Component>& comp) = 0; 313 314 // This is called when an input buffer is no longer in use by the codec. 315 // Input buffers that have been returned by onWorkDone() or flush() will not 316 // trigger a call to this function. 317 virtual void onInputBufferDone( 318 uint64_t frameIndex, size_t arrayIndex) = 0; 319 320 // This is called when the component becomes aware of a frame being 321 // rendered. 322 virtual void onFrameRendered( 323 uint64_t bufferQueueId, 324 int32_t slotId, 325 int64_t timestampNs) = 0; 326 327 virtual ~Listener(); 328 329 }; 330 331 struct Codec2Client::Component : public Codec2Client::Configurable { 332 333 typedef ::android::hardware::media::c2::V1_0::IComponent Base1_0; 334 typedef ::android::hardware::media::c2::V1_1::IComponent Base1_1; 335 typedef ::android::hardware::media::c2::V1_2::IComponent Base1_2; 336 typedef Base1_0 Base; 337 338 c2_status_t createBlockPool( 339 C2Allocator::id_t id, 340 C2BlockPool::local_id_t* blockPoolId, 341 std::shared_ptr<Configurable>* configurable); 342 343 c2_status_t destroyBlockPool( 344 C2BlockPool::local_id_t localId); 345 346 c2_status_t queue( 347 std::list<std::unique_ptr<C2Work>>* const items); 348 349 c2_status_t flush( 350 C2Component::flush_mode_t mode, 351 std::list<std::unique_ptr<C2Work>>* const flushedWork); 352 353 c2_status_t drain(C2Component::drain_mode_t mode); 354 355 c2_status_t start(); 356 357 c2_status_t stop(); 358 359 c2_status_t reset(); 360 361 c2_status_t release(); 362 363 /** 364 * Use tunneling. 365 * 366 * On success, @p sidebandHandle will be a newly allocated native handle. 367 * File descriptors in @p sidebandHandle must be closed and 368 * @p sidebandHandle itself must be deleted afterwards. 369 */ 370 c2_status_t configureVideoTunnel( 371 uint32_t avSyncHwId, 372 native_handle_t** sidebandHandle); 373 374 typedef ::android:: 375 IGraphicBufferProducer IGraphicBufferProducer; 376 typedef IGraphicBufferProducer:: 377 QueueBufferInput QueueBufferInput; 378 typedef IGraphicBufferProducer:: 379 QueueBufferOutput QueueBufferOutput; 380 381 typedef ::android::hardware::graphics::bufferqueue::V1_0:: 382 IGraphicBufferProducer HGraphicBufferProducer1; 383 typedef ::android::hardware::graphics::bufferqueue::V2_0:: 384 IGraphicBufferProducer HGraphicBufferProducer2; 385 typedef ::android::hardware::media::omx::V1_0:: 386 IGraphicBufferSource HGraphicBufferSource; 387 388 // Set the output surface to be used with a blockpool previously created by 389 // createBlockPool(). 390 c2_status_t setOutputSurface( 391 C2BlockPool::local_id_t blockPoolId, 392 const sp<IGraphicBufferProducer>& surface, 393 uint32_t generation, 394 int maxDequeueBufferCount); 395 396 // Extract a slot number from of the block, then call 397 // IGraphicBufferProducer::queueBuffer(). 398 // 399 // If the output surface has not been set, NO_INIT will be returned. 400 // 401 // If the block does not come from a bufferqueue-based blockpool, 402 // attachBuffer() will be called, followed by queueBuffer(). 403 // 404 // If the block has a bqId that does not match the id of the output surface, 405 // DEAD_OBJECT will be returned. 406 // 407 // If the call to queueBuffer() is successful but the block cannot be 408 // associated to the output surface for automatic cancellation upon 409 // destruction, UNKNOWN_ERROR will be returned. 410 // 411 // Otherwise, the return value from queueBuffer() will be returned. 412 status_t queueToOutputSurface( 413 const C2ConstGraphicBlock& block, 414 const QueueBufferInput& input, 415 QueueBufferOutput* output); 416 417 // Retrieve frame event history from the output surface. 418 void pollForRenderedFrames(FrameEventHistoryDelta* delta); 419 420 // Set max dequeue count for output surface. 421 void setOutputSurfaceMaxDequeueCount(int maxDequeueCount); 422 423 // Stop using the current output surface. 424 void stopUsingOutputSurface( 425 C2BlockPool::local_id_t blockPoolId); 426 427 // Connect to a given InputSurface. 428 c2_status_t connectToInputSurface( 429 const std::shared_ptr<InputSurface>& inputSurface, 430 std::shared_ptr<InputSurfaceConnection>* connection); 431 432 c2_status_t connectToOmxInputSurface( 433 const sp<HGraphicBufferProducer1>& producer, 434 const sp<HGraphicBufferSource>& source, 435 std::shared_ptr<InputSurfaceConnection>* connection); 436 437 c2_status_t disconnectFromInputSurface(); 438 439 // base cannot be null. 440 Component(const sp<Base>& base); 441 Component(const sp<Base1_1>& base); 442 Component(const sp<Base1_2>& base); 443 444 ~Component(); 445 446 protected: 447 sp<Base1_0> mBase1_0; 448 sp<Base1_1> mBase1_1; 449 sp<Base1_2> mBase1_2; 450 451 struct BufferPoolSender; 452 std::unique_ptr<BufferPoolSender> mBufferPoolSender; 453 454 struct OutputBufferQueue; 455 std::unique_ptr<OutputBufferQueue> mOutputBufferQueue; 456 457 // (b/202903117) Sometimes MediaCodec::setSurface races between normal 458 // setSurface and setSurface with ReleaseSurface due to timing issues. 459 // In order to prevent the race condition mutex is added. 460 std::mutex mOutputMutex; 461 462 static c2_status_t setDeathListener( 463 const std::shared_ptr<Component>& component, 464 const std::shared_ptr<Listener>& listener); 465 sp<::android::hardware::hidl_death_recipient> mDeathRecipient; 466 467 friend struct Codec2Client; 468 469 struct HidlListener; 470 void handleOnWorkDone(const std::list<std::unique_ptr<C2Work>> &workItems); 471 472 }; 473 474 struct Codec2Client::InputSurface : public Codec2Client::Configurable { 475 public: 476 typedef ::android::hardware::media::c2::V1_0::IInputSurface Base; 477 478 typedef ::android::hardware::media::c2::V1_0::IInputSurfaceConnection 479 ConnectionBase; 480 481 typedef Codec2Client::InputSurfaceConnection Connection; 482 483 typedef ::android::IGraphicBufferProducer IGraphicBufferProducer; 484 485 sp<IGraphicBufferProducer> getGraphicBufferProducer() const; 486 487 // Return the underlying IInputSurface. 488 sp<Base> getHalInterface() const; 489 490 // base cannot be null. 491 InputSurface(const sp<Base>& base); 492 493 protected: 494 sp<Base> mBase; 495 496 sp<IGraphicBufferProducer> mGraphicBufferProducer; 497 498 friend struct Codec2Client; 499 friend struct Component; 500 }; 501 502 struct Codec2Client::InputSurfaceConnection : public Codec2Client::Configurable { 503 504 typedef ::android::hardware::media::c2::V1_0::IInputSurfaceConnection Base; 505 506 c2_status_t disconnect(); 507 508 // base cannot be null. 509 InputSurfaceConnection(const sp<Base>& base); 510 511 protected: 512 sp<Base> mBase; 513 514 friend struct Codec2Client::InputSurface; 515 }; 516 517 } // namespace android 518 519 #endif // CODEC2_HIDL_CLIENT_H 520