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