mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-06 13:30:01 -05:00
spa: make events and commands as objects
So we can serialize and introspect them more easily
This commit is contained in:
parent
4c4c0f2a7f
commit
c951264fff
26 changed files with 423 additions and 327 deletions
|
|
@ -130,8 +130,10 @@ typedef void (*SpaNotify) (void *data);
|
|||
|
||||
#ifdef __GNUC__
|
||||
# define SPA_PRINTF_FUNC(fmt, arg1) __attribute__((format(printf, fmt, arg1)))
|
||||
# define SPA_ALIGNED(align) __attribute__ ((aligned (align)))
|
||||
#else
|
||||
# define SPA_PRINTF_FUNC(fmt, arg1)
|
||||
# define SPA_ALIGNED(align)
|
||||
#endif
|
||||
|
||||
#define SPA_ROUND_UP_N(num,align) ((((num) + ((align) - 1)) & ~((align) - 1)))
|
||||
|
|
|
|||
|
|
@ -49,11 +49,25 @@ typedef enum {
|
|||
SPA_NODE_COMMAND_CLOCK_UPDATE
|
||||
} SpaNodeCommandType;
|
||||
|
||||
#define SPA_NODE_COMMAND_TYPE(cmd) ((cmd)->body.body.type)
|
||||
|
||||
typedef struct {
|
||||
SpaPODObjectBody body;
|
||||
} SpaNodeCommandBody;
|
||||
|
||||
struct _SpaNodeCommand {
|
||||
SpaNodeCommandType type;
|
||||
uint32_t size;
|
||||
SpaPOD pod;
|
||||
SpaNodeCommandBody body;
|
||||
};
|
||||
|
||||
#define SPA_NODE_COMMAND_INIT(type) \
|
||||
{ { sizeof (SpaNodeCommandBody), SPA_POD_TYPE_OBJECT }, \
|
||||
{ { 0, type } } } \
|
||||
|
||||
#define SPA_NODE_COMMAND_INIT_COMPLEX(size,type,...) \
|
||||
{ { size, SPA_POD_TYPE_OBJECT }, \
|
||||
{ { 0, type }, __VA_ARGS__ } } \
|
||||
|
||||
/**
|
||||
* SpaNodeCommandClockUpdate:
|
||||
* @change_mask: marks which fields are updated
|
||||
|
|
@ -67,23 +81,41 @@ struct _SpaNodeCommand {
|
|||
* @state: the new clock state, when @change_mask = 1<<2
|
||||
*/
|
||||
typedef struct {
|
||||
SpaNodeCommand command;
|
||||
SpaPODObjectBody body;
|
||||
#define SPA_NODE_COMMAND_CLOCK_UPDATE_TIME (1 << 0)
|
||||
#define SPA_NODE_COMMAND_CLOCK_UPDATE_SCALE (1 << 1)
|
||||
#define SPA_NODE_COMMAND_CLOCK_UPDATE_STATE (1 << 2)
|
||||
#define SPA_NODE_COMMAND_CLOCK_UPDATE_LATENCY (1 << 3)
|
||||
uint32_t change_mask;
|
||||
int32_t rate;
|
||||
int64_t ticks;
|
||||
int64_t monotonic_time;
|
||||
int64_t offset;
|
||||
int32_t scale;
|
||||
SpaClockState state;
|
||||
SpaPODInt change_mask SPA_ALIGNED (8);
|
||||
SpaPODInt rate SPA_ALIGNED (8);
|
||||
SpaPODLong ticks SPA_ALIGNED (8);
|
||||
SpaPODLong monotonic_time SPA_ALIGNED (8);
|
||||
SpaPODLong offset SPA_ALIGNED (8);
|
||||
SpaPODInt scale SPA_ALIGNED (8);
|
||||
SpaPODInt state SPA_ALIGNED (8);
|
||||
#define SPA_NODE_COMMAND_CLOCK_UPDATE_FLAG_LIVE (1 << 0)
|
||||
uint32_t flags;
|
||||
int64_t latency;
|
||||
SpaPODInt flags SPA_ALIGNED (8);
|
||||
SpaPODLong latency SPA_ALIGNED (8);
|
||||
} SpaNodeCommandClockUpdateBody;
|
||||
|
||||
typedef struct {
|
||||
SpaPOD pod;
|
||||
SpaNodeCommandClockUpdateBody body;
|
||||
} SpaNodeCommandClockUpdate;
|
||||
|
||||
#define SPA_NODE_COMMAND_CLOCK_UPDATE_INIT(change_mask,rate,ticks,monotonic_time,offset,scale,state,flags,latency) \
|
||||
SPA_NODE_COMMAND_INIT_COMPLEX (sizeof (SpaNodeCommandClockUpdateBody), \
|
||||
SPA_NODE_COMMAND_CLOCK_UPDATE, \
|
||||
SPA_POD_INT_INIT (change_mask), \
|
||||
SPA_POD_INT_INIT (rate), \
|
||||
SPA_POD_LONG_INIT (ticks), \
|
||||
SPA_POD_LONG_INIT (monotonic_time), \
|
||||
SPA_POD_LONG_INIT (offset), \
|
||||
SPA_POD_INT_INIT (scale), \
|
||||
SPA_POD_INT_INIT (state), \
|
||||
SPA_POD_INT_INIT (flags), \
|
||||
SPA_POD_LONG_INIT (latency))
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -43,55 +43,103 @@ typedef struct _SpaNodeEvent SpaNodeEvent;
|
|||
|
||||
/**
|
||||
* SpaEventType:
|
||||
* @SPA_NODE_EVENT_TYPE_INVALID: invalid event, should be ignored
|
||||
* @SPA_NODE_EVENT_TYPE_ASYNC_COMPLETE: an async operation completed
|
||||
* @SPA_NODE_EVENT_TYPE_HAVE_OUTPUT: emited when an async node has output that can be pulled
|
||||
* @SPA_NODE_EVENT_TYPE_NEED_INPUT: emited when more data can be pushed to an async node
|
||||
* @SPA_NODE_EVENT_TYPE_REUSE_BUFFER: emited when a buffer can be reused
|
||||
* @SPA_NODE_EVENT_TYPE_ERROR: emited when error occured
|
||||
* @SPA_NODE_EVENT_TYPE_BUFFERING: emited when buffering is in progress
|
||||
* @SPA_NODE_EVENT_TYPE_REQUEST_REFRESH: emited when a keyframe refresh is needed
|
||||
* @SPA_NODE_EVENT_TYPE_REQUEST_CLOCK_UPDATE: the element asks for a clock update
|
||||
* @SPA_NODE_EVENT_INVALID: invalid event, should be ignored
|
||||
* @SPA_NODE_EVENT_ASYNC_COMPLETE: an async operation completed
|
||||
* @SPA_NODE_EVENT_HAVE_OUTPUT: emited when an async node has output that can be pulled
|
||||
* @SPA_NODE_EVENT_NEED_INPUT: emited when more data can be pushed to an async node
|
||||
* @SPA_NODE_EVENT_REUSE_BUFFER: emited when a buffer can be reused
|
||||
* @SPA_NODE_EVENT_ERROR: emited when error occured
|
||||
* @SPA_NODE_EVENT_BUFFERING: emited when buffering is in progress
|
||||
* @SPA_NODE_EVENT_REQUEST_REFRESH: emited when a keyframe refresh is needed
|
||||
* @SPA_NODE_EVENT_REQUEST_CLOCK_UPDATE: the element asks for a clock update
|
||||
*/
|
||||
typedef enum {
|
||||
SPA_NODE_EVENT_TYPE_INVALID = 0,
|
||||
SPA_NODE_EVENT_TYPE_ASYNC_COMPLETE,
|
||||
SPA_NODE_EVENT_TYPE_HAVE_OUTPUT,
|
||||
SPA_NODE_EVENT_TYPE_NEED_INPUT,
|
||||
SPA_NODE_EVENT_TYPE_REUSE_BUFFER,
|
||||
SPA_NODE_EVENT_TYPE_ERROR,
|
||||
SPA_NODE_EVENT_TYPE_BUFFERING,
|
||||
SPA_NODE_EVENT_TYPE_REQUEST_REFRESH,
|
||||
SPA_NODE_EVENT_TYPE_REQUEST_CLOCK_UPDATE,
|
||||
SPA_NODE_EVENT_INVALID = 0,
|
||||
SPA_NODE_EVENT_ASYNC_COMPLETE,
|
||||
SPA_NODE_EVENT_HAVE_OUTPUT,
|
||||
SPA_NODE_EVENT_NEED_INPUT,
|
||||
SPA_NODE_EVENT_REUSE_BUFFER,
|
||||
SPA_NODE_EVENT_ERROR,
|
||||
SPA_NODE_EVENT_BUFFERING,
|
||||
SPA_NODE_EVENT_REQUEST_REFRESH,
|
||||
SPA_NODE_EVENT_REQUEST_CLOCK_UPDATE,
|
||||
} SpaNodeEventType;
|
||||
|
||||
#define SPA_NODE_EVENT_TYPE(ev) ((ev)->body.body.type)
|
||||
|
||||
typedef struct {
|
||||
SpaPODObjectBody body;
|
||||
} SpaNodeEventBody;
|
||||
|
||||
struct _SpaNodeEvent {
|
||||
SpaNodeEventType type;
|
||||
uint32_t size;
|
||||
SpaPOD pod;
|
||||
SpaNodeEventBody body;
|
||||
};
|
||||
|
||||
#define SPA_NODE_EVENT_INIT(type) \
|
||||
{ { sizeof (SpaNodeEventBody), SPA_POD_TYPE_OBJECT }, \
|
||||
{ { 0, type } } } \
|
||||
|
||||
#define SPA_NODE_EVENT_INIT_COMPLEX(size,type,...) \
|
||||
{ { size, SPA_POD_TYPE_OBJECT }, \
|
||||
{ { 0, type }, __VA_ARGS__ } } \
|
||||
|
||||
typedef struct {
|
||||
SpaNodeEvent event;
|
||||
uint32_t seq;
|
||||
SpaResult res;
|
||||
SpaPODObjectBody body;
|
||||
SpaPODInt seq SPA_ALIGNED (8);
|
||||
SpaPODInt res SPA_ALIGNED (8);
|
||||
} SpaNodeEventAsyncCompleteBody;
|
||||
|
||||
typedef struct {
|
||||
SpaPOD pod;
|
||||
SpaNodeEventAsyncCompleteBody body;
|
||||
} SpaNodeEventAsyncComplete;
|
||||
|
||||
typedef struct {
|
||||
SpaNodeEvent event;
|
||||
uint32_t port_id;
|
||||
uint32_t buffer_id;
|
||||
} SpaNodeEventReuseBuffer;
|
||||
#define SPA_NODE_EVENT_ASYNC_COMPLETE_INIT(seq,res) \
|
||||
SPA_NODE_EVENT_INIT_COMPLEX (sizeof (SpaNodeEventAsyncCompleteBody), \
|
||||
SPA_NODE_EVENT_ASYNC_COMPLETE, \
|
||||
SPA_POD_INT_INIT (seq), \
|
||||
SPA_POD_INT_INIT (res))
|
||||
|
||||
typedef struct {
|
||||
SpaNodeEvent event;
|
||||
SpaPODObjectBody body;
|
||||
SpaPODInt port_id;
|
||||
SpaPODInt buffer_id;
|
||||
} SpaNodeEventReuseBufferBody;
|
||||
|
||||
typedef struct {
|
||||
SpaPOD pod;
|
||||
SpaNodeEventReuseBufferBody body;
|
||||
} SpaNodeEventReuseBuffer;
|
||||
|
||||
#define SPA_NODE_EVENT_REUSE_BUFFER_INIT(port_id,buffer_id) \
|
||||
SPA_NODE_EVENT_INIT_COMPLEX (sizeof (SpaNodeEventReuseBufferBody), \
|
||||
SPA_NODE_EVENT_REUSE_BUFFER, \
|
||||
SPA_POD_INT_INIT (port_id), \
|
||||
SPA_POD_INT_INIT (buffer_id))
|
||||
|
||||
typedef struct {
|
||||
SpaPODObjectBody body;
|
||||
#define SPA_NODE_EVENT_REQUEST_CLOCK_UPDATE_TIME (1 << 0)
|
||||
#define SPA_NODE_EVENT_REQUEST_CLOCK_UPDATE_SCALE (1 << 1)
|
||||
#define SPA_NODE_EVENT_REQUEST_CLOCK_UPDATE_STATE (1 << 2)
|
||||
uint32_t update_mask;
|
||||
int64_t timestamp;
|
||||
int64_t offset;
|
||||
SpaPODInt update_mask SPA_ALIGNED (8);
|
||||
SpaPODLong timestamp SPA_ALIGNED (8);
|
||||
SpaPODLong offset SPA_ALIGNED (8);
|
||||
} SpaNodeEventRequestClockUpdateBody;
|
||||
|
||||
typedef struct {
|
||||
SpaPOD pod;
|
||||
SpaNodeEventRequestClockUpdateBody body;
|
||||
} SpaNodeEventRequestClockUpdate;
|
||||
|
||||
#define SPA_NODE_EVENT_REQUEST_CLOCK_UPDATE_INIT(update_mask,timestamp,offset) \
|
||||
SPA_NODE_EVENT_INIT_COMPLEX (sizeof (SpaNodeEventRequestClockUpdateBody), \
|
||||
SPA_NODE_EVENT_REQUEST_CLOCK_UPDATE, \
|
||||
SPA_POD_INT_INIT (update_mask), \
|
||||
SPA_POD_LONG_INIT (timestamp), \
|
||||
SPA_POD_LONG_INIT (offset))
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -147,52 +147,66 @@ spa_pod_builder_primitive (SpaPODBuilder *builder, const SpaPOD *p)
|
|||
return ref;
|
||||
}
|
||||
|
||||
#define SPA_POD_BOOL_INIT(val) { { sizeof (uint32_t), SPA_POD_TYPE_BOOL }, val ? 1 : 0 }
|
||||
|
||||
static inline uint32_t
|
||||
spa_pod_builder_bool (SpaPODBuilder *builder, bool val)
|
||||
{
|
||||
const SpaPODBool p = { { sizeof (uint32_t), SPA_POD_TYPE_BOOL }, val ? 1 : 0 };
|
||||
const SpaPODBool p = SPA_POD_BOOL_INIT (val);
|
||||
return spa_pod_builder_primitive (builder, &p.pod);
|
||||
}
|
||||
|
||||
#define SPA_POD_URI_INIT(val) { { sizeof (uint32_t), SPA_POD_TYPE_URI }, val }
|
||||
|
||||
static inline uint32_t
|
||||
spa_pod_builder_uri (SpaPODBuilder *builder, uint32_t val)
|
||||
{
|
||||
const SpaPODURI p = { { sizeof (uint32_t), SPA_POD_TYPE_URI }, val };
|
||||
const SpaPODURI p = SPA_POD_URI_INIT (val);
|
||||
return spa_pod_builder_primitive (builder, &p.pod);
|
||||
}
|
||||
|
||||
#define SPA_POD_INT_INIT(val) { { sizeof (uint32_t), SPA_POD_TYPE_INT }, val }
|
||||
|
||||
static inline uint32_t
|
||||
spa_pod_builder_int (SpaPODBuilder *builder, int32_t val)
|
||||
{
|
||||
const SpaPODInt p = { { sizeof (uint32_t), SPA_POD_TYPE_INT }, val };
|
||||
const SpaPODInt p = SPA_POD_INT_INIT (val);
|
||||
return spa_pod_builder_primitive (builder, &p.pod);
|
||||
}
|
||||
|
||||
#define SPA_POD_LONG_INIT(val) { { sizeof (uint64_t), SPA_POD_TYPE_LONG }, val }
|
||||
|
||||
static inline uint32_t
|
||||
spa_pod_builder_long (SpaPODBuilder *builder, int64_t val)
|
||||
{
|
||||
const SpaPODLong p = { { sizeof (val), SPA_POD_TYPE_LONG }, val };
|
||||
const SpaPODLong p = SPA_POD_LONG_INIT (val);
|
||||
return spa_pod_builder_primitive (builder, &p.pod);
|
||||
}
|
||||
|
||||
#define SPA_POD_FLOAT_INIT(val) { { sizeof (float), SPA_POD_TYPE_FLOAT }, val }
|
||||
|
||||
static inline uint32_t
|
||||
spa_pod_builder_float (SpaPODBuilder *builder, float val)
|
||||
{
|
||||
const SpaPODFloat p = { { sizeof (val), SPA_POD_TYPE_FLOAT }, val };
|
||||
const SpaPODFloat p = SPA_POD_FLOAT_INIT (val);
|
||||
return spa_pod_builder_primitive (builder, &p.pod);
|
||||
}
|
||||
|
||||
#define SPA_POD_DOUBLE_INIT(val) { { sizeof (double), SPA_POD_TYPE_DOUBLE }, val }
|
||||
|
||||
static inline uint32_t
|
||||
spa_pod_builder_double (SpaPODBuilder *builder, double val)
|
||||
{
|
||||
const SpaPODDouble p = { { sizeof (val), SPA_POD_TYPE_DOUBLE }, val };
|
||||
const SpaPODDouble p = SPA_POD_DOUBLE_INIT (val);
|
||||
return spa_pod_builder_primitive (builder, &p.pod);
|
||||
}
|
||||
|
||||
#define SPA_POD_STRING_INIT(len) { { len, SPA_POD_TYPE_STRING } }
|
||||
|
||||
static inline uint32_t
|
||||
spa_pod_builder_string_len (SpaPODBuilder *builder, const char *str, uint32_t len)
|
||||
{
|
||||
const SpaPODString p = { { len, SPA_POD_TYPE_STRING } };
|
||||
const SpaPODString p = SPA_POD_STRING_INIT (len);
|
||||
uint32_t ref = spa_pod_builder_raw (builder, &p, sizeof (p));
|
||||
if (spa_pod_builder_raw_padded (builder, str, len) == -1)
|
||||
ref = -1;
|
||||
|
|
@ -206,27 +220,33 @@ spa_pod_builder_string (SpaPODBuilder *builder, const char *str)
|
|||
return spa_pod_builder_string_len (builder, str ? str : "", len + 1);
|
||||
}
|
||||
|
||||
#define SPA_POD_BYTES_INIT(len) { { len, SPA_POD_TYPE_BYTES } }
|
||||
|
||||
static inline uint32_t
|
||||
spa_pod_builder_bytes (SpaPODBuilder *builder, const void *bytes, uint32_t len)
|
||||
{
|
||||
const SpaPODBytes p = { { len, SPA_POD_TYPE_BYTES } };
|
||||
const SpaPODBytes p = SPA_POD_BYTES_INIT (len);
|
||||
uint32_t ref = spa_pod_builder_raw (builder, &p, sizeof (p));
|
||||
if (spa_pod_builder_raw_padded (builder, bytes, len) == -1)
|
||||
ref = -1;
|
||||
return ref;
|
||||
}
|
||||
|
||||
#define SPA_POD_RECTANGLE_INIT(width,height) { { sizeof (SpaRectangle), SPA_POD_TYPE_RECTANGLE }, { width, height } }
|
||||
|
||||
static inline uint32_t
|
||||
spa_pod_builder_rectangle (SpaPODBuilder *builder, uint32_t width, uint32_t height)
|
||||
{
|
||||
const SpaPODRectangle p = { { sizeof (SpaRectangle), SPA_POD_TYPE_RECTANGLE }, { width, height } };
|
||||
const SpaPODRectangle p = SPA_POD_RECTANGLE_INIT (width, height);
|
||||
return spa_pod_builder_primitive (builder, &p.pod);
|
||||
}
|
||||
|
||||
#define SPA_POD_FRACTION_INIT(num,denom) { { sizeof (SpaFraction), SPA_POD_TYPE_FRACTION }, { num, denom } }
|
||||
|
||||
static inline uint32_t
|
||||
spa_pod_builder_fraction (SpaPODBuilder *builder, uint32_t num, uint32_t denom)
|
||||
{
|
||||
const SpaPODFraction p = { { sizeof (SpaFraction), SPA_POD_TYPE_FRACTION }, { num, denom } };
|
||||
const SpaPODFraction p = SPA_POD_FRACTION_INIT (num, denom);
|
||||
return spa_pod_builder_primitive (builder, &p.pod);
|
||||
}
|
||||
|
||||
|
|
@ -247,31 +267,35 @@ spa_pod_builder_array (SpaPODBuilder *builder,
|
|||
const void *elems)
|
||||
{
|
||||
const SpaPODArray p = {
|
||||
{ (uint32_t)(sizeof (SpaPODArrayBody) + n_elems * child_size), SPA_POD_TYPE_ARRAY },
|
||||
{ sizeof (SpaPODArrayBody) + n_elems * child_size, SPA_POD_TYPE_ARRAY },
|
||||
{ { child_size, child_type } }
|
||||
};
|
||||
uint32_t ref = spa_pod_builder_raw_padded (builder, &p, sizeof(p));
|
||||
uint32_t ref = spa_pod_builder_raw (builder, &p, sizeof(p));
|
||||
if (spa_pod_builder_raw_padded (builder, elems, child_size * n_elems) == -1)
|
||||
ref = -1;
|
||||
return ref;
|
||||
}
|
||||
|
||||
#define SPA_POD_STRUCT_INIT(size) { { size, SPA_POD_TYPE_STRUCT } }
|
||||
|
||||
static inline uint32_t
|
||||
spa_pod_builder_push_struct (SpaPODBuilder *builder,
|
||||
SpaPODFrame *frame)
|
||||
{
|
||||
const SpaPODStruct p = { { 0, SPA_POD_TYPE_STRUCT } };
|
||||
const SpaPODStruct p = SPA_POD_STRUCT_INIT (0);
|
||||
return spa_pod_builder_push (builder, frame, &p.pod,
|
||||
spa_pod_builder_raw (builder, &p, sizeof(p)));
|
||||
}
|
||||
|
||||
#define SPA_POD_OBJECT_INIT(size,id,type) { { size, SPA_POD_TYPE_OBJECT }, { id, type } }
|
||||
|
||||
static inline uint32_t
|
||||
spa_pod_builder_push_object (SpaPODBuilder *builder,
|
||||
SpaPODFrame *frame,
|
||||
uint32_t id,
|
||||
uint32_t type)
|
||||
{
|
||||
const SpaPODObject p = { { sizeof (SpaPODObjectBody), SPA_POD_TYPE_OBJECT }, { id, type } };
|
||||
const SpaPODObject p = SPA_POD_OBJECT_INIT (sizeof (SpaPODObjectBody), id, type);
|
||||
return spa_pod_builder_push (builder, frame, &p.pod,
|
||||
spa_pod_builder_raw (builder, &p, sizeof(p)));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -80,6 +80,7 @@ spa_pod_iter_pod (SpaPODIter *iter, SpaPOD *pod)
|
|||
size = SPA_POD_CONTENTS_SIZE (SpaPODObject, pod);
|
||||
break;
|
||||
default:
|
||||
spa_pod_iter_contents (iter, NULL, 0);
|
||||
return false;
|
||||
}
|
||||
spa_pod_iter_contents (iter, data, size);
|
||||
|
|
@ -101,6 +102,15 @@ spa_pod_iter_next (SpaPODIter *iter)
|
|||
return res;
|
||||
}
|
||||
|
||||
static inline SpaPOD *
|
||||
spa_pod_iter_first (SpaPODIter *iter, SpaPOD *pod)
|
||||
{
|
||||
if (!spa_pod_iter_pod (iter, pod) ||
|
||||
!spa_pod_iter_has_next (iter))
|
||||
return false;
|
||||
return spa_pod_iter_next (iter);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
spa_pod_iter_getv (SpaPODIter *iter,
|
||||
uint32_t type,
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ typedef struct {
|
|||
|
||||
typedef struct {
|
||||
SpaPOD pod;
|
||||
/* array of uint32_t follows with the bitmap */
|
||||
/* array of uint8_t follows with the bitmap */
|
||||
} SpaPODBitmap;
|
||||
|
||||
typedef struct {
|
||||
|
|
@ -182,9 +182,9 @@ typedef struct {
|
|||
SPA_POD_FOREACH(SPA_MEMBER ((pod), (offset), SpaPOD),SPA_POD_SIZE (pod),iter)
|
||||
|
||||
#define SPA_POD_OBJECT_BODY_FOREACH(body, size, iter) \
|
||||
for ((iter) = SPA_MEMBER ((body), sizeof (SpaPODObjectBody), SpaPODProp); \
|
||||
(iter) < SPA_MEMBER ((body), (size), SpaPODProp); \
|
||||
(iter) = SPA_MEMBER ((iter), SPA_ROUND_UP_N (SPA_POD_SIZE (iter), 8), SpaPODProp))
|
||||
for ((iter) = SPA_MEMBER ((body), sizeof (SpaPODObjectBody), SpaPOD); \
|
||||
(iter) < SPA_MEMBER ((body), (size), SpaPOD); \
|
||||
(iter) = SPA_MEMBER ((iter), SPA_ROUND_UP_N (SPA_POD_SIZE (iter), 8), SpaPOD))
|
||||
|
||||
#define SPA_POD_OBJECT_FOREACH(obj, iter) \
|
||||
SPA_POD_OBJECT_BODY_FOREACH(&obj->body, SPA_POD_BODY_SIZE(obj), iter)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue