2017-11-21 19:34:37 +01:00
|
|
|
/* Simple Plugin API
|
|
|
|
|
*
|
2018-11-05 17:48:52 +01:00
|
|
|
* Copyright © 2018 Wim Taymans
|
2017-11-21 19:34:37 +01:00
|
|
|
*
|
2018-11-05 17:48:52 +01:00
|
|
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
|
|
|
* copy of this software and associated documentation files (the "Software"),
|
|
|
|
|
* to deal in the Software without restriction, including without limitation
|
|
|
|
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
|
|
|
* and/or sell copies of the Software, and to permit persons to whom the
|
|
|
|
|
* Software is furnished to do so, subject to the following conditions:
|
2017-11-21 19:34:37 +01:00
|
|
|
*
|
2018-11-05 17:48:52 +01:00
|
|
|
* The above copyright notice and this permission notice (including the next
|
|
|
|
|
* paragraph) shall be included in all copies or substantial portions of the
|
|
|
|
|
* Software.
|
|
|
|
|
*
|
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
|
|
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
|
|
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
|
|
|
* DEALINGS IN THE SOFTWARE.
|
2017-11-21 19:34:37 +01:00
|
|
|
*/
|
|
|
|
|
|
2019-01-14 12:58:23 +01:00
|
|
|
#ifndef SPA_IO_H
|
|
|
|
|
#define SPA_IO_H
|
2017-11-21 19:34:37 +01:00
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
|
extern "C" {
|
|
|
|
|
#endif
|
|
|
|
|
|
2018-08-23 17:47:57 +02:00
|
|
|
#include <spa/utils/defs.h>
|
2018-08-25 12:08:29 +02:00
|
|
|
#include <spa/pod/pod.h>
|
2018-07-19 15:17:21 +02:00
|
|
|
|
2018-10-23 16:14:17 +02:00
|
|
|
/** IO areas
|
2017-11-21 19:34:37 +01:00
|
|
|
*
|
|
|
|
|
* IO information for a port on a node. This is allocated
|
2018-10-23 16:14:17 +02:00
|
|
|
* by the host and configured on a node or all ports for which
|
|
|
|
|
* IO is requested.
|
2017-11-21 19:34:37 +01:00
|
|
|
*/
|
2018-08-23 17:47:57 +02:00
|
|
|
|
2018-08-25 12:08:29 +02:00
|
|
|
/** Different IO area types */
|
|
|
|
|
enum spa_io_type {
|
2018-08-29 18:08:52 +02:00
|
|
|
SPA_IO_Invalid,
|
2018-10-23 16:14:17 +02:00
|
|
|
SPA_IO_Buffers, /**< area to exchange buffers */
|
|
|
|
|
SPA_IO_Range, /**< expected byte range */
|
|
|
|
|
SPA_IO_Clock, /**< area to update clock information */
|
|
|
|
|
SPA_IO_Latency, /**< latency reporting */
|
|
|
|
|
SPA_IO_Control, /**< area for control messages */
|
|
|
|
|
SPA_IO_Notify, /**< area for notify messages */
|
|
|
|
|
SPA_IO_Position, /**< position information in the graph */
|
2019-07-09 16:56:05 +02:00
|
|
|
SPA_IO_RateMatch, /**< rate matching between nodes */
|
2018-08-25 12:08:29 +02:00
|
|
|
};
|
|
|
|
|
|
2017-11-21 19:34:37 +01:00
|
|
|
struct spa_io_buffers {
|
|
|
|
|
#define SPA_STATUS_OK 0
|
2019-09-16 12:55:23 +02:00
|
|
|
#define SPA_STATUS_NEED_DATA (1<<0)
|
|
|
|
|
#define SPA_STATUS_HAVE_DATA (1<<1)
|
2019-02-27 16:43:01 +01:00
|
|
|
#define SPA_STATUS_STOPPED (1<<2)
|
2017-11-21 19:34:37 +01:00
|
|
|
int32_t status; /**< the status code */
|
|
|
|
|
uint32_t buffer_id; /**< a buffer id */
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
#define SPA_IO_BUFFERS_INIT (struct spa_io_buffers) { SPA_STATUS_OK, SPA_ID_INVALID, }
|
|
|
|
|
|
|
|
|
|
/** A range, suitable for input ports that can suggest a range to output ports */
|
2018-08-28 18:16:41 +02:00
|
|
|
struct spa_io_range {
|
2017-11-21 19:34:37 +01:00
|
|
|
uint64_t offset; /**< offset in range */
|
|
|
|
|
uint32_t min_size; /**< minimum size of data */
|
|
|
|
|
uint32_t max_size; /**< maximum size of data */
|
|
|
|
|
};
|
|
|
|
|
|
2019-08-27 14:41:47 +02:00
|
|
|
/**
|
|
|
|
|
* Absolute time reporting.
|
|
|
|
|
*
|
|
|
|
|
* Nodes that can report clocking information will receive this io block.
|
|
|
|
|
* The application sets the id. This is usually set as part of the
|
|
|
|
|
* position information but can also be set separately.
|
|
|
|
|
*
|
|
|
|
|
* The clock counts the elapsed time according to the clock provider
|
|
|
|
|
* since the provider was last started.
|
|
|
|
|
*/
|
2018-07-17 09:50:51 +02:00
|
|
|
struct spa_io_clock {
|
2018-11-09 15:24:24 +01:00
|
|
|
uint32_t id; /**< unique clock id, set by application */
|
|
|
|
|
uint32_t flags; /**< clock flags */
|
2019-09-05 13:09:01 +02:00
|
|
|
uint64_t nsec; /**< time in nanoseconds against monotonic clock */
|
2019-08-27 14:41:47 +02:00
|
|
|
uint64_t count; /**< a media specific counter. Can be used to detect
|
|
|
|
|
* gaps in the media. It usually represents the amount
|
|
|
|
|
* of processed media units (packets, frames,
|
|
|
|
|
* samples, ...) */
|
|
|
|
|
struct spa_fraction rate; /**< rate for position/duration/delay */
|
2018-07-19 13:30:27 +02:00
|
|
|
uint64_t position; /**< current position */
|
2019-08-27 14:41:47 +02:00
|
|
|
uint64_t duration; /**< duration of current cycle */
|
2018-11-09 15:24:24 +01:00
|
|
|
int64_t delay; /**< delay between position and hardware,
|
|
|
|
|
* positive for capture, negative for playback */
|
|
|
|
|
double rate_diff; /**< rate difference between clock and monotonic time */
|
2019-08-27 14:41:47 +02:00
|
|
|
uint64_t next_nsec; /**< extimated next wakup time in nanoseconds */
|
2018-07-17 09:50:51 +02:00
|
|
|
};
|
|
|
|
|
|
2018-07-19 15:17:21 +02:00
|
|
|
/** latency reporting */
|
|
|
|
|
struct spa_io_latency {
|
|
|
|
|
struct spa_fraction rate; /**< rate for min/max */
|
|
|
|
|
uint64_t min; /**< min latency */
|
|
|
|
|
uint64_t max; /**< max latency */
|
|
|
|
|
};
|
|
|
|
|
|
2018-08-28 18:16:41 +02:00
|
|
|
/** control stream */
|
|
|
|
|
struct spa_io_sequence {
|
2018-08-25 12:08:29 +02:00
|
|
|
struct spa_pod_sequence sequence; /**< sequence of timed events */
|
|
|
|
|
};
|
|
|
|
|
|
2019-08-27 21:36:15 +02:00
|
|
|
/** bar and beat segment */
|
|
|
|
|
struct spa_io_segment_bar {
|
2019-08-29 18:21:32 +02:00
|
|
|
#define SPA_IO_SEGMENT_BAR_FLAG_VALID (1<<0)
|
|
|
|
|
uint32_t flags; /**< extra flags */
|
2019-09-02 12:05:05 +02:00
|
|
|
uint32_t offset; /**< offset in segment of this beat */
|
2019-08-27 14:41:47 +02:00
|
|
|
float signature_num; /**< time signature numerator */
|
|
|
|
|
float signature_denom; /**< time signature denominator */
|
2018-10-23 16:14:17 +02:00
|
|
|
double bpm; /**< beats per minute */
|
2019-08-27 21:36:15 +02:00
|
|
|
double beat; /**< current beat in segment */
|
2018-10-23 16:14:17 +02:00
|
|
|
uint32_t padding[16];
|
|
|
|
|
};
|
|
|
|
|
|
2019-08-27 21:36:15 +02:00
|
|
|
/** video frame segment */
|
|
|
|
|
struct spa_io_segment_video {
|
2019-08-29 18:21:32 +02:00
|
|
|
#define SPA_IO_SEGMENT_VIDEO_FLAG_VALID (1<<0)
|
|
|
|
|
#define SPA_IO_SEGMENT_VIDEO_FLAG_DROP_FRAME (1<<1)
|
|
|
|
|
#define SPA_IO_SEGMENT_VIDEO_FLAG_PULL_DOWN (1<<2)
|
|
|
|
|
#define SPA_IO_SEGMENT_VIDEO_FLAG_INTERLACED (1<<3)
|
2018-10-23 16:14:17 +02:00
|
|
|
uint32_t flags; /**< flags */
|
2019-09-02 12:05:05 +02:00
|
|
|
uint32_t offset; /**< offset in segment */
|
2019-08-29 18:21:32 +02:00
|
|
|
struct spa_fraction framerate;
|
2018-10-23 16:14:17 +02:00
|
|
|
uint32_t hours;
|
|
|
|
|
uint32_t minutes;
|
|
|
|
|
uint32_t seconds;
|
|
|
|
|
uint32_t frames;
|
|
|
|
|
uint32_t field_count; /**< 0 for progressive, 1 and 2 for interlaced */
|
2019-08-29 18:21:32 +02:00
|
|
|
uint32_t padding[17];
|
2018-10-23 16:14:17 +02:00
|
|
|
};
|
|
|
|
|
|
2019-08-27 21:36:15 +02:00
|
|
|
/**
|
2019-08-28 10:28:06 +02:00
|
|
|
* A segment converts a running time to a segment (stream) position.
|
2019-08-27 21:36:15 +02:00
|
|
|
*
|
2019-08-28 10:28:06 +02:00
|
|
|
* The segment position is valid when the current running time is between
|
2019-08-27 21:49:49 +02:00
|
|
|
* start and start + duration. The position is then
|
2019-08-27 21:36:15 +02:00
|
|
|
* calculated as:
|
|
|
|
|
*
|
2019-08-28 10:28:06 +02:00
|
|
|
* (running time - start) * rate + position;
|
2019-08-27 21:36:15 +02:00
|
|
|
*
|
2019-08-28 10:28:06 +02:00
|
|
|
* Support for looping is done by specifying the LOOPING flags with a
|
|
|
|
|
* non-zero duration. When the running time reaches start + duration,
|
|
|
|
|
* duration is added to start and the loop repeats.
|
2019-08-27 21:36:15 +02:00
|
|
|
*
|
2019-08-28 10:28:06 +02:00
|
|
|
* Care has to be taken when the running time + clock.duration extends
|
|
|
|
|
* past the start + duration from the segment; the user should correctly
|
2019-08-27 21:36:15 +02:00
|
|
|
* wrap around and partially repeat the loop in the current cycle.
|
|
|
|
|
*
|
|
|
|
|
* Extra information can be placed in the segment by setting the valid flags
|
|
|
|
|
* and filling up the corresponding structures.
|
|
|
|
|
*/
|
|
|
|
|
struct spa_io_segment {
|
2019-09-02 12:05:05 +02:00
|
|
|
uint32_t version;
|
|
|
|
|
#define SPA_IO_SEGMENT_FLAG_LOOPING (1<<0) /**< after the duration, the segment repeats */
|
|
|
|
|
#define SPA_IO_SEGMENT_FLAG_NO_POSITION (1<<1) /**< position is invalid. The position can be invalid
|
|
|
|
|
* after a seek, for example, when the exact mapping
|
|
|
|
|
* of the extra segment info (bar, video, ...) to
|
|
|
|
|
* position has not been determined yet */
|
|
|
|
|
uint32_t flags; /**< extra flags */
|
2019-08-28 10:28:06 +02:00
|
|
|
uint64_t start; /**< value of running time when this
|
2019-08-27 21:36:15 +02:00
|
|
|
* info is active. Can be in the future for
|
|
|
|
|
* pending changes. It does not have to be in
|
|
|
|
|
* exact multiples of the clock duration. */
|
2019-08-28 10:28:06 +02:00
|
|
|
uint64_t duration; /**< duration when this info becomes invalid expressed
|
|
|
|
|
* in running time. If the duration is 0, this
|
|
|
|
|
* segment extends to the next segment. If the
|
|
|
|
|
* segment becomes invalid and the looping flag is
|
|
|
|
|
* set, the segment repeats. */
|
2019-08-29 18:21:32 +02:00
|
|
|
double rate; /**< overal rate of the segment, can be negative for
|
2019-08-27 21:36:15 +02:00
|
|
|
* backwards time reporting. */
|
2019-08-29 18:21:32 +02:00
|
|
|
uint64_t position; /**< The position when the running time == start.
|
|
|
|
|
* can be invalid when the owner of the extra segment
|
|
|
|
|
* infomation has not yet made the mapping. */
|
2019-08-27 21:36:15 +02:00
|
|
|
|
2019-08-29 18:21:32 +02:00
|
|
|
struct spa_io_segment_bar bar;
|
|
|
|
|
struct spa_io_segment_video video;
|
2019-08-27 21:36:15 +02:00
|
|
|
};
|
|
|
|
|
|
2019-08-27 14:41:47 +02:00
|
|
|
enum spa_io_position_state {
|
|
|
|
|
SPA_IO_POSITION_STATE_STOPPED,
|
|
|
|
|
SPA_IO_POSITION_STATE_STARTING,
|
|
|
|
|
SPA_IO_POSITION_STATE_RUNNING,
|
|
|
|
|
};
|
|
|
|
|
|
2019-08-27 21:36:15 +02:00
|
|
|
/** the maximum number of segments visible in the future */
|
|
|
|
|
#define SPA_IO_POSITION_MAX_SEGMENTS 8
|
|
|
|
|
|
2019-08-27 14:41:47 +02:00
|
|
|
/**
|
|
|
|
|
* The position information adds extra meaning to the raw clock times.
|
|
|
|
|
*
|
|
|
|
|
* It is set on all nodes and the clock id will contain the clock of the
|
|
|
|
|
* master node in the graph.
|
|
|
|
|
*
|
2019-08-27 21:36:15 +02:00
|
|
|
* The position information contains 1 or more segments that convert the
|
|
|
|
|
* raw clock times to a stream time. They are sorted based on their
|
2019-08-27 21:49:49 +02:00
|
|
|
* start times, and thus the order in which they will activate in
|
2019-08-27 21:36:15 +02:00
|
|
|
* the future. This makes it possible to look ahead in the scheduled
|
|
|
|
|
* segments and anticipate the changes in the timeline.
|
2019-08-27 14:41:47 +02:00
|
|
|
*/
|
2018-10-23 16:14:17 +02:00
|
|
|
struct spa_io_position {
|
|
|
|
|
struct spa_io_clock clock; /**< clock position of driver, always valid and
|
|
|
|
|
* read only */
|
2019-08-28 10:28:06 +02:00
|
|
|
int64_t offset; /**< an offset to subtract from the clock position
|
|
|
|
|
* to get a running time. This is the time that
|
|
|
|
|
* the state has been in the RUNNING state and the
|
|
|
|
|
* time that should be used to compare the segment
|
|
|
|
|
* start values against. */
|
2019-08-27 14:41:47 +02:00
|
|
|
uint32_t state; /**< one of enum spa_io_position_state */
|
|
|
|
|
|
2019-08-27 21:36:15 +02:00
|
|
|
uint32_t n_segments; /**< number of segments */
|
|
|
|
|
struct spa_io_segment segments[SPA_IO_POSITION_MAX_SEGMENTS]; /**< segments */
|
2018-10-23 16:14:17 +02:00
|
|
|
};
|
2018-08-28 18:16:41 +02:00
|
|
|
|
2019-07-09 16:56:05 +02:00
|
|
|
/** rate matching */
|
|
|
|
|
struct spa_io_rate_match {
|
|
|
|
|
uint32_t delay; /**< extra delay in samples for resampler */
|
|
|
|
|
uint32_t size; /**< requested input size for resampler */
|
|
|
|
|
double rate; /**< rate for resampler */
|
|
|
|
|
};
|
|
|
|
|
|
2017-11-21 19:34:37 +01:00
|
|
|
#ifdef __cplusplus
|
|
|
|
|
} /* extern "C" */
|
|
|
|
|
#endif
|
|
|
|
|
|
2019-01-14 12:58:23 +01:00
|
|
|
#endif /* SPA_IO_H */
|