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