pod: improve parser and builder

Remove the spa_pod_iter helpers
Remove builder/parser vararg recurse option, you have to
manually recurse into structures when needed. This simplifies
things a lot.
Pass spa_pod_frames to builder and parser explicitly, we don't
have to keep an internal stack anymore.
The parser is now almost a mirror image of the builder.
Make the parser safer when iterating over objects, add functions
to check and get pod contents in a safe way.
Make the builder return errno style results on errors
Improve performance of object properties when they are stored and
retrieved in the same order.
Add many more tests for the builder and parser
Add some benchmarks
This commit is contained in:
Wim Taymans 2019-01-22 17:38:23 +01:00
parent 878ae769ef
commit 351fb9ce29
36 changed files with 1605 additions and 973 deletions

View file

@ -110,18 +110,19 @@ static void handle_events(struct data *data)
static void update_param(struct data *data)
{
struct spa_pod_builder b = { 0, };
struct spa_pod_frame f[2];
if (data->io_notify == NULL)
return;
spa_pod_builder_init(&b, data->io_notify, data->io_notify_size);
spa_pod_builder_push_sequence(&b, 0);
spa_pod_builder_push_sequence(&b, &f[0], 0);
spa_pod_builder_control(&b, 0, SPA_CONTROL_Properties);
spa_pod_builder_push_object(&b, SPA_TYPE_OBJECT_Props, 0);
spa_pod_builder_push_object(&b, &f[1], SPA_TYPE_OBJECT_Props, 0);
spa_pod_builder_prop(&b, SPA_PROP_contrast, 0);
spa_pod_builder_float(&b, (sin(data->param_accum) * 127.0) + 127.0);
spa_pod_builder_pop(&b);
spa_pod_builder_pop(&b);
spa_pod_builder_pop(&b, &f[1]);
spa_pod_builder_pop(&b, &f[0]);
data->param_accum += M_PI_M2 / 30.0;
if (data->param_accum >= M_PI_M2)

View file

@ -81,18 +81,19 @@ struct data {
static void update_volume(struct data *data)
{
struct spa_pod_builder b = { 0, };
struct spa_pod_frame f[2];
if (data->io_notify == NULL)
return;
spa_pod_builder_init(&b, data->io_notify, data->io_notify_size);
spa_pod_builder_push_sequence(&b, 0);
spa_pod_builder_push_sequence(&b, &f[0], 0);
spa_pod_builder_control(&b, 0, SPA_CONTROL_Properties);
spa_pod_builder_push_object(&b, SPA_TYPE_OBJECT_Props, 0);
spa_pod_builder_push_object(&b, &f[1], SPA_TYPE_OBJECT_Props, 0);
spa_pod_builder_prop(&b, SPA_PROP_volume, 0);
spa_pod_builder_float(&b, (sin(data->volume_accum) / 2.0) + 0.5);
spa_pod_builder_pop(&b);
spa_pod_builder_pop(&b);
spa_pod_builder_pop(&b, &f[1]);
spa_pod_builder_pop(&b, &f[0]);
data->volume_accum += M_PI_M2 / 1000.0;
if (data->volume_accum >= M_PI_M2)

View file

@ -101,15 +101,16 @@ static Uint32 id_to_sdl_format(uint32_t id)
static struct spa_pod *sdl_build_formats(SDL_RendererInfo *info, struct spa_pod_builder *b)
{
uint32_t i, c;
struct spa_pod_frame f[2];
spa_pod_builder_push_object(b, SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat);
spa_pod_builder_push_object(b, &f[0], SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat);
spa_pod_builder_prop(b, SPA_FORMAT_mediaType, 0);
spa_pod_builder_id(b, SPA_MEDIA_TYPE_video);
spa_pod_builder_prop(b, SPA_FORMAT_mediaSubtype, 0);
spa_pod_builder_id(b, SPA_MEDIA_SUBTYPE_raw);
spa_pod_builder_prop(b, SPA_FORMAT_VIDEO_format, 0);
spa_pod_builder_push_choice(b, SPA_CHOICE_Enum, 0);
spa_pod_builder_push_choice(b, &f[1], SPA_CHOICE_Enum, 0);
for (i = 0, c = 0; i < info->num_texture_formats; i++) {
uint32_t id = sdl_format_to_id(info->texture_formats[i]);
if (id == 0)
@ -123,7 +124,7 @@ static struct spa_pod *sdl_build_formats(SDL_RendererInfo *info, struct spa_pod_
if (id != SPA_VIDEO_FORMAT_UNKNOWN)
spa_pod_builder_id(b, id);
}
spa_pod_builder_pop(b);
spa_pod_builder_pop(b, &f[1]);
spa_pod_builder_add(b,
SPA_FORMAT_VIDEO_size, SPA_POD_CHOICE_RANGE_Rectangle(
&SPA_RECTANGLE(WIDTH, HEIGHT),
@ -135,5 +136,5 @@ static struct spa_pod *sdl_build_formats(SDL_RendererInfo *info, struct spa_pod_
&SPA_FRACTION(0,1),
&SPA_FRACTION(30,1)),
0);
return spa_pod_builder_pop(b);
return spa_pod_builder_pop(b, &f[0]);
}

View file

@ -362,6 +362,7 @@ handle_video_fields (ConvertData *d)
const GValue *value, *value2;
int i;
struct spa_pod_choice *choice;
struct spa_pod_frame f;
value = gst_structure_get_value (d->cs, "format");
if (value) {
@ -370,14 +371,14 @@ handle_video_fields (ConvertData *d)
for (i = 0; (v = get_nth_string (value, i)); i++) {
if (i == 0) {
spa_pod_builder_prop (&d->b, SPA_FORMAT_VIDEO_format, 0);
spa_pod_builder_push_choice(&d->b, get_range_type (value), 0);
spa_pod_builder_push_choice(&d->b, &f, get_range_type (value), 0);
}
idx = gst_video_format_from_string (v);
if (idx < (int)SPA_N_ELEMENTS (video_format_map))
spa_pod_builder_id (&d->b, video_format_map[idx]);
}
choice = spa_pod_builder_pop(&d->b);
choice = spa_pod_builder_pop(&d->b, &f);
if (i <= 1)
choice->body.type = SPA_CHOICE_None;
}
@ -388,12 +389,12 @@ handle_video_fields (ConvertData *d)
for (i = 0; get_nth_rectangle (value, value2, i, &v); i++) {
if (i == 0) {
spa_pod_builder_prop (&d->b, SPA_FORMAT_VIDEO_size, 0);
spa_pod_builder_push_choice(&d->b, get_range_type2 (value, value2), 0);
spa_pod_builder_push_choice(&d->b, &f, get_range_type2 (value, value2), 0);
}
spa_pod_builder_rectangle (&d->b, v.width, v.height);
}
choice = spa_pod_builder_pop(&d->b);
choice = spa_pod_builder_pop(&d->b, &f);
if (i <= 1)
choice->body.type = SPA_CHOICE_None;
}
@ -404,12 +405,12 @@ handle_video_fields (ConvertData *d)
for (i = 0; get_nth_fraction (value, i, &v); i++) {
if (i == 0) {
spa_pod_builder_prop (&d->b, SPA_FORMAT_VIDEO_framerate, 0);
spa_pod_builder_push_choice(&d->b, get_range_type (value), 0);
spa_pod_builder_push_choice(&d->b, &f, get_range_type (value), 0);
}
spa_pod_builder_fraction (&d->b, v.num, v.denom);
}
choice = spa_pod_builder_pop(&d->b);
choice = spa_pod_builder_pop(&d->b, &f);
if (i <= 1)
choice->body.type = SPA_CHOICE_None;
}
@ -420,12 +421,12 @@ handle_video_fields (ConvertData *d)
for (i = 0; get_nth_fraction (value, i, &v); i++) {
if (i == 0) {
spa_pod_builder_prop (&d->b, SPA_FORMAT_VIDEO_maxFramerate, 0);
spa_pod_builder_push_choice(&d->b, get_range_type (value), 0);
spa_pod_builder_push_choice(&d->b, &f, get_range_type (value), 0);
}
spa_pod_builder_fraction (&d->b, v.num, v.denom);
}
choice = spa_pod_builder_pop(&d->b);
choice = spa_pod_builder_pop(&d->b, &f);
if (i <= 1)
choice->body.type = SPA_CHOICE_None;
}
@ -437,6 +438,7 @@ handle_audio_fields (ConvertData *d)
{
const GValue *value;
struct spa_pod_choice *choice;
struct spa_pod_frame f;
int i = 0;
value = gst_structure_get_value (d->cs, "format");
@ -446,14 +448,14 @@ handle_audio_fields (ConvertData *d)
for (i = 0; (v = get_nth_string (value, i)); i++) {
if (i == 0) {
spa_pod_builder_prop (&d->b, SPA_FORMAT_AUDIO_format, 0);
spa_pod_builder_push_choice(&d->b, get_range_type (value), 0);
spa_pod_builder_push_choice(&d->b, &f, get_range_type (value), 0);
}
idx = gst_audio_format_from_string (v);
if (idx < (int)SPA_N_ELEMENTS (audio_format_map))
spa_pod_builder_id (&d->b, audio_format_map[idx]);
}
choice = spa_pod_builder_pop(&d->b);
choice = spa_pod_builder_pop(&d->b, &f);
if (i <= 1)
choice->body.type = SPA_CHOICE_None;
}
@ -474,12 +476,12 @@ handle_audio_fields (ConvertData *d)
if (i == 0) {
spa_pod_builder_prop (&d->b, SPA_FORMAT_AUDIO_layout, 0);
spa_pod_builder_push_choice(&d->b, get_range_type (value), 0);
spa_pod_builder_push_choice(&d->b, &f, get_range_type (value), 0);
}
spa_pod_builder_id (&d->b, layout);
}
choice = spa_pod_builder_pop(&d->b);
choice = spa_pod_builder_pop(&d->b, &f);
if (i <= 1)
choice->body.type = SPA_CHOICE_None;
}
@ -490,12 +492,12 @@ handle_audio_fields (ConvertData *d)
for (i = 0; get_nth_int (value, i, &v); i++) {
if (i == 0) {
spa_pod_builder_prop (&d->b, SPA_FORMAT_AUDIO_rate, 0);
spa_pod_builder_push_choice(&d->b, get_range_type (value), 0);
spa_pod_builder_push_choice(&d->b, &f, get_range_type (value), 0);
}
spa_pod_builder_int (&d->b, v);
}
choice = spa_pod_builder_pop(&d->b);
choice = spa_pod_builder_pop(&d->b, &f);
if (i <= 1)
choice->body.type = SPA_CHOICE_None;
}
@ -505,42 +507,46 @@ handle_audio_fields (ConvertData *d)
for (i = 0; get_nth_int (value, i, &v); i++) {
if (i == 0) {
spa_pod_builder_prop (&d->b, SPA_FORMAT_AUDIO_channels, 0);
spa_pod_builder_push_choice(&d->b, get_range_type (value), 0);
spa_pod_builder_push_choice(&d->b, &f, get_range_type (value), 0);
}
spa_pod_builder_int (&d->b, v);
}
choice = spa_pod_builder_pop(&d->b);
choice = spa_pod_builder_pop(&d->b, &f);
if (i <= 1)
choice->body.type = SPA_CHOICE_None;
}
return TRUE;
}
static uint32_t
write_pod (struct spa_pod_builder *b, const void *data, uint32_t size)
static int
builder_overflow (void *event_data, uint32_t size)
{
uint32_t ref = b->state.offset;
if (b->size <= ref) {
b->size = SPA_ROUND_UP_N (ref + size, 512);
b->data = realloc (b->data, b->size);
if (b->data == NULL)
return -1;
}
memcpy (SPA_MEMBER(b->data, ref, void), data, size);
return ref;
struct spa_pod_builder *b = event_data;
b->size = SPA_ROUND_UP_N (size, 512);
b->data = realloc (b->data, b->size);
if (b->data == NULL)
return -ENOMEM;
return 0;
}
static const struct spa_pod_builder_callbacks builder_callbacks = {
SPA_VERSION_POD_BUILDER_CALLBACKS,
.overflow = builder_overflow
};
static struct spa_pod *
convert_1 (ConvertData *d)
{
struct spa_pod_frame f;
if (!(d->type = find_media_types (gst_structure_get_name (d->cs))))
return NULL;
d->b.write = write_pod;
d->b.callbacks = &builder_callbacks;
d->b.callbacks_data = &d->b;
spa_pod_builder_push_object (&d->b, SPA_TYPE_OBJECT_Format, d->id);
spa_pod_builder_push_object (&d->b, &f, SPA_TYPE_OBJECT_Format, d->id);
spa_pod_builder_prop (&d->b, SPA_FORMAT_mediaType, 0);
spa_pod_builder_id(&d->b, d->type->media_type);
@ -553,7 +559,7 @@ convert_1 (ConvertData *d)
else if (d->type->media_type == SPA_MEDIA_TYPE_audio)
handle_audio_fields (d);
spa_pod_builder_pop (&d->b);
spa_pod_builder_pop (&d->b, &f);
return SPA_MEMBER (d->b.data, 0, struct spa_pod);
}
@ -628,7 +634,7 @@ static const char *audio_id_to_string(uint32_t id)
}
static void
handle_id_prop (struct spa_pod_prop *prop, const char *key, id_to_string_func func, GstCaps *res)
handle_id_prop (const struct spa_pod_prop *prop, const char *key, id_to_string_func func, GstCaps *res)
{
const char * str;
struct spa_pod *val;
@ -670,7 +676,7 @@ handle_id_prop (struct spa_pod_prop *prop, const char *key, id_to_string_func fu
}
static void
handle_int_prop (struct spa_pod_prop *prop, const char *key, GstCaps *res)
handle_int_prop (const struct spa_pod_prop *prop, const char *key, GstCaps *res)
{
struct spa_pod *val;
uint32_t *ints;
@ -714,7 +720,7 @@ handle_int_prop (struct spa_pod_prop *prop, const char *key, GstCaps *res)
}
static void
handle_rect_prop (struct spa_pod_prop *prop, const char *width, const char *height, GstCaps *res)
handle_rect_prop (const struct spa_pod_prop *prop, const char *width, const char *height, GstCaps *res)
{
struct spa_pod *val;
struct spa_rectangle *rect;
@ -767,7 +773,7 @@ handle_rect_prop (struct spa_pod_prop *prop, const char *width, const char *heig
}
static void
handle_fraction_prop (struct spa_pod_prop *prop, const char *key, GstCaps *res)
handle_fraction_prop (const struct spa_pod_prop *prop, const char *key, GstCaps *res)
{
struct spa_pod *val;
struct spa_fraction *fract;
@ -815,7 +821,7 @@ gst_caps_from_format (const struct spa_pod *format)
{
GstCaps *res = NULL;
uint32_t media_type, media_subtype;
struct spa_pod_prop *prop;
const struct spa_pod_prop *prop = NULL;
const struct spa_pod_object *obj = (const struct spa_pod_object *) format;
if (spa_format_parse(format, &media_type, &media_subtype) < 0)
@ -824,7 +830,7 @@ gst_caps_from_format (const struct spa_pod *format)
if (media_type == SPA_MEDIA_TYPE_video) {
if (media_subtype == SPA_MEDIA_SUBTYPE_raw) {
res = gst_caps_new_empty_simple ("video/x-raw");
if ((prop = spa_pod_object_find_prop (obj, SPA_FORMAT_VIDEO_format))) {
if ((prop = spa_pod_object_find_prop (obj, prop, SPA_FORMAT_VIDEO_format))) {
handle_id_prop (prop, "format", video_id_to_string, res);
}
}
@ -837,13 +843,13 @@ gst_caps_from_format (const struct spa_pod *format)
"alignment", G_TYPE_STRING, "au",
NULL);
}
if ((prop = spa_pod_object_find_prop (obj, SPA_FORMAT_VIDEO_size))) {
if ((prop = spa_pod_object_find_prop (obj, prop, SPA_FORMAT_VIDEO_size))) {
handle_rect_prop (prop, "width", "height", res);
}
if ((prop = spa_pod_object_find_prop (obj, SPA_FORMAT_VIDEO_framerate))) {
if ((prop = spa_pod_object_find_prop (obj, prop, SPA_FORMAT_VIDEO_framerate))) {
handle_fraction_prop (prop, "framerate", res);
}
if ((prop = spa_pod_object_find_prop (obj, SPA_FORMAT_VIDEO_maxFramerate))) {
if ((prop = spa_pod_object_find_prop (obj, prop, SPA_FORMAT_VIDEO_maxFramerate))) {
handle_fraction_prop (prop, "max-framerate", res);
}
} else if (media_type == SPA_MEDIA_TYPE_audio) {
@ -851,13 +857,13 @@ gst_caps_from_format (const struct spa_pod *format)
res = gst_caps_new_simple ("audio/x-raw",
"layout", G_TYPE_STRING, "interleaved",
NULL);
if ((prop = spa_pod_object_find_prop (obj, SPA_FORMAT_AUDIO_format))) {
if ((prop = spa_pod_object_find_prop (obj, prop, SPA_FORMAT_AUDIO_format))) {
handle_id_prop (prop, "format", audio_id_to_string, res);
}
if ((prop = spa_pod_object_find_prop (obj, SPA_FORMAT_AUDIO_rate))) {
if ((prop = spa_pod_object_find_prop (obj, prop, SPA_FORMAT_AUDIO_rate))) {
handle_int_prop (prop, "rate", res);
}
if ((prop = spa_pod_object_find_prop (obj, SPA_FORMAT_AUDIO_channels))) {
if ((prop = spa_pod_object_find_prop (obj, prop, SPA_FORMAT_AUDIO_channels))) {
handle_int_prop (prop, "channels", res);
}
}

View file

@ -230,12 +230,13 @@ pool_activated (GstPipeWirePool *pool, GstPipeWireSink *sink)
const struct spa_pod *port_params[2];
struct spa_pod_builder b = { NULL };
uint8_t buffer[1024];
struct spa_pod_frame f;
config = gst_buffer_pool_get_config (GST_BUFFER_POOL (pool));
gst_buffer_pool_config_get_params (config, &caps, &size, &min_buffers, &max_buffers);
spa_pod_builder_init (&b, buffer, sizeof (buffer));
spa_pod_builder_push_object (&b, SPA_TYPE_OBJECT_ParamBuffers, SPA_PARAM_Buffers);
spa_pod_builder_push_object (&b, &f, SPA_TYPE_OBJECT_ParamBuffers, SPA_PARAM_Buffers);
if (size == 0)
spa_pod_builder_add (&b,
SPA_PARAM_BUFFERS_size, SPA_POD_CHOICE_RANGE_Int(0, 0, INT32_MAX),
@ -251,7 +252,7 @@ pool_activated (GstPipeWirePool *pool, GstPipeWireSink *sink)
max_buffers ? max_buffers : INT32_MAX),
SPA_PARAM_BUFFERS_align, SPA_POD_Int(16),
0);
port_params[0] = spa_pod_builder_pop (&b);
port_params[0] = spa_pod_builder_pop (&b, &f);
port_params[1] = spa_pod_builder_add_object (&b,
SPA_TYPE_OBJECT_ParamMeta, SPA_PARAM_Meta,

View file

@ -58,12 +58,13 @@ client_node_marshal_update(void *object,
{
struct pw_proxy *proxy = object;
struct spa_pod_builder *b;
struct spa_pod_frame f;
uint32_t i, n_items;
b = pw_protocol_native_begin_proxy(proxy, PW_CLIENT_NODE_PROXY_METHOD_UPDATE);
spa_pod_builder_push_struct(b, &f);
spa_pod_builder_add(b,
"[",
SPA_POD_Int(change_mask),
SPA_POD_Int(max_input_ports),
SPA_POD_Int(max_output_ports),
@ -80,7 +81,7 @@ client_node_marshal_update(void *object,
SPA_POD_String(props->items[i].key),
SPA_POD_String(props->items[i].value), NULL);
}
spa_pod_builder_add(b, "]", NULL);
spa_pod_builder_pop(b, &f);
pw_protocol_native_end_proxy(proxy, b);
}
@ -96,12 +97,13 @@ client_node_marshal_port_update(void *object,
{
struct pw_proxy *proxy = object;
struct spa_pod_builder *b;
struct spa_pod_frame f[2];
uint32_t i, n_items;
b = pw_protocol_native_begin_proxy(proxy, PW_CLIENT_NODE_PROXY_METHOD_PORT_UPDATE);
spa_pod_builder_push_struct(b, &f[0]);
spa_pod_builder_add(b,
"[",
SPA_POD_Int(direction),
SPA_POD_Int(port_id),
SPA_POD_Int(change_mask),
@ -114,8 +116,8 @@ client_node_marshal_port_update(void *object,
if (info) {
n_items = info->props ? info->props->n_items : 0;
spa_pod_builder_push_struct(b, &f[1]);
spa_pod_builder_add(b,
"[",
SPA_POD_Int(info->flags),
SPA_POD_Int(info->rate),
SPA_POD_Int(n_items), NULL);
@ -124,13 +126,12 @@ client_node_marshal_port_update(void *object,
SPA_POD_String(info->props->items[i].key),
SPA_POD_String(info->props->items[i].value), NULL);
}
spa_pod_builder_add(b,
"]", NULL);
spa_pod_builder_pop(b, &f[1]);
} else {
spa_pod_builder_add(b,
SPA_POD_Pod(NULL), NULL);
}
spa_pod_builder_add(b, "]", NULL);
spa_pod_builder_pop(b, &f[0]);
pw_protocol_native_end_proxy(proxy, b);
}
@ -168,7 +169,7 @@ static int client_node_demarshal_add_mem(void *object, void *data, size_t size)
uint32_t mem_id, type, memfd_idx, flags;
int memfd;
spa_pod_parser_init(&prs, data, size, 0);
spa_pod_parser_init(&prs, data, size);
if (spa_pod_parser_get_struct(&prs,
SPA_POD_Int(&mem_id),
SPA_POD_Id(&type),
@ -192,7 +193,7 @@ static int client_node_demarshal_transport(void *object, void *data, size_t size
uint32_t node_id, ridx, widx;
int readfd, writefd;
spa_pod_parser_init(&prs, data, size, 0);
spa_pod_parser_init(&prs, data, size);
if (spa_pod_parser_get_struct(&prs,
SPA_POD_Int(&node_id),
SPA_POD_Int(&ridx),
@ -217,7 +218,7 @@ static int client_node_demarshal_set_param(void *object, void *data, size_t size
uint32_t seq, id, flags;
const struct spa_pod *param = NULL;
spa_pod_parser_init(&prs, data, size, 0);
spa_pod_parser_init(&prs, data, size);
if (spa_pod_parser_get_struct(&prs,
SPA_POD_Int(&seq),
SPA_POD_Id(&id),
@ -235,7 +236,7 @@ static int client_node_demarshal_event_event(void *object, void *data, size_t si
struct spa_pod_parser prs;
const struct spa_event *event;
spa_pod_parser_init(&prs, data, size, 0);
spa_pod_parser_init(&prs, data, size);
if (spa_pod_parser_get_struct(&prs,
SPA_POD_PodObject(&event)) < 0)
return -EINVAL;
@ -251,7 +252,7 @@ static int client_node_demarshal_command(void *object, void *data, size_t size)
const struct spa_command *command;
uint32_t seq;
spa_pod_parser_init(&prs, data, size, 0);
spa_pod_parser_init(&prs, data, size);
if (spa_pod_parser_get_struct(&prs,
SPA_POD_Int(&seq),
SPA_POD_PodObject(&command)) < 0)
@ -267,7 +268,7 @@ static int client_node_demarshal_add_port(void *object, void *data, size_t size)
struct spa_pod_parser prs;
int32_t seq, direction, port_id;
spa_pod_parser_init(&prs, data, size, 0);
spa_pod_parser_init(&prs, data, size);
if (spa_pod_parser_get_struct(&prs,
SPA_POD_Int(&seq),
SPA_POD_Int(&direction),
@ -284,7 +285,7 @@ static int client_node_demarshal_remove_port(void *object, void *data, size_t si
struct spa_pod_parser prs;
int32_t seq, direction, port_id;
spa_pod_parser_init(&prs, data, size, 0);
spa_pod_parser_init(&prs, data, size);
if (spa_pod_parser_get_struct(&prs,
SPA_POD_Int(&seq),
SPA_POD_Int(&direction),
@ -302,7 +303,7 @@ static int client_node_demarshal_port_set_param(void *object, void *data, size_t
uint32_t seq, direction, port_id, id, flags;
const struct spa_pod *param = NULL;
spa_pod_parser_init(&prs, data, size, 0);
spa_pod_parser_init(&prs, data, size);
if (spa_pod_parser_get_struct(&prs,
SPA_POD_Int(&seq),
SPA_POD_Int(&direction),
@ -321,13 +322,14 @@ static int client_node_demarshal_port_use_buffers(void *object, void *data, size
{
struct pw_proxy *proxy = object;
struct spa_pod_parser prs;
struct spa_pod_frame f;
uint32_t seq, direction, port_id, mix_id, n_buffers, data_id;
struct pw_client_node_buffer *buffers;
uint32_t i, j;
spa_pod_parser_init(&prs, data, size, 0);
if (spa_pod_parser_get(&prs,
"["
spa_pod_parser_init(&prs, data, size);
if (spa_pod_parser_push_struct(&prs, &f) < 0 ||
spa_pod_parser_get(&prs,
SPA_POD_Int(&seq),
SPA_POD_Int(&direction),
SPA_POD_Int(&port_id),
@ -389,7 +391,7 @@ static int client_node_demarshal_port_command(void *object, void *data, size_t s
const struct spa_command *command;
uint32_t direction, port_id;
spa_pod_parser_init(&prs, data, size, 0);
spa_pod_parser_init(&prs, data, size);
if (spa_pod_parser_get_struct(&prs,
SPA_POD_Int(&direction),
SPA_POD_Int(&port_id),
@ -408,7 +410,7 @@ static int client_node_demarshal_port_set_io(void *object, void *data, size_t si
struct spa_pod_parser prs;
uint32_t seq, direction, port_id, mix_id, id, memid, off, sz;
spa_pod_parser_init(&prs, data, size, 0);
spa_pod_parser_init(&prs, data, size);
if (spa_pod_parser_get_struct(&prs,
SPA_POD_Int(&seq),
SPA_POD_Int(&direction),
@ -434,7 +436,7 @@ static int client_node_demarshal_set_io(void *object, void *data, size_t size)
struct spa_pod_parser prs;
uint32_t id, memid, off, sz;
spa_pod_parser_init(&prs, data, size, 0);
spa_pod_parser_init(&prs, data, size);
if (spa_pod_parser_get_struct(&prs,
SPA_POD_Id(&id),
SPA_POD_Int(&memid),
@ -597,12 +599,13 @@ client_node_marshal_port_use_buffers(void *object,
{
struct pw_resource *resource = object;
struct spa_pod_builder *b;
struct spa_pod_frame f;
uint32_t i, j;
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_PORT_USE_BUFFERS);
spa_pod_builder_push_struct(b, &f);
spa_pod_builder_add(b,
"[",
SPA_POD_Int(seq),
SPA_POD_Int(direction),
SPA_POD_Int(port_id),
@ -636,7 +639,7 @@ client_node_marshal_port_use_buffers(void *object,
SPA_POD_Int(d->maxsize), NULL);
}
}
spa_pod_builder_add(b, "]", NULL);
spa_pod_builder_pop(b, &f);
pw_protocol_native_end_resource(resource, b);
}
@ -714,7 +717,7 @@ static int client_node_demarshal_done(void *object, void *data, size_t size)
struct spa_pod_parser prs;
uint32_t seq, res;
spa_pod_parser_init(&prs, data, size, 0);
spa_pod_parser_init(&prs, data, size);
if (spa_pod_parser_get_struct(&prs,
SPA_POD_Int(&seq),
SPA_POD_Int(&res)) < 0)
@ -728,14 +731,15 @@ static int client_node_demarshal_update(void *object, void *data, size_t size)
{
struct pw_resource *resource = object;
struct spa_pod_parser prs;
struct spa_pod_frame f;
uint32_t change_mask, max_input_ports, max_output_ports, n_params;
const struct spa_pod **params;
struct spa_dict props;
uint32_t i;
spa_pod_parser_init(&prs, data, size, 0);
if (spa_pod_parser_get(&prs,
"["
spa_pod_parser_init(&prs, data, size);
if (spa_pod_parser_push_struct(&prs, &f) < 0 ||
spa_pod_parser_get(&prs,
SPA_POD_Int(&change_mask),
SPA_POD_Int(&max_input_ports),
SPA_POD_Int(&max_output_ports),
@ -774,15 +778,16 @@ static int client_node_demarshal_port_update(void *object, void *data, size_t si
{
struct pw_resource *resource = object;
struct spa_pod_parser prs;
struct spa_pod_frame f;
uint32_t i, direction, port_id, change_mask, n_params;
const struct spa_pod **params = NULL;
struct spa_port_info info = { 0 }, *infop = NULL;
struct spa_pod *ipod;
struct spa_dict props;
spa_pod_parser_init(&prs, data, size, 0);
if (spa_pod_parser_get(&prs,
"["
spa_pod_parser_init(&prs, data, size);
if (spa_pod_parser_push_struct(&prs, &f) < 0 ||
spa_pod_parser_get(&prs,
SPA_POD_Int(&direction),
SPA_POD_Int(&port_id),
SPA_POD_Int(&change_mask),
@ -801,11 +806,12 @@ static int client_node_demarshal_port_update(void *object, void *data, size_t si
if (ipod) {
struct spa_pod_parser p2;
struct spa_pod_frame f2;
infop = &info;
spa_pod_parser_pod(&p2, ipod);
if (spa_pod_parser_get(&p2,
"["
if (spa_pod_parser_push_struct(&p2, &f2) < 0 ||
spa_pod_parser_get(&p2,
SPA_POD_Int(&info.flags),
SPA_POD_Int(&info.rate),
SPA_POD_Int(&props.n_items), NULL) < 0)
@ -838,7 +844,7 @@ static int client_node_demarshal_set_active(void *object, void *data, size_t siz
struct spa_pod_parser prs;
int active;
spa_pod_parser_init(&prs, data, size, 0);
spa_pod_parser_init(&prs, data, size);
if (spa_pod_parser_get_struct(&prs,
SPA_POD_Bool(&active)) < 0)
return -EINVAL;
@ -853,7 +859,7 @@ static int client_node_demarshal_event_method(void *object, void *data, size_t s
struct spa_pod_parser prs;
struct spa_event *event;
spa_pod_parser_init(&prs, data, size, 0);
spa_pod_parser_init(&prs, data, size);
if (spa_pod_parser_get_struct(&prs,
SPA_POD_PodObject(&event)) < 0)
return -EINVAL;

View file

@ -352,20 +352,22 @@ static inline void *begin_write(struct pw_protocol_native_connection *conn, uint
return p + 2;
}
static uint32_t write_pod(struct spa_pod_builder *b, const void *data, uint32_t size)
static int builder_overflow(void *callbacks_data, uint32_t size)
{
struct impl *impl = SPA_CONTAINER_OF(b, struct impl, builder);
uint32_t ref = b->state.offset;
struct impl *impl = callbacks_data;
struct spa_pod_builder *b = &impl->builder;
if (b->size <= ref) {
b->size = SPA_ROUND_UP_N(ref + size, 4096);
b->data = begin_write(&impl->this, b->size);
}
memcpy(SPA_MEMBER(b->data, ref, void), data, size);
return ref;
b->size = SPA_ROUND_UP_N(size, 4096);
if ((b->data = begin_write(&impl->this, b->size)) == NULL)
return -ENOMEM;
return 0;
}
static const struct spa_pod_builder_callbacks builder_callbacks = {
SPA_VERSION_POD_BUILDER_CALLBACKS,
.overflow = builder_overflow
};
struct spa_pod_builder *
pw_protocol_native_connection_begin_resource(struct pw_protocol_native_connection *conn,
struct pw_resource *resource,
@ -375,8 +377,9 @@ pw_protocol_native_connection_begin_resource(struct pw_protocol_native_connectio
impl->dest_id = resource->id;
impl->opcode = opcode;
impl->builder = (struct spa_pod_builder) { NULL, 0, 0, write_pod };
impl->builder = SPA_POD_BUILDER_INIT(NULL, 0);
impl->builder.callbacks = &builder_callbacks;
impl->builder.callbacks_data = impl;
return &impl->builder;
}
@ -389,8 +392,9 @@ pw_protocol_native_connection_begin_proxy(struct pw_protocol_native_connection *
impl->dest_id = proxy->id;
impl->opcode = opcode;
impl->builder = (struct spa_pod_builder) { NULL, 0, 0, write_pod, };
impl->builder = SPA_POD_BUILDER_INIT(NULL, 0);
impl->builder.callbacks = &builder_callbacks;
impl->builder.callbacks_data = impl;
return &impl->builder;
}

View file

@ -72,6 +72,22 @@ static void core_marshal_get_registry(void *object, uint32_t version, uint32_t n
pw_protocol_native_end_proxy(proxy, b);
}
static void push_dict(struct spa_pod_builder *b, const struct spa_dict *dict)
{
uint32_t i, n_items;
struct spa_pod_frame f;
n_items = dict ? dict->n_items : 0;
spa_pod_builder_push_struct(b, &f);
spa_pod_builder_int(b, n_items);
for (i = 0; i < n_items; i++) {
spa_pod_builder_string(b, dict->items[i].key);
spa_pod_builder_string(b, dict->items[i].value);
}
spa_pod_builder_pop(b, &f);
}
static void
core_marshal_create_object(void *object,
const char *factory_name,
@ -80,29 +96,19 @@ core_marshal_create_object(void *object,
{
struct pw_proxy *proxy = object;
struct spa_pod_builder *b;
uint32_t i, n_items;
struct spa_pod_frame f;
b = pw_protocol_native_begin_proxy(proxy, PW_CORE_PROXY_METHOD_CREATE_OBJECT);
n_items = props ? props->n_items : 0;
spa_pod_builder_add(b, "["
spa_pod_builder_push_struct(b, &f);
spa_pod_builder_add(b,
SPA_POD_String(factory_name),
SPA_POD_Id(type),
SPA_POD_Int(version),
SPA_POD_Int(n_items),
NULL);
for (i = 0; i < n_items; i++) {
spa_pod_builder_add(b,
SPA_POD_String(props->items[i].key),
SPA_POD_String(props->items[i].value),
NULL);
}
spa_pod_builder_add(b,
SPA_POD_Int(new_id),
"]",
NULL);
push_dict(b, props);
spa_pod_builder_int(b, new_id);
spa_pod_builder_pop(b, &f);
pw_protocol_native_end_proxy(proxy, b);
}
@ -125,20 +131,27 @@ static int core_demarshal_info(void *object, void *data, size_t size)
{
struct pw_proxy *proxy = object;
struct spa_dict props;
struct spa_pod_frame f[2];
struct pw_core_info info;
struct spa_pod_parser prs;
uint32_t i;
spa_pod_parser_init(&prs, data, size, 0);
spa_pod_parser_init(&prs, data, size);
if (spa_pod_parser_push_struct(&prs, &f[0]) < 0)
return -EINVAL;
if (spa_pod_parser_get(&prs,
"["
SPA_POD_Int(&info.id),
SPA_POD_Long(&info.change_mask),
SPA_POD_String(&info.user_name),
SPA_POD_String(&info.host_name),
SPA_POD_String(&info.version),
SPA_POD_String(&info.name),
SPA_POD_Int(&info.cookie),
SPA_POD_Int(&info.cookie), NULL) < 0)
return -EINVAL;
if (spa_pod_parser_push_struct(&prs, &f[1]) < 0)
return -EINVAL;
if (spa_pod_parser_get(&prs,
SPA_POD_Int(&props.n_items), NULL) < 0)
return -EINVAL;
@ -161,7 +174,7 @@ static int core_demarshal_done(void *object, void *data, size_t size)
struct spa_pod_parser prs;
uint32_t seq;
spa_pod_parser_init(&prs, data, size, 0);
spa_pod_parser_init(&prs, data, size);
if (spa_pod_parser_get_struct(&prs,
SPA_POD_Int(&seq)) < 0)
return -EINVAL;
@ -177,7 +190,7 @@ static int core_demarshal_error(void *object, void *data, size_t size)
uint32_t id, res;
const char *error;
spa_pod_parser_init(&prs, data, size, 0);
spa_pod_parser_init(&prs, data, size);
if (spa_pod_parser_get_struct(&prs,
SPA_POD_Int(&id),
SPA_POD_Int(&res),
@ -194,7 +207,7 @@ static int core_demarshal_remove_id(void *object, void *data, size_t size)
struct spa_pod_parser prs;
uint32_t id;
spa_pod_parser_init(&prs, data, size, 0);
spa_pod_parser_init(&prs, data, size);
if (spa_pod_parser_get_struct(&prs, SPA_POD_Int(&id)) < 0)
return -EINVAL;
@ -206,14 +219,12 @@ static void core_marshal_info(void *object, const struct pw_core_info *info)
{
struct pw_resource *resource = object;
struct spa_pod_builder *b;
uint32_t i, n_items;
struct spa_pod_frame f;
b = pw_protocol_native_begin_resource(resource, PW_CORE_PROXY_EVENT_INFO);
n_items = info->props ? info->props->n_items : 0;
spa_pod_builder_push_struct(b, &f);
spa_pod_builder_add(b,
"[",
SPA_POD_Int(info->id),
SPA_POD_Long(info->change_mask),
SPA_POD_String(info->user_name),
@ -221,16 +232,9 @@ static void core_marshal_info(void *object, const struct pw_core_info *info)
SPA_POD_String(info->version),
SPA_POD_String(info->name),
SPA_POD_Int(info->cookie),
SPA_POD_Int(n_items),
NULL);
for (i = 0; i < n_items; i++) {
spa_pod_builder_add(b,
SPA_POD_String(info->props->items[i].key),
SPA_POD_String(info->props->items[i].value),
NULL);
}
spa_pod_builder_add(b, "]", NULL);
push_dict(b, info->props);
spa_pod_builder_pop(b, &f);
pw_protocol_native_end_resource(resource, b);
}
@ -288,7 +292,7 @@ static int core_demarshal_hello(void *object, void *data, size_t size)
struct spa_pod_parser prs;
uint32_t version;
spa_pod_parser_init(&prs, data, size, 0);
spa_pod_parser_init(&prs, data, size);
if (spa_pod_parser_get_struct(&prs,
SPA_POD_Int(&version)) < 0)
return -EINVAL;
@ -303,7 +307,7 @@ static int core_demarshal_sync(void *object, void *data, size_t size)
struct spa_pod_parser prs;
uint32_t seq;
spa_pod_parser_init(&prs, data, size, 0);
spa_pod_parser_init(&prs, data, size);
if (spa_pod_parser_get_struct(&prs,
SPA_POD_Int(&seq)) < 0)
return -EINVAL;
@ -318,7 +322,7 @@ static int core_demarshal_get_registry(void *object, void *data, size_t size)
struct spa_pod_parser prs;
int32_t version, new_id;
spa_pod_parser_init(&prs, data, size, 0);
spa_pod_parser_init(&prs, data, size);
if (spa_pod_parser_get_struct(&prs,
SPA_POD_Int(&version),
SPA_POD_Int(&new_id)) < 0)
@ -332,16 +336,22 @@ static int core_demarshal_create_object(void *object, void *data, size_t size)
{
struct pw_resource *resource = object;
struct spa_pod_parser prs;
struct spa_pod_frame f[2];
uint32_t version, type, new_id, i;
const char *factory_name;
struct spa_dict props;
spa_pod_parser_init(&prs, data, size, 0);
if (spa_pod_parser_get(&prs,
"["
spa_pod_parser_init(&prs, data, size);
if (spa_pod_parser_push_struct(&prs, &f[0]) < 0 ||
spa_pod_parser_get(&prs,
SPA_POD_String(&factory_name),
SPA_POD_Id(&type),
SPA_POD_Int(&version),
NULL) < 0)
return -EINVAL;
if (spa_pod_parser_push_struct(&prs, &f[1]) < 0 ||
spa_pod_parser_get(&prs,
SPA_POD_Int(&props.n_items), NULL) < 0)
return -EINVAL;
@ -352,6 +362,8 @@ static int core_demarshal_create_object(void *object, void *data, size_t size)
SPA_POD_String(&props.items[i].value), NULL) < 0)
return -EINVAL;
}
spa_pod_parser_pop(&prs, &f[1]);
if (spa_pod_parser_get(&prs,
SPA_POD_Int(&new_id), NULL) < 0)
return -EINVAL;
@ -368,7 +380,7 @@ static int core_demarshal_destroy(void *object, void *data, size_t size)
struct spa_pod_parser prs;
uint32_t id;
spa_pod_parser_init(&prs, data, size, 0);
spa_pod_parser_init(&prs, data, size);
if (spa_pod_parser_get_struct(&prs,
SPA_POD_Int(&id)) < 0)
return -EINVAL;
@ -382,27 +394,20 @@ static void registry_marshal_global(void *object, uint32_t id, uint32_t parent_i
{
struct pw_resource *resource = object;
struct spa_pod_builder *b;
uint32_t i, n_items;
struct spa_pod_frame f;
b = pw_protocol_native_begin_resource(resource, PW_REGISTRY_PROXY_EVENT_GLOBAL);
n_items = props ? props->n_items : 0;
spa_pod_builder_push_struct(b, &f);
spa_pod_builder_add(b,
"[",
SPA_POD_Int(id),
SPA_POD_Int(parent_id),
SPA_POD_Int(permissions),
SPA_POD_Id(type),
SPA_POD_Int(version),
SPA_POD_Int(n_items), NULL);
for (i = 0; i < n_items; i++) {
spa_pod_builder_add(b,
SPA_POD_String(props->items[i].key),
SPA_POD_String(props->items[i].value), NULL);
}
spa_pod_builder_add(b, "]", NULL);
NULL);
push_dict(b, props);
spa_pod_builder_pop(b, &f);
pw_protocol_native_end_resource(resource, b);
}
@ -425,7 +430,7 @@ static int registry_demarshal_bind(void *object, void *data, size_t size)
struct spa_pod_parser prs;
uint32_t id, version, type, new_id;
spa_pod_parser_init(&prs, data, size, 0);
spa_pod_parser_init(&prs, data, size);
if (spa_pod_parser_get_struct(&prs,
SPA_POD_Int(&id),
SPA_POD_Id(&type),
@ -443,7 +448,7 @@ static int registry_demarshal_destroy(void *object, void *data, size_t size)
struct spa_pod_parser prs;
uint32_t id;
spa_pod_parser_init(&prs, data, size, 0);
spa_pod_parser_init(&prs, data, size);
if (spa_pod_parser_get_struct(&prs,
SPA_POD_Int(&id)) < 0)
return -EINVAL;
@ -456,27 +461,20 @@ static void module_marshal_info(void *object, const struct pw_module_info *info)
{
struct pw_resource *resource = object;
struct spa_pod_builder *b;
uint32_t i, n_items;
struct spa_pod_frame f;
b = pw_protocol_native_begin_resource(resource, PW_MODULE_PROXY_EVENT_INFO);
n_items = info->props ? info->props->n_items : 0;
spa_pod_builder_push_struct(b, &f);
spa_pod_builder_add(b,
"[",
SPA_POD_Int(info->id),
SPA_POD_Long(info->change_mask),
SPA_POD_String(info->name),
SPA_POD_String(info->filename),
SPA_POD_String(info->args),
SPA_POD_Int(n_items), NULL);
for (i = 0; i < n_items; i++) {
spa_pod_builder_add(b,
SPA_POD_String(info->props->items[i].key),
SPA_POD_String(info->props->items[i].value), NULL);
}
spa_pod_builder_add(b, "]", NULL);
NULL);
push_dict(b, info->props);
spa_pod_builder_pop(b, &f);
pw_protocol_native_end_resource(resource, b);
}
@ -485,18 +483,23 @@ static int module_demarshal_info(void *object, void *data, size_t size)
{
struct pw_proxy *proxy = object;
struct spa_pod_parser prs;
struct spa_pod_frame f[2];
struct spa_dict props;
struct pw_module_info info;
uint32_t i;
spa_pod_parser_init(&prs, data, size, 0);
if (spa_pod_parser_get(&prs,
"["
spa_pod_parser_init(&prs, data, size);
if (spa_pod_parser_push_struct(&prs, &f[0]) < 0 ||
spa_pod_parser_get(&prs,
SPA_POD_Int(&info.id),
SPA_POD_Long(&info.change_mask),
SPA_POD_String(&info.name),
SPA_POD_String(&info.filename),
SPA_POD_String(&info.args),
SPA_POD_String(&info.args), NULL) < 0)
return -EINVAL;
if (spa_pod_parser_push_struct(&prs, &f[1]) < 0 ||
spa_pod_parser_get(&prs,
SPA_POD_Int(&props.n_items), NULL) < 0)
return -EINVAL;
@ -516,25 +519,18 @@ static void device_marshal_info(void *object, const struct pw_device_info *info)
{
struct pw_resource *resource = object;
struct spa_pod_builder *b;
uint32_t i, n_items;
struct spa_pod_frame f;
b = pw_protocol_native_begin_resource(resource, PW_DEVICE_PROXY_EVENT_INFO);
n_items = info->props ? info->props->n_items : 0;
spa_pod_builder_push_struct(b, &f);
spa_pod_builder_add(b,
"[",
SPA_POD_Int(info->id),
SPA_POD_String(info->name),
SPA_POD_Long(info->change_mask),
SPA_POD_Int(n_items), NULL);
for (i = 0; i < n_items; i++) {
spa_pod_builder_add(b,
SPA_POD_String(info->props->items[i].key),
SPA_POD_String(info->props->items[i].value), NULL);
}
spa_pod_builder_add(b, "]", NULL);
NULL);
push_dict(b, info->props);
spa_pod_builder_pop(b, &f);
pw_protocol_native_end_resource(resource, b);
}
@ -543,16 +539,21 @@ static int device_demarshal_info(void *object, void *data, size_t size)
{
struct pw_proxy *proxy = object;
struct spa_pod_parser prs;
struct spa_pod_frame f[2];
struct spa_dict props;
struct pw_device_info info;
uint32_t i;
spa_pod_parser_init(&prs, data, size, 0);
if (spa_pod_parser_get(&prs,
"["
spa_pod_parser_init(&prs, data, size);
if (spa_pod_parser_push_struct(&prs, &f[0]) < 0 ||
spa_pod_parser_get(&prs,
SPA_POD_Int(&info.id),
SPA_POD_String(&info.name),
SPA_POD_Long(&info.change_mask),
SPA_POD_Long(&info.change_mask), NULL) < 0)
return -EINVAL;
if (spa_pod_parser_push_struct(&prs, &f[1]) < 0 ||
spa_pod_parser_get(&prs,
SPA_POD_Int(&props.n_items), NULL) < 0)
return -EINVAL;
@ -592,7 +593,7 @@ static int device_demarshal_param(void *object, void *data, size_t size)
uint32_t id, index, next;
struct spa_pod *param;
spa_pod_parser_init(&prs, data, size, 0);
spa_pod_parser_init(&prs, data, size);
if (spa_pod_parser_get_struct(&prs,
SPA_POD_Id(&id),
SPA_POD_Int(&index),
@ -628,7 +629,7 @@ static int device_demarshal_enum_params(void *object, void *data, size_t size)
uint32_t id, index, num;
struct spa_pod *filter;
spa_pod_parser_init(&prs, data, size, 0);
spa_pod_parser_init(&prs, data, size);
if (spa_pod_parser_get_struct(&prs,
SPA_POD_Id(&id),
SPA_POD_Int(&index),
@ -662,7 +663,7 @@ static int device_demarshal_set_param(void *object, void *data, size_t size)
uint32_t id, flags;
struct spa_pod *param;
spa_pod_parser_init(&prs, data, size, 0);
spa_pod_parser_init(&prs, data, size);
if (spa_pod_parser_get_struct(&prs,
SPA_POD_Id(&id),
SPA_POD_Int(&flags),
@ -677,27 +678,20 @@ static void factory_marshal_info(void *object, const struct pw_factory_info *inf
{
struct pw_resource *resource = object;
struct spa_pod_builder *b;
uint32_t i, n_items;
struct spa_pod_frame f;
b = pw_protocol_native_begin_resource(resource, PW_FACTORY_PROXY_EVENT_INFO);
n_items = info->props ? info->props->n_items : 0;
spa_pod_builder_push_struct(b, &f);
spa_pod_builder_add(b,
"[",
SPA_POD_Int(info->id),
SPA_POD_Long(info->change_mask),
SPA_POD_String(info->name),
SPA_POD_Id(info->type),
SPA_POD_Int(info->version),
SPA_POD_Int(n_items), NULL);
for (i = 0; i < n_items; i++) {
spa_pod_builder_add(b,
SPA_POD_String(info->props->items[i].key),
SPA_POD_String(info->props->items[i].value), NULL);
}
spa_pod_builder_add(b, "]", NULL);
NULL);
push_dict(b, info->props);
spa_pod_builder_pop(b, &f);
pw_protocol_native_end_resource(resource, b);
}
@ -706,18 +700,23 @@ static int factory_demarshal_info(void *object, void *data, size_t size)
{
struct pw_proxy *proxy = object;
struct spa_pod_parser prs;
struct spa_pod_frame f[2];
struct spa_dict props;
struct pw_factory_info info;
uint32_t i;
spa_pod_parser_init(&prs, data, size, 0);
if (spa_pod_parser_get(&prs,
"["
spa_pod_parser_init(&prs, data, size);
if (spa_pod_parser_push_struct(&prs, &f[0]) < 0 ||
spa_pod_parser_get(&prs,
SPA_POD_Int(&info.id),
SPA_POD_Long(&info.change_mask),
SPA_POD_String(&info.name),
SPA_POD_Id(&info.type),
SPA_POD_Int(&info.version),
SPA_POD_Int(&info.version), NULL) < 0)
return -EINVAL;
if (spa_pod_parser_push_struct(&prs, &f[1]) < 0 ||
spa_pod_parser_get(&prs,
SPA_POD_Int(&props.n_items), NULL) < 0)
return -EINVAL;
@ -737,14 +736,12 @@ static void node_marshal_info(void *object, const struct pw_node_info *info)
{
struct pw_resource *resource = object;
struct spa_pod_builder *b;
uint32_t i, n_items;
struct spa_pod_frame f;
b = pw_protocol_native_begin_resource(resource, PW_NODE_PROXY_EVENT_INFO);
n_items = info->props ? info->props->n_items : 0;
spa_pod_builder_push_struct(b, &f);
spa_pod_builder_add(b,
"[",
SPA_POD_Int(info->id),
SPA_POD_Long(info->change_mask),
SPA_POD_String(info->name),
@ -754,14 +751,9 @@ static void node_marshal_info(void *object, const struct pw_node_info *info)
SPA_POD_Int(info->n_output_ports),
SPA_POD_Id(info->state),
SPA_POD_String(info->error),
SPA_POD_Int(n_items), NULL);
for (i = 0; i < n_items; i++) {
spa_pod_builder_add(b,
SPA_POD_String(info->props->items[i].key),
SPA_POD_String(info->props->items[i].value), NULL);
}
spa_pod_builder_add(b, "]", NULL);
NULL);
push_dict(b, info->props);
spa_pod_builder_pop(b, &f);
pw_protocol_native_end_resource(resource, b);
}
@ -770,13 +762,14 @@ static int node_demarshal_info(void *object, void *data, size_t size)
{
struct pw_proxy *proxy = object;
struct spa_pod_parser prs;
struct spa_pod_frame f[2];
struct spa_dict props;
struct pw_node_info info;
uint32_t i;
spa_pod_parser_init(&prs, data, size, 0);
if (spa_pod_parser_get(&prs,
"["
spa_pod_parser_init(&prs, data, size);
if (spa_pod_parser_push_struct(&prs, &f[0]) < 0 ||
spa_pod_parser_get(&prs,
SPA_POD_Int(&info.id),
SPA_POD_Long(&info.change_mask),
SPA_POD_String(&info.name),
@ -785,7 +778,11 @@ static int node_demarshal_info(void *object, void *data, size_t size)
SPA_POD_Int(&info.max_output_ports),
SPA_POD_Int(&info.n_output_ports),
SPA_POD_Id(&info.state),
SPA_POD_String(&info.error),
SPA_POD_String(&info.error), NULL) < 0)
return -EINVAL;
if (spa_pod_parser_push_struct(&prs, &f[1]) < 0 ||
spa_pod_parser_get(&prs,
SPA_POD_Int(&props.n_items), NULL) < 0)
return -EINVAL;
@ -825,7 +822,7 @@ static int node_demarshal_param(void *object, void *data, size_t size)
uint32_t id, index, next;
struct spa_pod *param;
spa_pod_parser_init(&prs, data, size, 0);
spa_pod_parser_init(&prs, data, size);
if (spa_pod_parser_get_struct(&prs,
SPA_POD_Id(&id),
SPA_POD_Int(&index),
@ -861,7 +858,7 @@ static int node_demarshal_enum_params(void *object, void *data, size_t size)
uint32_t id, index, num;
struct spa_pod *filter;
spa_pod_parser_init(&prs, data, size, 0);
spa_pod_parser_init(&prs, data, size);
if (spa_pod_parser_get_struct(&prs,
SPA_POD_Id(&id),
SPA_POD_Int(&index),
@ -895,7 +892,7 @@ static int node_demarshal_set_param(void *object, void *data, size_t size)
uint32_t id, flags;
struct spa_pod *param;
spa_pod_parser_init(&prs, data, size, 0);
spa_pod_parser_init(&prs, data, size);
if (spa_pod_parser_get_struct(&prs,
SPA_POD_Id(&id),
SPA_POD_Int(&flags),
@ -923,7 +920,7 @@ static int node_demarshal_send_command(void *object, void *data, size_t size)
struct spa_pod_parser prs;
struct spa_command *command;
spa_pod_parser_init(&prs, data, size, 0);
spa_pod_parser_init(&prs, data, size);
if (spa_pod_parser_get_struct(&prs,
SPA_POD_Pod(&command)) < 0)
return -EINVAL;
@ -936,25 +933,18 @@ static void port_marshal_info(void *object, const struct pw_port_info *info)
{
struct pw_resource *resource = object;
struct spa_pod_builder *b;
uint32_t i, n_items;
struct spa_pod_frame f;
b = pw_protocol_native_begin_resource(resource, PW_PORT_PROXY_EVENT_INFO);
n_items = info->props ? info->props->n_items : 0;
spa_pod_builder_push_struct(b, &f);
spa_pod_builder_add(b,
"[",
SPA_POD_Int(info->id),
SPA_POD_Int(info->direction),
SPA_POD_Long(info->change_mask),
SPA_POD_Int(n_items), NULL);
for (i = 0; i < n_items; i++) {
spa_pod_builder_add(b,
SPA_POD_String(info->props->items[i].key),
SPA_POD_String(info->props->items[i].value), NULL);
}
spa_pod_builder_add(b, "]", NULL);
NULL);
push_dict(b, info->props);
spa_pod_builder_pop(b, &f);
pw_protocol_native_end_resource(resource, b);
}
@ -963,16 +953,21 @@ static int port_demarshal_info(void *object, void *data, size_t size)
{
struct pw_proxy *proxy = object;
struct spa_pod_parser prs;
struct spa_pod_frame f[2];
struct spa_dict props;
struct pw_port_info info;
uint32_t i;
spa_pod_parser_init(&prs, data, size, 0);
if (spa_pod_parser_get(&prs,
"["
spa_pod_parser_init(&prs, data, size);
if (spa_pod_parser_push_struct(&prs, &f[0]) < 0 ||
spa_pod_parser_get(&prs,
SPA_POD_Int(&info.id),
SPA_POD_Int(&info.direction),
SPA_POD_Long(&info.change_mask),
SPA_POD_Long(&info.change_mask), NULL) < 0)
return -EINVAL;
if (spa_pod_parser_push_struct(&prs, &f[1]) < 0 ||
spa_pod_parser_get(&prs,
SPA_POD_Int(&props.n_items), NULL) < 0)
return -EINVAL;
@ -1012,7 +1007,7 @@ static int port_demarshal_param(void *object, void *data, size_t size)
uint32_t id, index, next;
struct spa_pod *param;
spa_pod_parser_init(&prs, data, size, 0);
spa_pod_parser_init(&prs, data, size);
if (spa_pod_parser_get_struct(&prs,
SPA_POD_Id(&id),
SPA_POD_Int(&index),
@ -1048,7 +1043,7 @@ static int port_demarshal_enum_params(void *object, void *data, size_t size)
uint32_t id, index, num;
struct spa_pod *filter;
spa_pod_parser_init(&prs, data, size, 0);
spa_pod_parser_init(&prs, data, size);
if (spa_pod_parser_get_struct(&prs,
SPA_POD_Id(&id),
SPA_POD_Int(&index),
@ -1064,24 +1059,17 @@ static void client_marshal_info(void *object, const struct pw_client_info *info)
{
struct pw_resource *resource = object;
struct spa_pod_builder *b;
uint32_t i, n_items;
struct spa_pod_frame f;
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_PROXY_EVENT_INFO);
n_items = info->props ? info->props->n_items : 0;
spa_pod_builder_push_struct(b, &f);
spa_pod_builder_add(b,
"[",
SPA_POD_Int(info->id),
SPA_POD_Long(info->change_mask),
SPA_POD_Int(n_items), NULL);
for (i = 0; i < n_items; i++) {
spa_pod_builder_add(b,
SPA_POD_String(info->props->items[i].key),
SPA_POD_String(info->props->items[i].value), NULL);
}
spa_pod_builder_add(b, "]", NULL);
NULL);
push_dict(b, info->props);
spa_pod_builder_pop(b, &f);
pw_protocol_native_end_resource(resource, b);
}
@ -1090,15 +1078,20 @@ static int client_demarshal_info(void *object, void *data, size_t size)
{
struct pw_proxy *proxy = object;
struct spa_pod_parser prs;
struct spa_pod_frame f[2];
struct spa_dict props;
struct pw_client_info info;
uint32_t i;
spa_pod_parser_init(&prs, data, size, 0);
if (spa_pod_parser_get(&prs,
"["
spa_pod_parser_init(&prs, data, size);
if (spa_pod_parser_push_struct(&prs, &f[0]) < 0 ||
spa_pod_parser_get(&prs,
SPA_POD_Int(&info.id),
SPA_POD_Long(&info.change_mask),
SPA_POD_Long(&info.change_mask), NULL) < 0)
return -EINVAL;
if (spa_pod_parser_push_struct(&prs, &f[1]) < 0 ||
spa_pod_parser_get(&prs,
SPA_POD_Int(&props.n_items), NULL) < 0)
return -EINVAL;
@ -1119,6 +1112,7 @@ static void client_marshal_permissions(void *object, uint32_t index, uint32_t n_
{
struct pw_resource *resource = object;
struct spa_pod_builder *b;
struct spa_pod_frame f[2];
uint32_t i, n = 0;
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_PROXY_EVENT_PERMISSIONS);
@ -1128,19 +1122,19 @@ static void client_marshal_permissions(void *object, uint32_t index, uint32_t n_
n++;
}
spa_pod_builder_add(b,
"[",
SPA_POD_Int(index),
SPA_POD_Int(n), NULL);
spa_pod_builder_push_struct(b, &f[0]);
spa_pod_builder_int(b, index);
spa_pod_builder_push_struct(b, &f[1]);
spa_pod_builder_int(b, n);
for (i = 0; i < n_permissions; i++) {
if (permissions[i].permissions == SPA_ID_INVALID)
continue;
spa_pod_builder_add(b,
SPA_POD_Int(permissions[i].id),
SPA_POD_Int(permissions[i].permissions), NULL);
spa_pod_builder_int(b, permissions[i].id);
spa_pod_builder_int(b, permissions[i].permissions);
}
spa_pod_builder_add(b, "]", NULL);
spa_pod_builder_pop(b, &f[1]);
spa_pod_builder_pop(b, &f[0]);
pw_protocol_native_end_resource(resource, b);
}
@ -1150,12 +1144,18 @@ static int client_demarshal_permissions(void *object, void *data, size_t size)
struct pw_proxy *proxy = object;
struct pw_permission *permissions;
struct spa_pod_parser prs;
struct spa_pod_frame f[2];
uint32_t i, index, n_permissions;
spa_pod_parser_init(&prs, data, size, 0);
if (spa_pod_parser_get(&prs, "[",
SPA_POD_Int(&index),
SPA_POD_Int(&n_permissions), NULL) < 0)
spa_pod_parser_init(&prs, data, size);
if (spa_pod_parser_push_struct(&prs, &f[0]) < 0 ||
spa_pod_parser_get(&prs,
SPA_POD_Int(&index), NULL) < 0)
return -EINVAL;
if (spa_pod_parser_push_struct(&prs, &f[1]) < 0 ||
spa_pod_parser_get(&prs,
SPA_POD_Int(&n_permissions), NULL) < 0)
return -EINVAL;
permissions = alloca(n_permissions * sizeof(struct pw_permission));
@ -1189,7 +1189,7 @@ static int client_demarshal_error(void *object, void *data, size_t size)
uint32_t id, res;
const char *error;
spa_pod_parser_init(&prs, data, size, 0);
spa_pod_parser_init(&prs, data, size);
if (spa_pod_parser_get_struct(&prs,
SPA_POD_Int(&id),
SPA_POD_Int(&res),
@ -1218,21 +1218,13 @@ static void client_marshal_update_properties(void *object, const struct spa_dict
{
struct pw_proxy *proxy = object;
struct spa_pod_builder *b;
uint32_t i, n_items;
struct spa_pod_frame f;
b = pw_protocol_native_begin_proxy(proxy, PW_CLIENT_PROXY_METHOD_UPDATE_PROPERTIES);
n_items = props ? props->n_items : 0;
spa_pod_builder_add(b, "[",
SPA_POD_Int(n_items), NULL);
for (i = 0; i < n_items; i++) {
spa_pod_builder_add(b,
SPA_POD_String(props->items[i].key),
SPA_POD_String(props->items[i].value), NULL);
}
spa_pod_builder_add(b, "]", NULL);
spa_pod_builder_push_struct(b, &f);
push_dict(b, props);
spa_pod_builder_pop(b, &f);
pw_protocol_native_end_proxy(proxy, b);
}
@ -1242,12 +1234,14 @@ static int client_demarshal_update_properties(void *object, void *data, size_t s
struct pw_resource *resource = object;
struct spa_dict props;
struct spa_pod_parser prs;
struct spa_pod_frame f[2];
uint32_t i;
spa_pod_parser_init(&prs, data, size, 0);
if (spa_pod_parser_get(&prs,
"[",
SPA_POD_Int(&props.n_items), NULL) < 0)
spa_pod_parser_init(&prs, data, size);
if (spa_pod_parser_push_struct(&prs, &f[0]) < 0 ||
spa_pod_parser_push_struct(&prs, &f[1]) < 0 ||
spa_pod_parser_get(&prs,
SPA_POD_Int(&props.n_items), NULL) < 0)
return -EINVAL;
props.items = alloca(props.n_items * sizeof(struct spa_dict_item));
@ -1268,7 +1262,7 @@ static int client_demarshal_get_permissions(void *object, void *data, size_t siz
struct spa_pod_parser prs;
uint32_t index, num;
spa_pod_parser_init(&prs, data, size, 0);
spa_pod_parser_init(&prs, data, size);
if (spa_pod_parser_get_struct(&prs,
SPA_POD_Int(&index),
SPA_POD_Int(&num)) < 0)
@ -1283,19 +1277,18 @@ static void client_marshal_update_permissions(void *object, uint32_t n_permissio
{
struct pw_proxy *proxy = object;
struct spa_pod_builder *b;
struct spa_pod_frame f;
uint32_t i;
b = pw_protocol_native_begin_proxy(proxy, PW_CLIENT_PROXY_METHOD_UPDATE_PERMISSIONS);
spa_pod_builder_add(b, "[",
SPA_POD_Int(n_permissions), NULL);
spa_pod_builder_push_struct(b, &f);
spa_pod_builder_int(b, n_permissions);
for (i = 0; i < n_permissions; i++) {
spa_pod_builder_add(b,
SPA_POD_Int(permissions[i].id),
SPA_POD_Int(permissions[i].permissions), NULL);
spa_pod_builder_int(b, permissions[i].id);
spa_pod_builder_int(b, permissions[i].permissions);
}
spa_pod_builder_add(b, "]", NULL);
spa_pod_builder_pop(b, &f);
pw_protocol_native_end_proxy(proxy, b);
}
@ -1305,11 +1298,12 @@ static int client_demarshal_update_permissions(void *object, void *data, size_t
struct pw_resource *resource = object;
struct pw_permission *permissions;
struct spa_pod_parser prs;
struct spa_pod_frame f[1];
uint32_t i, n_permissions;
spa_pod_parser_init(&prs, data, size, 0);
if (spa_pod_parser_get(&prs,
"[",
spa_pod_parser_init(&prs, data, size);
if (spa_pod_parser_push_struct(&prs, &f[0]) < 0 ||
spa_pod_parser_get(&prs,
SPA_POD_Int(&n_permissions), NULL) < 0)
return -EINVAL;
@ -1329,14 +1323,12 @@ static void link_marshal_info(void *object, const struct pw_link_info *info)
{
struct pw_resource *resource = object;
struct spa_pod_builder *b;
uint32_t i, n_items;
struct spa_pod_frame f;
b = pw_protocol_native_begin_resource(resource, PW_LINK_PROXY_EVENT_INFO);
n_items = info->props ? info->props->n_items : 0;
spa_pod_builder_push_struct(b, &f);
spa_pod_builder_add(b,
"[",
SPA_POD_Int(info->id),
SPA_POD_Long(info->change_mask),
SPA_POD_Int(info->output_node_id),
@ -1346,14 +1338,9 @@ static void link_marshal_info(void *object, const struct pw_link_info *info)
SPA_POD_Int(info->state),
SPA_POD_String(info->error),
SPA_POD_Pod(info->format),
SPA_POD_Int(n_items), NULL);
for (i = 0; i < n_items; i++) {
spa_pod_builder_add(b,
SPA_POD_String(info->props->items[i].key),
SPA_POD_String(info->props->items[i].value), NULL);
}
spa_pod_builder_add(b, "]", NULL);
NULL);
push_dict(b, info->props);
spa_pod_builder_pop(b, &f);
pw_protocol_native_end_resource(resource, b);
}
@ -1362,13 +1349,14 @@ static int link_demarshal_info(void *object, void *data, size_t size)
{
struct pw_proxy *proxy = object;
struct spa_pod_parser prs;
struct spa_pod_frame f[2];
struct spa_dict props;
struct pw_link_info info = { 0, };
uint32_t i;
spa_pod_parser_init(&prs, data, size, 0);
if (spa_pod_parser_get(&prs,
"["
spa_pod_parser_init(&prs, data, size);
if (spa_pod_parser_push_struct(&prs, &f[0]) < 0 ||
spa_pod_parser_get(&prs,
SPA_POD_Int(&info.id),
SPA_POD_Long(&info.change_mask),
SPA_POD_Int(&info.output_node_id),
@ -1377,7 +1365,11 @@ static int link_demarshal_info(void *object, void *data, size_t size)
SPA_POD_Int(&info.input_port_id),
SPA_POD_Int(&info.state),
SPA_POD_String(&info.error),
SPA_POD_Pod(&info.format),
SPA_POD_Pod(&info.format), NULL) < 0)
return -EINVAL;
if (spa_pod_parser_push_struct(&prs, &f[1]) < 0 ||
spa_pod_parser_get(&prs,
SPA_POD_Int(&props.n_items), NULL) < 0)
return -EINVAL;
@ -1397,17 +1389,22 @@ static int registry_demarshal_global(void *object, void *data, size_t size)
{
struct pw_proxy *proxy = object;
struct spa_pod_parser prs;
struct spa_pod_frame f[2];
uint32_t id, parent_id, permissions, type, version, i;
struct spa_dict props;
spa_pod_parser_init(&prs, data, size, 0);
if (spa_pod_parser_get(&prs,
"["
spa_pod_parser_init(&prs, data, size);
if (spa_pod_parser_push_struct(&prs, &f[0]) < 0 ||
spa_pod_parser_get(&prs,
SPA_POD_Int(&id),
SPA_POD_Int(&parent_id),
SPA_POD_Int(&permissions),
SPA_POD_Id(&type),
SPA_POD_Int(&version),
SPA_POD_Int(&version), NULL) < 0)
return -EINVAL;
if (spa_pod_parser_push_struct(&prs, &f[1]) < 0 ||
spa_pod_parser_get(&prs,
SPA_POD_Int(&props.n_items), NULL) < 0)
return -EINVAL;
@ -1431,7 +1428,7 @@ static int registry_demarshal_global_remove(void *object, void *data, size_t siz
struct spa_pod_parser prs;
uint32_t id;
spa_pod_parser_init(&prs, data, size, 0);
spa_pod_parser_init(&prs, data, size);
if (spa_pod_parser_get_struct(&prs,
SPA_POD_Int(&id)) < 0)
return -EINVAL;

View file

@ -102,12 +102,15 @@ static struct monitor_item *add_item(struct pw_spa_monitor *this,
if (info) {
struct spa_pod_parser prs;
struct spa_pod_frame f;
spa_pod_parser_pod(&prs, info);
if (spa_pod_parser_get(&prs, "[", NULL) == 0) {
if (spa_pod_parser_push_struct(&prs, &f) == 0) {
while (true) {
const char *key, *val;
if (spa_pod_parser_get(&prs, "ss", &key, &val, NULL) < 0)
if (spa_pod_parser_get(&prs,
SPA_POD_String(&key),
SPA_POD_String(&val), NULL) < 0)
break;
pw_properties_set(props, key, val);
}

View file

@ -167,6 +167,7 @@ setup_props(struct pw_core *core, struct spa_node *spa_node, struct pw_propertie
uint32_t index = 0;
uint8_t buf[2048];
struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buf, sizeof(buf));
const struct spa_pod_prop *prop = NULL;
if ((res = spa_node_enum_params(spa_node, SPA_PARAM_Props, &index, NULL, &props, &b)) <= 0) {
pw_log_debug("spa_node_get_props failed: %d", res);
@ -174,14 +175,13 @@ setup_props(struct pw_core *core, struct spa_node *spa_node, struct pw_propertie
}
while ((key = pw_properties_iterate(pw_props, &state))) {
struct spa_pod_prop *prop;
uint32_t type = 0;
type = spa_debug_type_find_type(NULL, key);
if (type == SPA_TYPE_None)
continue;
if ((prop = spa_pod_find_prop(props, type))) {
if ((prop = spa_pod_find_prop(props, prop, type))) {
const char *value = pw_properties_get(pw_props, key);
pw_log_info("configure prop %s", key);

View file

@ -727,9 +727,9 @@ static int do_allocation(struct pw_link *this, uint32_t in_state, uint32_t out_s
spa_pod_parse_object(param,
SPA_TYPE_OBJECT_ParamBuffers, NULL,
SPA_PARAM_BUFFERS_buffers, SPA_POD_Int(&qmax_buffers),
SPA_PARAM_BUFFERS_size, SPA_POD_Int(&qminsize),
SPA_PARAM_BUFFERS_stride, SPA_POD_Int(&qstride),
SPA_PARAM_BUFFERS_buffers, SPA_POD_Int(&qmax_buffers));
SPA_PARAM_BUFFERS_stride, SPA_POD_Int(&qstride));
max_buffers =
qmax_buffers == 0 ? max_buffers : SPA_MIN(qmax_buffers,

View file

@ -648,18 +648,19 @@ static int process_notify(struct stream *impl, struct spa_pod_sequence *sequence
{
struct spa_pod_builder b = { 0 };
bool changed;
struct spa_pod_frame f[2];
spa_pod_builder_init(&b, impl->io_notify, impl->io_notify_size);
spa_pod_builder_push_sequence(&b, 0);
spa_pod_builder_push_sequence(&b, &f[0], 0);
if ((changed = impl->props.changed)) {
spa_pod_builder_control(&b, 0, SPA_CONTROL_Properties);
spa_pod_builder_push_object(&b, SPA_TYPE_OBJECT_Props, SPA_PARAM_Props);
spa_pod_builder_push_object(&b, &f[1], SPA_TYPE_OBJECT_Props, SPA_PARAM_Props);
spa_pod_builder_prop(&b, SPA_PROP_volume, 0);
spa_pod_builder_float(&b, impl->props.volume);
spa_pod_builder_pop(&b);
spa_pod_builder_pop(&b, &f[1]);
impl->props.changed = false;
}
spa_pod_builder_pop(&b);
spa_pod_builder_pop(&b, &f[0]);
if (changed && pw_log_level_enabled(SPA_LOG_LEVEL_DEBUG))
spa_debug_pod(2, NULL, &impl->io_notify->sequence.pod);