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]);
}