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