clean up pod_builder

Remove the frame argument from the builder, we can use the builder
allocated frames.
Add deref function to builder to make it more flexible later.
Add some more recursion depth checks in the parser.
Improve props filter, also filter other types.
This commit is contained in:
Wim Taymans 2017-11-08 15:48:31 +01:00
parent 30a4651c51
commit cc47fb7e3a
31 changed files with 246 additions and 218 deletions

View file

@ -242,7 +242,6 @@ static int port_enum_formats(struct spa_node *node,
struct spa_pod_builder *builder)
{
struct data *d = SPA_CONTAINER_OF(node, struct data, impl_node);
struct spa_pod_frame f[2];
SDL_RendererInfo info;
int i, c;
@ -251,12 +250,12 @@ static int port_enum_formats(struct spa_node *node,
SDL_GetRendererInfo(d->renderer, &info);
spa_pod_builder_push_object(builder, &f[0],
spa_pod_builder_push_object(builder,
d->t->param.idEnumFormat, d->type.format);
spa_pod_builder_id(builder, d->type.media_type.video);
spa_pod_builder_id(builder, d->type.media_subtype.raw);
spa_pod_builder_push_prop(builder, &f[1], d->type.format_video.format,
spa_pod_builder_push_prop(builder, d->type.format_video.format,
SPA_POD_PROP_FLAG_UNSET |
SPA_POD_PROP_RANGE_ENUM);
for (i = 0, c = 0; i < info.num_texture_formats; i++) {
@ -274,7 +273,7 @@ static int port_enum_formats(struct spa_node *node,
if (id != d->type.video_format.UNKNOWN)
spa_pod_builder_id(builder, id);
}
spa_pod_builder_pop(builder, &f[1]);
spa_pod_builder_pop(builder);
spa_pod_builder_add(builder,
":", d->type.format_video.size, "Rru", &SPA_RECTANGLE(WIDTH, HEIGHT),
2, &SPA_RECTANGLE(1,1),
@ -284,7 +283,7 @@ static int port_enum_formats(struct spa_node *node,
2, &SPA_FRACTION(0,1),
&SPA_FRACTION(30,1),
NULL);
spa_pod_builder_pop(builder, &f[0]);
spa_pod_builder_pop(builder);
(*index)++;

View file

@ -238,7 +238,6 @@ static int port_enum_formats(struct spa_node *node,
struct spa_pod_builder *builder)
{
struct data *d = SPA_CONTAINER_OF(node, struct data, impl_node);
struct spa_pod_frame f[2];
SDL_RendererInfo info;
int i, c;
@ -247,12 +246,12 @@ static int port_enum_formats(struct spa_node *node,
SDL_GetRendererInfo(d->renderer, &info);
spa_pod_builder_push_object(builder, &f[0],
spa_pod_builder_push_object(builder,
d->t->param.idEnumFormat, d->type.format);
spa_pod_builder_id(builder, d->type.media_type.video);
spa_pod_builder_id(builder, d->type.media_subtype.raw);
spa_pod_builder_push_prop(builder, &f[1], d->type.format_video.format,
spa_pod_builder_push_prop(builder, d->type.format_video.format,
SPA_POD_PROP_FLAG_UNSET |
SPA_POD_PROP_RANGE_ENUM);
for (i = 0, c = 0; i < info.num_texture_formats; i++) {
@ -270,7 +269,7 @@ static int port_enum_formats(struct spa_node *node,
if (id != d->type.video_format.UNKNOWN)
spa_pod_builder_id(builder, id);
}
spa_pod_builder_pop(builder, &f[1]);
spa_pod_builder_pop(builder);
spa_pod_builder_add(builder,
":", d->type.format_video.size, "Rru", &SPA_RECTANGLE(WIDTH, HEIGHT),
@ -281,7 +280,7 @@ static int port_enum_formats(struct spa_node *node,
2, &SPA_FRACTION(0,1),
&SPA_FRACTION(30,1),
NULL);
spa_pod_builder_pop(builder, &f[0]);
spa_pod_builder_pop(builder);
(*index)++;

View file

@ -306,7 +306,6 @@ static void on_state_changed(void *_data, enum pw_remote_state old, enum pw_remo
const struct spa_pod_object *params[1];
uint8_t buffer[1024];
struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buffer, sizeof(buffer));
struct spa_pod_frame f[2];
SDL_RendererInfo info;
int i, c;
@ -317,12 +316,12 @@ static void on_state_changed(void *_data, enum pw_remote_state old, enum pw_remo
SDL_GetRendererInfo(data->renderer, &info);
spa_pod_builder_push_object(&b, &f[0],
spa_pod_builder_push_object(&b,
data->type.param.idEnumFormat, data->type.format);
spa_pod_builder_id(&b, data->type.media_type.video);
spa_pod_builder_id(&b, data->type.media_subtype.raw);
spa_pod_builder_push_prop(&b, &f[1], data->type.format_video.format,
spa_pod_builder_push_prop(&b, data->type.format_video.format,
SPA_POD_PROP_FLAG_UNSET |
SPA_POD_PROP_RANGE_ENUM);
for (i = 0, c = 0; i < info.num_texture_formats; i++) {
@ -340,7 +339,7 @@ static void on_state_changed(void *_data, enum pw_remote_state old, enum pw_remo
if (id != data->type.video_format.UNKNOWN)
spa_pod_builder_id(&b, id);
}
spa_pod_builder_pop(&b, &f[1]);
spa_pod_builder_pop(&b);
spa_pod_builder_add(&b,
":", data->type.format_video.size, "Rru", &SPA_RECTANGLE(WIDTH, HEIGHT),
2, &SPA_RECTANGLE(1,1),
@ -350,8 +349,7 @@ static void on_state_changed(void *_data, enum pw_remote_state old, enum pw_remo
2, &SPA_RECTANGLE(0,1),
&SPA_RECTANGLE(30,1),
NULL);
spa_pod_builder_pop(&b, &f[0]);
params[0] = SPA_POD_BUILDER_DEREF(&b, f[0].ref, struct spa_pod_object);
params[0] = spa_pod_builder_pop_deref(&b);
printf("supported formats:\n");
spa_debug_pod(&params[0]->pod, SPA_DEBUG_FLAG_FORMAT);

View file

@ -372,9 +372,9 @@ get_range_type2 (const GValue *v1, const GValue *v2)
static gboolean
handle_video_fields (ConvertData *d)
{
struct spa_pod_frame f;
const GValue *value, *value2;
int i;
struct spa_pod_prop *prop;
value = gst_structure_get_value (d->cs, "format");
if (value) {
@ -382,7 +382,7 @@ handle_video_fields (ConvertData *d)
int idx;
for (i = 0; (v = get_nth_string (value, i)); i++) {
if (i == 0)
spa_pod_builder_push_prop (&d->b, &f,
spa_pod_builder_push_prop (&d->b,
type.format_video.format,
get_range_type (value));
@ -390,9 +390,9 @@ handle_video_fields (ConvertData *d)
if (idx < SPA_N_ELEMENTS (video_format_map))
spa_pod_builder_id (&d->b, *video_format_map[idx]);
}
prop = spa_pod_builder_pop_deref(&d->b);
if (i > 1)
SPA_POD_BUILDER_DEREF (&d->b, f.ref, struct spa_pod_prop)->body.flags |= SPA_POD_PROP_FLAG_UNSET;
spa_pod_builder_pop (&d->b, &f);
prop->body.flags |= SPA_POD_PROP_FLAG_UNSET;
}
value = gst_structure_get_value (d->cs, "width");
value2 = gst_structure_get_value (d->cs, "height");
@ -400,15 +400,15 @@ handle_video_fields (ConvertData *d)
struct spa_rectangle v;
for (i = 0; get_nth_rectangle (value, value2, i, &v); i++) {
if (i == 0)
spa_pod_builder_push_prop (&d->b, &f,
spa_pod_builder_push_prop (&d->b,
type.format_video.size,
get_range_type2 (value, value2));
spa_pod_builder_rectangle (&d->b, v.width, v.height);
}
prop = spa_pod_builder_pop_deref(&d->b);
if (i > 1)
SPA_POD_BUILDER_DEREF (&d->b, f.ref, struct spa_pod_prop)->body.flags |= SPA_POD_PROP_FLAG_UNSET;
spa_pod_builder_pop (&d->b, &f);
prop->body.flags |= SPA_POD_PROP_FLAG_UNSET;
}
value = gst_structure_get_value (d->cs, "framerate");
@ -416,15 +416,15 @@ handle_video_fields (ConvertData *d)
struct spa_fraction v;
for (i = 0; get_nth_fraction (value, i, &v); i++) {
if (i == 0)
spa_pod_builder_push_prop (&d->b, &f,
spa_pod_builder_push_prop (&d->b,
type.format_video.framerate,
get_range_type (value));
spa_pod_builder_fraction (&d->b, v.num, v.denom);
}
prop = spa_pod_builder_pop_deref(&d->b);
if (i > 1)
SPA_POD_BUILDER_DEREF (&d->b, f.ref, struct spa_pod_prop)->body.flags |= SPA_POD_PROP_FLAG_UNSET;
spa_pod_builder_pop (&d->b, &f);
prop->body.flags |= SPA_POD_PROP_FLAG_UNSET;
}
value = gst_structure_get_value (d->cs, "max-framerate");
@ -432,15 +432,15 @@ handle_video_fields (ConvertData *d)
struct spa_fraction v;
for (i = 0; get_nth_fraction (value, i, &v); i++) {
if (i == 0)
spa_pod_builder_push_prop (&d->b, &f,
spa_pod_builder_push_prop (&d->b,
type.format_video.max_framerate,
get_range_type (value));
spa_pod_builder_fraction (&d->b, v.num, v.denom);
}
prop = spa_pod_builder_pop_deref(&d->b);
if (i > 1)
SPA_POD_BUILDER_DEREF (&d->b, f.ref, struct spa_pod_prop)->body.flags |= SPA_POD_PROP_FLAG_UNSET;
spa_pod_builder_pop (&d->b, &f);
prop->body.flags |= SPA_POD_PROP_FLAG_UNSET;
}
return TRUE;
}
@ -448,8 +448,8 @@ handle_video_fields (ConvertData *d)
static gboolean
handle_audio_fields (ConvertData *d)
{
struct spa_pod_frame f;
const GValue *value;
struct spa_pod_prop *prop;
int i = 0;
value = gst_structure_get_value (d->cs, "format");
@ -458,7 +458,7 @@ handle_audio_fields (ConvertData *d)
int idx;
for (i = 0; (v = get_nth_string (value, i)); i++) {
if (i == 0)
spa_pod_builder_push_prop (&d->b, &f,
spa_pod_builder_push_prop (&d->b,
type.format_audio.format,
get_range_type (value));
@ -466,9 +466,9 @@ handle_audio_fields (ConvertData *d)
if (idx < SPA_N_ELEMENTS (audio_format_map))
spa_pod_builder_id (&d->b, *audio_format_map[idx]);
}
prop = spa_pod_builder_pop_deref(&d->b);
if (i > 1)
SPA_POD_BUILDER_DEREF (&d->b, f.ref, struct spa_pod_prop)->body.flags |= SPA_POD_PROP_FLAG_UNSET;
spa_pod_builder_pop (&d->b, &f);
prop->body.flags |= SPA_POD_PROP_FLAG_UNSET;
}
value = gst_structure_get_value (d->cs, "layout");
@ -485,45 +485,45 @@ handle_audio_fields (ConvertData *d)
break;
if (i == 0)
spa_pod_builder_push_prop (&d->b, &f,
spa_pod_builder_push_prop (&d->b,
type.format_audio.layout,
get_range_type (value));
spa_pod_builder_int (&d->b, layout);
}
prop = spa_pod_builder_pop_deref(&d->b);
if (i > 1)
SPA_POD_BUILDER_DEREF (&d->b, f.ref, struct spa_pod_prop)->body.flags |= SPA_POD_PROP_FLAG_UNSET;
spa_pod_builder_pop (&d->b, &f);
prop->body.flags |= SPA_POD_PROP_FLAG_UNSET;
}
value = gst_structure_get_value (d->cs, "rate");
if (value) {
int v;
for (i = 0; get_nth_int (value, i, &v); i++) {
if (i == 0)
spa_pod_builder_push_prop (&d->b, &f,
spa_pod_builder_push_prop (&d->b,
type.format_audio.rate,
get_range_type (value));
spa_pod_builder_int (&d->b, v);
}
prop = spa_pod_builder_pop_deref(&d->b);
if (i > 1)
SPA_POD_BUILDER_DEREF (&d->b, f.ref, struct spa_pod_prop)->body.flags |= SPA_POD_PROP_FLAG_UNSET;
spa_pod_builder_pop (&d->b, &f);
prop->body.flags |= SPA_POD_PROP_FLAG_UNSET;
}
value = gst_structure_get_value (d->cs, "channels");
if (value) {
int v;
for (i = 0; get_nth_int (value, i, &v); i++) {
if (i == 0)
spa_pod_builder_push_prop (&d->b, &f,
spa_pod_builder_push_prop (&d->b,
type.format_audio.channels,
get_range_type (value));
spa_pod_builder_int (&d->b, v);
}
prop = spa_pod_builder_pop_deref(&d->b);
if (i > 1)
SPA_POD_BUILDER_DEREF (&d->b, f.ref, struct spa_pod_prop)->body.flags |= SPA_POD_PROP_FLAG_UNSET;
spa_pod_builder_pop (&d->b, &f);
prop->body.flags |= SPA_POD_PROP_FLAG_UNSET;
}
return TRUE;
}
@ -546,7 +546,6 @@ static struct spa_pod_object *
convert_1 (GstCapsFeatures *cf, GstStructure *cs)
{
ConvertData d;
struct spa_pod_frame f;
spa_zero (d);
d.cf = cf;
@ -557,7 +556,7 @@ convert_1 (GstCapsFeatures *cf, GstStructure *cs)
d.b.write = write_pod;
spa_pod_builder_push_object (&d.b, &f, 0, type.format);
spa_pod_builder_push_object (&d.b, 0, type.format);
spa_pod_builder_id(&d.b, *d.type->media_type);
spa_pod_builder_id(&d.b, *d.type->media_subtype);
@ -566,7 +565,7 @@ convert_1 (GstCapsFeatures *cf, GstStructure *cs)
else if (*d.type->media_type == type.media_type.audio)
handle_audio_fields (&d);
spa_pod_builder_pop (&d.b, &f);
spa_pod_builder_pop (&d.b);
return SPA_MEMBER (d.b.data, 0, struct spa_pod_object);
}

View file

@ -231,13 +231,12 @@ pool_activated (GstPipeWirePool *pool, GstPipeWireSink *sink)
struct spa_pod_object *port_params[3];
struct spa_pod_builder b = { NULL };
uint8_t buffer[1024];
struct spa_pod_frame f[1];
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, &f[0], t->param.idBuffers, t->param_alloc_buffers.Buffers);
spa_pod_builder_push_object (&b, t->param.idBuffers, t->param_alloc_buffers.Buffers);
if (size == 0)
spa_pod_builder_add (&b,
":", t->param_alloc_buffers.size, "iru", 0, SPA_PROP_RANGE(0, INT32_MAX), NULL);
@ -252,8 +251,7 @@ pool_activated (GstPipeWirePool *pool, GstPipeWireSink *sink)
max_buffers ? max_buffers : INT32_MAX),
":", t->param_alloc_buffers.align, "i", 16,
NULL);
spa_pod_builder_pop (&b, &f[0]);
port_params[0] = SPA_POD_BUILDER_DEREF (&b, f[0].ref, struct spa_pod_object);
port_params[0] = spa_pod_builder_pop_deref (&b);
port_params[1] = spa_pod_builder_object (&b,
t->param.idMeta, t->param_alloc_meta_enable.MetaEnable,

View file

@ -1327,7 +1327,7 @@ static bool on_global(void *data, struct pw_global *global)
if (spa_node_enum_params(node->node, SPA_ID_INVALID, &index, NULL, &b) == SPA_RESULT_OK) {
int min_latency = -1;
struct spa_pod_object *props = SPA_POD_BUILDER_DEREF(&b, 0, struct spa_pod_object);
struct spa_pod_object *props = spa_pod_builder_deref(&b, 0);
spa_pod_object_parse(props,
":", impl->prop_min_latency, "?i", &min_latency, NULL);

View file

@ -378,7 +378,7 @@ 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, NULL, write_pod };
impl->builder = (struct spa_pod_builder) { NULL, 0, 0, write_pod };
return &impl->builder;
}
@ -407,7 +407,7 @@ 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, NULL, write_pod };
impl->builder = (struct spa_pod_builder) { NULL, 0, 0, write_pod };
return &impl->builder;
}

View file

@ -166,7 +166,7 @@ setup_props(struct pw_core *core, struct spa_node *spa_node, struct pw_propertie
pw_log_debug("spa_node_get_props failed: %d", res);
return SPA_RESULT_ERROR;
}
props = SPA_POD_BUILDER_DEREF(&b, 0, struct spa_pod_object);
props = spa_pod_builder_deref(&b, 0);
while ((key = pw_properties_iterate(pw_props, &state))) {
struct spa_pod_prop *prop;

View file

@ -771,7 +771,7 @@ int pw_core_find_format(struct pw_core *core,
asprintf(error, "no more input formats");
goto error;
}
format = SPA_POD_BUILDER_DEREF(&fb, 0, struct spa_pod_object);
format = spa_pod_builder_deref(&fb, 0);
pw_log_debug("enum output %d with filter: %p", oidx, format);
if (pw_log_level_enabled(SPA_LOG_LEVEL_DEBUG))
spa_debug_pod(&format->pod, SPA_DEBUG_FLAG_FORMAT);
@ -787,7 +787,7 @@ int pw_core_find_format(struct pw_core *core,
asprintf(error, "error output enum formats: %d", res);
goto error;
}
format = SPA_POD_BUILDER_DEREF(&fb, 0, struct spa_pod_object);
format = spa_pod_builder_deref(&fb, 0);
pw_log_debug("Got filtered:");
if (pw_log_level_enabled(SPA_LOG_LEVEL_DEBUG))

View file

@ -136,7 +136,7 @@ static int do_negotiate(struct pw_link *this, uint32_t in_state, uint32_t out_st
if ((res = pw_core_find_format(this->core, output, input, NULL, 0, NULL, &b, &error)) < 0)
goto error;
format = spa_pod_object_copy(SPA_POD_BUILDER_DEREF(&b, 0, struct spa_pod_object));
format = spa_pod_object_copy(spa_pod_builder_deref(&b, 0));
spa_pod_object_fixate(format);
if (out_state > PW_PORT_STATE_CONFIGURE && output->node->info.state == PW_NODE_STATE_IDLE) {
@ -147,7 +147,7 @@ static int do_negotiate(struct pw_link *this, uint32_t in_state, uint32_t out_st
asprintf(&error, "error get output format: %d", res);
goto error;
}
current = SPA_POD_BUILDER_DEREF(&b, 0, struct spa_pod_object);
current = spa_pod_builder_deref(&b, 0);
if (spa_pod_object_compare(current, format) < 0) {
pw_log_debug("link %p: output format change, renegotiate", this);
pw_node_set_state(output->node, PW_NODE_STATE_SUSPENDED);
@ -166,7 +166,7 @@ static int do_negotiate(struct pw_link *this, uint32_t in_state, uint32_t out_st
asprintf(&error, "error get input format: %d", res);
goto error;
}
current = SPA_POD_BUILDER_DEREF(&b, 0, struct spa_pod_object);
current = spa_pod_builder_deref(&b, 0);
if (spa_pod_object_compare(current, format) < 0) {
pw_log_debug("link %p: input format change, renegotiate", this);
pw_node_set_state(input->node, PW_NODE_STATE_SUSPENDED);
@ -410,10 +410,9 @@ param_filter(struct pw_link *this,
if (spa_node_port_enum_params(in_port->node->node, in_port->direction, in_port->port_id,
id, &iidx, NULL, &ib) < 0)
break;
iparam = SPA_POD_BUILDER_DEREF(&ib, 0, struct spa_pod_object);
iparam = spa_pod_builder_deref(&ib, 0);
for (oidx = 0;;) {
struct spa_pod_frame f;
uint32_t offset;
spa_pod_builder_init(&ob, obuf, sizeof(obuf));
@ -421,7 +420,7 @@ param_filter(struct pw_link *this,
out_port->port_id, id, &oidx,
NULL, &ob) < 0)
break;
oparam = SPA_POD_BUILDER_DEREF(&ob, 0, struct spa_pod_object);
oparam = spa_pod_builder_deref(&ob, 0);
if (iidx == 1 && pw_log_level_enabled(SPA_LOG_LEVEL_DEBUG))
spa_debug_pod(&oparam->pod, 0);
@ -430,17 +429,17 @@ param_filter(struct pw_link *this,
continue;
offset = result->offset;
spa_pod_builder_push_object(result, &f, id, iparam->body.type);
spa_pod_builder_push_object(result, id, iparam->body.type);
if ((res = spa_props_filter(result,
SPA_POD_CONTENTS(struct spa_pod_object, iparam),
SPA_POD_CONTENTS_SIZE(struct spa_pod_object, iparam),
SPA_POD_CONTENTS(struct spa_pod_object, oparam),
SPA_POD_CONTENTS_SIZE(struct spa_pod_object, oparam))) < 0) {
result->offset = offset;
result->stack = NULL;
result->depth = 0;
continue;
}
spa_pod_builder_pop(result, &f);
spa_pod_builder_pop(result);
num++;
}
if (pw_log_level_enabled(SPA_LOG_LEVEL_DEBUG))

View file

@ -239,7 +239,7 @@ update_info(struct pw_node *this)
this->core->type.param.idEnumFormat, &state,
NULL, &b) < 0)
break;
fmt = SPA_POD_BUILDER_DEREF(&b, 0, struct spa_pod_object);
fmt = spa_pod_builder_deref(&b, 0);
this->info.input_params =
realloc(this->info.input_params,
@ -262,7 +262,7 @@ update_info(struct pw_node *this)
this->core->type.param.idEnumFormat, &state,
NULL, &b) < 0)
break;
fmt = SPA_POD_BUILDER_DEREF(&b, 0, struct spa_pod_object);
fmt = spa_pod_builder_deref(&b, 0);
this->info.output_params =
realloc(this->info.output_params,

View file

@ -658,7 +658,7 @@ static void add_port_update(struct pw_proxy *proxy, struct pw_port *port, uint32
data->t->param.idList, &idx1,
NULL, &b) < 0)
break;
param = SPA_POD_BUILDER_DEREF(&b, 0, struct spa_pod_object);
param = spa_pod_builder_deref(&b, 0);
spa_pod_object_parse(param,
":", data->t->param.listId, "I", &id, NULL);
@ -670,7 +670,7 @@ static void add_port_update(struct pw_proxy *proxy, struct pw_port *port, uint32
id, &idx2,
NULL, &b) < 0)
break;
param = SPA_POD_BUILDER_DEREF(&b, 0, struct spa_pod_object);
param = spa_pod_builder_deref(&b, 0);
params = realloc(params, sizeof(struct spa_pod_object *) * (n_params + 1));
params[n_params] = spa_pod_object_copy(param);

View file

@ -54,7 +54,11 @@ pw_spa_pod_copy(const struct spa_pod *pod)
return pod ? memcpy(malloc(SPA_POD_SIZE(pod)), pod, SPA_POD_SIZE(pod)) : NULL;
}
#define spa_pod_object_copy(p) ((struct spa_pod_object*)pw_spa_pod_copy(&(p)->pod))
static inline struct spa_pod_object *
spa_pod_object_copy(const struct spa_pod_object *pod)
{
return (struct spa_pod_object*) pw_spa_pod_copy(&pod->pod);
}
#ifdef __cplusplus
} /* extern "C" */