Loading...
Searching...
No Matches
filter.h
Go to the documentation of this file.
/* Simple Plugin API */
/* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */
/* SPDX-License-Identifier: MIT */
#ifndef SPA_POD_FILTER_H
#define SPA_POD_FILTER_H
#include <errno.h>
#include <stdint.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <spa/param/props.h>
#include <spa/pod/iter.h>
#include <spa/pod/builder.h>
#include <spa/pod/compare.h>
#include <spa/pod/dynamic.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifndef SPA_API_POD_FILTER
#ifdef SPA_API_IMPL
#define SPA_API_POD_FILTER SPA_API_IMPL
#else
#define SPA_API_POD_FILTER static inline
#endif
#endif
SPA_API_POD_FILTER int spa_pod_filter_flags_value(struct spa_pod_builder *b,
uint32_t type, const void *r1, const void *r2, uint32_t size)
{
switch (type) {
case SPA_TYPE_Int:
{
int32_t val;
if (size < sizeof(int32_t))
return -EINVAL;
val = (*(int32_t *) r1) & (*(int32_t *) r2);
if (val == 0)
return 0;
spa_pod_builder_int(b, val);
break;
}
case SPA_TYPE_Long:
{
int64_t val;
if (size < sizeof(int64_t))
return -EINVAL;
val = (*(int64_t *) r1) & (*(int64_t *) r2);
if (val == 0)
return 0;
spa_pod_builder_long(b, val);
break;
}
default:
return -ENOTSUP;
}
return 1;
}
SPA_API_POD_FILTER int
spa_pod_filter_prop(struct spa_pod_builder *b,
const struct spa_pod_prop *p1,
const struct spa_pod_prop *p2)
{
const struct spa_pod *v1, *v2;
struct spa_pod_choice *nc, dummy;
uint32_t j, k, nalt1, nalt2, nc_offs;
void *alt1, *alt2, *a1, *a2;
uint32_t type, size, p1c, p2c;
struct spa_pod_frame f;
int res, n_copied = 0;
v1 = spa_pod_get_values(&p1->value, &nalt1, &p1c);
v2 = spa_pod_get_values(&p2->value, &nalt2, &p2c);
/* empty/invalid choices */
if (nalt1 < 1 || nalt2 < 1)
return -EINVAL;
alt1 = SPA_POD_BODY(v1);
alt2 = SPA_POD_BODY(v2);
type = v1->type;
size = v1->size;
/* incompatible property types */
if (type != v2->type || size != v2->size || p1->key != p2->key)
return -EINVAL;
/* start with copying the property */
spa_pod_builder_prop(b, p1->key, p1->flags & p2->flags);
spa_pod_builder_push_choice(b, &f, SPA_CHOICE_None, 0);
spa_zero(dummy);
nc_offs = f.offset;
/* start with an empty child and we will select a good default
* below */
spa_pod_builder_child(b, size, type);
/* we should prefer alt2 values but only if they are within the
* range. Swap the order otherwise. */
if (!spa_pod_compare_is_valid_choice(type, size, alt2, alt2, nalt2, p2c)) {
SPA_SWAP(alt2, alt1);
SPA_SWAP(nalt2, nalt1);
SPA_SWAP(p2c, p1c);
}
if ((p1c == SPA_CHOICE_None && p2c == SPA_CHOICE_None) ||
(p1c == SPA_CHOICE_None && p2c == SPA_CHOICE_Enum) ||
(p1c == SPA_CHOICE_Enum && p2c == SPA_CHOICE_None) ||
(p1c == SPA_CHOICE_Enum && p2c == SPA_CHOICE_Enum)) {
/* copy all equal values. Start with alt2 so that they are prefered. */
for (j = 0, a2 = alt2; j < nalt2; j++, a2 = SPA_PTROFF(a2, size, void)) {
for (k = 0, a1 = alt1; k < nalt1; k++, a1 = SPA_PTROFF(a1,size,void)) {
if (spa_pod_compare_value(type, a1, a2, size) == 0) {
if (n_copied++ == 0)
spa_pod_builder_raw(b, a1, size);
spa_pod_builder_raw(b, a1, size);
}
}
}
}
else if ((p1c == SPA_CHOICE_None && p2c == SPA_CHOICE_Range) ||
(p1c == SPA_CHOICE_Enum && p2c == SPA_CHOICE_Range) ||
(p1c == SPA_CHOICE_None && p2c == SPA_CHOICE_Step) ||
(p1c == SPA_CHOICE_Enum && p2c == SPA_CHOICE_Step)) {
void *min = SPA_PTROFF(alt2,size,void);
void *max = SPA_PTROFF(min,size,void);
void *step = p2c == SPA_CHOICE_Step ? SPA_PTROFF(max,size,void) : NULL;
bool found_def = false;
/* we should prefer the alt2 range default value but only if valid */
if (spa_pod_compare_value(type, alt2, min, size) >= 0 &&
spa_pod_compare_value(type, alt2, max, size) <= 0) {
for (j = 0, a1 = alt1; j < nalt1; j++, a1 = SPA_PTROFF(a1,size,void)) {
if (spa_pod_compare_value(type, a1, alt2, size) == 0) {
/* it is in the enum, use as default then */
spa_pod_builder_raw(b, a1, size);
found_def = true;
break;
}
}
}
/* copy all values inside the range */
for (j = 0, a1 = alt1; j < nalt1; j++, a1 = SPA_PTROFF(a1,size,void)) {
if ((res = spa_pod_compare_is_in_range(type, a1, min, max, step, size)) < 0)
return res;
if (res == 0)
continue;
if (n_copied++ == 0 && !found_def)
spa_pod_builder_raw(b, a1, size);
spa_pod_builder_raw(b, a1, size);
}
}
else if ((p1c == SPA_CHOICE_Range && p2c == SPA_CHOICE_None) ||
(p1c == SPA_CHOICE_Range && p2c == SPA_CHOICE_Enum) ||
(p1c == SPA_CHOICE_Step && p2c == SPA_CHOICE_None) ||
(p1c == SPA_CHOICE_Step && p2c == SPA_CHOICE_Enum)) {
void *min = SPA_PTROFF(alt1,size,void);
void *max = SPA_PTROFF(min,size,void);
void *step = p1c == SPA_CHOICE_Step ? SPA_PTROFF(max,size,void) : NULL;
/* copy all values inside the range, this will automatically prefer
* a valid alt2 value */
for (j = 0, a2 = alt2; j < nalt2; j++, a2 = SPA_PTROFF(a2,size,void)) {
if ((res = spa_pod_compare_is_in_range(type, a2, min, max, step, size)) < 0)
return res;
if (res == 0)
continue;
if (n_copied++ == 0)
spa_pod_builder_raw(b, a2, size);
spa_pod_builder_raw(b, a2, size);
}
}
else if ((p1c == SPA_CHOICE_Range && p2c == SPA_CHOICE_Range) ||
(p1c == SPA_CHOICE_Range && p2c == SPA_CHOICE_Step) ||
(p1c == SPA_CHOICE_Step && p2c == SPA_CHOICE_Range) ||
(p1c == SPA_CHOICE_Step && p2c == SPA_CHOICE_Step)) {
void *min1 = SPA_PTROFF(alt1,size,void);
void *max1 = SPA_PTROFF(min1,size,void);
void *min2 = SPA_PTROFF(alt2,size,void);
void *max2 = SPA_PTROFF(min2,size,void);
/* max of min */
if (spa_pod_compare_value(type, min1, min2, size) < 0)
min1 = min2;
/* min of max */
if (spa_pod_compare_value(type, max2, max1, size) < 0)
max1 = max2;
/* reject impossible range */
if (spa_pod_compare_value(type, max1, min1, size) < 0)
return -EINVAL;
/* prefer alt2 if in new range */
a1 = alt2;
if ((res = spa_pod_compare_is_in_range(type, a1, min1, max1, NULL, size)) < 0)
return res;
if (res == 0) {
/* try alt1 otherwise */
a1 = alt1;
if ((res = spa_pod_compare_is_in_range(type, a1, min1, max1, NULL, size)) < 0)
return res;
/* fall back to new min value then */
if (res == 0)
a1 = min1;
}
spa_pod_builder_raw(b, a1, size);
spa_pod_builder_raw(b, min1, size);
spa_pod_builder_raw(b, max1, size);
nc = (struct spa_pod_choice*)spa_pod_builder_deref_fallback(b, nc_offs, &dummy.pod);
nc->body.type = SPA_CHOICE_Range;
}
else if ((p1c == SPA_CHOICE_None && p2c == SPA_CHOICE_Flags) ||
(p1c == SPA_CHOICE_Flags && p2c == SPA_CHOICE_None) ||
(p1c == SPA_CHOICE_Flags && p2c == SPA_CHOICE_Flags)) {
if (spa_pod_filter_flags_value(b, type, alt1, alt2, size) != 1)
return -EINVAL;
nc = (struct spa_pod_choice*)spa_pod_builder_deref_fallback(b, nc_offs, &dummy.pod);
nc->body.type = SPA_CHOICE_Flags;
}
else if (p1c == SPA_CHOICE_Range && p2c == SPA_CHOICE_Flags)
return -ENOTSUP;
else if (p1c == SPA_CHOICE_Enum && p2c == SPA_CHOICE_Flags)
return -ENOTSUP;
else if (p1c == SPA_CHOICE_Step && p2c == SPA_CHOICE_Flags)
return -ENOTSUP;
else if (p1c == SPA_CHOICE_Flags && p2c == SPA_CHOICE_Range)
return -ENOTSUP;
else if (p1c == SPA_CHOICE_Flags && p2c == SPA_CHOICE_Step)
return -ENOTSUP;
else if (p1c == SPA_CHOICE_Flags && p2c == SPA_CHOICE_Enum)
return -ENOTSUP;
nc = (struct spa_pod_choice*)spa_pod_builder_deref_fallback(b, nc_offs, &dummy.pod);
if (nc->body.type == SPA_CHOICE_None) {
if (n_copied == 0) {
return -EINVAL;
} else if (n_copied == 1) {
/* we always copy the default value twice, so remove it
* again when it was the only one added */
spa_pod_builder_remove(b, size);
} else if (n_copied > 1) {
nc->body.type = SPA_CHOICE_Enum;
}
}
spa_pod_builder_pop(b, &f);
return 0;
}
SPA_API_POD_FILTER int spa_pod_filter_part(struct spa_pod_builder *b,
const struct spa_pod *pod, uint32_t pod_size,
const struct spa_pod *filter, uint32_t filter_size)
{
const struct spa_pod *pp, *pf;
int res = 0;
pf = filter;
SPA_POD_FOREACH(pod, pod_size, pp) {
bool do_copy = false, do_advance = false;
uint32_t filter_offset = 0;
struct spa_pod_frame f;
switch (pp->type) {
case SPA_TYPE_Object:
if (pf != NULL) {
struct spa_pod_object *op = (struct spa_pod_object *) pp;
struct spa_pod_object *of = (struct spa_pod_object *) pf;
const struct spa_pod_prop *p1, *p2;
if (pf->type != pp->type)
return -EINVAL;
spa_pod_builder_push_object(b, &f, op->body.type, op->body.id);
p2 = NULL;
SPA_POD_OBJECT_FOREACH(op, p1) {
p2 = spa_pod_object_find_prop(of, p2, p1->key);
if (p2 != NULL)
res = spa_pod_filter_prop(b, p1, p2);
else if (SPA_FLAG_IS_SET(p1->flags, SPA_POD_PROP_FLAG_MANDATORY))
res = -EINVAL;
else if (!SPA_FLAG_IS_SET(p1->flags, SPA_POD_PROP_FLAG_DROP))
spa_pod_builder_raw_padded(b, p1, SPA_POD_PROP_SIZE(p1));
if (res < 0)
break;
}
if (res >= 0) {
p1 = NULL;
SPA_POD_OBJECT_FOREACH(of, p2) {
p1 = spa_pod_object_find_prop(op, p1, p2->key);
if (p1 != NULL)
continue;
if (SPA_FLAG_IS_SET(p2->flags, SPA_POD_PROP_FLAG_MANDATORY))
res = -EINVAL;
else if (!SPA_FLAG_IS_SET(p2->flags, SPA_POD_PROP_FLAG_DROP))
spa_pod_builder_raw_padded(b, p2, SPA_POD_PROP_SIZE(p2));
if (res < 0)
break;
}
}
spa_pod_builder_pop(b, &f);
do_advance = true;
}
else
do_copy = true;
break;
case SPA_TYPE_Struct:
if (pf != NULL) {
if (pf->type != pp->type)
return -EINVAL;
filter_offset = sizeof(struct spa_pod_struct);
spa_pod_builder_push_struct(b, &f);
res = spa_pod_filter_part(b,
SPA_PTROFF(pp,filter_offset,const struct spa_pod),
SPA_POD_SIZE(pp) - filter_offset,
SPA_PTROFF(pf,filter_offset,const struct spa_pod),
SPA_POD_SIZE(pf) - filter_offset);
spa_pod_builder_pop(b, &f);
do_advance = true;
}
else
do_copy = true;
break;
default:
if (pf != NULL) {
if (spa_pod_memcmp(pp, pf) != 0)
return -EINVAL;
do_advance = true;
}
do_copy = true;
break;
}
if (do_copy)
spa_pod_builder_raw_padded(b, pp, SPA_POD_SIZE(pp));
if (do_advance) {
pf = (const struct spa_pod*)spa_pod_next(pf);
if (!spa_pod_is_inside(filter, filter_size, pf))
pf = NULL;
}
if (res < 0)
break;
}
return res;
}
SPA_API_POD_FILTER int
spa_pod_filter(struct spa_pod_builder *b,
struct spa_pod **result,
const struct spa_pod *pod,
const struct spa_pod *filter)
{
int res;
struct spa_pod_builder_state state;
spa_return_val_if_fail(pod != NULL, -EINVAL);
spa_return_val_if_fail(b != NULL, -EINVAL);
spa_pod_builder_get_state(b, &state);
if (filter == NULL) {
res = spa_pod_builder_raw_padded(b, pod, SPA_POD_SIZE(pod));
} else {
struct spa_pod_dynamic_builder db;
spa_pod_dynamic_builder_continue(&db, b);
res = spa_pod_filter_part(&db.b, pod, SPA_POD_SIZE(pod), filter, SPA_POD_SIZE(filter));
if (res >= 0)
res = spa_pod_builder_raw_padded(b, db.b.data, db.b.state.offset);
spa_pod_dynamic_builder_clean(&db);
}
if (res >= 0 && result) {
*result = (struct spa_pod*)spa_pod_builder_deref(b, state.offset);
if (*result == NULL)
res = -ENOSPC;
}
return res;
}
SPA_API_POD_FILTER int spa_pod_filter_object_make(struct spa_pod_object *pod)
{
struct spa_pod_prop *res;
int count = 0;
SPA_POD_OBJECT_FOREACH(pod, res) {
if (spa_pod_is_choice(&res->value) &&
!SPA_FLAG_IS_SET(res->flags, SPA_POD_PROP_FLAG_DONT_FIXATE)) {
uint32_t nvals, choice;
struct spa_pod *v = spa_pod_get_values(&res->value, &nvals, &choice);
const void *vals = SPA_POD_BODY(v);
if (nvals < 1)
continue;
if (spa_pod_compare_is_valid_choice(v->type, v->size,
vals, vals, nvals, choice)) {
((struct spa_pod_choice*)&res->value)->body.type = SPA_CHOICE_None;
count++;
}
}
}
return count;
}
SPA_API_POD_FILTER int spa_pod_filter_make(struct spa_pod *pod)
{
if (!spa_pod_is_object(pod))
return -EINVAL;
return spa_pod_filter_object_make((struct spa_pod_object *)pod);
}
* \}
*/
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* SPA_POD_FILTER_H */
builder.h
spa/pod/builder.h
compare.h
spa/pod/compare.h
res
uint32_t int int res
Definition core.h:433
spa_pod_builder_pop
SPA_API_POD_BUILDER void * spa_pod_builder_pop(struct spa_pod_builder *builder, struct spa_pod_frame *frame)
Definition builder.h:213
spa_pod_builder_int
SPA_API_POD_BUILDER int spa_pod_builder_int(struct spa_pod_builder *builder, int32_t val)
Definition builder.h:296
spa_pod_builder_long
SPA_API_POD_BUILDER int spa_pod_builder_long(struct spa_pod_builder *builder, int64_t val)
Definition builder.h:305
spa_pod_builder_push_choice
SPA_API_POD_BUILDER int spa_pod_builder_push_choice(struct spa_pod_builder *builder, struct spa_pod_frame *frame, uint32_t type, uint32_t flags)
Definition builder.h:446
spa_pod_compare_is_in_range
SPA_API_POD_COMPARE int spa_pod_compare_is_in_range(uint32_t type, const void *v, const void *min, const void *max, const void *step, uint32_t size 1)
Definition compare.h:225
spa_pod_builder_child
SPA_API_POD_BUILDER int spa_pod_builder_child(struct spa_pod_builder *builder, uint32_t size, uint32_t type)
Definition builder.h:268
spa_pod_get_values
SPA_API_POD_ITER struct spa_pod * spa_pod_get_values(const struct spa_pod *pod, uint32_t *n_vals, uint32_t *choice)
Definition iter.h:229
spa_pod_filter_flags_value
SPA_API_POD_FILTER int spa_pod_filter_flags_value(struct spa_pod_builder *b, uint32_t type, const void *r1, const void *r2, uint32_t size)
Definition filter.h:44
SPA_POD_PROP_FLAG_MANDATORY
#define SPA_POD_PROP_FLAG_MANDATORY
is mandatory, when filtering, both sides need this property or filtering fails.
Definition pod.h:241
spa_pod_compare_is_valid_choice
SPA_API_POD_COMPARE int spa_pod_compare_is_valid_choice(uint32_t type, uint32_t size, const void *val, const void *vals, uint32_t n_vals, uint32_t choice)
Definition compare.h:236
spa_pod_filter_prop
SPA_API_POD_FILTER int spa_pod_filter_prop(struct spa_pod_builder *b, const struct spa_pod_prop *p1, const struct spa_pod_prop *p2)
Definition filter.h:77
spa_pod_builder_get_state
SPA_API_POD_BUILDER void spa_pod_builder_get_state(struct spa_pod_builder *builder, struct spa_pod_builder_state *state)
Definition builder.h:75
SPA_POD_PROP_FLAG_DROP
#define SPA_POD_PROP_FLAG_DROP
drop property, when filtering, both sides need the property or it will be dropped.
Definition pod.h:246
spa_pod_object_find_prop
SPA_API_POD_ITER const struct spa_pod_prop * spa_pod_object_find_prop(const struct spa_pod_object *pod, const struct spa_pod_prop *start, uint32_t key)
Definition iter.h:254
spa_pod_compare_value
SPA_API_POD_COMPARE int spa_pod_compare_value(uint32_t type, const void *r1, const void *r2, uint32_t size)
Definition compare.h:43
SPA_POD_OBJECT_FOREACH
#define SPA_POD_OBJECT_FOREACH(obj, iter)
Definition iter.h:118
SPA_POD_BODY
#define SPA_POD_BODY(pod)
Definition pod.h:44
spa_pod_is_object
SPA_API_POD_BODY int spa_pod_is_object(const struct spa_pod *pod)
Definition body.h:428
spa_pod_next
SPA_API_POD_ITER void * spa_pod_next(const void *iter)
Definition iter.h:46
spa_pod_builder_push_struct
SPA_API_POD_BUILDER int spa_pod_builder_push_struct(struct spa_pod_builder *builder, struct spa_pod_frame *frame)
Definition builder.h:462
spa_pod_filter_make
SPA_API_POD_FILTER int spa_pod_filter_make(struct spa_pod *pod)
Definition filter.h:424
spa_pod_builder_deref
SPA_API_POD_BUILDER struct spa_pod * spa_pod_builder_deref(struct spa_pod_builder *builder, uint32_t offset)
Definition builder.h:121
spa_pod_builder_push_object
SPA_API_POD_BUILDER int spa_pod_builder_push_object(struct spa_pod_builder *builder, struct spa_pod_frame *frame, uint32_t type, uint32_t id)
Definition builder.h:475
SPA_POD_PROP_FLAG_DONT_FIXATE
#define SPA_POD_PROP_FLAG_DONT_FIXATE
choices need no fixation
Definition pod.h:244
spa_pod_builder_remove
SPA_API_POD_BUILDER void spa_pod_builder_remove(struct spa_pod_builder *builder, uint32_t size)
Definition builder.h:187
spa_pod_filter
SPA_API_POD_FILTER int spa_pod_filter(struct spa_pod_builder *b, struct spa_pod **result, const struct spa_pod *pod, const struct spa_pod *filter)
Definition filter.h:370
SPA_POD_FOREACH
#define SPA_POD_FOREACH(pod, size, iter)
Definition iter.h:105
SPA_POD_PROP_SIZE
#define SPA_POD_PROP_SIZE(prop)
Definition pod.h:224
spa_pod_is_inside
SPA_API_POD_ITER bool spa_pod_is_inside(const void *pod, uint32_t size, const void *iter)
Definition iter.h:38
spa_pod_builder_raw
SPA_API_POD_BUILDER int spa_pod_builder_raw(struct spa_pod_builder *builder, const void *data, uint32_t size)
Definition builder.h:150
spa_pod_filter_object_make
SPA_API_POD_FILTER int spa_pod_filter_object_make(struct spa_pod_object *pod)
Definition filter.h:400
spa_pod_builder_raw_padded
SPA_API_POD_BUILDER int spa_pod_builder_raw_padded(struct spa_pod_builder *builder, const void *data, uint32_t size)
Definition builder.h:205
spa_pod_filter_part
SPA_API_POD_FILTER int spa_pod_filter_part(struct spa_pod_builder *b, const struct spa_pod *pod, uint32_t pod_size, const struct spa_pod *filter, uint32_t filter_size)
Definition filter.h:270
SPA_POD_SIZE
#define SPA_POD_SIZE(pod)
Definition pod.h:35
spa_pod_memcmp
SPA_API_POD_COMPARE int spa_pod_memcmp(const struct spa_pod *a, const struct spa_pod *b)
Definition compare.h:90
spa_pod_is_choice
SPA_API_POD_BODY int spa_pod_is_choice(const struct spa_pod *pod)
Definition body.h:389
spa_pod_builder_prop
SPA_API_POD_BUILDER int spa_pod_builder_prop(struct spa_pod_builder *builder, uint32_t key, uint32_t flags)
Definition builder.h:490
spa_pod_builder_deref_fallback
SPA_API_POD_BUILDER struct spa_pod * spa_pod_builder_deref_fallback(struct spa_pod_builder *builder, uint32_t offset, struct spa_pod *fallback)
Definition builder.h:108
SPA_CHOICE_Step
@ SPA_CHOICE_Step
range with step: default, min, max, step
Definition pod.h:163
SPA_CHOICE_None
@ SPA_CHOICE_None
no choice, first value is current
Definition pod.h:161
SPA_CHOICE_Flags
@ SPA_CHOICE_Flags
flags: first value is flags
Definition pod.h:165
SPA_CHOICE_Range
@ SPA_CHOICE_Range
range: default, min, max
Definition pod.h:162
SPA_CHOICE_Enum
@ SPA_CHOICE_Enum
list: default, alternative,...
Definition pod.h:164
SPA_TYPE_Int
@ SPA_TYPE_Int
Definition type.h:45
SPA_TYPE_Long
@ SPA_TYPE_Long
Definition type.h:46
SPA_TYPE_Object
@ SPA_TYPE_Object
Definition type.h:56
SPA_TYPE_Struct
@ SPA_TYPE_Struct
Definition type.h:55
spa_zero
#define spa_zero(x)
Definition defs.h:512
spa_return_val_if_fail
#define spa_return_val_if_fail(expr, val)
Definition defs.h:460
SPA_SWAP
#define SPA_SWAP(a, b)
Definition defs.h:195
SPA_FLAG_IS_SET
#define SPA_FLAG_IS_SET(field, flag)
Definition defs.h:90
SPA_PTROFF
#define SPA_PTROFF(ptr_, offset_, type_)
Return the address (buffer + offset) as pointer of type.
Definition defs.h:222
iter.h
spa/pod/iter.h
props.h
SPA_API_POD_FILTER
#define SPA_API_POD_FILTER
Definition filter.h:35
string.h
spa/utils/string.h
spa_pod_builder_state
Definition builder.h:42
spa_pod_builder
Definition builder.h:63
spa_pod_builder::data
void * data
Definition builder.h:64
spa_pod_choice_body::type
uint32_t type
type of choice, one of enum spa_choice_type
Definition pod.h:169
spa_pod_choice
Definition pod.h:176
spa_pod_choice::body
struct spa_pod_choice_body body
Definition pod.h:178
spa_pod_choice::pod
struct spa_pod pod
Definition pod.h:177
spa_pod_dynamic_builder
Definition dynamic.h:29
spa_pod_dynamic_builder::b
struct spa_pod_builder b
Definition dynamic.h:30
spa_pod_frame
Definition body.h:38
spa_pod_object_body::type
uint32_t type
one of enum spa_type
Definition pod.h:197
spa_pod_object_body::id
uint32_t id
id of the object, depends on the object type
Definition pod.h:198
spa_pod_object
Definition pod.h:202
spa_pod_object::body
struct spa_pod_object_body body
Definition pod.h:204
spa_pod_prop
Definition pod.h:227
spa_pod_prop::key
uint32_t key
key of property, list of valid keys depends on the object type
Definition pod.h:228
spa_pod_prop::flags
uint32_t flags
flags for property
Definition pod.h:248
spa_pod_prop::value
struct spa_pod value
Definition pod.h:249
spa_pod_struct
Definition pod.h:186
spa_pod
Definition pod.h:57
spa_pod::type
uint32_t type
Definition pod.h:59
spa_pod::size
uint32_t size
Definition pod.h:58