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. 183 static std::shared_ptr<Component> CreateComponentByName( 184 char const* componentName, 185 std::shared_ptr<Listener> const& listener, 186 std::shared_ptr<Codec2Client>* owner = nullptr); 187 188 // Try to create a component interface with a given name from all known 189 // IComponentStore services. 190 static std::shared_ptr<Interface> CreateInterfaceByName( 191 char const* interfaceName, 192 std::shared_ptr<Codec2Client>* owner = nullptr); 193 194 // List traits from all known IComponentStore services. 195 static std::vector<C2Component::Traits> const& ListComponents(); 196 197 // Create an input surface. 198 static std::shared_ptr<InputSurface> CreateInputSurface( 199 char const* serviceName = nullptr); 200 201 // base cannot be null. 202 Codec2Client(sp<Base> const& base, size_t serviceIndex); 203 204 protected: 205 sp<Base> mBase; 206 207 // Finds the first store where the predicate returns OK, and returns the last 208 // predicate result. Uses key to remember the last store found, and if cached, 209 // it tries that store before trying all stores (one retry). 210 static c2_status_t ForAllServices( 211 const std::string& key, 212 std::function<c2_status_t(std::shared_ptr<Codec2Client> const&)> 213 predicate); 214 215 size_t mServiceIndex; 216 mutable std::vector<C2Component::Traits> mTraitsList; 217 218 sp<::android::hardware::media::bufferpool::V2_0::IClientManager> 219 mHostPoolManager; 220 221 static std::shared_ptr<Codec2Client> _CreateFromIndex(size_t index); 222 223 std::vector<C2Component::Traits> _listComponents(bool* success) const; 224 225 class Cache; 226 }; 227 228 struct Codec2Client::Interface : public Codec2Client::Configurable { 229 230 typedef ::android::hardware::media::c2::V1_0::IComponentInterface Base; 231 232 Interface(const sp<Base>& base); 233 234 protected: 235 sp<Base> mBase; 236 }; 237 238 struct Codec2Client::Listener { 239 240 // This is called when the component produces some output. 241 virtual void onWorkDone( 242 const std::weak_ptr<Component>& comp, 243 std::list<std::unique_ptr<C2Work>>& workItems) = 0; 244 245 // This is called when the component goes into a tripped state. 246 virtual void onTripped( 247 const std::weak_ptr<Component>& comp, 248 const std::vector<std::shared_ptr<C2SettingResult>>& settingResults 249 ) = 0; 250 251 // This is called when the component encounters an error. 252 virtual void onError( 253 const std::weak_ptr<Component>& comp, 254 uint32_t errorCode) = 0; 255 256 // This is called when the process that hosts the component shuts down 257 // unexpectedly. 258 virtual void onDeath( 259 const std::weak_ptr<Component>& comp) = 0; 260 261 // This is called when an input buffer is no longer in use by the codec. 262 // Input buffers that have been returned by onWorkDone() or flush() will not 263 // trigger a call to this function. 264 virtual void onInputBufferDone( 265 uint64_t frameIndex, size_t arrayIndex) = 0; 266 267 // This is called when the component becomes aware of a frame being 268 // rendered. 269 virtual void onFrameRendered( 270 uint64_t bufferQueueId, 271 int32_t slotId, 272 int64_t timestampNs) = 0; 273 274 virtual ~Listener(); 275 276 }; 277 278 struct Codec2Client::Component : public Codec2Client::Configurable { 279 280 typedef ::android::hardware::media::c2::V1_0::IComponent Base; 281 282 c2_status_t createBlockPool( 283 C2Allocator::id_t id, 284 C2BlockPool::local_id_t* blockPoolId, 285 std::shared_ptr<Configurable>* configurable); 286 287 c2_status_t destroyBlockPool( 288 C2BlockPool::local_id_t localId); 289 290 c2_status_t queue( 291 std::list<std::unique_ptr<C2Work>>* const items); 292 293 c2_status_t flush( 294 C2Component::flush_mode_t mode, 295 std::list<std::unique_ptr<C2Work>>* const flushedWork); 296 297 c2_status_t drain(C2Component::drain_mode_t mode); 298 299 c2_status_t start(); 300 301 c2_status_t stop(); 302 303 c2_status_t reset(); 304 305 c2_status_t release(); 306 307 typedef ::android:: 308 IGraphicBufferProducer IGraphicBufferProducer; 309 typedef IGraphicBufferProducer:: 310 QueueBufferInput QueueBufferInput; 311 typedef IGraphicBufferProducer:: 312 QueueBufferOutput QueueBufferOutput; 313 314 typedef ::android::hardware::graphics::bufferqueue::V1_0:: 315 IGraphicBufferProducer HGraphicBufferProducer1; 316 typedef ::android::hardware::graphics::bufferqueue::V2_0:: 317 IGraphicBufferProducer HGraphicBufferProducer2; 318 typedef ::android::hardware::media::omx::V1_0:: 319 IGraphicBufferSource HGraphicBufferSource; 320 321 // Set the output surface to be used with a blockpool previously created by 322 // createBlockPool(). 323 c2_status_t setOutputSurface( 324 C2BlockPool::local_id_t blockPoolId, 325 const sp<IGraphicBufferProducer>& surface, 326 uint32_t generation); 327 328 // Extract a slot number from of the block, then call 329 // IGraphicBufferProducer::queueBuffer(). 330 // 331 // If the output surface has not been set, NO_INIT will be returned. 332 // 333 // If the block does not come from a bufferqueue-based blockpool, 334 // attachBuffer() will be called, followed by queueBuffer(). 335 // 336 // If the block has a bqId that does not match the id of the output surface, 337 // DEAD_OBJECT will be returned. 338 // 339 // If the call to queueBuffer() is successful but the block cannot be 340 // associated to the output surface for automatic cancellation upon 341 // destruction, UNKNOWN_ERROR will be returned. 342 // 343 // Otherwise, the return value from queueBuffer() will be returned. 344 status_t queueToOutputSurface( 345 const C2ConstGraphicBlock& block, 346 const QueueBufferInput& input, 347 QueueBufferOutput* output); 348 349 // Connect to a given InputSurface. 350 c2_status_t connectToInputSurface( 351 const std::shared_ptr<InputSurface>& inputSurface, 352 std::shared_ptr<InputSurfaceConnection>* connection); 353 354 c2_status_t connectToOmxInputSurface( 355 const sp<HGraphicBufferProducer1>& producer, 356 const sp<HGraphicBufferSource>& source, 357 std::shared_ptr<InputSurfaceConnection>* connection); 358 359 c2_status_t disconnectFromInputSurface(); 360 361 // base cannot be null. 362 Component(const sp<Base>& base); 363 364 ~Component(); 365 366 protected: 367 sp<Base> mBase; 368 369 ::android::hardware::media::c2::V1_0::utils::DefaultBufferPoolSender 370 mBufferPoolSender; 371 372 ::android::hardware::media::c2::V1_0::utils::OutputBufferQueue 373 mOutputBufferQueue; 374 375 static c2_status_t setDeathListener( 376 const std::shared_ptr<Component>& component, 377 const std::shared_ptr<Listener>& listener); 378 sp<::android::hardware::hidl_death_recipient> mDeathRecipient; 379 380 friend struct Codec2Client; 381 382 struct HidlListener; 383 void handleOnWorkDone(const std::list<std::unique_ptr<C2Work>> &workItems); 384 385 }; 386 387 struct Codec2Client::InputSurface : public Codec2Client::Configurable { 388 public: 389 typedef ::android::hardware::media::c2::V1_0::IInputSurface Base; 390 391 typedef ::android::hardware::media::c2::V1_0::IInputSurfaceConnection 392 ConnectionBase; 393 394 typedef Codec2Client::InputSurfaceConnection Connection; 395 396 typedef ::android::IGraphicBufferProducer IGraphicBufferProducer; 397 398 sp<IGraphicBufferProducer> getGraphicBufferProducer() const; 399 400 // Return the underlying IInputSurface. 401 sp<Base> getHalInterface() const; 402 403 // base cannot be null. 404 InputSurface(const sp<Base>& base); 405 406 protected: 407 sp<Base> mBase; 408 409 sp<IGraphicBufferProducer> mGraphicBufferProducer; 410 411 friend struct Codec2Client; 412 friend struct Component; 413 }; 414 415 struct Codec2Client::InputSurfaceConnection : public Codec2Client::Configurable { 416 417 typedef ::android::hardware::media::c2::V1_0::IInputSurfaceConnection Base; 418 419 c2_status_t disconnect(); 420 421 // base cannot be null. 422 InputSurfaceConnection(const sp<Base>& base); 423 424 protected: 425 sp<Base> mBase; 426 427 friend struct Codec2Client::InputSurface; 428 }; 429 430 } // namespace android 431 432 #endif // CODEC2_HIDL_CLIENT_H 433 434