1 /* 2 * Copyright (C) 2016 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 C2COMPONENT_H_ 18 19 #define C2COMPONENT_H_ 20 21 #include <stdbool.h> 22 #include <stdint.h> 23 24 #include <list> 25 #include <memory> 26 #include <vector> 27 #include <functional> 28 29 #include <C2Enum.h> 30 #include <C2Param.h> 31 #include <C2Work.h> 32 33 /// \defgroup components Components 34 /// @{ 35 36 struct C2FieldSupportedValuesQuery { 37 enum type_t : uint32_t { 38 POSSIBLE, ///< query all possible values regardless of other settings 39 CURRENT, ///< query currently possible values given dependent settings 40 }; 41 42 private: 43 C2ParamField _mField; 44 type_t _mType; 45 public: 46 c2_status_t status; 47 C2FieldSupportedValues values; 48 C2FieldSupportedValuesQueryC2FieldSupportedValuesQuery49 C2FieldSupportedValuesQuery(const C2ParamField &field_, type_t type_) 50 : _mField(field_), _mType(type_), status(C2_NO_INIT) { } 51 52 static C2FieldSupportedValuesQuery CurrentC2FieldSupportedValuesQuery53 Current(const C2ParamField &field_) { 54 return C2FieldSupportedValuesQuery(field_, CURRENT); 55 } 56 57 static C2FieldSupportedValuesQuery PossibleC2FieldSupportedValuesQuery58 Possible(const C2ParamField &field_) { 59 return C2FieldSupportedValuesQuery(field_, POSSIBLE); 60 } 61 fieldC2FieldSupportedValuesQuery62 inline C2ParamField field() const { return _mField; }; 63 typeC2FieldSupportedValuesQuery64 inline type_t type() const { return _mType; } 65 }; 66 67 /** 68 * Component interface object. This object contains all of the configuration of a potential or 69 * actual component. It can be created and used independently of an actual C2Component instance to 70 * query support and parameters for various component settings and configurations for a potential 71 * component. Actual components also expose this interface. 72 */ 73 74 class C2ComponentInterface { 75 public: 76 // ALWAYS AVAILABLE METHODS 77 // ============================================================================================= 78 79 /** 80 * Returns the name of this component or component interface object. 81 * This is a unique name for this component or component interface 'class'; however, multiple 82 * instances of this component SHALL have the same name. 83 * 84 * When attached to a component, this method MUST be supported in any component state. 85 * This call does not change the state nor the internal configuration of the component. 86 * 87 * This method MUST be "non-blocking" and return within 1ms. 88 * 89 * \return the name of this component or component interface object. 90 * \retval an empty string if there was not enough memory to allocate the actual name. 91 */ 92 virtual C2String getName() const = 0; 93 94 /** 95 * Returns a unique ID for this component or interface object. 96 * This ID is used as work targets, unique work IDs, and when configuring tunneling. 97 * 98 * When attached to a component, this method MUST be supported in any component state. 99 * This call does not change the state nor the internal configuration of the component. 100 * 101 * This method MUST be "non-blocking" and return within 1ms. 102 * 103 * \return a unique node ID for this component or component interface instance. 104 */ 105 virtual c2_node_id_t getId() const = 0; 106 107 /** 108 * Queries a set of parameters from the component or interface object. 109 * Querying is performed at best effort: the component SHALL query all supported parameters and 110 * skip unsupported ones, heap allocated parameters that could not be allocated or parameters 111 * that could not be queried without blocking. Any errors are communicated in the return value. 112 * Additionally, preallocated (e.g. stack) parameters that could not be queried are invalidated. 113 * Invalid or blocking parameters to be allocated on the heap are omitted from the result. 114 * 115 * \note Parameter values do not depend on the order of query. 116 * 117 * \todo This method cannot be used to query info-buffers. Is that a problem? 118 * 119 * When attached to a component, this method MUST be supported in any component state except 120 * released. 121 * This call does not change the state nor the internal configuration of the component. 122 * 123 * This method has a variable blocking behavior based on state. 124 * In the stopped state this method MUST be "non-blocking" and return within 1ms. 125 * In the running states this method may be momentarily blocking, but MUST return within 5ms. 126 * 127 * \param[in,out] stackParams a list of params queried. These are initialized specific to each 128 * setting; e.g. size and index are set and rest of the members are 129 * cleared. 130 * \note Flexible settings that are of incorrect size will be 131 * invalidated. 132 * \param[in] heapParamIndices a vector of param indices for params to be queried and returned 133 * on the heap. These parameters will be returned in heapParams. 134 * Unsupported param indices will be ignored. 135 * \param[in] mayBlock if true (C2_MAY_BLOCK), implementation may momentarily block. 136 * Otherwise (C2_DONT_BLOCK), it must be "non-blocking". 137 * \param[out] heapParams a list of params where to which the supported heap parameters 138 * will be appended in the order they appear in heapParamIndices. 139 * 140 * \retval C2_OK all parameters could be queried 141 * \retval C2_BAD_INDEX all supported parameters could be queried, but some parameters were not 142 * supported 143 * \retval C2_BAD_STATE when called in the released component state (user error) 144 * (this error code is only allowed for interfaces connected to components) 145 * \retval C2_NO_MEMORY could not allocate memory for a supported parameter 146 * \retval C2_BLOCKING the operation must block to complete but mayBlock is false 147 * (this error code is only allowed for interfaces connected to components) 148 * \retval C2_TIMED_OUT could not query the parameters within the time limit (unexpected) 149 * (this error code is only allowed for interfaces connected to components 150 * in the running state) 151 * \retval C2_CORRUPTED some unknown error prevented the querying of the parameters 152 * (unexpected) 153 * (this error code is only allowed for interfaces connected to components) 154 */ 155 virtual c2_status_t query_vb( 156 const std::vector<C2Param*> &stackParams, 157 const std::vector<C2Param::Index> &heapParamIndices, 158 c2_blocking_t mayBlock, 159 std::vector<std::unique_ptr<C2Param>>* const heapParams) const = 0; 160 161 /** 162 * Sets a set of parameters for the component or interface object. 163 * 164 * Tuning is performed at best effort: the component SHALL process the configuration updates in 165 * the order they appear in |params|. If any parameter update fails, the component shall 166 * communicate the failure in the return value and in |failures|, and still process the 167 * remaining parameters. Unsupported parameters are skipped, though they are communicated in 168 * ther return value. Most parameters are updated at best effort - such that even if client 169 * specifies an unsupported value for a field, the closest supported value is used. On the 170 * other hand, strict parameters only accept specific values for their fields, and if the client 171 * specifies an unsupported value, the parameter setting shall fail for that field. 172 * If the client tries to change the value of a field that requires momentary blocking without 173 * setting |mayBlock| to C2_MAY_BLOCK, that parameter shall also be skipped and a specific 174 * return value shall be used. Final values for all parameters set are propagated back to the 175 * caller in |params|. 176 * 177 * \note Parameter tuning DOES depend on the order of the tuning parameters. E.g. some parameter 178 * update may allow some subsequent values for further parameter updates. 179 * 180 * When attached to a component, this method MUST be supported in any component state except 181 * released. 182 * 183 * This method has a variable blocking behavior based on state. 184 * In the stopped state this method MUST be "non-blocking" and return within 1ms. 185 * In the running states this method may be momentarily blocking, but MUST return within 5ms. 186 * 187 * \param[in,out] params a list of parameter updates. These will be updated to the actual 188 * parameter values after the updates (this is because tuning is performed 189 * at best effort). 190 * \todo params that could not be updated are not marked here, so are 191 * confusing - are they "existing" values or intended to be configured 192 * values? 193 * \param[in] mayBlock if true (C2_MAY_BLOCK), implementation may momentarily block. 194 * Otherwise (C2_DONT_BLOCK), it must be "non-blocking". 195 * \param[out] failures a list of parameter failures and optional guidance 196 * 197 * \retval C2_OK all parameters could be updated successfully 198 * \retval C2_BAD_INDEX all supported parameters could be updated successfully, but some 199 * parameters were not supported 200 * \retval C2_BAD_VALUE some supported parameters could not be updated successfully because 201 * they contained unsupported values. These are returned in |failures|. 202 * \retval C2_BAD_STATE when called in the released component state (user error) 203 * (this error code is only allowed for interfaces connected to components) 204 * \retval C2_NO_MEMORY some supported parameters could not be updated successfully because 205 * they contained unsupported values, but could not allocate a failure 206 * object for them. 207 * \retval C2_TIMED_OUT could not set the parameters within the time limit (unexpected) 208 * (this error code is only allowed for interfaces connected to components 209 * in the running state) 210 * \retval C2_BLOCKING the operation must block to complete but mayBlock is false 211 * (this error code is only allowed for interfaces connected to components) 212 * \retval C2_CORRUPTED some unknown error prevented the update of the parameters 213 * (unexpected) 214 * (this error code is only allowed for interfaces connected to components) 215 */ 216 virtual c2_status_t config_vb( 217 const std::vector<C2Param*> ¶ms, 218 c2_blocking_t mayBlock, 219 std::vector<std::unique_ptr<C2SettingResult>>* const failures) = 0; 220 221 // TUNNELING 222 // ============================================================================================= 223 224 /** 225 * Creates a tunnel from this component to the target component. 226 * 227 * If the component is successfully created, subsequent work items queued may include a 228 * tunneled path between these components. 229 * 230 * When attached to a component, this method MUST be supported in any component state except 231 * released. 232 * 233 * This method may be momentarily blocking, but MUST return within 5ms. 234 * 235 * \retval C2_OK the tunnel was successfully created 236 * \retval C2_BAD_INDEX the target component does not exist 237 * \retval C2_DUPLICATE the tunnel already exists 238 * \retval C2_OMITTED tunneling is not supported by this component 239 * \retval C2_CANNOT_DO the specific tunnel is not supported 240 * \retval C2_BAD_STATE when called in the released component state (user error) 241 * (this error code is only allowed for interfaces connected to components) 242 * 243 * \retval C2_TIMED_OUT could not create the tunnel within the time limit (unexpected) 244 * \retval C2_CORRUPTED some unknown error prevented the creation of the tunnel (unexpected) 245 * (this error code is only allowed for interfaces connected to components) 246 */ 247 virtual c2_status_t createTunnel_sm(c2_node_id_t targetComponent) = 0; 248 249 /** 250 * Releases a tunnel from this component to the target component. 251 * 252 * The release of a tunnel is delayed while there are pending work items for the tunnel. 253 * After releasing a tunnel, subsequent work items queued MUST NOT include a tunneled 254 * path between these components. 255 * 256 * When attached to a component, this method MUST be supported in any component state except 257 * released. 258 * 259 * This method may be momentarily blocking, but MUST return within 5ms. 260 * 261 * \retval C2_OK the tunnel was marked for release successfully 262 * \retval C2_BAD_INDEX the target component does not exist 263 * \retval C2_NOT_FOUND the tunnel does not exist 264 * \retval C2_OMITTED tunneling is not supported by this component 265 * \retval C2_BAD_STATE when called in the released component state (user error) 266 * (this error code is only allowed for interfaces connected to components) 267 * 268 * \retval C2_TIMED_OUT could not mark the tunnel for release within the time limit (unexpected) 269 * \retval C2_CORRUPTED some unknown error prevented the release of the tunnel (unexpected) 270 * (this error code is only allowed for interfaces connected to components) 271 */ 272 virtual c2_status_t releaseTunnel_sm(c2_node_id_t targetComponent) = 0; 273 274 // REFLECTION MECHANISM (USED FOR EXTENSION) 275 // ============================================================================================= 276 277 /** 278 * Returns the set of supported parameters. 279 * 280 * When attached to a component, this method MUST be supported in any component state except 281 * released. 282 * 283 * This method MUST be "non-blocking" and return within 1ms. 284 * 285 * \param[out] params a vector of supported parameters will be appended to this vector. 286 * 287 * \retval C2_OK the operation completed successfully. 288 * \retval C2_BAD_STATE when called in the released component state (user error) 289 * (this error code is only allowed for interfaces connected to components) 290 * \retval C2_NO_MEMORY not enough memory to complete this method. 291 */ 292 virtual c2_status_t querySupportedParams_nb( 293 std::vector<std::shared_ptr<C2ParamDescriptor>> * const params) const = 0; 294 295 /** 296 * Retrieves the supported values for the queried fields. 297 * 298 * Client SHALL set the parameter-field specifier and the type of supported values query (e.g. 299 * currently supported values, or potential supported values) in fields. 300 * Upon return the component SHALL fill in the supported values for the fields listed as well 301 * as a status for each field. Component shall process all fields queried even if some queries 302 * fail. 303 * 304 * When attached to a component, this method MUST be supported in any component state except 305 * released. 306 * 307 * This method has a variable blocking behavior based on state. 308 * In the stopped state this method MUST be "non-blocking" and return within 1ms. 309 * In the running states this method may be momentarily blocking, but MUST return within 5ms. 310 * 311 * \param[in out] fields a vector of fields descriptor structures. 312 * \param[in] mayBlock if true (C2_MAY_BLOCK), implementation may momentarily block. 313 * Otherwise (C2_DONT_BLOCK), it must be "non-blocking". 314 * 315 * \retval C2_OK the operation completed successfully. 316 * \retval C2_BAD_STATE when called in the released component state (user error) 317 * (this error code is only allowed for interfaces connected to components) 318 * \retval C2_BAD_INDEX at least one field was not recognized as a component field 319 * \retval C2_TIMED_OUT could not query supported values within the time limit (unexpected) 320 * (this error code is only allowed for interfaces connected to components 321 * in the running state) 322 * \retval C2_BLOCKING the operation must block to complete but mayBlock is false 323 * (this error code is only allowed for interfaces connected to components) 324 * \retval C2_CORRUPTED some unknown error prevented the operation from completing (unexpected) 325 * (this error code is only allowed for interfaces connected to components) 326 */ 327 virtual c2_status_t querySupportedValues_vb( 328 std::vector<C2FieldSupportedValuesQuery> &fields, c2_blocking_t mayBlock) const = 0; 329 330 virtual ~C2ComponentInterface() = default; 331 }; 332 333 class C2Component { 334 public: 335 class Listener { 336 public: 337 virtual void onWorkDone_nb(std::weak_ptr<C2Component> component, 338 std::list<std::unique_ptr<C2Work>> workItems) = 0; 339 340 virtual void onTripped_nb(std::weak_ptr<C2Component> component, 341 std::vector<std::shared_ptr<C2SettingResult>> settingResult) = 0; 342 343 virtual void onError_nb(std::weak_ptr<C2Component> component, 344 uint32_t errorCode) = 0; 345 346 // virtual void onTunnelReleased(<from>, <to>) = 0; 347 348 // virtual void onComponentReleased(<id>) = 0; 349 350 virtual ~Listener() = default; 351 }; 352 353 /** 354 * Sets the listener for this component 355 * 356 * This method MUST be supported in all states except released. 357 * The listener can only be set to non-null value in stopped state (that does not include 358 * tripped or error). It can be set to nullptr in both stopped and running states. 359 * Components only use the listener in running state. 360 * 361 * If listener is nullptr, the component SHALL guarantee that no more listener callbacks are 362 * done to the original listener once this method returns. (Any pending listener callbacks will 363 * need to be completed during this call - hence this call may be temporarily blocking.) 364 * 365 * This method has a variable blocking behavior based on state. 366 * In the stopped state this method MUST be "non-blocking" and return within 1ms. 367 * In the running states this method may be momentarily blocking, but MUST return within 5ms. 368 * 369 * Component SHALL handle listener notifications from the same thread (the thread used is 370 * at the component's discretion.) 371 * 372 * \note This could also be accomplished by passing a weak_ptr to a component-specific listener 373 * here and requiring the client to always promote the weak_ptr before any callback. This would 374 * put the burden on the client to clear the listener - wait for its deletion - at which point 375 * it is guaranteed that no more listener callbacks will occur. 376 * 377 * \param[in] listener the component listener object 378 * \param[in] mayBlock if true (C2_MAY_BLOCK), implementation may momentarily block. 379 * Otherwise (C2_DONT_BLOCK), it must be "non-blocking". 380 * 381 * \retval C2_BAD_STATE attempting to change the listener in the running state to a non-null 382 * value (user error), or called in the released state 383 * \retval C2_BLOCKING the operation must block to complete but mayBlock is false 384 * \retval C2_OK listener was updated successfully. 385 */ 386 virtual c2_status_t setListener_vb( 387 const std::shared_ptr<Listener> &listener, c2_blocking_t mayBlock) = 0; 388 389 /// component domain (e.g. audio or video) 390 enum domain_t : uint32_t; 391 392 /// component kind (e.g. encoder, decoder or filter) 393 enum kind_t : uint32_t; 394 395 /// component rank. This number is used to determine component ordering (the lower the sooner) 396 /// in the component list. 397 typedef uint32_t rank_t; 398 399 /// component attributes 400 enum attrib_t : uint64_t; 401 402 /** 403 * Information about a component. 404 */ 405 struct Traits { 406 // public: 407 C2String name; ///< name of the component 408 domain_t domain; ///< component domain 409 kind_t kind; ///< component kind 410 rank_t rank; ///< component rank 411 C2String mediaType; ///< media type supported by the component 412 C2String owner; ///< name of the component store owning this component 413 414 /** 415 * name alias(es) for backward compatibility. 416 * \note Multiple components can have the same alias as long as their media-type differs. 417 */ 418 std::vector<C2String> aliases; ///< name aliases for backward compatibility 419 }; 420 421 // METHODS AVAILABLE WHEN RUNNING 422 // ============================================================================================= 423 424 /** 425 * Queues up work for the component. 426 * 427 * This method MUST be supported in running (including tripped and error) states. 428 * 429 * This method MUST be "non-blocking" and return within 1 ms 430 * 431 * It is acceptable for this method to return OK and return an error value using the 432 * onWorkDone() callback. 433 * 434 * \retval C2_OK the work was successfully queued 435 * \retval C2_BAD_INDEX some component(s) in the work do(es) not exist 436 * \retval C2_CANNOT_DO the components are not tunneled 437 * \retval C2_BAD_STATE when called in the stopped or released state (user error) 438 * 439 * \retval C2_NO_MEMORY not enough memory to queue the work 440 * \retval C2_CORRUPTED some unknown error prevented queuing the work (unexpected) 441 */ 442 virtual c2_status_t queue_nb(std::list<std::unique_ptr<C2Work>>* const items) = 0; 443 444 /** 445 * Announces a work to be queued later for the component. This reserves a slot for the queue 446 * to ensure correct work ordering even if the work is queued later. 447 * 448 * This method MUST be supported in running (including tripped and error) states. 449 * 450 * This method MUST be "non-blocking" and return within 1 ms 451 * 452 * \retval C2_OK the work announcement has been successfully recorded 453 * \retval C2_BAD_INDEX some component(s) in the work outline do(es) not exist 454 * \retval C2_CANNOT_DO the componentes are not tunneled 455 * \retval C2_BAD_STATE when called in the stopped or released state (user error) 456 * 457 * \retval C2_NO_MEMORY not enough memory to record the work announcement 458 * \retval C2_CORRUPTED some unknown error prevented recording the announcement (unexpected) 459 * 460 * \todo Can this be rolled into queue_nb? 461 * \todo Expose next work item for each component to detect stalls 462 */ 463 virtual c2_status_t announce_nb(const std::vector<C2WorkOutline> &items) = 0; 464 465 enum flush_mode_t : uint32_t { 466 /// flush work from this component only 467 FLUSH_COMPONENT, 468 469 /// flush work from this component and all components connected downstream from it via 470 /// tunneling 471 FLUSH_CHAIN = (1 << 16), 472 }; 473 474 /** 475 * Discards and abandons any pending work for the component, and optionally any component 476 * downstream. 477 * 478 * \todo define this: we could flush all work before last item queued for component across all 479 * components linked to this; flush only work items that are queued to this 480 * component 481 * \todo return work # of last flushed item; or all flushed (but not returned items) 482 * \todo we could make flush take a work item and flush all work before/after that item to allow 483 * TBD (slicing/seek?) 484 * \todo we could simply take a list of numbers and flush those... this is bad for decoders 485 * also, what would happen to fine grade references? 486 * 487 * This method MUST be supported in running (including tripped and error) states. 488 * 489 * This method may be momentarily blocking, but must return within 5ms. 490 * 491 * Work that could be immediately abandoned/discarded SHALL be returned in |flushedWork|; this 492 * can be done in an arbitrary order. 493 * 494 * Work that could not be abandoned or discarded immediately SHALL be marked to be 495 * discarded at the earliest opportunity, and SHALL be returned via the onWorkDone() callback. 496 * This shall be completed within 500ms. 497 * 498 * \param mode flush mode 499 * 500 * \retval C2_OK the component has been successfully flushed 501 * \retval C2_BAD_STATE when called in the stopped or released state (user error) 502 * \retval C2_TIMED_OUT the flush could not be completed within the time limit (unexpected) 503 * \retval C2_CORRUPTED some unknown error prevented flushing from completion (unexpected) 504 */ 505 virtual c2_status_t flush_sm(flush_mode_t mode, std::list<std::unique_ptr<C2Work>>* const flushedWork) = 0; 506 507 enum drain_mode_t : uint32_t { 508 /// drain component only and add an "end-of-stream" marker. Component shall process all 509 /// queued work and complete the current stream. If new input is received, it shall start 510 /// a new stream. \todo define what a stream is. 511 DRAIN_COMPONENT_WITH_EOS, 512 /// drain component without setting "end-of-stream" marker. Component shall process all 513 /// queued work but shall expect more work items for the same stream. 514 DRAIN_COMPONENT_NO_EOS = (1 << 0), 515 516 /// marks the last work item with a persistent "end-of-stream" marker that will drain 517 /// downstream components 518 /// \todo this may confuse work-ordering downstream 519 DRAIN_CHAIN = (1 << 16), 520 521 /** 522 * \todo define this; we could place EOS to all upstream components, just this component, or 523 * all upstream and downstream component. 524 * \todo should EOS carry over to downstream components? 525 */ 526 }; 527 528 /** 529 * Drains the component, and optionally downstream components. This is a signalling method; 530 * as such it does not wait for any work completion. 531 * 532 * Marks last work item as "drain-till-here", so component is notified not to wait for further 533 * work before it processes work already queued. This method can also used to set the 534 * end-of-stream flag after work has been queued. Client can continue to queue further work 535 * immediately after this method returns. 536 * 537 * This method MUST be supported in running (including tripped) states. 538 * 539 * This method MUST be "non-blocking" and return within 1ms. 540 * 541 * Work that is completed SHALL be returned via the onWorkDone() callback. 542 * 543 * \param mode drain mode 544 * 545 * \retval C2_OK the drain request has been successfully recorded 546 * \retval C2_BAD_STATE when called in the stopped or released state (user error) 547 * \retval C2_BAD_VALUE the drain mode is not supported by the component 548 * \todo define supported modes discovery 549 * \retval C2_TIMED_OUT the flush could not be completed within the time limit (unexpected) 550 * \retval C2_CORRUPTED some unknown error prevented flushing from completion (unexpected) 551 */ 552 virtual c2_status_t drain_nb(drain_mode_t mode) = 0; 553 554 // STATE CHANGE METHODS 555 // ============================================================================================= 556 557 /** 558 * Starts the component. 559 * 560 * This method MUST be supported in stopped state, as well as during the tripped state. 561 * 562 * If the return value is C2_OK, the component shall be in the running state. 563 * If the return value is C2_BAD_STATE or C2_DUPLICATE, no state change is expected as a 564 * response to this call. 565 * Otherwise, the component shall be in the stopped state. 566 * 567 * \note If a component is in the tripped state and start() is called while the component 568 * configuration still results in a trip, start shall succeed and a new onTripped callback 569 * should be used to communicate the configuration conflict that results in the new trip. 570 * 571 * \todo This method MUST return within 500ms. Seems this should be able to return quickly, as 572 * there are no immediate guarantees. Though there are guarantees for responsiveness immediately 573 * after start returns. 574 * 575 * \retval C2_OK the component has started (or resumed) successfully 576 * \retval C2_DUPLICATE when called during another start call from another thread 577 * \retval C2_BAD_STATE when called in any state other than the stopped state or tripped state, 578 * including when called during another state change call from another 579 * thread (user error) 580 * \retval C2_NO_MEMORY not enough memory to start the component 581 * \retval C2_TIMED_OUT the component could not be started within the time limit (unexpected) 582 * \retval C2_CORRUPTED some unknown error prevented starting the component (unexpected) 583 */ 584 virtual c2_status_t start() = 0; 585 586 /** 587 * Stops the component. 588 * 589 * This method MUST be supported in running (including tripped) state. 590 * 591 * This method MUST return withing 500ms. 592 * 593 * Upon this call, all pending work SHALL be abandoned and all buffer references SHALL be 594 * released. 595 * If the return value is C2_BAD_STATE or C2_DUPLICATE, no state change is expected as a 596 * response to this call. 597 * For all other return values, the component shall be in the stopped state. 598 * 599 * \todo should this return completed work, since client will just free it? Perhaps just to 600 * verify accounting. 601 * 602 * This does not alter any settings and tunings that may have resulted in a tripped state. 603 * (Is this material given the definition? Perhaps in case we want to start again.) 604 * 605 * \retval C2_OK the component has started successfully 606 * \retval C2_DUPLICATE when called during another stop call from another thread 607 * \retval C2_BAD_STATE when called in any state other than the running state, including when 608 * called during another state change call from another thread (user error) 609 * \retval C2_TIMED_OUT the component could not be stopped within the time limit (unexpected) 610 * \retval C2_CORRUPTED some unknown error prevented stopping the component (unexpected) 611 */ 612 virtual c2_status_t stop() = 0; 613 614 /** 615 * Resets the component. 616 * 617 * This method MUST be supported in all (including tripped) states other than released. 618 * 619 * This method MUST be supported during any other blocking call. 620 * 621 * This method MUST return withing 500ms. 622 * 623 * After this call returns all work SHALL be abandoned, all buffer references SHALL be released. 624 * If the return value is C2_BAD_STATE or C2_DUPLICATE, no state change is expected as a 625 * response to this call. 626 * For all other return values, the component shall be in the stopped state. 627 * 628 * \todo should this return completed work, since client will just free it? Also, if it unblocks 629 * a stop, where should completed work be returned? 630 * 631 * This brings settings back to their default - "guaranteeing" no tripped space. 632 * 633 * \todo reclaim support - it seems that since ownership is passed, this will allow reclaiming 634 * stuff. 635 * 636 * \retval C2_OK the component has been reset 637 * \retval C2_DUPLICATE when called during another reset call from another thread 638 * \retval C2_BAD_STATE when called in the released state 639 * \retval C2_TIMED_OUT the component could not be reset within the time limit (unexpected) 640 * \retval C2_CORRUPTED some unknown error prevented resetting the component (unexpected) 641 */ 642 virtual c2_status_t reset() = 0; 643 644 /** 645 * Releases the component. 646 * 647 * This method MUST be supported in stopped state. 648 * 649 * This method MUST return withing 500ms. Upon return all references shall be abandoned. 650 * 651 * \retval C2_OK the component has been released 652 * \retval C2_DUPLICATE the component is already released 653 * \retval C2_BAD_STATE the component is running 654 * \retval C2_TIMED_OUT the component could not be released within the time limit (unexpected) 655 * \retval C2_CORRUPTED some unknown error prevented releasing the component (unexpected) 656 */ 657 virtual c2_status_t release() = 0; 658 659 /** 660 * Returns the interface for this component. 661 * 662 * \return the component interface 663 */ 664 virtual std::shared_ptr<C2ComponentInterface> intf() = 0; 665 666 virtual ~C2Component() = default; 667 }; 668 669 C2ENUM(C2Component::kind_t, uint32_t, 670 KIND_OTHER, 671 KIND_DECODER, 672 KIND_ENCODER 673 ); 674 675 C2ENUM(C2Component::domain_t, uint32_t, 676 DOMAIN_OTHER, 677 DOMAIN_VIDEO, 678 DOMAIN_AUDIO, 679 DOMAIN_IMAGE 680 ); 681 682 class C2FrameInfoParser { 683 public: 684 /** 685 * \return the content type supported by this info parser. 686 * 687 * \todo this may be redundant 688 */ 689 virtual C2StringLiteral getType() const = 0; 690 691 /** 692 * \return a vector of supported parameter indices parsed by this info parser. 693 * 694 * This method MUST be "non-blocking" and return within 1ms. 695 * 696 * \todo sticky vs. non-sticky params? this may be communicated by param-reflector. 697 */ 698 virtual const std::vector<C2Param::Index> getParsedParams() const = 0; 699 700 /** 701 * Resets this info parser. This brings this parser to its initial state after creation. 702 * 703 * This method SHALL return within 5ms. 704 * 705 * \retval C2_OK the info parser was reset 706 * \retval C2_TIMED_OUT could not reset the parser within the time limit (unexpected) 707 * \retval C2_CORRUPTED some unknown error prevented the resetting of the parser (unexpected) 708 */ reset()709 virtual c2_status_t reset() { return C2_OK; } 710 711 virtual c2_status_t parseFrame(C2FrameData &frame); 712 713 virtual ~C2FrameInfoParser() = default; 714 }; 715 716 class C2AllocatorStore { 717 public: 718 typedef C2Allocator::id_t id_t; 719 720 enum : C2Allocator::id_t { 721 DEFAULT_LINEAR, ///< basic linear allocator type 722 DEFAULT_GRAPHIC, ///< basic graphic allocator type 723 PLATFORM_START = 0x10, 724 VENDOR_START = 0x100, 725 BAD_ID = C2Allocator::BAD_ID, ///< DO NOT USE 726 }; 727 728 /** 729 * Returns the unique name of this allocator store. 730 * 731 * This method MUST be "non-blocking" and return within 1ms. 732 * 733 * \return the name of this allocator store. 734 * \retval an empty string if there was not enough memory to allocate the actual name. 735 */ 736 virtual C2String getName() const = 0; 737 738 /** 739 * Returns the set of allocators supported by this allocator store. 740 * 741 * This method MUST be "non-blocking" and return within 1ms. 742 * 743 * \retval vector of allocator information (as shared pointers) 744 * \retval an empty vector if there was not enough memory to allocate the whole vector. 745 */ 746 virtual std::vector<std::shared_ptr<const C2Allocator::Traits>> listAllocators_nb() const = 0; 747 748 /** 749 * Retrieves/creates a shared allocator object. 750 * 751 * This method MUST be return within 5ms. 752 * 753 * The allocator is created on first use, and the same allocator is returned on subsequent 754 * concurrent uses in the same process. The allocator is freed when it is no longer referenced. 755 * 756 * \param id the ID of the allocator to create. This is defined by the store, but 757 * the ID of the default linear and graphic allocators is formalized. 758 * \param allocator shared pointer where the created allocator is stored. Cleared on failure 759 * and updated on success. 760 * 761 * \retval C2_OK the allocator was created successfully 762 * \retval C2_TIMED_OUT could not create the allocator within the time limit (unexpected) 763 * \retval C2_CORRUPTED some unknown error prevented the creation of the allocator (unexpected) 764 * 765 * \retval C2_NOT_FOUND no such allocator 766 * \retval C2_NO_MEMORY not enough memory to create the allocator 767 */ 768 virtual c2_status_t fetchAllocator(id_t id, std::shared_ptr<C2Allocator>* const allocator) = 0; 769 770 virtual ~C2AllocatorStore() = default; 771 }; 772 773 class C2ComponentStore { 774 public: 775 /** 776 * Returns the name of this component or component interface object. 777 * This is a unique name for this component or component interface 'class'; however, multiple 778 * instances of this component SHALL have the same name. 779 * 780 * This method MUST be supported in any state. This call does not change the state nor the 781 * internal states of the component. 782 * 783 * This method MUST be "non-blocking" and return within 1ms. 784 * 785 * \return the name of this component or component interface object. 786 * \retval an empty string if there was not enough memory to allocate the actual name. 787 */ 788 virtual C2String getName() const = 0; 789 790 /** 791 * Creates a component. 792 * 793 * This method SHALL return within 100ms. 794 * 795 * \param name name of the component to create 796 * \param component shared pointer where the created component is stored. Cleared on 797 * failure and updated on success. 798 * 799 * \retval C2_OK the component was created successfully 800 * \retval C2_TIMED_OUT could not create the component within the time limit (unexpected) 801 * \retval C2_CORRUPTED some unknown error prevented the creation of the component (unexpected) 802 * 803 * \retval C2_NOT_FOUND no such component 804 * \retval C2_NO_MEMORY not enough memory to create the component 805 */ 806 virtual c2_status_t createComponent( 807 C2String name, std::shared_ptr<C2Component>* const component) = 0; 808 809 /** 810 * Creates a component interface. 811 * 812 * This method SHALL return within 100ms. 813 * 814 * \param name name of the component interface to create 815 * \param interface shared pointer where the created interface is stored 816 * 817 * \retval C2_OK the component interface was created successfully 818 * \retval C2_TIMED_OUT could not create the component interface within the time limit 819 * (unexpected) 820 * \retval C2_CORRUPTED some unknown error prevented the creation of the component interface 821 * (unexpected) 822 * 823 * \retval C2_NOT_FOUND no such component interface 824 * \retval C2_NO_MEMORY not enough memory to create the component interface 825 * 826 * \todo Do we need an interface, or could this just be a component that is never started? 827 */ 828 virtual c2_status_t createInterface( 829 C2String name, std::shared_ptr<C2ComponentInterface>* const interface) = 0; 830 831 /** 832 * Returns the list of components supported by this component store. 833 * 834 * This method MUST return within 500ms. 835 * 836 * \retval vector of component information. 837 */ 838 virtual std::vector<std::shared_ptr<const C2Component::Traits>> listComponents() = 0; 839 840 // -------------------------------------- UTILITY METHODS -------------------------------------- 841 842 // on-demand buffer layout conversion (swizzling) 843 // 844 virtual c2_status_t copyBuffer( 845 std::shared_ptr<C2GraphicBuffer> src, std::shared_ptr<C2GraphicBuffer> dst) = 0; 846 847 // -------------------------------------- CONFIGURATION API ----------------------------------- 848 // e.g. for global settings (system-wide stride, etc.) 849 850 /** 851 * Queries a set of system-wide parameters. 852 * Querying is performed at best effort: the store SHALL query all supported parameters and 853 * skip unsupported ones, or heap allocated parameters that could not be allocated. Any errors 854 * are communicated in the return value. Additionally, preallocated (e.g. stack) parameters that 855 * could not be queried are invalidated. Parameters to be allocated on the heap are omitted from 856 * the result. 857 * 858 * \note Parameter values do not depend on the order of query. 859 * 860 * This method may be momentarily blocking, but MUST return within 5ms. 861 * 862 * \param stackParams a list of params queried. These are initialized specific to each 863 * setting; e.g. size and index are set and rest of the members are 864 * cleared. 865 * NOTE: Flexible settings that are of incorrect size will be invalidated. 866 * \param heapParamIndices a vector of param indices for params to be queried and returned on the 867 * heap. These parameters will be returned in heapParams. Unsupported param 868 * indices will be ignored. 869 * \param heapParams a list of params where to which the supported heap parameters will be 870 * appended in the order they appear in heapParamIndices. 871 * 872 * \retval C2_OK all parameters could be queried 873 * \retval C2_BAD_INDEX all supported parameters could be queried, but some parameters were not 874 * supported 875 * \retval C2_NO_MEMORY could not allocate memory for a supported parameter 876 * \retval C2_CORRUPTED some unknown error prevented the querying of the parameters 877 * (unexpected) 878 */ 879 virtual c2_status_t query_sm( 880 const std::vector<C2Param*> &stackParams, 881 const std::vector<C2Param::Index> &heapParamIndices, 882 std::vector<std::unique_ptr<C2Param>>* const heapParams) const = 0; 883 884 /** 885 * Sets a set of system-wide parameters. 886 * 887 * \note There are no settable system-wide parameters defined thus far, but may be added in the 888 * future. 889 * 890 * Tuning is performed at best effort: the store SHALL update all supported configuration at 891 * best effort (unless configured otherwise) and skip unsupported ones. Any errors are 892 * communicated in the return value and in |failures|. 893 * 894 * \note Parameter tuning DOES depend on the order of the tuning parameters. E.g. some parameter 895 * update may allow some subsequent parameter update. 896 * 897 * This method may be momentarily blocking, but MUST return within 5ms. 898 * 899 * \param params a list of parameter updates. These will be updated to the actual 900 * parameter values after the updates (this is because tuning is performed 901 * at best effort). 902 * \todo params that could not be updated are not marked here, so are 903 * confusing - are they "existing" values or intended to be configured 904 * values? 905 * \param failures a list of parameter failures 906 * 907 * \retval C2_OK all parameters could be updated successfully 908 * \retval C2_BAD_INDEX all supported parameters could be updated successfully, but some 909 * parameters were not supported 910 * \retval C2_BAD_VALUE some supported parameters could not be updated successfully because 911 * they contained unsupported values. These are returned in |failures|. 912 * \retval C2_NO_MEMORY some supported parameters could not be updated successfully because 913 * they contained unsupported values, but could not allocate a failure 914 * object for them. 915 * \retval C2_CORRUPTED some unknown error prevented the update of the parameters 916 * (unexpected) 917 */ 918 virtual c2_status_t config_sm( 919 const std::vector<C2Param*> ¶ms, 920 std::vector<std::unique_ptr<C2SettingResult>>* const failures) = 0; 921 922 // REFLECTION MECHANISM (USED FOR EXTENSION) 923 // ============================================================================================= 924 925 /** 926 * Returns the parameter reflector. 927 * 928 * This is used to describe parameter fields. This is shared for all components created by 929 * this component store. 930 * 931 * This method MUST be "non-blocking" and return within 1ms. 932 * 933 * \return a shared parameter reflector object. 934 */ 935 virtual std::shared_ptr<C2ParamReflector> getParamReflector() const = 0; 936 937 /** 938 * Returns the set of supported parameters. 939 * 940 * This method MUST be "non-blocking" and return within 1ms. 941 * 942 * \param[out] params a vector of supported parameters will be appended to this vector. 943 * 944 * \retval C2_OK the operation completed successfully. 945 * \retval C2_NO_MEMORY not enough memory to complete this method. 946 */ 947 virtual c2_status_t querySupportedParams_nb( 948 std::vector<std::shared_ptr<C2ParamDescriptor>> * const params) const = 0; 949 950 /** 951 * Retrieves the supported values for the queried fields. 952 * 953 * Client SHALL set the parameter-field specifier and the type of supported values query (e.g. 954 * currently supported values, or potential supported values) in fields. 955 * Upon return the store SHALL fill in the supported values for the fields listed as well 956 * as a status for each field. Store shall process all fields queried even if some queries 957 * fail. 958 * 959 * This method may be momentarily blocking, but MUST return within 5ms. 960 * 961 * \param[in out] fields a vector of fields descriptor structures. 962 * 963 * \retval C2_OK the operation completed successfully. 964 * \retval C2_BAD_INDEX at least one field was not recognized as a component store field 965 */ 966 virtual c2_status_t querySupportedValues_sm( 967 std::vector<C2FieldSupportedValuesQuery> &fields) const = 0; 968 969 virtual ~C2ComponentStore() = default; 970 }; 971 972 // ================================================================================================ 973 974 /// @} 975 976 #endif // C2COMPONENT_H_ 977