blob: 8810725790fd7b65747a7e28024b24cf678540dc [file] [log] [blame]
Pawin Vongmasa36653902018-11-15 00:10:25 -08001/*
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
36struct 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
42private:
43 C2ParamField _mField;
44 type_t _mType;
45public:
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
74class C2ComponentInterface {
75public:
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
333class C2Component {
334public:
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
668C2ENUM(C2Component::kind_t, uint32_t,
669 KIND_OTHER,
670 KIND_DECODER,
671 KIND_ENCODER
672);
673
674C2ENUM(C2Component::domain_t, uint32_t,
675 DOMAIN_OTHER,
676 DOMAIN_VIDEO,
677 DOMAIN_AUDIO,
678 DOMAIN_IMAGE
679);
680
681class C2FrameInfoParser {
682public:
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
715class C2AllocatorStore {
716public:
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
772class C2ComponentStore {
773public:
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_