Home | History | Annotate | Download | only in include
      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 
     49     C2FieldSupportedValuesQuery(const C2ParamField &field_, type_t type_)
     50         : _mField(field_), _mType(type_), status(C2_NO_INIT) { }
     51 
     52     static C2FieldSupportedValuesQuery
     53     Current(const C2ParamField &field_) {
     54         return C2FieldSupportedValuesQuery(field_, CURRENT);
     55     }
     56 
     57     static C2FieldSupportedValuesQuery
     58     Possible(const C2ParamField &field_) {
     59         return C2FieldSupportedValuesQuery(field_, POSSIBLE);
     60     }
     61 
     62     inline C2ParamField field() const { return _mField; };
     63 
     64     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*> &params,
    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 
    413         /**
    414          * name alias(es) for backward compatibility.
    415          * \note Multiple components can have the same alias as long as their media-type differs.
    416          */
    417         std::vector<C2StringLiteral> aliases; ///< name aliases for backward compatibility
    418     };
    419 
    420     // METHODS AVAILABLE WHEN RUNNING
    421     // =============================================================================================
    422 
    423     /**
    424      * Queues up work for the component.
    425      *
    426      * This method MUST be supported in running (including tripped and error) states.
    427      *
    428      * This method MUST be "non-blocking" and return within 1 ms
    429      *
    430      * It is acceptable for this method to return OK and return an error value using the
    431      * onWorkDone() callback.
    432      *
    433      * \retval C2_OK        the work was successfully queued
    434      * \retval C2_BAD_INDEX some component(s) in the work do(es) not exist
    435      * \retval C2_CANNOT_DO the components are not tunneled
    436      * \retval C2_BAD_STATE when called in the stopped or released state (user error)
    437      *
    438      * \retval C2_NO_MEMORY not enough memory to queue the work
    439      * \retval C2_CORRUPTED some unknown error prevented queuing the work (unexpected)
    440      */
    441     virtual c2_status_t queue_nb(std::list<std::unique_ptr<C2Work>>* const items) = 0;
    442 
    443     /**
    444      * Announces a work to be queued later for the component. This reserves a slot for the queue
    445      * to ensure correct work ordering even if the work is queued later.
    446      *
    447      * This method MUST be supported in running (including tripped and error) states.
    448      *
    449      * This method MUST be "non-blocking" and return within 1 ms
    450      *
    451      * \retval C2_OK        the work announcement has been successfully recorded
    452      * \retval C2_BAD_INDEX some component(s) in the work outline do(es) not exist
    453      * \retval C2_CANNOT_DO the componentes are not tunneled
    454      * \retval C2_BAD_STATE when called in the stopped or released state (user error)
    455      *
    456      * \retval C2_NO_MEMORY not enough memory to record the work announcement
    457      * \retval C2_CORRUPTED some unknown error prevented recording the announcement (unexpected)
    458      *
    459      * \todo Can this be rolled into queue_nb?
    460      * \todo Expose next work item for each component to detect stalls
    461      */
    462     virtual c2_status_t announce_nb(const std::vector<C2WorkOutline> &items) = 0;
    463 
    464     enum flush_mode_t : uint32_t {
    465         /// flush work from this component only
    466         FLUSH_COMPONENT,
    467 
    468         /// flush work from this component and all components connected downstream from it via
    469         /// tunneling
    470         FLUSH_CHAIN = (1 << 16),
    471     };
    472 
    473     /**
    474      * Discards and abandons any pending work for the component, and optionally any component
    475      * downstream.
    476      *
    477      * \todo define this: we could flush all work before last item queued for component across all
    478      *                    components linked to this; flush only work items that are queued to this
    479      *                    component
    480      * \todo return work # of last flushed item; or all flushed (but not returned items)
    481      * \todo we could make flush take a work item and flush all work before/after that item to allow
    482      *       TBD (slicing/seek?)
    483      * \todo we could simply take a list of numbers and flush those... this is bad for decoders
    484      *       also, what would happen to fine grade references?
    485      *
    486      * This method MUST be supported in running (including tripped and error) states.
    487      *
    488      * This method may be momentarily blocking, but must return within 5ms.
    489      *
    490      * Work that could be immediately abandoned/discarded SHALL be returned in |flushedWork|; this
    491      * can be done in an arbitrary order.
    492      *
    493      * Work that could not be abandoned or discarded immediately SHALL be marked to be
    494      * discarded at the earliest opportunity, and SHALL be returned via the onWorkDone() callback.
    495      * This shall be completed within 500ms.
    496      *
    497      * \param mode flush mode
    498      *
    499      * \retval C2_OK        the component has been successfully flushed
    500      * \retval C2_BAD_STATE when called in the stopped or released state (user error)
    501      * \retval C2_TIMED_OUT the flush could not be completed within the time limit (unexpected)
    502      * \retval C2_CORRUPTED some unknown error prevented flushing from completion (unexpected)
    503      */
    504     virtual c2_status_t flush_sm(flush_mode_t mode, std::list<std::unique_ptr<C2Work>>* const flushedWork) = 0;
    505 
    506     enum drain_mode_t : uint32_t {
    507         /// drain component only and add an "end-of-stream" marker. Component shall process all
    508         /// queued work and complete the current stream. If new input is received, it shall start
    509         /// a new stream. \todo define what a stream is.
    510         DRAIN_COMPONENT_WITH_EOS,
    511         /// drain component without setting "end-of-stream" marker. Component shall process all
    512         /// queued work but shall expect more work items for the same stream.
    513         DRAIN_COMPONENT_NO_EOS = (1 << 0),
    514 
    515         /// marks the last work item with a persistent "end-of-stream" marker that will drain
    516         /// downstream components
    517         /// \todo this may confuse work-ordering downstream
    518         DRAIN_CHAIN = (1 << 16),
    519 
    520         /**
    521          * \todo define this; we could place EOS to all upstream components, just this component, or
    522          *       all upstream and downstream component.
    523          * \todo should EOS carry over to downstream components?
    524          */
    525     };
    526 
    527     /**
    528      * Drains the component, and optionally downstream components. This is a signalling method;
    529      * as such it does not wait for any work completion.
    530      *
    531      * Marks last work item as "drain-till-here", so component is notified not to wait for further
    532      * work before it processes work already queued. This method can also used to set the
    533      * end-of-stream flag after work has been queued. Client can continue to queue further work
    534      * immediately after this method returns.
    535      *
    536      * This method MUST be supported in running (including tripped) states.
    537      *
    538      * This method MUST be "non-blocking" and return within 1ms.
    539      *
    540      * Work that is completed SHALL be returned via the onWorkDone() callback.
    541      *
    542      * \param mode drain mode
    543      *
    544      * \retval C2_OK        the drain request has been successfully recorded
    545      * \retval C2_BAD_STATE when called in the stopped or released state (user error)
    546      * \retval C2_BAD_VALUE the drain mode is not supported by the component
    547      *                      \todo define supported modes discovery
    548      * \retval C2_TIMED_OUT the flush could not be completed within the time limit (unexpected)
    549      * \retval C2_CORRUPTED some unknown error prevented flushing from completion (unexpected)
    550      */
    551     virtual c2_status_t drain_nb(drain_mode_t mode) = 0;
    552 
    553     // STATE CHANGE METHODS
    554     // =============================================================================================
    555 
    556     /**
    557      * Starts the component.
    558      *
    559      * This method MUST be supported in stopped state, as well as during the tripped state.
    560      *
    561      * If the return value is C2_OK, the component shall be in the running state.
    562      * If the return value is C2_BAD_STATE or C2_DUPLICATE, no state change is expected as a
    563      * response to this call.
    564      * Otherwise, the component shall be in the stopped state.
    565      *
    566      * \note If a component is in the tripped state and start() is called while the component
    567      * configuration still results in a trip, start shall succeed and a new onTripped callback
    568      * should be used to communicate the configuration conflict that results in the new trip.
    569      *
    570      * \todo This method MUST return within 500ms. Seems this should be able to return quickly, as
    571      * there are no immediate guarantees. Though there are guarantees for responsiveness immediately
    572      * after start returns.
    573      *
    574      * \retval C2_OK        the component has started (or resumed) successfully
    575      * \retval C2_DUPLICATE when called during another start call from another thread
    576      * \retval C2_BAD_STATE when called in any state other than the stopped state or tripped state,
    577      *                      including when called during another state change call from another
    578      *                      thread (user error)
    579      * \retval C2_NO_MEMORY not enough memory to start the component
    580      * \retval C2_TIMED_OUT the component could not be started within the time limit (unexpected)
    581      * \retval C2_CORRUPTED some unknown error prevented starting the component (unexpected)
    582      */
    583     virtual c2_status_t start() = 0;
    584 
    585     /**
    586      * Stops the component.
    587      *
    588      * This method MUST be supported in running (including tripped) state.
    589      *
    590      * This method MUST return withing 500ms.
    591      *
    592      * Upon this call, all pending work SHALL be abandoned and all buffer references SHALL be
    593      * released.
    594      * If the return value is C2_BAD_STATE or C2_DUPLICATE, no state change is expected as a
    595      * response to this call.
    596      * For all other return values, the component shall be in the stopped state.
    597      *
    598      * \todo should this return completed work, since client will just free it? Perhaps just to
    599      * verify accounting.
    600      *
    601      * This does not alter any settings and tunings that may have resulted in a tripped state.
    602      * (Is this material given the definition? Perhaps in case we want to start again.)
    603      *
    604      * \retval C2_OK        the component has started successfully
    605      * \retval C2_DUPLICATE when called during another stop call from another thread
    606      * \retval C2_BAD_STATE when called in any state other than the running state, including when
    607      *                      called during another state change call from another thread (user error)
    608      * \retval C2_TIMED_OUT the component could not be stopped within the time limit (unexpected)
    609      * \retval C2_CORRUPTED some unknown error prevented stopping the component (unexpected)
    610      */
    611     virtual c2_status_t stop() = 0;
    612 
    613     /**
    614      * Resets the component.
    615      *
    616      * This method MUST be supported in all (including tripped) states other than released.
    617      *
    618      * This method MUST be supported during any other blocking call.
    619      *
    620      * This method MUST return withing 500ms.
    621      *
    622      * After this call returns all work SHALL be abandoned, all buffer references SHALL be released.
    623      * If the return value is C2_BAD_STATE or C2_DUPLICATE, no state change is expected as a
    624      * response to this call.
    625      * For all other return values, the component shall be in the stopped state.
    626      *
    627      * \todo should this return completed work, since client will just free it? Also, if it unblocks
    628      * a stop, where should completed work be returned?
    629      *
    630      * This brings settings back to their default - "guaranteeing" no tripped space.
    631      *
    632      * \todo reclaim support - it seems that since ownership is passed, this will allow reclaiming
    633      * stuff.
    634      *
    635      * \retval C2_OK        the component has been reset
    636      * \retval C2_DUPLICATE when called during another reset call from another thread
    637      * \retval C2_BAD_STATE when called in the released state
    638      * \retval C2_TIMED_OUT the component could not be reset within the time limit (unexpected)
    639      * \retval C2_CORRUPTED some unknown error prevented resetting the component (unexpected)
    640      */
    641     virtual c2_status_t reset() = 0;
    642 
    643     /**
    644      * Releases the component.
    645      *
    646      * This method MUST be supported in stopped state.
    647      *
    648      * This method MUST return withing 500ms. Upon return all references shall be abandoned.
    649      *
    650      * \retval C2_OK        the component has been released
    651      * \retval C2_DUPLICATE the component is already released
    652      * \retval C2_BAD_STATE the component is running
    653      * \retval C2_TIMED_OUT the component could not be released within the time limit (unexpected)
    654      * \retval C2_CORRUPTED some unknown error prevented releasing the component (unexpected)
    655      */
    656     virtual c2_status_t release() = 0;
    657 
    658     /**
    659      * Returns the interface for this component.
    660      *
    661      * \return the component interface
    662      */
    663     virtual std::shared_ptr<C2ComponentInterface> intf() = 0;
    664 
    665     virtual ~C2Component() = default;
    666 };
    667 
    668 C2ENUM(C2Component::kind_t, uint32_t,
    669     KIND_OTHER,
    670     KIND_DECODER,
    671     KIND_ENCODER
    672 );
    673 
    674 C2ENUM(C2Component::domain_t, uint32_t,
    675     DOMAIN_OTHER,
    676     DOMAIN_VIDEO,
    677     DOMAIN_AUDIO,
    678     DOMAIN_IMAGE
    679 );
    680 
    681 class C2FrameInfoParser {
    682 public:
    683     /**
    684      * \return the content type supported by this info parser.
    685      *
    686      * \todo this may be redundant
    687      */
    688     virtual C2StringLiteral getType() const = 0;
    689 
    690     /**
    691      * \return a vector of supported parameter indices parsed by this info parser.
    692      *
    693      * This method MUST be "non-blocking" and return within 1ms.
    694      *
    695      * \todo sticky vs. non-sticky params? this may be communicated by param-reflector.
    696      */
    697     virtual const std::vector<C2Param::Index> getParsedParams() const = 0;
    698 
    699     /**
    700      * Resets this info parser. This brings this parser to its initial state after creation.
    701      *
    702      * This method SHALL return within 5ms.
    703      *
    704      * \retval C2_OK        the info parser was reset
    705      * \retval C2_TIMED_OUT could not reset the parser within the time limit (unexpected)
    706      * \retval C2_CORRUPTED some unknown error prevented the resetting of the parser (unexpected)
    707      */
    708     virtual c2_status_t reset() { return C2_OK; }
    709 
    710     virtual c2_status_t parseFrame(C2FrameData &frame);
    711 
    712     virtual ~C2FrameInfoParser() = default;
    713 };
    714 
    715 class C2AllocatorStore {
    716 public:
    717     typedef C2Allocator::id_t id_t;
    718 
    719     enum : C2Allocator::id_t {
    720         DEFAULT_LINEAR,     ///< basic linear allocator type
    721         DEFAULT_GRAPHIC,    ///< basic graphic allocator type
    722         PLATFORM_START = 0x10,
    723         VENDOR_START   = 0x100,
    724         BAD_ID         = C2Allocator::BAD_ID, ///< DO NOT USE
    725     };
    726 
    727     /**
    728      * Returns the unique name of this allocator store.
    729      *
    730      * This method MUST be "non-blocking" and return within 1ms.
    731      *
    732      * \return the name of this allocator store.
    733      * \retval an empty string if there was not enough memory to allocate the actual name.
    734      */
    735     virtual C2String getName() const = 0;
    736 
    737     /**
    738      * Returns the set of allocators supported by this allocator store.
    739      *
    740      * This method MUST be "non-blocking" and return within 1ms.
    741      *
    742      * \retval vector of allocator information (as shared pointers)
    743      * \retval an empty vector if there was not enough memory to allocate the whole vector.
    744      */
    745     virtual std::vector<std::shared_ptr<const C2Allocator::Traits>> listAllocators_nb() const = 0;
    746 
    747     /**
    748      * Retrieves/creates a shared allocator object.
    749      *
    750      * This method MUST be return within 5ms.
    751      *
    752      * The allocator is created on first use, and the same allocator is returned on subsequent
    753      * concurrent uses in the same process. The allocator is freed when it is no longer referenced.
    754      *
    755      * \param id      the ID of the allocator to create. This is defined by the store, but
    756      *                the ID of the default linear and graphic allocators is formalized.
    757      * \param allocator shared pointer where the created allocator is stored. Cleared on failure
    758      *                  and updated on success.
    759      *
    760      * \retval C2_OK        the allocator was created successfully
    761      * \retval C2_TIMED_OUT could not create the allocator within the time limit (unexpected)
    762      * \retval C2_CORRUPTED some unknown error prevented the creation of the allocator (unexpected)
    763      *
    764      * \retval C2_NOT_FOUND no such allocator
    765      * \retval C2_NO_MEMORY not enough memory to create the allocator
    766      */
    767     virtual c2_status_t fetchAllocator(id_t id, std::shared_ptr<C2Allocator>* const allocator) = 0;
    768 
    769     virtual ~C2AllocatorStore() = default;
    770 };
    771 
    772 class C2ComponentStore {
    773 public:
    774     /**
    775      * Returns the name of this component or component interface object.
    776      * This is a unique name for this component or component interface 'class'; however, multiple
    777      * instances of this component SHALL have the same name.
    778      *
    779      * This method MUST be supported in any state. This call does not change the state nor the
    780      * internal states of the component.
    781      *
    782      * This method MUST be "non-blocking" and return within 1ms.
    783      *
    784      * \return the name of this component or component interface object.
    785      * \retval an empty string if there was not enough memory to allocate the actual name.
    786      */
    787     virtual C2String getName() const = 0;
    788 
    789     /**
    790      * Creates a component.
    791      *
    792      * This method SHALL return within 100ms.
    793      *
    794      * \param name          name of the component to create
    795      * \param component     shared pointer where the created component is stored. Cleared on
    796      *                      failure and updated on success.
    797      *
    798      * \retval C2_OK        the component was created successfully
    799      * \retval C2_TIMED_OUT could not create the component within the time limit (unexpected)
    800      * \retval C2_CORRUPTED some unknown error prevented the creation of the component (unexpected)
    801      *
    802      * \retval C2_NOT_FOUND no such component
    803      * \retval C2_NO_MEMORY not enough memory to create the component
    804      */
    805     virtual c2_status_t createComponent(
    806             C2String name, std::shared_ptr<C2Component>* const component) = 0;
    807 
    808     /**
    809      * Creates a component interface.
    810      *
    811      * This method SHALL return within 100ms.
    812      *
    813      * \param name          name of the component interface to create
    814      * \param interface     shared pointer where the created interface is stored
    815      *
    816      * \retval C2_OK        the component interface was created successfully
    817      * \retval C2_TIMED_OUT could not create the component interface within the time limit
    818      *                      (unexpected)
    819      * \retval C2_CORRUPTED some unknown error prevented the creation of the component interface
    820      *                      (unexpected)
    821      *
    822      * \retval C2_NOT_FOUND no such component interface
    823      * \retval C2_NO_MEMORY not enough memory to create the component interface
    824      *
    825      * \todo Do we need an interface, or could this just be a component that is never started?
    826      */
    827     virtual c2_status_t createInterface(
    828             C2String name, std::shared_ptr<C2ComponentInterface>* const interface) = 0;
    829 
    830     /**
    831      * Returns the list of components supported by this component store.
    832      *
    833      * This method MUST return within 500ms.
    834      *
    835      * \retval vector of component information.
    836      */
    837     virtual std::vector<std::shared_ptr<const C2Component::Traits>> listComponents() = 0;
    838 
    839     // -------------------------------------- UTILITY METHODS --------------------------------------
    840 
    841     // on-demand buffer layout conversion (swizzling)
    842     //
    843     virtual c2_status_t copyBuffer(
    844             std::shared_ptr<C2GraphicBuffer> src, std::shared_ptr<C2GraphicBuffer> dst) = 0;
    845 
    846     // -------------------------------------- CONFIGURATION API -----------------------------------
    847     // e.g. for global settings (system-wide stride, etc.)
    848 
    849     /**
    850      * Queries a set of system-wide parameters.
    851      * Querying is performed at best effort: the store SHALL query all supported parameters and
    852      * skip unsupported ones, or heap allocated parameters that could not be allocated. Any errors
    853      * are communicated in the return value. Additionally, preallocated (e.g. stack) parameters that
    854      * could not be queried are invalidated. Parameters to be allocated on the heap are omitted from
    855      * the result.
    856      *
    857      * \note Parameter values do not depend on the order of query.
    858      *
    859      * This method may be momentarily blocking, but MUST return within 5ms.
    860      *
    861      * \param stackParams   a list of params queried. These are initialized specific to each
    862      *                      setting; e.g. size and index are set and rest of the members are
    863      *                      cleared.
    864      *                      NOTE: Flexible settings that are of incorrect size will be invalidated.
    865      * \param heapParamIndices a vector of param indices for params to be queried and returned on the
    866      *                      heap. These parameters will be returned in heapParams. Unsupported param
    867      *                      indices will be ignored.
    868      * \param heapParams    a list of params where to which the supported heap parameters will be
    869      *                      appended in the order they appear in heapParamIndices.
    870      *
    871      * \retval C2_OK        all parameters could be queried
    872      * \retval C2_BAD_INDEX all supported parameters could be queried, but some parameters were not
    873      *                      supported
    874      * \retval C2_NO_MEMORY could not allocate memory for a supported parameter
    875      * \retval C2_CORRUPTED some unknown error prevented the querying of the parameters
    876      *                      (unexpected)
    877      */
    878     virtual c2_status_t query_sm(
    879         const std::vector<C2Param*> &stackParams,
    880         const std::vector<C2Param::Index> &heapParamIndices,
    881         std::vector<std::unique_ptr<C2Param>>* const heapParams) const = 0;
    882 
    883     /**
    884      * Sets a set of system-wide parameters.
    885      *
    886      * \note There are no settable system-wide parameters defined thus far, but may be added in the
    887      * future.
    888      *
    889      * Tuning is performed at best effort: the store SHALL update all supported configuration at
    890      * best effort (unless configured otherwise) and skip unsupported ones. Any errors are
    891      * communicated in the return value and in |failures|.
    892      *
    893      * \note Parameter tuning DOES depend on the order of the tuning parameters. E.g. some parameter
    894      * update may allow some subsequent parameter update.
    895      *
    896      * This method may be momentarily blocking, but MUST return within 5ms.
    897      *
    898      * \param params        a list of parameter updates. These will be updated to the actual
    899      *                      parameter values after the updates (this is because tuning is performed
    900      *                      at best effort).
    901      *                      \todo params that could not be updated are not marked here, so are
    902      *                      confusing - are they "existing" values or intended to be configured
    903      *                      values?
    904      * \param failures      a list of parameter failures
    905      *
    906      * \retval C2_OK        all parameters could be updated successfully
    907      * \retval C2_BAD_INDEX all supported parameters could be updated successfully, but some
    908      *                      parameters were not supported
    909      * \retval C2_BAD_VALUE some supported parameters could not be updated successfully because
    910      *                      they contained unsupported values. These are returned in |failures|.
    911      * \retval C2_NO_MEMORY some supported parameters could not be updated successfully because
    912      *                      they contained unsupported values, but could not allocate a failure
    913      *                      object for them.
    914      * \retval C2_CORRUPTED some unknown error prevented the update of the parameters
    915      *                      (unexpected)
    916      */
    917     virtual c2_status_t config_sm(
    918             const std::vector<C2Param*> &params,
    919             std::vector<std::unique_ptr<C2SettingResult>>* const failures) = 0;
    920 
    921     // REFLECTION MECHANISM (USED FOR EXTENSION)
    922     // =============================================================================================
    923 
    924     /**
    925      * Returns the parameter reflector.
    926      *
    927      * This is used to describe parameter fields. This is shared for all components created by
    928      * this component store.
    929      *
    930      * This method MUST be "non-blocking" and return within 1ms.
    931      *
    932      * \return a shared parameter reflector object.
    933      */
    934     virtual std::shared_ptr<C2ParamReflector> getParamReflector() const = 0;
    935 
    936     /**
    937      * Returns the set of supported parameters.
    938      *
    939      * This method MUST be "non-blocking" and return within 1ms.
    940      *
    941      * \param[out] params a vector of supported parameters will be appended to this vector.
    942      *
    943      * \retval C2_OK        the operation completed successfully.
    944      * \retval C2_NO_MEMORY not enough memory to complete this method.
    945      */
    946     virtual c2_status_t querySupportedParams_nb(
    947             std::vector<std::shared_ptr<C2ParamDescriptor>> * const params) const = 0;
    948 
    949     /**
    950      * Retrieves the supported values for the queried fields.
    951      *
    952      * Client SHALL set the parameter-field specifier and the type of supported values query (e.g.
    953      * currently supported values, or potential supported values) in fields.
    954      * Upon return the store SHALL fill in the supported values for the fields listed as well
    955      * as a status for each field. Store shall process all fields queried even if some queries
    956      * fail.
    957      *
    958      * This method may be momentarily blocking, but MUST return within 5ms.
    959      *
    960      * \param[in out] fields a vector of fields descriptor structures.
    961      *
    962      * \retval C2_OK        the operation completed successfully.
    963      * \retval C2_BAD_INDEX at least one field was not recognized as a component store field
    964      */
    965     virtual c2_status_t querySupportedValues_sm(
    966             std::vector<C2FieldSupportedValuesQuery> &fields) const = 0;
    967 
    968     virtual ~C2ComponentStore() = default;
    969 };
    970 
    971 // ================================================================================================
    972 
    973 /// @}
    974 
    975 #endif  // C2COMPONENT_H_
    976