spa: use dynamic builder where we can

With the spa_auto support this becomes feasable and avoids problems when
the pod size is unknown and ends up larger than our stack buffer.
This commit is contained in:
Wim Taymans 2023-10-11 18:04:17 +02:00
parent 779f06865c
commit 7a0b400c18
4 changed files with 105 additions and 83 deletions

View file

@ -26,6 +26,7 @@
#include <spa/param/param.h> #include <spa/param/param.h>
#include <spa/pod/filter.h> #include <spa/pod/filter.h>
#include <spa/pod/parser.h> #include <spa/pod/parser.h>
#include <spa/pod/dynamic.h>
#include <spa/debug/pod.h> #include <spa/debug/pod.h>
#include <spa/debug/log.h> #include <spa/debug/log.h>
@ -484,7 +485,8 @@ static int impl_enum_params(void *object, int seq,
{ {
struct impl *this = object; struct impl *this = object;
struct spa_pod *param; struct spa_pod *param;
struct spa_pod_builder b = { 0 }; spa_auto(spa_pod_dynamic_builder) b = { 0 };
struct spa_pod_builder_state state;
uint8_t buffer[4096]; uint8_t buffer[4096];
struct spa_result_device_params result; struct spa_result_device_params result;
uint32_t count = 0; uint32_t count = 0;
@ -496,6 +498,9 @@ static int impl_enum_params(void *object, int seq,
spa_return_val_if_fail(this != NULL, -EINVAL); spa_return_val_if_fail(this != NULL, -EINVAL);
spa_return_val_if_fail(num != 0, -EINVAL); spa_return_val_if_fail(num != 0, -EINVAL);
spa_pod_dynamic_builder_init(&b, buffer, sizeof(buffer), 4096);
spa_pod_builder_get_state(&b.b, &state);
card = this->card; card = this->card;
result.id = id; result.id = id;
@ -503,7 +508,7 @@ static int impl_enum_params(void *object, int seq,
next: next:
result.index = result.next++; result.index = result.next++;
spa_pod_builder_init(&b, buffer, sizeof(buffer)); spa_pod_builder_reset(&b.b, &state);
switch (id) { switch (id) {
case SPA_PARAM_EnumProfile: case SPA_PARAM_EnumProfile:
@ -511,7 +516,7 @@ static int impl_enum_params(void *object, int seq,
return 0; return 0;
pr = card->profiles[result.index]; pr = card->profiles[result.index];
param = build_profile(&b, id, pr, false); param = build_profile(&b.b, id, pr, false);
break; break;
case SPA_PARAM_Profile: case SPA_PARAM_Profile:
@ -519,7 +524,7 @@ static int impl_enum_params(void *object, int seq,
return 0; return 0;
pr = card->profiles[card->active_profile_index]; pr = card->profiles[card->active_profile_index];
param = build_profile(&b, id, pr, true); param = build_profile(&b.b, id, pr, true);
break; break;
case SPA_PARAM_EnumRoute: case SPA_PARAM_EnumRoute:
@ -527,7 +532,7 @@ static int impl_enum_params(void *object, int seq,
return 0; return 0;
p = card->ports[result.index]; p = card->ports[result.index];
param = build_route(&b, id, p, NULL, SPA_ID_INVALID); param = build_route(&b.b, id, p, NULL, SPA_ID_INVALID);
break; break;
case SPA_PARAM_Route: case SPA_PARAM_Route:
@ -543,7 +548,7 @@ static int impl_enum_params(void *object, int seq,
result.index++; result.index++;
} }
result.next = result.index + 1; result.next = result.index + 1;
param = build_route(&b, id, p, dev, card->active_profile_index); param = build_route(&b.b, id, p, dev, card->active_profile_index);
if (param == NULL) if (param == NULL)
return -errno; return -errno;
break; break;
@ -552,7 +557,7 @@ static int impl_enum_params(void *object, int seq,
return -ENOENT; return -ENOENT;
} }
if (spa_pod_filter(&b, &result.param, param, filter) < 0) if (spa_pod_filter(&b.b, &result.param, param, filter) < 0)
goto next; goto next;
spa_device_emit_result(&this->hooks, seq, 0, spa_device_emit_result(&this->hooks, seq, 0,

View file

@ -15,6 +15,7 @@
#include <spa/utils/string.h> #include <spa/utils/string.h>
#include <spa/param/audio/format.h> #include <spa/param/audio/format.h>
#include <spa/pod/filter.h> #include <spa/pod/filter.h>
#include <spa/pod/dynamic.h>
#include <spa/debug/log.h> #include <spa/debug/log.h>
#include <spa/debug/pod.h> #include <spa/debug/pod.h>
@ -100,7 +101,8 @@ static int impl_node_enum_params(void *object, int seq,
{ {
struct state *this = object; struct state *this = object;
struct spa_pod *param; struct spa_pod *param;
struct spa_pod_builder b = { 0 }; spa_auto(spa_pod_dynamic_builder) b = { 0 };
struct spa_pod_builder_state state;
uint8_t buffer[4096]; uint8_t buffer[4096];
struct spa_result_node_params result; struct spa_result_node_params result;
uint32_t count = 0; uint32_t count = 0;
@ -108,12 +110,15 @@ static int impl_node_enum_params(void *object, int seq,
spa_return_val_if_fail(this != NULL, -EINVAL); spa_return_val_if_fail(this != NULL, -EINVAL);
spa_return_val_if_fail(num != 0, -EINVAL); spa_return_val_if_fail(num != 0, -EINVAL);
spa_pod_dynamic_builder_init(&b, buffer, sizeof(buffer), 4096);
spa_pod_builder_get_state(&b.b, &state);
result.id = id; result.id = id;
result.next = start; result.next = start;
next: next:
result.index = result.next++; result.index = result.next++;
spa_pod_builder_init(&b, buffer, sizeof(buffer)); spa_pod_builder_reset(&b.b, &state);
switch (id) { switch (id) {
case SPA_PARAM_PropInfo: case SPA_PARAM_PropInfo:
@ -122,7 +127,7 @@ static int impl_node_enum_params(void *object, int seq,
switch (result.index) { switch (result.index) {
case 0: case 0:
param = spa_pod_builder_add_object(&b, param = spa_pod_builder_add_object(&b.b,
SPA_TYPE_OBJECT_PropInfo, id, SPA_TYPE_OBJECT_PropInfo, id,
SPA_PROP_INFO_id, SPA_POD_Id(SPA_PROP_device), SPA_PROP_INFO_id, SPA_POD_Id(SPA_PROP_device),
SPA_PROP_INFO_name, SPA_POD_String(SPA_KEY_API_ALSA_PATH), SPA_PROP_INFO_name, SPA_POD_String(SPA_KEY_API_ALSA_PATH),
@ -130,21 +135,21 @@ static int impl_node_enum_params(void *object, int seq,
SPA_PROP_INFO_type, SPA_POD_Stringn(p->device, sizeof(p->device))); SPA_PROP_INFO_type, SPA_POD_Stringn(p->device, sizeof(p->device)));
break; break;
case 1: case 1:
param = spa_pod_builder_add_object(&b, param = spa_pod_builder_add_object(&b.b,
SPA_TYPE_OBJECT_PropInfo, id, SPA_TYPE_OBJECT_PropInfo, id,
SPA_PROP_INFO_id, SPA_POD_Id(SPA_PROP_deviceName), SPA_PROP_INFO_id, SPA_POD_Id(SPA_PROP_deviceName),
SPA_PROP_INFO_description, SPA_POD_String("The ALSA device name"), SPA_PROP_INFO_description, SPA_POD_String("The ALSA device name"),
SPA_PROP_INFO_type, SPA_POD_Stringn(p->device_name, sizeof(p->device_name))); SPA_PROP_INFO_type, SPA_POD_Stringn(p->device_name, sizeof(p->device_name)));
break; break;
case 2: case 2:
param = spa_pod_builder_add_object(&b, param = spa_pod_builder_add_object(&b.b,
SPA_TYPE_OBJECT_PropInfo, id, SPA_TYPE_OBJECT_PropInfo, id,
SPA_PROP_INFO_id, SPA_POD_Id(SPA_PROP_cardName), SPA_PROP_INFO_id, SPA_POD_Id(SPA_PROP_cardName),
SPA_PROP_INFO_description, SPA_POD_String("The ALSA card name"), SPA_PROP_INFO_description, SPA_POD_String("The ALSA card name"),
SPA_PROP_INFO_type, SPA_POD_Stringn(p->card_name, sizeof(p->card_name))); SPA_PROP_INFO_type, SPA_POD_Stringn(p->card_name, sizeof(p->card_name)));
break; break;
case 3: case 3:
param = spa_pod_builder_add_object(&b, param = spa_pod_builder_add_object(&b.b,
SPA_TYPE_OBJECT_PropInfo, id, SPA_TYPE_OBJECT_PropInfo, id,
SPA_PROP_INFO_id, SPA_POD_Id(SPA_PROP_latencyOffsetNsec), SPA_PROP_INFO_id, SPA_POD_Id(SPA_PROP_latencyOffsetNsec),
SPA_PROP_INFO_description, SPA_POD_String("Latency offset (ns)"), SPA_PROP_INFO_description, SPA_POD_String("Latency offset (ns)"),
@ -153,7 +158,7 @@ static int impl_node_enum_params(void *object, int seq,
case 4: case 4:
if (!this->is_iec958 && !this->is_hdmi) if (!this->is_iec958 && !this->is_hdmi)
goto next; goto next;
param = spa_pod_builder_add_object(&b, param = spa_pod_builder_add_object(&b.b,
SPA_TYPE_OBJECT_PropInfo, id, SPA_TYPE_OBJECT_PropInfo, id,
SPA_PROP_INFO_id, SPA_POD_Id(SPA_PROP_iec958Codecs), SPA_PROP_INFO_id, SPA_POD_Id(SPA_PROP_iec958Codecs),
SPA_PROP_INFO_name, SPA_POD_String("iec958.codecs"), SPA_PROP_INFO_name, SPA_POD_String("iec958.codecs"),
@ -163,7 +168,7 @@ static int impl_node_enum_params(void *object, int seq,
SPA_PROP_INFO_container, SPA_POD_Id(SPA_TYPE_Array)); SPA_PROP_INFO_container, SPA_POD_Id(SPA_TYPE_Array));
break; break;
default: default:
param = spa_alsa_enum_propinfo(this, result.index - 5, &b); param = spa_alsa_enum_propinfo(this, result.index - 5, &b.b);
if (param == NULL) if (param == NULL)
return 0; return 0;
} }
@ -177,9 +182,9 @@ static int impl_node_enum_params(void *object, int seq,
switch (result.index) { switch (result.index) {
case 0: case 0:
spa_pod_builder_push_object(&b, &f, spa_pod_builder_push_object(&b.b, &f,
SPA_TYPE_OBJECT_Props, id); SPA_TYPE_OBJECT_Props, id);
spa_pod_builder_add(&b, spa_pod_builder_add(&b.b,
SPA_PROP_device, SPA_POD_Stringn(p->device, sizeof(p->device)), SPA_PROP_device, SPA_POD_Stringn(p->device, sizeof(p->device)),
SPA_PROP_deviceName, SPA_POD_Stringn(p->device_name, sizeof(p->device_name)), SPA_PROP_deviceName, SPA_POD_Stringn(p->device_name, sizeof(p->device_name)),
SPA_PROP_cardName, SPA_POD_Stringn(p->card_name, sizeof(p->card_name)), SPA_PROP_cardName, SPA_POD_Stringn(p->card_name, sizeof(p->card_name)),
@ -188,12 +193,12 @@ static int impl_node_enum_params(void *object, int seq,
if (this->is_iec958 || this->is_hdmi) { if (this->is_iec958 || this->is_hdmi) {
n_codecs = spa_alsa_get_iec958_codecs(this, codecs, SPA_N_ELEMENTS(codecs)); n_codecs = spa_alsa_get_iec958_codecs(this, codecs, SPA_N_ELEMENTS(codecs));
spa_pod_builder_prop(&b, SPA_PROP_iec958Codecs, 0); spa_pod_builder_prop(&b.b, SPA_PROP_iec958Codecs, 0);
spa_pod_builder_array(&b, sizeof(uint32_t), SPA_TYPE_Id, spa_pod_builder_array(&b.b, sizeof(uint32_t), SPA_TYPE_Id,
n_codecs, codecs); n_codecs, codecs);
} }
spa_alsa_add_prop_params(this, &b); spa_alsa_add_prop_params(this, &b.b);
param = spa_pod_builder_pop(&b, &f); param = spa_pod_builder_pop(&b.b, &f);
break; break;
default: default:
return 0; return 0;
@ -203,13 +208,13 @@ static int impl_node_enum_params(void *object, int seq,
case SPA_PARAM_IO: case SPA_PARAM_IO:
switch (result.index) { switch (result.index) {
case 0: case 0:
param = spa_pod_builder_add_object(&b, param = spa_pod_builder_add_object(&b.b,
SPA_TYPE_OBJECT_ParamIO, id, SPA_TYPE_OBJECT_ParamIO, id,
SPA_PARAM_IO_id, SPA_POD_Id(SPA_IO_Clock), SPA_PARAM_IO_id, SPA_POD_Id(SPA_IO_Clock),
SPA_PARAM_IO_size, SPA_POD_Int(sizeof(struct spa_io_clock))); SPA_PARAM_IO_size, SPA_POD_Int(sizeof(struct spa_io_clock)));
break; break;
case 1: case 1:
param = spa_pod_builder_add_object(&b, param = spa_pod_builder_add_object(&b.b,
SPA_TYPE_OBJECT_ParamIO, id, SPA_TYPE_OBJECT_ParamIO, id,
SPA_PARAM_IO_id, SPA_POD_Id(SPA_IO_Position), SPA_PARAM_IO_id, SPA_POD_Id(SPA_IO_Position),
SPA_PARAM_IO_size, SPA_POD_Int(sizeof(struct spa_io_position))); SPA_PARAM_IO_size, SPA_POD_Int(sizeof(struct spa_io_position)));
@ -222,7 +227,7 @@ static int impl_node_enum_params(void *object, int seq,
case SPA_PARAM_ProcessLatency: case SPA_PARAM_ProcessLatency:
switch (result.index) { switch (result.index) {
case 0: case 0:
param = spa_process_latency_build(&b, id, &this->process_latency); param = spa_process_latency_build(&b.b, id, &this->process_latency);
break; break;
default: default:
return 0; return 0;
@ -233,7 +238,7 @@ static int impl_node_enum_params(void *object, int seq,
return -ENOENT; return -ENOENT;
} }
if (spa_pod_filter(&b, &result.param, param, filter) < 0) if (spa_pod_filter(&b.b, &result.param, param, filter) < 0)
goto next; goto next;
spa_node_emit_result(&this->hooks, seq, 0, SPA_RESULT_TYPE_NODE_PARAMS, &result); spa_node_emit_result(&this->hooks, seq, 0, SPA_RESULT_TYPE_NODE_PARAMS, &result);
@ -469,7 +474,8 @@ impl_node_port_enum_params(void *object, int seq,
struct state *this = object; struct state *this = object;
struct spa_pod *param; struct spa_pod *param;
struct spa_pod_builder b = { 0 }; spa_auto(spa_pod_dynamic_builder) b = { 0 };
struct spa_pod_builder_state state;
uint8_t buffer[1024]; uint8_t buffer[1024];
struct spa_result_node_params result; struct spa_result_node_params result;
uint32_t count = 0; uint32_t count = 0;
@ -479,12 +485,15 @@ impl_node_port_enum_params(void *object, int seq,
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL); spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
spa_pod_dynamic_builder_init(&b, buffer, sizeof(buffer), 4096);
spa_pod_builder_get_state(&b.b, &state);
result.id = id; result.id = id;
result.next = start; result.next = start;
next: next:
result.index = result.next++; result.index = result.next++;
spa_pod_builder_init(&b, buffer, sizeof(buffer)); spa_pod_builder_reset(&b.b, &state);
switch (id) { switch (id) {
case SPA_PARAM_EnumFormat: case SPA_PARAM_EnumFormat:
@ -498,15 +507,15 @@ impl_node_port_enum_params(void *object, int seq,
switch (this->current_format.media_subtype) { switch (this->current_format.media_subtype) {
case SPA_MEDIA_SUBTYPE_raw: case SPA_MEDIA_SUBTYPE_raw:
param = spa_format_audio_raw_build(&b, id, param = spa_format_audio_raw_build(&b.b, id,
&this->current_format.info.raw); &this->current_format.info.raw);
break; break;
case SPA_MEDIA_SUBTYPE_iec958: case SPA_MEDIA_SUBTYPE_iec958:
param = spa_format_audio_iec958_build(&b, id, param = spa_format_audio_iec958_build(&b.b, id,
&this->current_format.info.iec958); &this->current_format.info.iec958);
break; break;
case SPA_MEDIA_SUBTYPE_dsd: case SPA_MEDIA_SUBTYPE_dsd:
param = spa_format_audio_dsd_build(&b, id, param = spa_format_audio_dsd_build(&b.b, id,
&this->current_format.info.dsd); &this->current_format.info.dsd);
break; break;
default: default:
@ -520,7 +529,7 @@ impl_node_port_enum_params(void *object, int seq,
if (result.index > 0) if (result.index > 0)
return 0; return 0;
param = spa_pod_builder_add_object(&b, param = spa_pod_builder_add_object(&b.b,
SPA_TYPE_OBJECT_ParamBuffers, id, SPA_TYPE_OBJECT_ParamBuffers, id,
SPA_PARAM_BUFFERS_buffers, SPA_POD_CHOICE_RANGE_Int(2, 1, MAX_BUFFERS), SPA_PARAM_BUFFERS_buffers, SPA_POD_CHOICE_RANGE_Int(2, 1, MAX_BUFFERS),
SPA_PARAM_BUFFERS_blocks, SPA_POD_Int(this->blocks), SPA_PARAM_BUFFERS_blocks, SPA_POD_Int(this->blocks),
@ -534,7 +543,7 @@ impl_node_port_enum_params(void *object, int seq,
case SPA_PARAM_Meta: case SPA_PARAM_Meta:
switch (result.index) { switch (result.index) {
case 0: case 0:
param = spa_pod_builder_add_object(&b, param = spa_pod_builder_add_object(&b.b,
SPA_TYPE_OBJECT_ParamMeta, id, SPA_TYPE_OBJECT_ParamMeta, id,
SPA_PARAM_META_type, SPA_POD_Id(SPA_META_Header), SPA_PARAM_META_type, SPA_POD_Id(SPA_META_Header),
SPA_PARAM_META_size, SPA_POD_Int(sizeof(struct spa_meta_header))); SPA_PARAM_META_size, SPA_POD_Int(sizeof(struct spa_meta_header)));
@ -547,13 +556,13 @@ impl_node_port_enum_params(void *object, int seq,
case SPA_PARAM_IO: case SPA_PARAM_IO:
switch (result.index) { switch (result.index) {
case 0: case 0:
param = spa_pod_builder_add_object(&b, param = spa_pod_builder_add_object(&b.b,
SPA_TYPE_OBJECT_ParamIO, id, SPA_TYPE_OBJECT_ParamIO, id,
SPA_PARAM_IO_id, SPA_POD_Id(SPA_IO_Buffers), SPA_PARAM_IO_id, SPA_POD_Id(SPA_IO_Buffers),
SPA_PARAM_IO_size, SPA_POD_Int(sizeof(struct spa_io_buffers))); SPA_PARAM_IO_size, SPA_POD_Int(sizeof(struct spa_io_buffers)));
break; break;
case 1: case 1:
param = spa_pod_builder_add_object(&b, param = spa_pod_builder_add_object(&b.b,
SPA_TYPE_OBJECT_ParamIO, id, SPA_TYPE_OBJECT_ParamIO, id,
SPA_PARAM_IO_id, SPA_POD_Id(SPA_IO_RateMatch), SPA_PARAM_IO_id, SPA_POD_Id(SPA_IO_RateMatch),
SPA_PARAM_IO_size, SPA_POD_Int(sizeof(struct spa_io_rate_match))); SPA_PARAM_IO_size, SPA_POD_Int(sizeof(struct spa_io_rate_match)));
@ -570,7 +579,7 @@ impl_node_port_enum_params(void *object, int seq,
struct spa_latency_info latency = this->latency[result.index]; struct spa_latency_info latency = this->latency[result.index];
if (latency.direction == SPA_DIRECTION_INPUT) if (latency.direction == SPA_DIRECTION_INPUT)
spa_process_latency_info_add(&this->process_latency, &latency); spa_process_latency_info_add(&this->process_latency, &latency);
param = spa_latency_build(&b, id, &latency); param = spa_latency_build(&b.b, id, &latency);
break; break;
} }
default: default:
@ -591,7 +600,7 @@ impl_node_port_enum_params(void *object, int seq,
return -ENOENT; return -ENOENT;
} }
if (spa_pod_filter(&b, &result.param, param, filter) < 0) if (spa_pod_filter(&b.b, &result.param, param, filter) < 0)
goto next; goto next;
spa_node_emit_result(&this->hooks, seq, 0, SPA_RESULT_TYPE_NODE_PARAMS, &result); spa_node_emit_result(&this->hooks, seq, 0, SPA_RESULT_TYPE_NODE_PARAMS, &result);

View file

@ -16,6 +16,7 @@
#include <spa/monitor/device.h> #include <spa/monitor/device.h>
#include <spa/param/audio/format.h> #include <spa/param/audio/format.h>
#include <spa/pod/filter.h> #include <spa/pod/filter.h>
#include <spa/pod/dynamic.h>
#include "alsa.h" #include "alsa.h"
@ -100,7 +101,8 @@ static int impl_node_enum_params(void *object, int seq,
struct state *this = object; struct state *this = object;
struct spa_pod *param; struct spa_pod *param;
uint8_t buffer[4096]; uint8_t buffer[4096];
struct spa_pod_builder b = { 0 }; spa_auto(spa_pod_dynamic_builder) b = { 0 };
struct spa_pod_builder_state state;
struct props *p; struct props *p;
struct spa_result_node_params result; struct spa_result_node_params result;
uint32_t count = 0; uint32_t count = 0;
@ -108,6 +110,9 @@ static int impl_node_enum_params(void *object, int seq,
spa_return_val_if_fail(this != NULL, -EINVAL); spa_return_val_if_fail(this != NULL, -EINVAL);
spa_return_val_if_fail(num != 0, -EINVAL); spa_return_val_if_fail(num != 0, -EINVAL);
spa_pod_dynamic_builder_init(&b, buffer, sizeof(buffer), 4096);
spa_pod_builder_get_state(&b.b, &state);
p = &this->props; p = &this->props;
result.id = id; result.id = id;
@ -115,13 +120,13 @@ static int impl_node_enum_params(void *object, int seq,
next: next:
result.index = result.next++; result.index = result.next++;
spa_pod_builder_init(&b, buffer, sizeof(buffer)); spa_pod_builder_reset(&b.b, &state);
switch (id) { switch (id) {
case SPA_PARAM_PropInfo: case SPA_PARAM_PropInfo:
switch (result.index) { switch (result.index) {
case 0: case 0:
param = spa_pod_builder_add_object(&b, param = spa_pod_builder_add_object(&b.b,
SPA_TYPE_OBJECT_PropInfo, id, SPA_TYPE_OBJECT_PropInfo, id,
SPA_PROP_INFO_id, SPA_POD_Id(SPA_PROP_device), SPA_PROP_INFO_id, SPA_POD_Id(SPA_PROP_device),
SPA_PROP_INFO_name, SPA_POD_String(SPA_KEY_API_ALSA_PATH), SPA_PROP_INFO_name, SPA_POD_String(SPA_KEY_API_ALSA_PATH),
@ -129,28 +134,28 @@ static int impl_node_enum_params(void *object, int seq,
SPA_PROP_INFO_type, SPA_POD_Stringn(p->device, sizeof(p->device))); SPA_PROP_INFO_type, SPA_POD_Stringn(p->device, sizeof(p->device)));
break; break;
case 1: case 1:
param = spa_pod_builder_add_object(&b, param = spa_pod_builder_add_object(&b.b,
SPA_TYPE_OBJECT_PropInfo, id, SPA_TYPE_OBJECT_PropInfo, id,
SPA_PROP_INFO_id, SPA_POD_Id(SPA_PROP_deviceName), SPA_PROP_INFO_id, SPA_POD_Id(SPA_PROP_deviceName),
SPA_PROP_INFO_description, SPA_POD_String("The ALSA device name"), SPA_PROP_INFO_description, SPA_POD_String("The ALSA device name"),
SPA_PROP_INFO_type, SPA_POD_Stringn(p->device_name, sizeof(p->device_name))); SPA_PROP_INFO_type, SPA_POD_Stringn(p->device_name, sizeof(p->device_name)));
break; break;
case 2: case 2:
param = spa_pod_builder_add_object(&b, param = spa_pod_builder_add_object(&b.b,
SPA_TYPE_OBJECT_PropInfo, id, SPA_TYPE_OBJECT_PropInfo, id,
SPA_PROP_INFO_id, SPA_POD_Id(SPA_PROP_cardName), SPA_PROP_INFO_id, SPA_POD_Id(SPA_PROP_cardName),
SPA_PROP_INFO_description, SPA_POD_String("The ALSA card name"), SPA_PROP_INFO_description, SPA_POD_String("The ALSA card name"),
SPA_PROP_INFO_type, SPA_POD_Stringn(p->card_name, sizeof(p->card_name))); SPA_PROP_INFO_type, SPA_POD_Stringn(p->card_name, sizeof(p->card_name)));
break; break;
case 3: case 3:
param = spa_pod_builder_add_object(&b, param = spa_pod_builder_add_object(&b.b,
SPA_TYPE_OBJECT_PropInfo, id, SPA_TYPE_OBJECT_PropInfo, id,
SPA_PROP_INFO_id, SPA_POD_Id(SPA_PROP_latencyOffsetNsec), SPA_PROP_INFO_id, SPA_POD_Id(SPA_PROP_latencyOffsetNsec),
SPA_PROP_INFO_description, SPA_POD_String("Latency offset (ns)"), SPA_PROP_INFO_description, SPA_POD_String("Latency offset (ns)"),
SPA_PROP_INFO_type, SPA_POD_CHOICE_RANGE_Long(0LL, 0LL, 2 * SPA_NSEC_PER_SEC)); SPA_PROP_INFO_type, SPA_POD_CHOICE_RANGE_Long(0LL, 0LL, 2 * SPA_NSEC_PER_SEC));
break; break;
default: default:
param = spa_alsa_enum_propinfo(this, result.index - 4, &b); param = spa_alsa_enum_propinfo(this, result.index - 4, &b.b);
if (param == NULL) if (param == NULL)
return 0; return 0;
} }
@ -162,16 +167,16 @@ static int impl_node_enum_params(void *object, int seq,
switch (result.index) { switch (result.index) {
case 0: case 0:
spa_pod_builder_push_object(&b, &f, spa_pod_builder_push_object(&b.b, &f,
SPA_TYPE_OBJECT_Props, id); SPA_TYPE_OBJECT_Props, id);
spa_pod_builder_add(&b, spa_pod_builder_add(&b.b,
SPA_PROP_device, SPA_POD_Stringn(p->device, sizeof(p->device)), SPA_PROP_device, SPA_POD_Stringn(p->device, sizeof(p->device)),
SPA_PROP_deviceName, SPA_POD_Stringn(p->device_name, sizeof(p->device_name)), SPA_PROP_deviceName, SPA_POD_Stringn(p->device_name, sizeof(p->device_name)),
SPA_PROP_cardName, SPA_POD_Stringn(p->card_name, sizeof(p->card_name)), SPA_PROP_cardName, SPA_POD_Stringn(p->card_name, sizeof(p->card_name)),
SPA_PROP_latencyOffsetNsec, SPA_POD_Long(this->process_latency.ns), SPA_PROP_latencyOffsetNsec, SPA_POD_Long(this->process_latency.ns),
0); 0);
spa_alsa_add_prop_params(this, &b); spa_alsa_add_prop_params(this, &b.b);
param = spa_pod_builder_pop(&b, &f); param = spa_pod_builder_pop(&b.b, &f);
break; break;
default: default:
return 0; return 0;
@ -181,13 +186,13 @@ static int impl_node_enum_params(void *object, int seq,
case SPA_PARAM_IO: case SPA_PARAM_IO:
switch (result.index) { switch (result.index) {
case 0: case 0:
param = spa_pod_builder_add_object(&b, param = spa_pod_builder_add_object(&b.b,
SPA_TYPE_OBJECT_ParamIO, id, SPA_TYPE_OBJECT_ParamIO, id,
SPA_PARAM_IO_id, SPA_POD_Id(SPA_IO_Clock), SPA_PARAM_IO_id, SPA_POD_Id(SPA_IO_Clock),
SPA_PARAM_IO_size, SPA_POD_Int(sizeof(struct spa_io_clock))); SPA_PARAM_IO_size, SPA_POD_Int(sizeof(struct spa_io_clock)));
break; break;
case 1: case 1:
param = spa_pod_builder_add_object(&b, param = spa_pod_builder_add_object(&b.b,
SPA_TYPE_OBJECT_ParamIO, id, SPA_TYPE_OBJECT_ParamIO, id,
SPA_PARAM_IO_id, SPA_POD_Id(SPA_IO_Position), SPA_PARAM_IO_id, SPA_POD_Id(SPA_IO_Position),
SPA_PARAM_IO_size, SPA_POD_Int(sizeof(struct spa_io_position))); SPA_PARAM_IO_size, SPA_POD_Int(sizeof(struct spa_io_position)));
@ -200,7 +205,7 @@ static int impl_node_enum_params(void *object, int seq,
case SPA_PARAM_ProcessLatency: case SPA_PARAM_ProcessLatency:
switch (result.index) { switch (result.index) {
case 0: case 0:
param = spa_process_latency_build(&b, id, &this->process_latency); param = spa_process_latency_build(&b.b, id, &this->process_latency);
break; break;
default: default:
return 0; return 0;
@ -211,7 +216,7 @@ static int impl_node_enum_params(void *object, int seq,
return -ENOENT; return -ENOENT;
} }
if (spa_pod_filter(&b, &result.param, param, filter) < 0) if (spa_pod_filter(&b.b, &result.param, param, filter) < 0)
goto next; goto next;
spa_node_emit_result(&this->hooks, seq, 0, SPA_RESULT_TYPE_NODE_PARAMS, &result); spa_node_emit_result(&this->hooks, seq, 0, SPA_RESULT_TYPE_NODE_PARAMS, &result);
@ -431,22 +436,25 @@ impl_node_port_enum_params(void *object, int seq,
{ {
struct state *this = object; struct state *this = object;
struct spa_pod *param; struct spa_pod *param;
struct spa_pod_builder b = { 0 }; spa_auto(spa_pod_dynamic_builder) b = { 0 };
struct spa_pod_builder_state state;
uint8_t buffer[1024]; uint8_t buffer[1024];
struct spa_result_node_params result; struct spa_result_node_params result;
uint32_t count = 0; uint32_t count = 0;
spa_return_val_if_fail(this != NULL, -EINVAL); spa_return_val_if_fail(this != NULL, -EINVAL);
spa_return_val_if_fail(num != 0, -EINVAL); spa_return_val_if_fail(num != 0, -EINVAL);
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL); spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
spa_pod_dynamic_builder_init(&b, buffer, sizeof(buffer), 4096);
spa_pod_builder_get_state(&b.b, &state);
result.id = id; result.id = id;
result.next = start; result.next = start;
next: next:
result.index = result.next++; result.index = result.next++;
spa_pod_builder_init(&b, buffer, sizeof(buffer)); spa_pod_builder_reset(&b.b, &state);
switch (id) { switch (id) {
case SPA_PARAM_EnumFormat: case SPA_PARAM_EnumFormat:
@ -458,7 +466,7 @@ impl_node_port_enum_params(void *object, int seq,
if (result.index > 0) if (result.index > 0)
return 0; return 0;
param = spa_format_audio_raw_build(&b, id, &this->current_format.info.raw); param = spa_format_audio_raw_build(&b.b, id, &this->current_format.info.raw);
break; break;
case SPA_PARAM_Buffers: case SPA_PARAM_Buffers:
@ -467,7 +475,7 @@ impl_node_port_enum_params(void *object, int seq,
if (result.index > 0) if (result.index > 0)
return 0; return 0;
param = spa_pod_builder_add_object(&b, param = spa_pod_builder_add_object(&b.b,
SPA_TYPE_OBJECT_ParamBuffers, id, SPA_TYPE_OBJECT_ParamBuffers, id,
SPA_PARAM_BUFFERS_buffers, SPA_POD_CHOICE_RANGE_Int(2, 1, MAX_BUFFERS), SPA_PARAM_BUFFERS_buffers, SPA_POD_CHOICE_RANGE_Int(2, 1, MAX_BUFFERS),
SPA_PARAM_BUFFERS_blocks, SPA_POD_Int(this->blocks), SPA_PARAM_BUFFERS_blocks, SPA_POD_Int(this->blocks),
@ -481,7 +489,7 @@ impl_node_port_enum_params(void *object, int seq,
case SPA_PARAM_Meta: case SPA_PARAM_Meta:
switch (result.index) { switch (result.index) {
case 0: case 0:
param = spa_pod_builder_add_object(&b, param = spa_pod_builder_add_object(&b.b,
SPA_TYPE_OBJECT_ParamMeta, id, SPA_TYPE_OBJECT_ParamMeta, id,
SPA_PARAM_META_type, SPA_POD_Id(SPA_META_Header), SPA_PARAM_META_type, SPA_POD_Id(SPA_META_Header),
SPA_PARAM_META_size, SPA_POD_Int(sizeof(struct spa_meta_header))); SPA_PARAM_META_size, SPA_POD_Int(sizeof(struct spa_meta_header)));
@ -494,13 +502,13 @@ impl_node_port_enum_params(void *object, int seq,
case SPA_PARAM_IO: case SPA_PARAM_IO:
switch (result.index) { switch (result.index) {
case 0: case 0:
param = spa_pod_builder_add_object(&b, param = spa_pod_builder_add_object(&b.b,
SPA_TYPE_OBJECT_ParamIO, id, SPA_TYPE_OBJECT_ParamIO, id,
SPA_PARAM_IO_id, SPA_POD_Id(SPA_IO_Buffers), SPA_PARAM_IO_id, SPA_POD_Id(SPA_IO_Buffers),
SPA_PARAM_IO_size, SPA_POD_Int(sizeof(struct spa_io_buffers))); SPA_PARAM_IO_size, SPA_POD_Int(sizeof(struct spa_io_buffers)));
break; break;
case 1: case 1:
param = spa_pod_builder_add_object(&b, param = spa_pod_builder_add_object(&b.b,
SPA_TYPE_OBJECT_ParamIO, id, SPA_TYPE_OBJECT_ParamIO, id,
SPA_PARAM_IO_id, SPA_POD_Id(SPA_IO_RateMatch), SPA_PARAM_IO_id, SPA_POD_Id(SPA_IO_RateMatch),
SPA_PARAM_IO_size, SPA_POD_Int(sizeof(struct spa_io_rate_match))); SPA_PARAM_IO_size, SPA_POD_Int(sizeof(struct spa_io_rate_match)));
@ -517,7 +525,7 @@ impl_node_port_enum_params(void *object, int seq,
struct spa_latency_info latency = this->latency[result.index]; struct spa_latency_info latency = this->latency[result.index];
if (latency.direction == SPA_DIRECTION_OUTPUT) if (latency.direction == SPA_DIRECTION_OUTPUT)
spa_process_latency_info_add(&this->process_latency, &latency); spa_process_latency_info_add(&this->process_latency, &latency);
param = spa_latency_build(&b, id, &latency); param = spa_latency_build(&b.b, id, &latency);
break; break;
} }
default: default:
@ -539,7 +547,7 @@ impl_node_port_enum_params(void *object, int seq,
return -ENOENT; return -ENOENT;
} }
if (spa_pod_filter(&b, &result.param, param, filter) < 0) if (spa_pod_filter(&b.b, &result.param, param, filter) < 0)
goto next; goto next;
spa_node_emit_result(&this->hooks, seq, 0, SPA_RESULT_TYPE_NODE_PARAMS, &result); spa_node_emit_result(&this->hooks, seq, 0, SPA_RESULT_TYPE_NODE_PARAMS, &result);

View file

@ -153,7 +153,8 @@ static int impl_node_enum_params(void *object, int seq,
{ {
struct impl *this = object; struct impl *this = object;
uint8_t buffer[4096]; uint8_t buffer[4096];
struct spa_pod_dynamic_builder b; spa_auto(spa_pod_dynamic_builder) b = { 0 };
struct spa_pod_builder_state state;
struct spa_result_node_params result; struct spa_result_node_params result;
uint32_t count = 0; uint32_t count = 0;
int res; int res;
@ -161,6 +162,9 @@ static int impl_node_enum_params(void *object, int seq,
spa_return_val_if_fail(this != NULL, -EINVAL); spa_return_val_if_fail(this != NULL, -EINVAL);
spa_return_val_if_fail(num != 0, -EINVAL); spa_return_val_if_fail(num != 0, -EINVAL);
spa_pod_dynamic_builder_init(&b, buffer, sizeof(buffer), 4096);
spa_pod_builder_get_state(&b.b, &state);
result.id = id; result.id = id;
result.next = start; result.next = start;
next: next:
@ -168,7 +172,7 @@ next:
spa_log_debug(this->log, "%p: %d id:%u", this, seq, id); spa_log_debug(this->log, "%p: %d id:%u", this, seq, id);
spa_pod_dynamic_builder_init(&b, buffer, sizeof(buffer), 4096); spa_pod_builder_reset(&b.b, &state);
switch (id) { switch (id) {
case SPA_PARAM_EnumPortConfig: case SPA_PARAM_EnumPortConfig:
@ -215,16 +219,12 @@ next:
default: default:
return -ENOENT; return -ENOENT;
} }
if (res == 1) {
spa_node_emit_result(&this->hooks, seq, 0, SPA_RESULT_TYPE_NODE_PARAMS, &result);
count++;
}
spa_pod_dynamic_builder_clean(&b);
if (res != 1) if (res != 1)
return res; return res;
spa_node_emit_result(&this->hooks, seq, 0, SPA_RESULT_TYPE_NODE_PARAMS, &result);
count++;
if (count != num) if (count != num)
goto next; goto next;
@ -580,8 +580,9 @@ static int recalc_latency(struct impl *this, struct spa_node *src, enum spa_dire
static int recalc_tag(struct impl *this, struct spa_node *src, enum spa_direction direction, static int recalc_tag(struct impl *this, struct spa_node *src, enum spa_direction direction,
uint32_t port_id, struct spa_node *dst) uint32_t port_id, struct spa_node *dst)
{ {
struct spa_pod_builder b = { 0 }; spa_auto(spa_pod_dynamic_builder) b = { 0 };
uint8_t buffer[1024]; struct spa_pod_builder_state state;
uint8_t buffer[2048];
struct spa_pod *param; struct spa_pod *param;
uint32_t index = 0; uint32_t index = 0;
struct spa_tag_info info; struct spa_tag_info info;
@ -592,26 +593,25 @@ static int recalc_tag(struct impl *this, struct spa_node *src, enum spa_directio
if (this->target == this->follower) if (this->target == this->follower)
return 0; return 0;
spa_pod_dynamic_builder_init(&b, buffer, sizeof(buffer), 2048);
spa_pod_builder_get_state(&b.b, &state);
while (true) { while (true) {
void *state = NULL; void *tag_state = NULL;
spa_pod_builder_init(&b, buffer, sizeof(buffer)); spa_pod_builder_reset(&b.b, &state);
if ((res = spa_node_port_enum_params_sync(src, if ((res = spa_node_port_enum_params_sync(src,
direction, port_id, SPA_PARAM_Tag, direction, port_id, SPA_PARAM_Tag,
&index, NULL, &param, &b)) != 1) { &index, NULL, &param, &b.b)) != 1) {
param = NULL; param = NULL;
break; break;
} }
if ((res = spa_tag_parse(param, &info, &state)) < 0) if ((res = spa_tag_parse(param, &info, &tag_state)) < 0)
return res; return res;
if (info.direction == direction) if (info.direction == direction)
break; break;
} }
if ((res = spa_node_port_set_param(dst, return spa_node_port_set_param(dst, SPA_DIRECTION_REVERSE(direction), 0,
SPA_DIRECTION_REVERSE(direction), 0, SPA_PARAM_Tag, 0, param);
SPA_PARAM_Tag, 0, param)) < 0)
return res;
return 0;
} }