1 /* 2 * Copyright (C) 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/types.h> 22 23 #include <C2PlatformSupport.h> 24 #include <C2Component.h> 25 #include <C2Buffer.h> 26 #include <C2Param.h> 27 #include <C2.h> 28 29 #include <hidl/HidlSupport.h> 30 #include <utils/StrongPointer.h> 31 32 #include <functional> 33 #include <map> 34 #include <memory> 35 #include <mutex> 36 37 /** 38 * This file contains minimal interfaces for the framework to access Codec2.0. 39 * 40 * Codec2Client is the main class that contains the following inner classes: 41 * - Listener 42 * - Configurable 43 * - Interface 44 * - Component 45 * 46 * Classes in Codec2Client, interfaces in Codec2.0, and HIDL interfaces are 47 * related as follows: 48 * - Codec2Client <==> C2ComponentStore <==> IComponentStore 49 * - Codec2Client::Listener <==> C2Component::Listener <==> IComponentListener 50 * - Codec2Client::Configurable <==> [No equivalent] <==> IConfigurable 51 * - Codec2Client::Interface <==> C2ComponentInterface <==> IComponentInterface 52 * - Codec2Client::Component <==> C2Component <==> IComponent 53 * 54 * The entry point is Codec2Client::CreateFromService(), which creates a 55 * Codec2Client object. From Codec2Client, Interface and Component objects can 56 * be created by calling createComponent() and createInterface(). 57 * 58 * createComponent() takes a Listener object, which must be implemented by the 59 * user. 60 * 61 * At the present, createBlockPool() is the only method that yields a 62 * Configurable object. Note, however, that Interface, Component and 63 * Codec2Client are all subclasses of Configurable. 64 */ 65 66 // Forward declaration of Codec2.0 HIDL interfaces 67 namespace hardware { 68 namespace google { 69 namespace media { 70 namespace c2 { 71 namespace V1_0 { 72 struct IConfigurable; 73 struct IComponentInterface; 74 struct IComponent; 75 struct IComponentStore; 76 struct IInputSurface; 77 struct IInputSurfaceConnection; 78 } // namespace V1_0 79 } // namespace c2 80 } // namespace media 81 } // namespace google 82 } // namespace hardware 83 84 namespace android { 85 namespace hardware { 86 namespace media { 87 namespace bufferpool { 88 namespace V1_0 { 89 struct IClientManager; 90 } // namespace V1_0 91 } // namespace bufferpool 92 } // namespace media 93 } // namespace hardware 94 } // namespace android 95 96 // Forward declarations of other classes 97 namespace android { 98 namespace hardware { 99 namespace graphics { 100 namespace bufferqueue { 101 namespace V1_0 { 102 struct IGraphicBufferProducer; 103 } // namespace V1_0 104 } // namespace bufferqueue 105 } // namespace graphics 106 namespace media { 107 namespace omx { 108 namespace V1_0 { 109 struct IGraphicBufferSource; 110 } // namespace V1_0 111 } // namespace omx 112 } // namespace media 113 } // namespace hardware 114 } // namespace android 115 116 namespace android { 117 118 // This class is supposed to be called Codec2Client::Configurable, but forward 119 // declaration of an inner class is not possible. 120 struct Codec2ConfigurableClient { 121 122 typedef ::hardware::google::media::c2::V1_0::IConfigurable Base; 123 124 const C2String& getName() const; 125 126 c2_status_t query( 127 const std::vector<C2Param*>& stackParams, 128 const std::vector<C2Param::Index> &heapParamIndices, 129 c2_blocking_t mayBlock, 130 std::vector<std::unique_ptr<C2Param>>* const heapParams) const; 131 132 c2_status_t config( 133 const std::vector<C2Param*> ¶ms, 134 c2_blocking_t mayBlock, 135 std::vector<std::unique_ptr<C2SettingResult>>* const failures); 136 137 c2_status_t querySupportedParams( 138 std::vector<std::shared_ptr<C2ParamDescriptor>>* const params 139 ) const; 140 141 c2_status_t querySupportedValues( 142 std::vector<C2FieldSupportedValuesQuery>& fields, 143 c2_blocking_t mayBlock) const; 144 145 // base cannot be null. 146 Codec2ConfigurableClient(const sp<Base>& base); 147 148 protected: 149 C2String mName; 150 sp<Base> mBase; 151 152 Base* base() const; 153 154 friend struct Codec2Client; 155 }; 156 157 struct Codec2Client : public Codec2ConfigurableClient { 158 159 typedef ::hardware::google::media::c2::V1_0::IComponentStore Base; 160 161 struct Listener; 162 163 typedef Codec2ConfigurableClient Configurable; 164 165 typedef Configurable Interface; // These two types may diverge in the future. 166 167 struct Component; 168 169 struct InputSurface; 170 171 struct InputSurfaceConnection; 172 173 typedef Codec2Client Store; 174 getInstanceNameCodec2Client175 std::string getInstanceName() const { return mInstanceName; } 176 177 c2_status_t createComponent( 178 const C2String& name, 179 const std::shared_ptr<Listener>& listener, 180 std::shared_ptr<Component>* const component); 181 182 c2_status_t createInterface( 183 const C2String& name, 184 std::shared_ptr<Interface>* const interface); 185 186 c2_status_t createInputSurface( 187 std::shared_ptr<InputSurface>* const inputSurface); 188 189 const std::vector<C2Component::Traits>& listComponents() const; 190 191 c2_status_t copyBuffer( 192 const std::shared_ptr<C2Buffer>& src, 193 const std::shared_ptr<C2Buffer>& dst); 194 195 std::shared_ptr<C2ParamReflector> getParamReflector(); 196 197 static std::shared_ptr<Codec2Client> CreateFromService( 198 const char* instanceName, 199 bool waitForService = true); 200 201 // Try to create a component with a given name from all known 202 // IComponentStore services. 203 static std::shared_ptr<Component> CreateComponentByName( 204 const char* componentName, 205 const std::shared_ptr<Listener>& listener, 206 std::shared_ptr<Codec2Client>* owner = nullptr); 207 208 // Try to create a component interface with a given name from all known 209 // IComponentStore services. 210 static std::shared_ptr<Interface> CreateInterfaceByName( 211 const char* interfaceName, 212 std::shared_ptr<Codec2Client>* owner = nullptr); 213 214 // List traits from all known IComponentStore services. 215 static const std::vector<C2Component::Traits>& ListComponents(); 216 217 // base cannot be null. 218 Codec2Client(const sp<Base>& base, std::string instanceName); 219 220 protected: 221 Base* base() const; 222 223 // Finds the first store where the predicate returns OK, and returns the last 224 // predicate result. Uses key to remember the last store found, and if cached, 225 // it tries that store before trying all stores (one retry). 226 static c2_status_t ForAllStores( 227 const std::string& key, 228 std::function<c2_status_t(const std::shared_ptr<Codec2Client>&)> predicate); 229 230 mutable std::mutex mMutex; 231 mutable bool mListed; 232 std::string mInstanceName; 233 mutable std::vector<C2Component::Traits> mTraitsList; 234 mutable std::vector<std::unique_ptr<std::vector<std::string>>> 235 mAliasesBuffer; 236 237 sp<::android::hardware::media::bufferpool::V1_0::IClientManager> 238 mHostPoolManager; 239 }; 240 241 struct Codec2Client::Listener { 242 243 virtual void onWorkDone( 244 const std::weak_ptr<Component>& comp, 245 std::list<std::unique_ptr<C2Work>>& workItems) = 0; 246 247 virtual void onTripped( 248 const std::weak_ptr<Component>& comp, 249 const std::vector<std::shared_ptr<C2SettingResult>>& settingResults 250 ) = 0; 251 252 virtual void onError( 253 const std::weak_ptr<Component>& comp, 254 uint32_t errorCode) = 0; 255 256 virtual void onDeath( 257 const std::weak_ptr<Component>& comp) = 0; 258 259 struct RenderedFrame { 260 uint64_t bufferQueueId; 261 int32_t slotId; 262 int64_t timestampNs; 263 }; 264 265 virtual void onFramesRendered( 266 const std::vector<RenderedFrame>& renderedFrames) = 0; 267 268 virtual ~Listener(); 269 270 }; 271 272 struct Codec2Client::Component : public Codec2Client::Configurable { 273 274 typedef ::hardware::google::media::c2::V1_0::IComponent Base; 275 276 c2_status_t createBlockPool( 277 C2Allocator::id_t id, 278 C2BlockPool::local_id_t* blockPoolId, 279 std::shared_ptr<Configurable>* configurable); 280 281 c2_status_t destroyBlockPool( 282 C2BlockPool::local_id_t localId); 283 284 c2_status_t queue( 285 std::list<std::unique_ptr<C2Work>>* const items); 286 287 c2_status_t flush( 288 C2Component::flush_mode_t mode, 289 std::list<std::unique_ptr<C2Work>>* const flushedWork); 290 291 c2_status_t drain(C2Component::drain_mode_t mode); 292 293 c2_status_t start(); 294 295 c2_status_t stop(); 296 297 c2_status_t reset(); 298 299 c2_status_t release(); 300 301 typedef ::android:: 302 IGraphicBufferProducer IGraphicBufferProducer; 303 typedef IGraphicBufferProducer:: 304 QueueBufferInput QueueBufferInput; 305 typedef IGraphicBufferProducer:: 306 QueueBufferOutput QueueBufferOutput; 307 308 typedef ::android::hardware::graphics::bufferqueue::V1_0:: 309 IGraphicBufferProducer HGraphicBufferProducer; 310 typedef ::android::hardware::media::omx::V1_0:: 311 IGraphicBufferSource HGraphicBufferSource; 312 313 // Set the output surface to be used with a blockpool previously created by 314 // createBlockPool(). 315 c2_status_t setOutputSurface( 316 C2BlockPool::local_id_t blockPoolId, 317 const sp<IGraphicBufferProducer>& surface, 318 uint32_t generation); 319 320 // Extract a slot number from of the block, then call 321 // IGraphicBufferProducer::queueBuffer(). 322 // 323 // If the output surface has not been set, NO_INIT will be returned. 324 // 325 // If the block does not come from a bufferqueue-based blockpool, 326 // attachBuffer() will be called, followed by queueBuffer(). 327 // 328 // If the block has a bqId that does not match the id of the output surface, 329 // DEAD_OBJECT will be returned. 330 // 331 // If the call to queueBuffer() is successful but the block cannot be 332 // associated to the output surface for automatic cancellation upon 333 // destruction, UNKNOWN_ERROR will be returned. 334 // 335 // Otherwise, the return value from queueBuffer() will be returned. 336 status_t queueToOutputSurface( 337 const C2ConstGraphicBlock& block, 338 const QueueBufferInput& input, 339 QueueBufferOutput* output); 340 341 c2_status_t connectToOmxInputSurface( 342 const sp<HGraphicBufferProducer>& producer, 343 const sp<HGraphicBufferSource>& source); 344 345 c2_status_t disconnectFromInputSurface(); 346 347 void handleOnWorkDone(const std::list<std::unique_ptr<C2Work>> &workItems); 348 349 // base cannot be null. 350 Component(const sp<Base>& base); 351 352 ~Component(); 353 354 protected: 355 Base* base() const; 356 357 mutable std::mutex mInputBuffersMutex; 358 mutable std::map<uint64_t, std::vector<std::shared_ptr<C2Buffer>>> 359 mInputBuffers; 360 361 ::hardware::google::media::c2::V1_0::utils::DefaultBufferPoolSender 362 mBufferPoolSender; 363 364 std::mutex mOutputBufferQueueMutex; 365 sp<IGraphicBufferProducer> mOutputIgbp; 366 uint64_t mOutputBqId; 367 uint32_t mOutputGeneration; 368 369 static c2_status_t setDeathListener( 370 const std::shared_ptr<Component>& component, 371 const std::shared_ptr<Listener>& listener); 372 sp<::android::hardware::hidl_death_recipient> mDeathRecipient; 373 374 friend struct Codec2Client; 375 }; 376 377 struct Codec2Client::InputSurface { 378 public: 379 typedef ::hardware::google::media::c2::V1_0::IInputSurface Base; 380 381 typedef ::hardware::google::media::c2::V1_0::IInputSurfaceConnection 382 ConnectionBase; 383 384 typedef Codec2Client::InputSurfaceConnection Connection; 385 386 typedef ::android::IGraphicBufferProducer IGraphicBufferProducer; 387 388 c2_status_t connectToComponent( 389 const std::shared_ptr<Component>& component, 390 std::shared_ptr<Connection>* connection); 391 392 std::shared_ptr<Configurable> getConfigurable() const; 393 394 const sp<IGraphicBufferProducer>& getGraphicBufferProducer() const; 395 396 // base cannot be null. 397 InputSurface(const sp<Base>& base); 398 399 protected: 400 Base* base() const; 401 sp<Base> mBase; 402 403 sp<IGraphicBufferProducer> mGraphicBufferProducer; 404 405 friend struct Codec2Client; 406 friend struct Component; 407 }; 408 409 struct Codec2Client::InputSurfaceConnection { 410 411 typedef ::hardware::google::media::c2::V1_0::IInputSurfaceConnection Base; 412 413 c2_status_t disconnect(); 414 415 // base cannot be null. 416 InputSurfaceConnection(const sp<Base>& base); 417 418 protected: 419 Base* base() const; 420 sp<Base> mBase; 421 422 friend struct Codec2Client::InputSurface; 423 }; 424 425 } // namespace android 426 427 #endif // CODEC2_HIDL_CLIENT_H_ 428 429