1 /* Simple Plugin API 2 * 3 * Copyright © 2018 Wim Taymans 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the "Software"), 7 * to deal in the Software without restriction, including without limitation 8 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 * and/or sell copies of the Software, and to permit persons to whom the 10 * Software is furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice (including the next 13 * paragraph) shall be included in all copies or substantial portions of the 14 * Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 * DEALINGS IN THE SOFTWARE. 23 */ 24 25 #ifndef SPA_IO_H 26 #define SPA_IO_H 27 28 #ifdef __cplusplus 29 extern "C" { 30 #endif 31 32 #include <spa/utils/defs.h> 33 #include <spa/pod/pod.h> 34 35 /** IO areas 36 * 37 * IO information for a port on a node. This is allocated 38 * by the host and configured on a node or all ports for which 39 * IO is requested. 40 * 41 * The plugin will communicate with the host through the IO 42 * areas. 43 */ 44 45 /** Different IO area types */ 46 enum spa_io_type { 47 SPA_IO_Invalid, 48 SPA_IO_Buffers, /**< area to exchange buffers, struct spa_io_buffers */ 49 SPA_IO_Range, /**< expected byte range, struct spa_io_range */ 50 SPA_IO_Clock, /**< area to update clock information, struct spa_io_clock */ 51 SPA_IO_Latency, /**< latency reporting, struct spa_io_latency */ 52 SPA_IO_Control, /**< area for control messages, struct spa_io_sequence */ 53 SPA_IO_Notify, /**< area for notify messages, struct spa_io_sequence */ 54 SPA_IO_Position, /**< position information in the graph, struct spa_io_position */ 55 SPA_IO_RateMatch, /**< rate matching between nodes, struct spa_io_rate_match */ 56 SPA_IO_Memory, /**< memory pointer, struct spa_io_memory */ 57 }; 58 59 /** 60 * IO area to exchange buffers. 61 * 62 * A set of buffers should first be configured on the node/port. 63 * Further references to those buffers will be made by using the 64 * id of the buffer. 65 * 66 * If status is SPA_STATUS_OK, the host should ignore 67 * the io area. 68 * 69 * If status is SPA_STATUS_NEED_DATA, the host should: 70 * 1) recycle the buffer in buffer_id, if possible 71 * 2) prepare a new buffer and place the id in buffer_id. 72 * 73 * If status is SPA_STATUS_HAVE_DATA, the host should consume 74 * the buffer in buffer_id and set the state to 75 * SPA_STATUS_NEED_DATA when new data is requested. 76 * 77 * If status is SPA_STATUS_STOPPED, some error occurred on the 78 * port. 79 * 80 * If status is SPA_STATUS_DRAINED, data from the io area was 81 * used to drain. 82 * 83 * Status can also be a negative errno value to indicate errors. 84 * such as: 85 * -EINVAL: buffer_id is invalid 86 * -EPIPE: no more buffers available 87 */ 88 struct spa_io_buffers { 89 #define SPA_STATUS_OK 0 90 #define SPA_STATUS_NEED_DATA (1<<0) 91 #define SPA_STATUS_HAVE_DATA (1<<1) 92 #define SPA_STATUS_STOPPED (1<<2) 93 #define SPA_STATUS_DRAINED (1<<3) 94 int32_t status; /**< the status code */ 95 uint32_t buffer_id; /**< a buffer id */ 96 }; 97 98 #define SPA_IO_BUFFERS_INIT (struct spa_io_buffers) { SPA_STATUS_OK, SPA_ID_INVALID, } 99 100 /** 101 * IO area to exchange a memory region 102 */ 103 struct spa_io_memory { 104 int32_t status; /**< the status code */ 105 uint32_t size; /**< the size of \a data */ 106 void *data; /**< a memory pointer */ 107 }; 108 #define SPA_IO_MEMORY_INIT (struct spa_io_memory) { SPA_STATUS_OK, 0, NULL, } 109 110 /** A range, suitable for input ports that can suggest a range to output ports */ 111 struct spa_io_range { 112 uint64_t offset; /**< offset in range */ 113 uint32_t min_size; /**< minimum size of data */ 114 uint32_t max_size; /**< maximum size of data */ 115 }; 116 117 /** 118 * Absolute time reporting. 119 * 120 * Nodes that can report clocking information will receive this io block. 121 * The application sets the id. This is usually set as part of the 122 * position information but can also be set separately. 123 * 124 * The clock counts the elapsed time according to the clock provider 125 * since the provider was last started. 126 */ 127 struct spa_io_clock { 128 uint32_t flags; /**< clock flags */ 129 uint32_t id; /**< unique clock id, set by application */ 130 char name[64]; /**< clock name prefixed with API, set by node. The clock name 131 * is unique per clock and can be used to check if nodes 132 * share the same clock. */ 133 uint64_t nsec; /**< time in nanoseconds against monotonic clock */ 134 struct spa_fraction rate; /**< rate for position/duration/delay */ 135 uint64_t position; /**< current position */ 136 uint64_t duration; /**< duration of current cycle */ 137 int64_t delay; /**< delay between position and hardware, 138 * positive for capture, negative for playback */ 139 double rate_diff; /**< rate difference between clock and monotonic time */ 140 uint64_t next_nsec; /**< extimated next wakeup time in nanoseconds */ 141 uint32_t padding[8]; 142 }; 143 144 /* the size of the video in this cycle */ 145 struct spa_io_video_size { 146 #define SPA_IO_VIDEO_SIZE_VALID (1<<0) 147 uint32_t flags; /**< optional flags */ 148 uint32_t stride; /**< video stride in bytes */ 149 struct spa_rectangle size; /**< the video size */ 150 struct spa_fraction framerate; /**< the minimum framerate, the cycle duration is 151 * always smaller to ensure there is only one 152 * video frame per cycle. */ 153 uint32_t padding[4]; 154 }; 155 156 /** latency reporting */ 157 struct spa_io_latency { 158 struct spa_fraction rate; /**< rate for min/max */ 159 uint64_t min; /**< min latency */ 160 uint64_t max; /**< max latency */ 161 }; 162 163 /** control stream, io area for SPA_IO_Control and SPA_IO_Notify */ 164 struct spa_io_sequence { 165 struct spa_pod_sequence sequence; /**< sequence of timed events */ 166 }; 167 168 /** bar and beat segment */ 169 struct spa_io_segment_bar { 170 #define SPA_IO_SEGMENT_BAR_FLAG_VALID (1<<0) 171 uint32_t flags; /**< extra flags */ 172 uint32_t offset; /**< offset in segment of this beat */ 173 float signature_num; /**< time signature numerator */ 174 float signature_denom; /**< time signature denominator */ 175 double bpm; /**< beats per minute */ 176 double beat; /**< current beat in segment */ 177 uint32_t padding[8]; 178 }; 179 180 /** video frame segment */ 181 struct spa_io_segment_video { 182 #define SPA_IO_SEGMENT_VIDEO_FLAG_VALID (1<<0) 183 #define SPA_IO_SEGMENT_VIDEO_FLAG_DROP_FRAME (1<<1) 184 #define SPA_IO_SEGMENT_VIDEO_FLAG_PULL_DOWN (1<<2) 185 #define SPA_IO_SEGMENT_VIDEO_FLAG_INTERLACED (1<<3) 186 uint32_t flags; /**< flags */ 187 uint32_t offset; /**< offset in segment */ 188 struct spa_fraction framerate; 189 uint32_t hours; 190 uint32_t minutes; 191 uint32_t seconds; 192 uint32_t frames; 193 uint32_t field_count; /**< 0 for progressive, 1 and 2 for interlaced */ 194 uint32_t padding[11]; 195 }; 196 197 /** 198 * A segment converts a running time to a segment (stream) position. 199 * 200 * The segment position is valid when the current running time is between 201 * start and start + duration. The position is then 202 * calculated as: 203 * 204 * (running time - start) * rate + position; 205 * 206 * Support for looping is done by specifying the LOOPING flags with a 207 * non-zero duration. When the running time reaches start + duration, 208 * duration is added to start and the loop repeats. 209 * 210 * Care has to be taken when the running time + clock.duration extends 211 * past the start + duration from the segment; the user should correctly 212 * wrap around and partially repeat the loop in the current cycle. 213 * 214 * Extra information can be placed in the segment by setting the valid flags 215 * and filling up the corresponding structures. 216 */ 217 struct spa_io_segment { 218 uint32_t version; 219 #define SPA_IO_SEGMENT_FLAG_LOOPING (1<<0) /**< after the duration, the segment repeats */ 220 #define SPA_IO_SEGMENT_FLAG_NO_POSITION (1<<1) /**< position is invalid. The position can be invalid 221 * after a seek, for example, when the exact mapping 222 * of the extra segment info (bar, video, ...) to 223 * position has not been determined yet */ 224 uint32_t flags; /**< extra flags */ 225 uint64_t start; /**< value of running time when this 226 * info is active. Can be in the future for 227 * pending changes. It does not have to be in 228 * exact multiples of the clock duration. */ 229 uint64_t duration; /**< duration when this info becomes invalid expressed 230 * in running time. If the duration is 0, this 231 * segment extends to the next segment. If the 232 * segment becomes invalid and the looping flag is 233 * set, the segment repeats. */ 234 double rate; /**< overal rate of the segment, can be negative for 235 * backwards time reporting. */ 236 uint64_t position; /**< The position when the running time == start. 237 * can be invalid when the owner of the extra segment 238 * information has not yet made the mapping. */ 239 240 struct spa_io_segment_bar bar; 241 struct spa_io_segment_video video; 242 }; 243 244 enum spa_io_position_state { 245 SPA_IO_POSITION_STATE_STOPPED, 246 SPA_IO_POSITION_STATE_STARTING, 247 SPA_IO_POSITION_STATE_RUNNING, 248 }; 249 250 /** the maximum number of segments visible in the future */ 251 #define SPA_IO_POSITION_MAX_SEGMENTS 8 252 253 /** 254 * The position information adds extra meaning to the raw clock times. 255 * 256 * It is set on all nodes and the clock id will contain the clock of the 257 * driving node in the graph. 258 * 259 * The position information contains 1 or more segments that convert the 260 * raw clock times to a stream time. They are sorted based on their 261 * start times, and thus the order in which they will activate in 262 * the future. This makes it possible to look ahead in the scheduled 263 * segments and anticipate the changes in the timeline. 264 */ 265 struct spa_io_position { 266 struct spa_io_clock clock; /**< clock position of driver, always valid and 267 * read only */ 268 struct spa_io_video_size video; /**< size of the video in the current cycle */ 269 int64_t offset; /**< an offset to subtract from the clock position 270 * to get a running time. This is the time that 271 * the state has been in the RUNNING state and the 272 * time that should be used to compare the segment 273 * start values against. */ 274 uint32_t state; /**< one of enum spa_io_position_state */ 275 276 uint32_t n_segments; /**< number of segments */ 277 struct spa_io_segment segments[SPA_IO_POSITION_MAX_SEGMENTS]; /**< segments */ 278 }; 279 280 /** rate matching */ 281 struct spa_io_rate_match { 282 uint32_t delay; /**< extra delay in samples for resampler */ 283 uint32_t size; /**< requested input size for resampler */ 284 double rate; /**< rate for resampler */ 285 #define SPA_IO_RATE_MATCH_FLAG_ACTIVE (1 << 0) 286 uint32_t flags; /**< extra flags */ 287 uint32_t padding[7]; 288 }; 289 290 #ifdef __cplusplus 291 } /* extern "C" */ 292 #endif 293 294 #endif /* SPA_IO_H */ 295