From 8a6ce3b1794e36aec81dc4fd005870e891a9a32b Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Fri, 17 Mar 2017 11:58:09 +0100 Subject: [PATCH] Make AllocParams into POD objects Make allocparams into pod objects. This makes it easy to serialize, copy, create and intersect them. Add convenience macros for properties Add helper function to collect object properties. --- pinos/client/protocol-native.c | 41 ++--- pinos/client/serialize.c | 4 +- pinos/client/utils.h | 2 +- pinos/gst/gstpinospool.c | 64 +++++--- pinos/gst/gstpinossrc.c | 14 +- pinos/modules/module-access.c | 2 + pinos/modules/module-protocol-dbus.c | 4 +- pinos/server/link.c | 83 +++++++--- pinos/server/protocol-native.c | 94 ++++------- spa/include/spa/defs.h | 1 + spa/include/spa/format-builder.h | 25 +-- spa/include/spa/format.h | 17 +- spa/include/spa/meson.build | 2 + spa/include/spa/pod-builder.h | 35 +++- spa/include/spa/pod-iter.h | 48 +----- spa/include/spa/pod-utils.h | 208 ++++++++++++++++++++++++ spa/include/spa/pod.h | 59 +------ spa/include/spa/port.h | 108 ++++++++---- spa/include/spa/props.h | 19 +-- spa/lib/debug.c | 55 +------ spa/lib/props.c | 10 +- spa/plugins/alsa/alsa-sink.c | 174 +++++++------------- spa/plugins/alsa/alsa-source.c | 159 +++++++----------- spa/plugins/alsa/alsa-utils.h | 4 +- spa/plugins/audiotestsrc/audiotestsrc.c | 177 ++++++++------------ spa/plugins/ffmpeg/ffmpeg-dec.c | 6 +- spa/plugins/ffmpeg/ffmpeg-enc.c | 10 +- spa/plugins/v4l2/v4l2-source.c | 121 +++++--------- spa/plugins/v4l2/v4l2-utils.c | 75 ++++----- spa/plugins/videotestsrc/draw.c | 2 +- spa/plugins/videotestsrc/videotestsrc.c | 164 ++++++++----------- spa/plugins/volume/volume.c | 129 ++++++--------- spa/plugins/xv/xv-sink.c | 54 ++---- spa/tests/test-props.c | 32 ++-- 34 files changed, 948 insertions(+), 1054 deletions(-) create mode 100644 spa/include/spa/pod-utils.h diff --git a/pinos/client/protocol-native.c b/pinos/client/protocol-native.c index 0024a8ce8..917f7de2b 100644 --- a/pinos/client/protocol-native.c +++ b/pinos/client/protocol-native.c @@ -109,11 +109,8 @@ core_marshal_sync (void *object, core_update_map (proxy->context); - spa_pod_builder_add (&b.b, - SPA_POD_TYPE_STRUCT, &f, - SPA_POD_TYPE_INT, seq, - -SPA_POD_TYPE_STRUCT, &f, - 0); + spa_pod_builder_struct (&b.b, &f, + SPA_POD_TYPE_INT, seq); pinos_connection_end_write (connection, proxy->id, 1, b.b.offset); } @@ -129,11 +126,8 @@ core_marshal_get_registry (void *object, core_update_map (proxy->context); - spa_pod_builder_add (&b.b, - SPA_POD_TYPE_STRUCT, &f, - SPA_POD_TYPE_INT, new_id, - -SPA_POD_TYPE_STRUCT, &f, - 0); + spa_pod_builder_struct (&b.b, &f, + SPA_POD_TYPE_INT, new_id); pinos_connection_end_write (connection, proxy->id, 2, b.b.offset); } @@ -529,7 +523,7 @@ client_node_marshal_port_update (void *object, for (i = 0; i < info->n_params; i++) { SpaAllocParam *p = info->params[i]; - spa_pod_builder_add (&b.b, SPA_POD_TYPE_BYTES, p, p->size, 0); + spa_pod_builder_add (&b.b, SPA_POD_TYPE_POD, p, 0); } n_items = info->extra ? info->extra->n_items : 0; spa_pod_builder_add (&b.b, SPA_POD_TYPE_INT, n_items, 0); @@ -556,11 +550,8 @@ client_node_marshal_state_change (void *object, core_update_map (proxy->context); - spa_pod_builder_add (&b.b, - SPA_POD_TYPE_STRUCT, &f, - SPA_POD_TYPE_INT, state, - -SPA_POD_TYPE_STRUCT, &f, - 0); + spa_pod_builder_struct (&b.b, &f, + SPA_POD_TYPE_INT, state); pinos_connection_end_write (connection, proxy->id, 2, b.b.offset); } @@ -576,11 +567,8 @@ client_node_marshal_event (void *object, core_update_map (proxy->context); - spa_pod_builder_add (&b.b, - SPA_POD_TYPE_STRUCT, &f, - SPA_POD_TYPE_POD, event, - -SPA_POD_TYPE_STRUCT, &f, - 0); + spa_pod_builder_struct (&b.b, &f, + SPA_POD_TYPE_POD, event); pinos_connection_end_write (connection, proxy->id, 3, b.b.offset); } @@ -595,10 +583,7 @@ client_node_marshal_destroy (void *object) core_update_map (proxy->context); - spa_pod_builder_add (&b.b, - SPA_POD_TYPE_STRUCT, &f, - -SPA_POD_TYPE_STRUCT, &f, - 0); + spa_pod_builder_struct (&b.b, &f, 0); pinos_connection_end_write (connection, proxy->id, 4, b.b.offset); } @@ -1020,11 +1005,9 @@ registry_marshal_bind (void *object, core_update_map (proxy->context); - spa_pod_builder_add (&b.b, - SPA_POD_TYPE_STRUCT, &f, + spa_pod_builder_struct (&b.b, &f, SPA_POD_TYPE_INT, id, - SPA_POD_TYPE_INT, new_id, - -SPA_POD_TYPE_STRUCT, &f, 0); + SPA_POD_TYPE_INT, new_id); pinos_connection_end_write (connection, proxy->id, 0, b.b.offset); } diff --git a/pinos/client/serialize.c b/pinos/client/serialize.c index 12745c1e5..063d2e249 100644 --- a/pinos/client/serialize.c +++ b/pinos/client/serialize.c @@ -101,7 +101,7 @@ pinos_serialize_port_info_get_size (const SpaPortInfo *info) len = sizeof (SpaPortInfo); len += info->n_params * sizeof (SpaAllocParam *); for (i = 0; i < info->n_params; i++) - len += info->params[i]->size; + len += SPA_POD_SIZE (info->params[i]); return len; } @@ -130,7 +130,7 @@ pinos_serialize_port_info_serialize (void *p, const SpaPortInfo *info) p = SPA_MEMBER (ap, sizeof (SpaAllocParam*) * info->n_params, void); for (i = 0; i < info->n_params; i++) { - len = info->params[i]->size; + len = SPA_POD_SIZE (info->params[i]); memcpy (p, info->params[i], len); ap[i] = SPA_INT_TO_PTR (SPA_PTRDIFF (p, pi)); p = SPA_MEMBER (p, len, void); diff --git a/pinos/client/utils.h b/pinos/client/utils.h index 0539f5875..7cf394d30 100644 --- a/pinos/client/utils.h +++ b/pinos/client/utils.h @@ -25,7 +25,7 @@ extern "C" { #endif #include -#include +#include const char * pinos_split_walk (const char *str, const char *delimiter, diff --git a/pinos/gst/gstpinospool.c b/pinos/gst/gstpinospool.c index 7138a9a8c..dd821e7ae 100644 --- a/pinos/gst/gstpinospool.c +++ b/pinos/gst/gstpinospool.c @@ -97,6 +97,24 @@ release_buffer (GstBufferPool * pool, GstBuffer *buffer) GST_OBJECT_UNLOCK (pool); } +#define PROP(f,key,type,...) \ + SPA_POD_PROP (f,key,SPA_POD_PROP_FLAG_READWRITE,type,1,__VA_ARGS__) +#define PROP_R(f,key,type,...) \ + SPA_POD_PROP (f,key,SPA_POD_PROP_FLAG_READABLE,type,1,__VA_ARGS__) +#define PROP_MM(f,key,type,...) \ + SPA_POD_PROP (f,key,SPA_POD_PROP_FLAG_READWRITE | \ + SPA_POD_PROP_RANGE_MIN_MAX,type,3,__VA_ARGS__) +#define PROP_U_MM(f,key,type,...) \ + SPA_POD_PROP (f,key,SPA_POD_PROP_FLAG_READWRITE | \ + SPA_POD_PROP_FLAG_UNSET | \ + SPA_POD_PROP_RANGE_MIN_MAX,type,3,__VA_ARGS__) +#define PROP_EN(f,key,type,n,...) \ + SPA_POD_PROP (f,key,SPA_POD_PROP_FLAG_READWRITE | \ + SPA_POD_PROP_RANGE_ENUM,type,n,__VA_ARGS__) +#define PROP_U_EN(f,key,type,n,...) \ + SPA_POD_PROP (f,key,SPA_POD_PROP_FLAG_READWRITE | \ + SPA_POD_PROP_FLAG_UNSET | \ + SPA_POD_PROP_RANGE_ENUM,type,n,__VA_ARGS__) static gboolean do_start (GstBufferPool * pool) { @@ -107,33 +125,33 @@ do_start (GstBufferPool * pool) guint min_buffers; guint max_buffers; SpaAllocParam *port_params[3]; - SpaAllocParamBuffers param_buffers; - SpaAllocParamMetaEnable param_meta_enable; - SpaAllocParamMetaEnableRingbuffer param_meta_enable_rb; + SpaPODBuilder b = { NULL }; + uint8_t buffer[1024]; + SpaPODFrame f[2]; config = gst_buffer_pool_get_config (pool); gst_buffer_pool_config_get_params (config, &caps, &size, &min_buffers, &max_buffers); - port_params[0] = ¶m_buffers.param; - param_buffers.param.type = SPA_ALLOC_PARAM_TYPE_BUFFERS; - param_buffers.param.size = sizeof (SpaAllocParamBuffers); - param_buffers.minsize = size; - param_buffers.stride = 0; - param_buffers.min_buffers = min_buffers; - param_buffers.max_buffers = max_buffers; - param_buffers.align = 16; - port_params[1] = ¶m_meta_enable.param; - param_meta_enable.param.type = SPA_ALLOC_PARAM_TYPE_META_ENABLE; - param_meta_enable.param.size = sizeof (SpaAllocParamMetaEnable); - param_meta_enable.type = SPA_META_TYPE_HEADER; - port_params[2] = ¶m_meta_enable_rb.param; - param_meta_enable_rb.param.type = SPA_ALLOC_PARAM_TYPE_META_ENABLE; - param_meta_enable_rb.param.size = sizeof (SpaAllocParamMetaEnableRingbuffer); - param_meta_enable_rb.type = SPA_META_TYPE_RINGBUFFER; - param_meta_enable_rb.minsize = size * SPA_MAX (4, SPA_MAX (min_buffers, max_buffers)); - param_meta_enable_rb.stride = 0; - param_meta_enable_rb.blocks = 1; - param_meta_enable_rb.align = 16; + spa_pod_builder_init (&b, buffer, sizeof (buffer)); + spa_pod_builder_object (&b, &f[0], 0, SPA_ALLOC_PARAM_TYPE_BUFFERS, + PROP (&f[1], SPA_ALLOC_PARAM_BUFFERS_SIZE, SPA_POD_TYPE_INT, size), + PROP (&f[1], SPA_ALLOC_PARAM_BUFFERS_STRIDE, SPA_POD_TYPE_INT, 0), + PROP_MM (&f[1], SPA_ALLOC_PARAM_BUFFERS_BUFFERS, SPA_POD_TYPE_INT, min_buffers, min_buffers, max_buffers), + PROP (&f[1], SPA_ALLOC_PARAM_BUFFERS_ALIGN, SPA_POD_TYPE_INT, 16)); + port_params[0] = SPA_POD_BUILDER_DEREF (&b, f[0].ref, SpaAllocParam); + + spa_pod_builder_object (&b, &f[0], 0, SPA_ALLOC_PARAM_TYPE_META_ENABLE, + PROP (&f[1], SPA_ALLOC_PARAM_META_ENABLE_TYPE, SPA_POD_TYPE_INT, SPA_META_TYPE_HEADER)); + port_params[1] = SPA_POD_BUILDER_DEREF (&b, f[0].ref, SpaAllocParam); + + spa_pod_builder_object (&b, &f[0], 0, SPA_ALLOC_PARAM_TYPE_META_ENABLE, + PROP (&f[1], SPA_ALLOC_PARAM_META_ENABLE_TYPE, SPA_POD_TYPE_INT, SPA_META_TYPE_RINGBUFFER), + PROP (&f[1], SPA_ALLOC_PARAM_META_ENABLE_RB_SIZE, SPA_POD_TYPE_INT, + size * SPA_MAX (4, SPA_MAX (min_buffers, max_buffers))), + PROP (&f[1], SPA_ALLOC_PARAM_META_ENABLE_RB_STRIDE, SPA_POD_TYPE_INT, 0), + PROP (&f[1], SPA_ALLOC_PARAM_META_ENABLE_RB_BLOCKS, SPA_POD_TYPE_INT, 1), + PROP (&f[1], SPA_ALLOC_PARAM_META_ENABLE_RB_ALIGN, SPA_POD_TYPE_INT, 16)); + port_params[2] = SPA_POD_BUILDER_DEREF (&b, f[0].ref, SpaAllocParam); pinos_stream_finish_format (p->stream, SPA_RESULT_OK, port_params, 2); diff --git a/pinos/gst/gstpinossrc.c b/pinos/gst/gstpinossrc.c index 5197ed80e..363338ad3 100644 --- a/pinos/gst/gstpinossrc.c +++ b/pinos/gst/gstpinossrc.c @@ -765,6 +765,8 @@ connect_error: } } +#define PROP(f,key,type,...) \ + SPA_POD_PROP (f,key,SPA_POD_PROP_FLAG_READWRITE,type,1,__VA_ARGS__) static void on_format_changed (PinosListener *listener, PinosStream *stream, @@ -781,12 +783,14 @@ on_format_changed (PinosListener *listener, if (res) { SpaAllocParam *params[1]; - SpaAllocParamMetaEnable param_meta; + SpaPODBuilder b = { NULL }; + uint8_t buffer[128]; + SpaPODFrame f[2]; - params[0] = ¶m_meta.param; - param_meta.param.type = SPA_ALLOC_PARAM_TYPE_META_ENABLE; - param_meta.param.size = sizeof (param_meta); - param_meta.type = SPA_META_TYPE_HEADER; + spa_pod_builder_init (&b, buffer, sizeof (buffer)); + spa_pod_builder_object (&b, &f[0], 0, SPA_ALLOC_PARAM_TYPE_META_ENABLE, + PROP (&f[1], SPA_ALLOC_PARAM_META_ENABLE_TYPE, SPA_POD_TYPE_INT, SPA_META_TYPE_HEADER)); + params[0] = SPA_POD_BUILDER_DEREF (&b, f[0].ref, SpaAllocParam); GST_DEBUG_OBJECT (pinossrc, "doing finish format"); pinos_stream_finish_format (pinossrc->stream, SPA_RESULT_OK, params, 1); diff --git a/pinos/modules/module-access.c b/pinos/modules/module-access.c index d6d1eb97f..4b0c3a264 100644 --- a/pinos/modules/module-access.c +++ b/pinos/modules/module-access.c @@ -34,6 +34,7 @@ typedef struct { PinosListener check_dispatch; } ModuleImpl; +#if 0 static bool check_global_owner (PinosCore *core, PinosClient *client, @@ -53,6 +54,7 @@ check_global_owner (PinosCore *core, return false; } +#endif static void do_check_send (PinosListener *listener, diff --git a/pinos/modules/module-protocol-dbus.c b/pinos/modules/module-protocol-dbus.c index 547bfb7cb..4cda9a075 100644 --- a/pinos/modules/module-protocol-dbus.c +++ b/pinos/modules/module-protocol-dbus.c @@ -195,8 +195,8 @@ pinos_properties_from_variant (GVariant *variant) { PinosProperties *props; GVariantIter iter; - GVariant *value; - gchar *key; + //GVariant *value; + //gchar *key; props = pinos_properties_new (NULL, NULL); diff --git a/pinos/server/link.c b/pinos/server/link.c index 8cf9318ef..94d7d9fcd 100644 --- a/pinos/server/link.c +++ b/pinos/server/link.c @@ -19,8 +19,9 @@ #include -#include #include +#include +#include #include "pinos/client/pinos.h" #include "pinos/client/interfaces.h" @@ -145,7 +146,7 @@ find_param (const SpaPortInfo *info, SpaAllocParamType type) uint32_t i; for (i = 0; i < info->n_params; i++) { - if (info->params[i]->type == type) + if (spa_pod_is_object_type (&info->params[i]->pod, type)) return info->params[i]; } return NULL; @@ -157,9 +158,15 @@ find_meta_enable (const SpaPortInfo *info, SpaMetaType type) uint32_t i; for (i = 0; i < info->n_params; i++) { - if (info->params[i]->type == SPA_ALLOC_PARAM_TYPE_META_ENABLE && - ((SpaAllocParamMetaEnable*)info->params[i])->type == type) { - return info->params[i]; + if (spa_pod_is_object_type (&info->params[i]->pod, SPA_ALLOC_PARAM_TYPE_META_ENABLE)) { + uint32_t qtype; + + if (spa_alloc_param_query (info->params[i], + SPA_ALLOC_PARAM_META_ENABLE_TYPE, SPA_POD_TYPE_INT, &qtype, 0) != 1) + continue; + + if (qtype == type) + return info->params[i]; } } return NULL; @@ -201,11 +208,16 @@ alloc_buffers (PinosLink *this, for (i = 0; i < n_params; i++) { SpaAllocParam *ap = params[i]; - if (ap->type == SPA_ALLOC_PARAM_TYPE_META_ENABLE) { - SpaAllocParamMetaEnable *pme = (SpaAllocParamMetaEnable *) ap; + if (ap->pod.type == SPA_ALLOC_PARAM_TYPE_META_ENABLE) { + uint32_t type; - metas[n_metas].type = pme->type; - metas[n_metas].size = spa_meta_type_get_size (pme->type); + if (spa_alloc_param_query (ap, + SPA_ALLOC_PARAM_META_ENABLE_TYPE, SPA_POD_TYPE_INT, &type, + 0) != 1) + continue; + + metas[n_metas].type = type; + metas[n_metas].size = spa_meta_type_get_size (type); meta_size += metas[n_metas].size; n_metas++; skel_size += sizeof (SpaMeta); @@ -380,33 +392,60 @@ do_allocation (PinosLink *this, SpaNodeState in_state, SpaNodeState out_state) return SPA_RESULT_OK; if (impl->buffers == NULL) { - SpaAllocParamBuffers *in_alloc, *out_alloc; - SpaAllocParamMetaEnableRingbuffer *in_me, *out_me; + SpaAllocParam *in_alloc, *out_alloc; + SpaAllocParam *in_me, *out_me; uint32_t max_buffers; - size_t minsize, stride, blocks; + size_t minsize = 1024, stride = 0; in_me = find_meta_enable (iinfo, SPA_META_TYPE_RINGBUFFER); out_me = find_meta_enable (oinfo, SPA_META_TYPE_RINGBUFFER); if (in_me && out_me) { + uint32_t ms1, ms2, s1, s2; max_buffers = 1; - minsize = SPA_MAX (out_me->minsize, in_me->minsize); - stride = SPA_MAX (out_me->stride, in_me->stride); - blocks = SPA_MAX (1, SPA_MAX (out_me->blocks, in_me->blocks)); + + if (spa_alloc_param_query (in_me, + SPA_ALLOC_PARAM_META_ENABLE_RB_SIZE, SPA_POD_TYPE_INT, &ms1, + SPA_ALLOC_PARAM_META_ENABLE_RB_STRIDE, SPA_POD_TYPE_INT, &s1, 0) == 2 && + spa_alloc_param_query (in_me, + SPA_ALLOC_PARAM_META_ENABLE_RB_SIZE, SPA_POD_TYPE_INT, &ms2, + SPA_ALLOC_PARAM_META_ENABLE_RB_STRIDE, SPA_POD_TYPE_INT, &s2, 0) == 2) { + minsize = SPA_MAX (ms1, ms2); + stride = SPA_MAX (s1, s2); + } } else { max_buffers = MAX_BUFFERS; minsize = stride = 0; - blocks = 1; in_alloc = find_param (iinfo, SPA_ALLOC_PARAM_TYPE_BUFFERS); if (in_alloc) { - max_buffers = in_alloc->max_buffers == 0 ? max_buffers : SPA_MIN (in_alloc->max_buffers, max_buffers); - minsize = SPA_MAX (minsize, in_alloc->minsize); - stride = SPA_MAX (stride, in_alloc->stride); + uint32_t qmax_buffers = max_buffers, + qminsize = minsize, + qstride = stride; + + spa_alloc_param_query (in_alloc, + SPA_ALLOC_PARAM_BUFFERS_SIZE, SPA_POD_TYPE_INT, &qminsize, + SPA_ALLOC_PARAM_BUFFERS_STRIDE, SPA_POD_TYPE_INT, &qstride, + SPA_ALLOC_PARAM_BUFFERS_BUFFERS, SPA_POD_TYPE_INT, &qmax_buffers, + 0); + + max_buffers = qmax_buffers == 0 ? max_buffers : SPA_MIN (qmax_buffers, max_buffers); + minsize = SPA_MAX (minsize, qminsize); + stride = SPA_MAX (stride, qstride); } out_alloc = find_param (oinfo, SPA_ALLOC_PARAM_TYPE_BUFFERS); if (out_alloc) { - max_buffers = out_alloc->max_buffers == 0 ? max_buffers : SPA_MIN (out_alloc->max_buffers, max_buffers); - minsize = SPA_MAX (minsize, out_alloc->minsize); - stride = SPA_MAX (stride, out_alloc->stride); + uint32_t qmax_buffers = max_buffers, + qminsize = minsize, + qstride = stride; + + spa_alloc_param_query (out_alloc, + SPA_ALLOC_PARAM_BUFFERS_SIZE, SPA_POD_TYPE_INT, &qminsize, + SPA_ALLOC_PARAM_BUFFERS_STRIDE, SPA_POD_TYPE_INT, &qstride, + SPA_ALLOC_PARAM_BUFFERS_BUFFERS, SPA_POD_TYPE_INT, &qmax_buffers, + 0); + + max_buffers = qmax_buffers == 0 ? max_buffers : SPA_MIN (qmax_buffers, max_buffers); + minsize = SPA_MAX (minsize, qminsize); + stride = SPA_MAX (stride, qstride); } } diff --git a/pinos/server/protocol-native.c b/pinos/server/protocol-native.c index a58e5ebe3..d14337978 100644 --- a/pinos/server/protocol-native.c +++ b/pinos/server/protocol-native.c @@ -115,10 +115,8 @@ core_marshal_done (void *object, core_update_map (resource->client); - spa_pod_builder_add (&b.b, - SPA_POD_TYPE_STRUCT, &f, - SPA_POD_TYPE_INT, seq, - -SPA_POD_TYPE_STRUCT, &f, 0); + spa_pod_builder_struct (&b.b, &f, + SPA_POD_TYPE_INT, seq); pinos_connection_end_write (connection, resource->id, 1, b.b.offset); } @@ -142,12 +140,10 @@ core_marshal_error (void *object, vsnprintf (buffer, sizeof (buffer), error, ap); va_end (ap); - spa_pod_builder_add (&b.b, - SPA_POD_TYPE_STRUCT, &f, + spa_pod_builder_struct (&b.b, &f, SPA_POD_TYPE_INT, id, SPA_POD_TYPE_INT, res, - SPA_POD_TYPE_STRING, buffer, - -SPA_POD_TYPE_STRUCT, &f, 0); + SPA_POD_TYPE_STRING, buffer); pinos_connection_end_write (connection, resource->id, 2, b.b.offset); } @@ -163,10 +159,8 @@ core_marshal_remove_id (void *object, core_update_map (resource->client); - spa_pod_builder_add (&b.b, - SPA_POD_TYPE_STRUCT, &f, - SPA_POD_TYPE_INT, id, - -SPA_POD_TYPE_STRUCT, &f, 0); + spa_pod_builder_struct (&b.b, &f, + SPA_POD_TYPE_INT, id); pinos_connection_end_write (connection, resource->id, 3, b.b.offset); } @@ -377,11 +371,9 @@ registry_marshal_global (void *object, core_update_map (resource->client); - spa_pod_builder_add (&b.b, - SPA_POD_TYPE_STRUCT, &f, + spa_pod_builder_struct (&b.b, &f, SPA_POD_TYPE_INT, id, - SPA_POD_TYPE_STRING, type, - -SPA_POD_TYPE_STRUCT, &f, 0); + SPA_POD_TYPE_STRING, type); pinos_connection_end_write (connection, resource->id, 0, b.b.offset); } @@ -397,10 +389,8 @@ registry_marshal_global_remove (void *object, core_update_map (resource->client); - spa_pod_builder_add (&b.b, - SPA_POD_TYPE_STRUCT, &f, - SPA_POD_TYPE_INT, id, - -SPA_POD_TYPE_STRUCT, &f, 0); + spa_pod_builder_struct (&b.b, &f, + SPA_POD_TYPE_INT, id); pinos_connection_end_write (connection, resource->id, 1, b.b.offset); } @@ -549,10 +539,8 @@ client_node_marshal_done (void *object, core_update_map (resource->client); - spa_pod_builder_add (&b.b, - SPA_POD_TYPE_STRUCT, &f, - SPA_POD_TYPE_INT, pinos_connection_add_fd (connection, datafd), - -SPA_POD_TYPE_STRUCT, &f, 0); + spa_pod_builder_struct (&b.b, &f, + SPA_POD_TYPE_INT, pinos_connection_add_fd (connection, datafd)); pinos_connection_end_write (connection, resource->id, 0, b.b.offset); } @@ -568,10 +556,8 @@ client_node_marshal_event (void *object, core_update_map (resource->client); - spa_pod_builder_add (&b.b, - SPA_POD_TYPE_STRUCT, &f, - SPA_POD_TYPE_POD, event, - -SPA_POD_TYPE_STRUCT, &f, 0); + spa_pod_builder_struct (&b.b, &f, + SPA_POD_TYPE_POD, event); pinos_connection_end_write (connection, resource->id, 1, b.b.offset); } @@ -589,12 +575,10 @@ client_node_marshal_add_port (void *object, core_update_map (resource->client); - spa_pod_builder_add (&b.b, - SPA_POD_TYPE_STRUCT, &f, + spa_pod_builder_struct (&b.b, &f, SPA_POD_TYPE_INT, seq, SPA_POD_TYPE_INT, direction, - SPA_POD_TYPE_INT, port_id, - -SPA_POD_TYPE_STRUCT, &f, 0); + SPA_POD_TYPE_INT, port_id); pinos_connection_end_write (connection, resource->id, 2, b.b.offset); } @@ -612,12 +596,10 @@ client_node_marshal_remove_port (void *object, core_update_map (resource->client); - spa_pod_builder_add (&b.b, - SPA_POD_TYPE_STRUCT, &f, + spa_pod_builder_struct (&b.b, &f, SPA_POD_TYPE_INT, seq, SPA_POD_TYPE_INT, direction, - SPA_POD_TYPE_INT, port_id, - -SPA_POD_TYPE_STRUCT, &f, 0); + SPA_POD_TYPE_INT, port_id); pinos_connection_end_write (connection, resource->id, 3, b.b.offset); } @@ -665,12 +647,10 @@ client_node_marshal_set_property (void *object, core_update_map (resource->client); - spa_pod_builder_add (&b.b, - SPA_POD_TYPE_STRUCT, &f, + spa_pod_builder_struct (&b.b, &f, SPA_POD_TYPE_INT, seq, SPA_POD_TYPE_INT, id, - SPA_POD_TYPE_BYTES, value, size, - -SPA_POD_TYPE_STRUCT, &f, 0); + SPA_POD_TYPE_BYTES, value, size); pinos_connection_end_write (connection, resource->id, 5, b.b.offset); } @@ -693,8 +673,7 @@ client_node_marshal_add_mem (void *object, core_update_map (resource->client); - spa_pod_builder_add (&b.b, - SPA_POD_TYPE_STRUCT, &f, + spa_pod_builder_struct (&b.b, &f, SPA_POD_TYPE_INT, direction, SPA_POD_TYPE_INT, port_id, SPA_POD_TYPE_INT, mem_id, @@ -702,8 +681,7 @@ client_node_marshal_add_mem (void *object, SPA_POD_TYPE_INT, pinos_connection_add_fd (connection, memfd), SPA_POD_TYPE_INT, flags, SPA_POD_TYPE_INT, offset, - SPA_POD_TYPE_INT, size, - -SPA_POD_TYPE_STRUCT, &f, 0); + SPA_POD_TYPE_INT, size); pinos_connection_end_write (connection, resource->id, 6, b.b.offset); } @@ -775,11 +753,9 @@ client_node_marshal_node_command (void *object, core_update_map (resource->client); - spa_pod_builder_add (&b.b, - SPA_POD_TYPE_STRUCT, &f, + spa_pod_builder_struct (&b.b, &f, SPA_POD_TYPE_INT, seq, - SPA_POD_TYPE_POD, command, - -SPA_POD_TYPE_STRUCT, &f, 0); + SPA_POD_TYPE_POD, command); pinos_connection_end_write (connection, resource->id, 8, b.b.offset); } @@ -796,11 +772,9 @@ client_node_marshal_port_command (void *object, core_update_map (resource->client); - spa_pod_builder_add (&b.b, - SPA_POD_TYPE_STRUCT, &f, + spa_pod_builder_struct (&b.b, &f, SPA_POD_TYPE_INT, port_id, - SPA_POD_TYPE_POD, command, - -SPA_POD_TYPE_STRUCT, &f, 0); + SPA_POD_TYPE_POD, command); pinos_connection_end_write (connection, resource->id, 9, b.b.offset); } @@ -818,12 +792,10 @@ client_node_marshal_transport (void *object, core_update_map (resource->client); - spa_pod_builder_add (&b.b, - SPA_POD_TYPE_STRUCT, &f, + spa_pod_builder_struct (&b.b, &f, SPA_POD_TYPE_INT, pinos_connection_add_fd (connection, memfd), SPA_POD_TYPE_INT, offset, - SPA_POD_TYPE_INT, size, - -SPA_POD_TYPE_STRUCT, &f, 0); + SPA_POD_TYPE_INT, size); pinos_connection_end_write (connection, resource->id, 10, b.b.offset); } @@ -861,7 +833,7 @@ client_node_demarshal_port_update (void *object, { PinosResource *resource = object; SpaPODIter it; - uint32_t i, t, direction, port_id, change_mask, n_possible_formats, sz; + uint32_t i, t, direction, port_id, change_mask, n_possible_formats; const SpaProps *props = NULL; const SpaFormat **possible_formats = NULL, *format = NULL; SpaPortInfo info, *infop = NULL; @@ -905,7 +877,7 @@ client_node_demarshal_port_update (void *object, info.params = alloca (info.n_params * sizeof (SpaAllocParam *)); for (i = 0; i < info.n_params; i++) - if (!spa_pod_iter_get (&it, SPA_POD_TYPE_BYTES, &info.params[i], &sz, 0)) + if (!spa_pod_iter_get (&it, SPA_POD_TYPE_OBJECT, &info.params[i], 0)) return false; if (!spa_pod_iter_get (&it, SPA_POD_TYPE_INT, &dict.n_items, 0)) @@ -994,15 +966,13 @@ link_marshal_info (void *object, core_update_map (resource->client); - spa_pod_builder_add (&b.b, - SPA_POD_TYPE_STRUCT, &f, + spa_pod_builder_struct (&b.b, &f, SPA_POD_TYPE_INT, info->id, SPA_POD_TYPE_LONG, info->change_mask, SPA_POD_TYPE_INT, info->output_node_id, SPA_POD_TYPE_INT, info->output_port_id, SPA_POD_TYPE_INT, info->input_node_id, - SPA_POD_TYPE_INT, info->input_port_id, - -SPA_POD_TYPE_STRUCT, &f, 0); + SPA_POD_TYPE_INT, info->input_port_id); pinos_connection_end_write (connection, resource->id, 0, b.b.offset); } diff --git a/spa/include/spa/defs.h b/spa/include/spa/defs.h index 39ee8f7a2..ed669bafd 100644 --- a/spa/include/spa/defs.h +++ b/spa/include/spa/defs.h @@ -70,6 +70,7 @@ typedef enum { SPA_RESULT_NO_PERMISSION = -33, SPA_RESULT_SKIPPED = -34, SPA_RESULT_OUT_OF_BUFFERS = -35, + SPA_RESULT_INCOMPATIBLE_PROPS = -36, } SpaResult; #define SPA_ASYNC_MASK (3 << 30) diff --git a/spa/include/spa/format-builder.h b/spa/include/spa/format-builder.h index 651b69afb..781563b4d 100644 --- a/spa/include/spa/format-builder.h +++ b/spa/include/spa/format-builder.h @@ -43,26 +43,11 @@ spa_pod_builder_push_format (SpaPODBuilder *builder, spa_pod_builder_raw (builder, &p, sizeof(p))); } -static inline uint32_t -spa_pod_builder_format (SpaPODBuilder *builder, - uint32_t media_type, - uint32_t media_subtype, - uint32_t type, ...) -{ - SpaPODFrame f; - va_list args; - uint32_t off; - - off = spa_pod_builder_push_format (builder, &f, media_type, media_subtype); - - va_start (args, type); - spa_pod_builder_addv (builder, type, args); - va_end (args); - - spa_pod_builder_pop (builder, &f); - - return off; -} +#define spa_pod_builder_format(b,f,media_type,media_subtype,...) \ + spa_pod_builder_object(b, f, 0, 0, \ + SPA_POD_TYPE_INT,media_type, \ + SPA_POD_TYPE_INT,media_subtype, \ + __VA_ARGS__) SpaResult spa_format_filter (const SpaFormat *format, diff --git a/spa/include/spa/format.h b/spa/include/spa/format.h index e2d3f0fbc..a4e9da9a4 100644 --- a/spa/include/spa/format.h +++ b/spa/include/spa/format.h @@ -32,7 +32,7 @@ typedef struct _SpaFormat SpaFormat; #include #include -#include +#include typedef enum { SPA_MEDIA_TYPE_INVALID = 0, @@ -118,7 +118,20 @@ struct _SpaFormat { static inline SpaPODProp * spa_format_find_prop (const SpaFormat *format, uint32_t key) { - return spa_pod_contents_find_prop (&format->pod, SPA_ROUND_UP_N (sizeof (SpaFormat), 8), key); + return spa_pod_contents_find_prop (&format->pod, sizeof (SpaFormat), key); +} + +static inline uint32_t +spa_format_query (const SpaFormat *format, uint32_t key, ...) +{ + uint32_t count; + va_list args; + + va_start (args, key); + count = spa_pod_contents_queryv (&format->pod, sizeof (SpaFormat), key, args); + va_end (args); + + return count; } static inline SpaResult diff --git a/spa/include/spa/meson.build b/spa/include/spa/meson.build index 6ea8bf635..aae9ffca7 100644 --- a/spa/include/spa/meson.build +++ b/spa/include/spa/meson.build @@ -16,6 +16,8 @@ spa_headers = [ 'plugin.h', 'pod.h', 'pod-builder.h', + 'pod-iter.h', + 'pod-utils.h', 'port.h', 'props.h', 'ringbuffer.h' diff --git a/spa/include/spa/pod-builder.h b/spa/include/spa/pod-builder.h index c3a86b8ab..f8205123e 100644 --- a/spa/include/spa/pod-builder.h +++ b/spa/include/spa/pod-builder.h @@ -25,7 +25,8 @@ extern "C" { #endif #include -#include +#include +#include typedef struct _SpaPODFrame { struct _SpaPODFrame *parent; @@ -345,7 +346,7 @@ spa_pod_builder_addv (SpaPODBuilder *builder, break; case -SPA_POD_TYPE_STRING: { - char *str = va_arg (args, char *); + const char *str = va_arg (args, const char *); uint32_t len = va_arg (args, uint32_t); spa_pod_builder_string_len (builder, str, len); break; @@ -356,12 +357,24 @@ spa_pod_builder_addv (SpaPODBuilder *builder, spa_pod_builder_rectangle (builder, width, height); break; } + case -SPA_POD_TYPE_RECTANGLE: + { + const SpaRectangle *val = va_arg (args, SpaRectangle *); + spa_pod_builder_rectangle (builder, val->width, val->height); + break; + } case SPA_POD_TYPE_FRACTION: { uint32_t num = va_arg (args, uint32_t), denom = va_arg (args, uint32_t); spa_pod_builder_fraction (builder, num, denom); break; } + case -SPA_POD_TYPE_FRACTION: + { + const SpaFraction *val = va_arg (args, SpaFraction *); + spa_pod_builder_fraction (builder, val->num, val->denom); + break; + } case SPA_POD_TYPE_BITMASK: break; case SPA_POD_TYPE_ARRAY: @@ -414,7 +427,7 @@ spa_pod_builder_addv (SpaPODBuilder *builder, } case SPA_POD_TYPE_POD: { - SpaPOD *value = va_arg (args, SpaPOD *); + const SpaPOD *value = va_arg (args, SpaPOD *); spa_pod_builder_raw_padded (builder, value, SPA_POD_SIZE (value)); break; } @@ -437,6 +450,22 @@ spa_pod_builder_add (SpaPODBuilder *builder, va_end (args); } +#define SPA_POD_OBJECT(f,id,type,...) \ + SPA_POD_TYPE_OBJECT, f, id, type, __VA_ARGS__, -SPA_POD_TYPE_OBJECT, f + +#define SPA_POD_STRUCT(f,...) \ + SPA_POD_TYPE_STRUCT, f, __VA_ARGS__, -SPA_POD_TYPE_STRUCT, f + +#define SPA_POD_PROP(f,key,flags,type,...) \ + SPA_POD_TYPE_PROP, f, key, flags, type, __VA_ARGS__, -SPA_POD_TYPE_PROP, f + + +#define spa_pod_builder_object(b,f,id,type,...) \ + spa_pod_builder_add(b, SPA_POD_OBJECT (f,id,type,__VA_ARGS__), 0) + +#define spa_pod_builder_struct(b,f,...) \ + spa_pod_builder_add(b, SPA_POD_STRUCT (f,__VA_ARGS__), 0) + #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/spa/include/spa/pod-iter.h b/spa/include/spa/pod-iter.h index 26e78c3c2..8dfc91d04 100644 --- a/spa/include/spa/pod-iter.h +++ b/spa/include/spa/pod-iter.h @@ -27,7 +27,7 @@ extern "C" { #include #include -#include +#include typedef struct { const void *data; @@ -118,50 +118,12 @@ spa_pod_iter_getv (SpaPODIter *iter, { while (type && spa_pod_iter_has_next (iter)) { SpaPOD *pod = spa_pod_iter_next (iter); - if (pod->type != type) + + if (type != SPA_POD_TYPE_POD && pod->type != type) return false; - switch (type) { - case SPA_POD_TYPE_BOOL: - case SPA_POD_TYPE_URI: - case SPA_POD_TYPE_INT: - *(va_arg (args, int32_t*)) = ((SpaPODInt *)(pod))->value; - break; - case SPA_POD_TYPE_LONG: - *(va_arg (args, int64_t*)) = ((SpaPODLong *)(pod))->value; - break; - case SPA_POD_TYPE_FLOAT: - *(va_arg (args, float*)) = ((SpaPODFloat *)(pod))->value; - break; - case SPA_POD_TYPE_DOUBLE: - *(va_arg (args, double*)) = ((SpaPODDouble *)(pod))->value; - break; - case SPA_POD_TYPE_STRING: - *(va_arg (args, char **)) = SPA_POD_CONTENTS (SpaPODString, pod); - break; - case SPA_POD_TYPE_RECTANGLE: - *(va_arg (args, SpaRectangle *)) = ((SpaPODRectangle *)(pod))->value; - break; - case SPA_POD_TYPE_FRACTION: - *(va_arg (args, SpaFraction *)) = ((SpaPODFraction *)(pod))->value; - break; - case SPA_POD_TYPE_BITMASK: - *(va_arg (args, uint32_t **)) = SPA_POD_CONTENTS (SpaPOD, pod); - break; - case SPA_POD_TYPE_ARRAY: - case SPA_POD_TYPE_STRUCT: - case SPA_POD_TYPE_OBJECT: - case SPA_POD_TYPE_PROP: - *(va_arg (args, SpaPOD **)) = pod; - break; - case SPA_POD_TYPE_BYTES: - *(va_arg (args, void **)) = SPA_POD_CONTENTS (SpaPODBytes, pod); - *(va_arg (args, uint32_t *)) = SPA_POD_BODY_SIZE (pod); - break; - default: - case SPA_POD_TYPE_INVALID: - return false; - } + SPA_POD_COLLECT (pod, type, args); + type = va_arg (args, uint32_t); } return true; diff --git a/spa/include/spa/pod-utils.h b/spa/include/spa/pod-utils.h new file mode 100644 index 000000000..c4053f536 --- /dev/null +++ b/spa/include/spa/pod-utils.h @@ -0,0 +1,208 @@ +/* Simple Plugin API + * Copyright (C) 2017 Wim Taymans + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __SPA_POD_UTILS_H__ +#define __SPA_POD_UTILS_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +#define SPA_POD_BODY_SIZE(pod) (((SpaPOD*)(pod))->size) +#define SPA_POD_TYPE(pod) (((SpaPOD*)(pod))->type) +#define SPA_POD_SIZE(pod) (sizeof(SpaPOD) + SPA_POD_BODY_SIZE(pod)) +#define SPA_POD_CONTENTS_SIZE(type,pod) (SPA_POD_SIZE(pod)-sizeof(type)) + +#define SPA_POD_CONTENTS(type,pod) SPA_MEMBER((pod),sizeof(type),void) +#define SPA_POD_CONTENTS_CONST(type,pod) SPA_MEMBER((pod),sizeof(type),const void) +#define SPA_POD_BODY(pod) SPA_MEMBER((pod),sizeof(SpaPOD),void) +#define SPA_POD_BODY_CONST(pod) SPA_MEMBER((pod),sizeof(SpaPOD),const void) + +#define SPA_POD_VALUE(type,pod) (((type*)pod)->value) + +#define SPA_POD_PROP_N_VALUES(prop) (((prop)->pod.size - sizeof (SpaPODPropBody)) / (prop)->body.value.size) + +static inline bool +spa_pod_is_object_type (SpaPOD *pod, uint32_t type) +{ + return (pod->type == SPA_POD_TYPE_OBJECT && ((SpaPODObject*)pod)->body.type == type); +} + +#define SPA_POD_ARRAY_BODY_FOREACH(body, _size, iter) \ + for ((iter) = SPA_MEMBER ((body), sizeof(SpaPODArrayBody), __typeof__(*(iter))); \ + (iter) < SPA_MEMBER ((body), (_size), __typeof__(*(iter))); \ + (iter) = SPA_MEMBER ((iter), (body)->child.size, __typeof__(*(iter)))) + +#define SPA_POD_FOREACH(pod, size, iter) \ + for ((iter) = (pod); \ + (iter) < SPA_MEMBER ((pod), (size), SpaPOD); \ + (iter) = SPA_MEMBER ((iter), SPA_ROUND_UP_N (SPA_POD_SIZE (iter), 8), SpaPOD)) + +#define SPA_POD_CONTENTS_FOREACH(pod, offset, iter) \ + SPA_POD_FOREACH(SPA_MEMBER ((pod), (offset), SpaPOD),SPA_POD_SIZE (pod),iter) + +#define SPA_POD_OBJECT_BODY_FOREACH(body, size, iter) \ + for ((iter) = SPA_MEMBER ((body), sizeof (SpaPODObjectBody), SpaPOD); \ + (iter) < SPA_MEMBER ((body), (size), SpaPOD); \ + (iter) = SPA_MEMBER ((iter), SPA_ROUND_UP_N (SPA_POD_SIZE (iter), 8), SpaPOD)) + +#define SPA_POD_OBJECT_FOREACH(obj, iter) \ + SPA_POD_OBJECT_BODY_FOREACH(&obj->body, SPA_POD_BODY_SIZE(obj), iter) + +#define SPA_POD_PROP_ALTERNATIVE_FOREACH(body, _size, iter) \ + for ((iter) = SPA_MEMBER ((body), (body)->value.size + sizeof (SpaPODPropBody), __typeof__(*iter)); \ + (iter) <= SPA_MEMBER ((body), (_size)-(body)->value.size, __typeof__(*iter)); \ + (iter) = SPA_MEMBER ((iter), (body)->value.size, __typeof__(*iter))) + +static inline SpaPODProp * +spa_pod_contents_find_prop (const SpaPOD *pod, uint32_t offset, uint32_t key) +{ + SpaPOD *res; + SPA_POD_CONTENTS_FOREACH (pod, offset, res) { + if (res->type == SPA_POD_TYPE_PROP && ((SpaPODProp*)res)->body.key == key) + return (SpaPODProp *)res; + } + return NULL; +} + +static inline SpaPODProp * +spa_pod_object_find_prop (const SpaPODObject *obj, uint32_t key) +{ + return spa_pod_contents_find_prop (&obj->pod, sizeof (SpaPODObject), key); +} + +#define SPA_POD_COLLECT(pod,type,args) \ + switch (type) { \ + case SPA_POD_TYPE_BOOL: \ + case SPA_POD_TYPE_URI: \ + case SPA_POD_TYPE_INT: \ + *(va_arg (args, int32_t*)) = SPA_POD_VALUE(SpaPODInt, pod); \ + break; \ + case SPA_POD_TYPE_LONG: \ + *(va_arg (args, int64_t*)) = SPA_POD_VALUE (SpaPODLong, pod); \ + break; \ + case SPA_POD_TYPE_FLOAT: \ + *(va_arg (args, float*)) = SPA_POD_VALUE (SpaPODFloat, pod); \ + break; \ + case SPA_POD_TYPE_DOUBLE: \ + *(va_arg (args, double*)) = SPA_POD_VALUE (SpaPODDouble, pod); \ + break; \ + case SPA_POD_TYPE_STRING: \ + *(va_arg (args, char **)) = SPA_POD_CONTENTS (SpaPODString, pod); \ + break; \ + case -SPA_POD_TYPE_STRING: \ + { \ + char *dest = va_arg (args, char *); \ + uint32_t maxlen = va_arg (args, uint32_t); \ + strncpy (dest, SPA_POD_CONTENTS (SpaPODString, pod), maxlen-1); \ + break; \ + } \ + case SPA_POD_TYPE_RECTANGLE: \ + *(va_arg (args, SpaRectangle *)) = SPA_POD_VALUE (SpaPODRectangle, pod); \ + break; \ + case SPA_POD_TYPE_FRACTION: \ + *(va_arg (args, SpaFraction *)) = SPA_POD_VALUE (SpaPODFraction, pod); \ + break; \ + case SPA_POD_TYPE_BITMASK: \ + *(va_arg (args, uint32_t **)) = SPA_POD_CONTENTS (SpaPOD, pod); \ + break; \ + case SPA_POD_TYPE_ARRAY: \ + case SPA_POD_TYPE_STRUCT: \ + case SPA_POD_TYPE_OBJECT: \ + case SPA_POD_TYPE_PROP: \ + case SPA_POD_TYPE_POD: \ + *(va_arg (args, SpaPOD **)) = pod; \ + break; \ + case SPA_POD_TYPE_BYTES: \ + *(va_arg (args, void **)) = SPA_POD_CONTENTS (SpaPODBytes, pod); \ + *(va_arg (args, uint32_t *)) = SPA_POD_BODY_SIZE (pod); \ + break; \ + default: \ + break; \ + } \ + +#define SPA_POD_COLLECT_SKIP(type,args) \ + switch (type) { \ + case SPA_POD_TYPE_BYTES: \ + va_arg (args, void*); \ + case SPA_POD_TYPE_BOOL: \ + case SPA_POD_TYPE_URI: \ + case SPA_POD_TYPE_INT: \ + case SPA_POD_TYPE_LONG: \ + case SPA_POD_TYPE_FLOAT: \ + case SPA_POD_TYPE_DOUBLE: \ + case SPA_POD_TYPE_STRING: \ + case SPA_POD_TYPE_RECTANGLE: \ + case SPA_POD_TYPE_FRACTION: \ + case SPA_POD_TYPE_BITMASK: \ + case SPA_POD_TYPE_ARRAY: \ + case SPA_POD_TYPE_STRUCT: \ + case SPA_POD_TYPE_OBJECT: \ + case SPA_POD_TYPE_PROP: \ + case SPA_POD_TYPE_POD: \ + va_arg (args, void*); \ + default: \ + break; \ + } \ + +static inline uint32_t +spa_pod_contents_queryv (const SpaPOD *pod, uint32_t offset, uint32_t key, va_list args) +{ + uint32_t count = 0; + + while (key) { + uint32_t type; + SpaPODProp *prop = spa_pod_contents_find_prop (pod, offset, key); + + type = va_arg (args, uint32_t); + + if (prop && prop->body.key == key && + prop->body.value.type == type && + !(prop->body.flags & SPA_POD_PROP_FLAG_UNSET)) { + SPA_POD_COLLECT (&prop->body.value, type, args); + count++; + } else { + SPA_POD_COLLECT_SKIP (type, args); + } + key = va_arg (args, uint32_t); + } + return count; +} + +static inline uint32_t +spa_pod_contents_query (const SpaPOD *pod, uint32_t offset, uint32_t key, ...) +{ + va_list args; + uint32_t count; + + va_start (args, key); + count = spa_pod_contents_queryv (pod, offset, key, args); + va_end (args); + + return count; +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* __SPA_POD_UTILS_H__ */ diff --git a/spa/include/spa/pod.h b/spa/include/spa/pod.h index 73bed224b..823a3a1ca 100644 --- a/spa/include/spa/pod.h +++ b/spa/include/spa/pod.h @@ -27,6 +27,8 @@ extern "C" { #define SPA_POD_URI "http://spaplug.in/ns/pod" #define SPA_POD_PREFIX SPA_POD_URI "#" +#include + #include /** @@ -57,19 +59,10 @@ typedef struct { uint32_t type; } SpaPOD; -#define SPA_POD_BODY_SIZE(pod) (((SpaPOD*)(pod))->size) -#define SPA_POD_TYPE(pod) (((SpaPOD*)(pod))->type) -#define SPA_POD_SIZE(pod) (sizeof(SpaPOD) + SPA_POD_BODY_SIZE(pod)) -#define SPA_POD_CONTENTS_SIZE(type,pod) (SPA_POD_SIZE(pod)-sizeof(type)) - -#define SPA_POD_CONTENTS(type,pod) SPA_MEMBER((pod),sizeof(type),void) -#define SPA_POD_CONTENTS_CONST(type,pod) SPA_MEMBER((pod),sizeof(type),const void) -#define SPA_POD_BODY(pod) SPA_MEMBER((pod),sizeof(SpaPOD),void) -#define SPA_POD_BODY_CONST(pod) SPA_MEMBER((pod),sizeof(SpaPOD),const void) - typedef struct { SpaPOD pod; int32_t value; + int32_t __padding; } SpaPODInt; typedef SpaPODInt SpaPODBool; @@ -155,8 +148,6 @@ typedef struct { SpaPODPropBody body; } SpaPODProp; -#define SPA_POD_PROP_N_VALUES(prop) (((prop)->pod.size - sizeof (SpaPODPropBody)) / (prop)->body.value.size) - typedef struct { uint32_t id; uint32_t type; @@ -168,50 +159,6 @@ typedef struct { SpaPODObjectBody body; } SpaPODObject; -#define SPA_POD_ARRAY_BODY_FOREACH(body, _size, iter) \ - for ((iter) = SPA_MEMBER ((body), sizeof(SpaPODArrayBody), __typeof__(*(iter))); \ - (iter) < SPA_MEMBER ((body), (_size), __typeof__(*(iter))); \ - (iter) = SPA_MEMBER ((iter), (body)->child.size, __typeof__(*(iter)))) - -#define SPA_POD_FOREACH(pod, size, iter) \ - for ((iter) = (pod); \ - (iter) < SPA_MEMBER ((pod), (size), SpaPOD); \ - (iter) = SPA_MEMBER ((iter), SPA_ROUND_UP_N (SPA_POD_SIZE (iter), 8), SpaPOD)) - -#define SPA_POD_CONTENTS_FOREACH(pod, offset, iter) \ - SPA_POD_FOREACH(SPA_MEMBER ((pod), (offset), SpaPOD),SPA_POD_SIZE (pod),iter) - -#define SPA_POD_OBJECT_BODY_FOREACH(body, size, iter) \ - for ((iter) = SPA_MEMBER ((body), sizeof (SpaPODObjectBody), SpaPOD); \ - (iter) < SPA_MEMBER ((body), (size), SpaPOD); \ - (iter) = SPA_MEMBER ((iter), SPA_ROUND_UP_N (SPA_POD_SIZE (iter), 8), SpaPOD)) - -#define SPA_POD_OBJECT_FOREACH(obj, iter) \ - SPA_POD_OBJECT_BODY_FOREACH(&obj->body, SPA_POD_BODY_SIZE(obj), iter) - -#define SPA_POD_PROP_ALTERNATIVE_FOREACH(body, _size, iter) \ - for ((iter) = SPA_MEMBER ((body), (body)->value.size + sizeof (SpaPODPropBody), __typeof__(*iter)); \ - (iter) <= SPA_MEMBER ((body), (_size)-(body)->value.size, __typeof__(*iter)); \ - (iter) = SPA_MEMBER ((iter), (body)->value.size, __typeof__(*iter))) - -static inline SpaPODProp * -spa_pod_contents_find_prop (const SpaPOD *pod, uint32_t offset, uint32_t key) -{ - SpaPOD *res; - SPA_POD_CONTENTS_FOREACH (pod, offset, res) { - if (res->type == SPA_POD_TYPE_PROP && ((SpaPODProp*)res)->body.key == key) - return (SpaPODProp *)res; - } - return NULL; -} - -static inline SpaPODProp * -spa_pod_object_find_prop (const SpaPODObject *obj, uint32_t key) -{ - return spa_pod_contents_find_prop (&obj->pod, sizeof (SpaPODObject), key); -} - - #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/spa/include/spa/port.h b/spa/include/spa/port.h index a5909f10f..cf2795135 100644 --- a/spa/include/spa/port.h +++ b/spa/include/spa/port.h @@ -29,13 +29,10 @@ typedef struct _SpaAllocParam SpaAllocParam; #include #include #include +#include #define SPA_ALLOC_PARAM_URI "http://spaplug.in/ns/alloc-param" -#define SPA_ALLOC_PARAM_PREFIX SPA_ALLOC_PARAM_URI "#" - -#define SPA_ALLOC_PARAM__Buffers SPA_ALLOC_PARAM_PREFIX "Buffers" -#define SPA_ALLOC_PARAM__MetaEnable SPA_ALLOC_PARAM_PREFIX "MetaEnable" -#define SPA_ALLOC_PARAM__VideoPadding SPA_ALLOC_PARAM_PREFIX "VideoPadding" +#define SPA_ALLOC_PARAM_URI_PREFIX SPA_ALLOC_PARAM_URI "-" /** * SpaAllocParamType: @@ -51,42 +48,83 @@ typedef enum { SPA_ALLOC_PARAM_TYPE_VIDEO_PADDING, } SpaAllocParamType; +typedef struct { + SpaPODObjectBody body; + /* SpaPODProp follow */ +} SpaAllocParamBody; + struct _SpaAllocParam { - uint32_t type; - uint32_t size; + SpaPOD pod; + SpaAllocParamBody body; }; -typedef struct { - SpaAllocParam param; - uint32_t minsize; - int32_t stride; - uint32_t min_buffers; - uint32_t max_buffers; - uint32_t align; -} SpaAllocParamBuffers; +static inline uint32_t +spa_alloc_param_query (const SpaAllocParam *param, uint32_t key, ...) +{ + uint32_t count; + va_list args; -typedef struct { - SpaAllocParam param; - SpaMetaType type; -} SpaAllocParamMetaEnable; + va_start (args, key); + count = spa_pod_contents_queryv (¶m->pod, sizeof (SpaAllocParam), key, args); + va_end (args); -typedef struct { - SpaAllocParam param; - SpaMetaType type; - uint32_t minsize; - int32_t stride; - uint32_t blocks; - uint32_t align; -} SpaAllocParamMetaEnableRingbuffer; + return count; +} -typedef struct { - SpaAllocParam param; - uint32_t padding_top; - uint32_t padding_bottom; - uint32_t padding_left; - uint32_t padding_right; - uint32_t stride_align[4]; -} SpaAllocParamVideoPadding; +#define SPA_ALLOC_PARAM_BUFFERS SPA_ALLOC_PARAM_URI_PREFIX "buffers" +#define SPA_ALLOC_PARAM_BUFFERS_PREFIX SPA_ALLOC_PARAM_BUFFERS "#" + +#define SPA_ALLOC_PARAM_BUFFERS__size SPA_ALLOC_PARAM_BUFFERS_PREFIX "size" +#define SPA_ALLOC_PARAM_BUFFERS__stride SPA_ALLOC_PARAM_BUFFERS_PREFIX "stride" +#define SPA_ALLOC_PARAM_BUFFERS__buffers SPA_ALLOC_PARAM_BUFFERS_PREFIX "buffers" +#define SPA_ALLOC_PARAM_BUFFERS__align SPA_ALLOC_PARAM_BUFFERS_PREFIX "align" + +typedef enum { + SPA_ALLOC_PARAM_BUFFERS_SIZE = 1, + SPA_ALLOC_PARAM_BUFFERS_STRIDE, + SPA_ALLOC_PARAM_BUFFERS_BUFFERS, + SPA_ALLOC_PARAM_BUFFERS_ALIGN, +} SpaAllocParamBuffersKey; + +#define SPA_ALLOC_PARAM_META_ENABLE SPA_ALLOC_PARAM_URI_PREFIX "meta-enable" +#define SPA_ALLOC_PARAM_META_ENABLE_PREFIX SPA_ALLOC_PARAM_META_ENABLE "#" +#define SPA_ALLOC_PARAM_META_ENABLE__type SPA_ALLOC_PARAM_META_ENABLE_PREFIX "type" + +#define SPA_ALLOC_PARAM_META_ENABLE__ringbufferSize SPA_ALLOC_PARAM_META_ENABLE_PREFIX "ringbufferSize" +#define SPA_ALLOC_PARAM_META_ENABLE__ringbufferStride SPA_ALLOC_PARAM_META_ENABLE_PREFIX "ringbufferStride" +#define SPA_ALLOC_PARAM_META_ENABLE__ringbufferBlocks SPA_ALLOC_PARAM_META_ENABLE_PREFIX "ringbufferBlocks" +#define SPA_ALLOC_PARAM_META_ENABLE__ringbufferAlign SPA_ALLOC_PARAM_META_ENABLE_PREFIX "ringbufferAlign" + +typedef enum { + SPA_ALLOC_PARAM_META_ENABLE_TYPE = 1, + SPA_ALLOC_PARAM_META_ENABLE_RB_SIZE, + SPA_ALLOC_PARAM_META_ENABLE_RB_STRIDE, + SPA_ALLOC_PARAM_META_ENABLE_RB_BLOCKS, + SPA_ALLOC_PARAM_META_ENABLE_RB_ALIGN, +} SpaAllocParamMetaEnableKey; + +#define SPA_ALLOC_PARAM_VIDEO_PADDING SPA_ALLOC_PARAM_URI_PREFIX "video-padding" +#define SPA_ALLOC_PARAM_VIDEO_PADDING_PREFIX SPA_ALLOC_PARAM_VIDEO_PADDING "#" + +#define SPA_ALLOC_PARAM_VIDEO_PADDING__top SPA_ALLOC_PARAM_VIDEO_PADDING_PREFIX "top" +#define SPA_ALLOC_PARAM_VIDEO_PADDING__bottom SPA_ALLOC_PARAM_VIDEO_PADDING_PREFIX "bottom" +#define SPA_ALLOC_PARAM_VIDEO_PADDING__left SPA_ALLOC_PARAM_VIDEO_PADDING_PREFIX "left" +#define SPA_ALLOC_PARAM_VIDEO_PADDING__right SPA_ALLOC_PARAM_VIDEO_PADDING_PREFIX "right" +#define SPA_ALLOC_PARAM_VIDEO_PADDING__strideAlign0 SPA_ALLOC_PARAM_VIDEO_PADDING_PREFIX "strideAlign0" +#define SPA_ALLOC_PARAM_VIDEO_PADDING__strideAlign1 SPA_ALLOC_PARAM_VIDEO_PADDING_PREFIX "strideAlign1" +#define SPA_ALLOC_PARAM_VIDEO_PADDING__strideAlign2 SPA_ALLOC_PARAM_VIDEO_PADDING_PREFIX "strideAlign2" +#define SPA_ALLOC_PARAM_VIDEO_PADDING__strideAlign3 SPA_ALLOC_PARAM_VIDEO_PADDING_PREFIX "strideAlign3" + +typedef enum { + SPA_ALLOC_PARAM_VIDEO_PADDING_TOP = 1, + SPA_ALLOC_PARAM_VIDEO_PADDING_BOTTOM, + SPA_ALLOC_PARAM_VIDEO_PADDING_LEFT, + SPA_ALLOC_PARAM_VIDEO_PADDING_RIGHT, + SPA_ALLOC_PARAM_VIDEO_PADDING_STRIDE_ALIGN0, + SPA_ALLOC_PARAM_VIDEO_PADDING_STRIDE_ALIGN1, + SPA_ALLOC_PARAM_VIDEO_PADDING_STRIDE_ALIGN2, + SPA_ALLOC_PARAM_VIDEO_PADDING_STRIDE_ALIGN3, +} SpaAllocParamVideoPaddingKey; /** * SpaPortInfoFlags: diff --git a/spa/include/spa/props.h b/spa/include/spa/props.h index dd64e8fcc..d3e601925 100644 --- a/spa/include/spa/props.h +++ b/spa/include/spa/props.h @@ -40,23 +40,20 @@ spa_pod_builder_push_props (SpaPODBuilder *builder, return spa_pod_builder_push_object (builder, frame, 0, 0); } +#define spa_pod_builder_props(b,f,...) \ + spa_pod_builder_object(b, f, 0, 0,__VA_ARGS__) + static inline uint32_t -spa_pod_builder_props (SpaPODBuilder *builder, - uint32_t type, ...) +spa_props_query (const SpaProps *props, uint32_t key, ...) { - SpaPODFrame f; + uint32_t count; va_list args; - uint32_t off; - off = spa_pod_builder_push_props (builder, &f); - - va_start (args, type); - spa_pod_builder_addv (builder, type, args); + va_start (args, key); + count = spa_pod_contents_queryv (&props->pod, sizeof (SpaProps), key, args); va_end (args); - spa_pod_builder_pop (builder, &f); - - return off; + return count; } #ifdef __cplusplus diff --git a/spa/lib/debug.c b/spa/lib/debug.c index 7c0a5aed4..cb93839de 100644 --- a/spa/lib/debug.c +++ b/spa/lib/debug.c @@ -61,58 +61,7 @@ spa_debug_port_info (const SpaPortInfo *info) fprintf (stderr, " n_params: \t%d\n", info->n_params); for (i = 0; i < info->n_params; i++) { SpaAllocParam *param = info->params[i]; - fprintf (stderr, " param %d, type %d, size %u:\n", i, param->type, param->size); - switch (param->type) { - case SPA_ALLOC_PARAM_TYPE_INVALID: - fprintf (stderr, " INVALID\n"); - break; - case SPA_ALLOC_PARAM_TYPE_BUFFERS: - { - SpaAllocParamBuffers *p = (SpaAllocParamBuffers *)param; - fprintf (stderr, " SpaAllocParamBuffers:\n"); - fprintf (stderr, " minsize: \t\t%d\n", p->minsize); - fprintf (stderr, " stride: \t\t%d\n", p->stride); - fprintf (stderr, " min_buffers: \t%d\n", p->min_buffers); - fprintf (stderr, " max_buffers: \t%d\n", p->max_buffers); - fprintf (stderr, " align: \t\t%d\n", p->align); - break; - } - case SPA_ALLOC_PARAM_TYPE_META_ENABLE: - { - SpaAllocParamMetaEnable *p = (SpaAllocParamMetaEnable *)param; - fprintf (stderr, " SpaAllocParamMetaEnable:\n"); - fprintf (stderr, " type: \t%d (%s)\n", p->type, META_TYPE_NAME(p->type)); - switch (p->type) { - case SPA_META_TYPE_RINGBUFFER: - { - SpaAllocParamMetaEnableRingbuffer *rb = (SpaAllocParamMetaEnableRingbuffer *)p; - fprintf (stderr, " minsize: \t\t%d\n", rb->minsize); - fprintf (stderr, " stride: \t\t%d\n", rb->stride); - fprintf (stderr, " blocks: \t\t%d\n", rb->blocks); - fprintf (stderr, " align: \t\t%d\n", rb->align); - break; - } - default: - break; - } - break; - } - case SPA_ALLOC_PARAM_TYPE_VIDEO_PADDING: - { - SpaAllocParamVideoPadding *p = (SpaAllocParamVideoPadding *)param; - fprintf (stderr, " SpaAllocParamVideoPadding:\n"); - fprintf (stderr, " padding_top: \t%d\n", p->padding_top); - fprintf (stderr, " padding_bottom: \t%d\n", p->padding_bottom); - fprintf (stderr, " padding_left: \t%d\n", p->padding_left); - fprintf (stderr, " padding_right: \t%d\n", p->padding_right); - fprintf (stderr, " stide_align: \t[%d, %d, %d, %d]\n", - p->stride_align[0], p->stride_align[1], p->stride_align[2], p->stride_align[3]); - break; - } - default: - fprintf (stderr, " UNKNOWN\n"); - break; - } + spa_debug_pod (¶m->pod); } return SPA_RESULT_OK; } @@ -354,7 +303,7 @@ print_pod_value (uint32_t size, uint32_t type, void *body, int prefix) printf ("%-*sFloat %f\n", prefix, "", *(float *) body); break; case SPA_POD_TYPE_DOUBLE: - printf ("%-*sDouble %g\n", prefix, "", *(double *) body); + printf ("%-*sDouble %f\n", prefix, "", *(double *) body); break; case SPA_POD_TYPE_STRING: printf ("%-*sString \"%s\"\n", prefix, "", (char *) body); diff --git a/spa/lib/props.c b/spa/lib/props.c index f4038bd45..6ee9e299e 100644 --- a/spa/lib/props.c +++ b/spa/lib/props.c @@ -158,9 +158,9 @@ spa_props_filter (SpaPODBuilder *b, continue; } - /* incompatible formats */ + /* incompatible property types */ if (p1->body.value.type != p2->body.value.type) - return SPA_RESULT_NO_FORMAT; + return SPA_RESULT_INCOMPATIBLE_PROPS; rt1 = p1->body.flags & SPA_POD_PROP_RANGE_MASK; rt2 = p2->body.flags & SPA_POD_PROP_RANGE_MASK; @@ -206,7 +206,7 @@ spa_props_filter (SpaPODBuilder *b, } } if (n_copied == 0) - return SPA_RESULT_NO_FORMAT; + return SPA_RESULT_INCOMPATIBLE_PROPS; np->body.flags |= SPA_POD_PROP_RANGE_ENUM | SPA_POD_PROP_FLAG_UNSET; } @@ -223,7 +223,7 @@ spa_props_filter (SpaPODBuilder *b, n_copied++; } if (n_copied == 0) - return SPA_RESULT_NO_FORMAT; + return SPA_RESULT_INCOMPATIBLE_PROPS; np->body.flags |= SPA_POD_PROP_RANGE_ENUM | SPA_POD_PROP_FLAG_UNSET; } @@ -245,7 +245,7 @@ spa_props_filter (SpaPODBuilder *b, n_copied++; } if (n_copied == 0) - return SPA_RESULT_NO_FORMAT; + return SPA_RESULT_INCOMPATIBLE_PROPS; np->body.flags |= SPA_POD_PROP_RANGE_ENUM | SPA_POD_PROP_FLAG_UNSET; } diff --git a/spa/plugins/alsa/alsa-sink.c b/spa/plugins/alsa/alsa-sink.c index 9012dd57a..b2acdad6e 100644 --- a/spa/plugins/alsa/alsa-sink.c +++ b/spa/plugins/alsa/alsa-sink.c @@ -62,13 +62,28 @@ enum { PROP_ID_PERIOD_EVENT, }; +#define PROP(f,key,type,...) \ + SPA_POD_PROP (f,key,SPA_POD_PROP_FLAG_READWRITE,type,1,__VA_ARGS__) +#define PROP_MM(f,key,type,...) \ + SPA_POD_PROP (f,key,SPA_POD_PROP_FLAG_READWRITE | \ + SPA_POD_PROP_RANGE_MIN_MAX,type,3,__VA_ARGS__) +#define PROP_U_MM(f,key,type,...) \ + SPA_POD_PROP (f,key,SPA_POD_PROP_FLAG_READWRITE | \ + SPA_POD_PROP_FLAG_UNSET | \ + SPA_POD_PROP_RANGE_MIN_MAX,type,3,__VA_ARGS__) +#define PROP_U_EN(f,key,type,n,...) \ + SPA_POD_PROP (f,key,SPA_POD_PROP_FLAG_READWRITE | \ + SPA_POD_PROP_FLAG_UNSET | \ + SPA_POD_PROP_RANGE_ENUM,type,n,__VA_ARGS__) + + static SpaResult spa_alsa_sink_node_get_props (SpaNode *node, SpaProps **props) { SpaALSASink *this; SpaPODBuilder b = { NULL, }; - SpaPODFrame f; + SpaPODFrame f[2]; if (node == NULL || props == NULL) return SPA_RESULT_INVALID_ARGUMENTS; @@ -77,46 +92,15 @@ spa_alsa_sink_node_get_props (SpaNode *node, spa_pod_builder_init (&b, this->props_buffer, sizeof (this->props_buffer)); - *props = SPA_MEMBER (b.data, spa_pod_builder_props (&b, - SPA_POD_TYPE_PROP, &f, - PROP_ID_DEVICE, SPA_POD_PROP_FLAG_READWRITE | - SPA_POD_PROP_RANGE_NONE, - -SPA_POD_TYPE_STRING, 1, - this->props.device, sizeof (this->props.device), - -SPA_POD_TYPE_PROP, &f, - SPA_POD_TYPE_PROP, &f, - PROP_ID_DEVICE_NAME, SPA_POD_PROP_FLAG_READABLE | - SPA_POD_PROP_RANGE_NONE, - -SPA_POD_TYPE_STRING, 1, - this->props.device_name, sizeof (this->props.device_name), - -SPA_POD_TYPE_PROP, &f, - SPA_POD_TYPE_PROP, &f, - PROP_ID_CARD_NAME, SPA_POD_PROP_FLAG_READABLE | - SPA_POD_PROP_RANGE_NONE, - -SPA_POD_TYPE_STRING, 1, - this->props.card_name, sizeof (this->props.card_name), - -SPA_POD_TYPE_PROP, &f, - SPA_POD_TYPE_PROP, &f, - PROP_ID_PERIOD_SIZE, SPA_POD_PROP_FLAG_READWRITE | - SPA_POD_PROP_RANGE_MIN_MAX, - SPA_POD_TYPE_INT, 3, - this->props.period_size, - 1, INT32_MAX, - -SPA_POD_TYPE_PROP, &f, - SPA_POD_TYPE_PROP, &f, - PROP_ID_PERIODS, SPA_POD_PROP_FLAG_READWRITE | - SPA_POD_PROP_RANGE_MIN_MAX, - SPA_POD_TYPE_INT, 3, - this->props.periods, - 1, INT32_MAX, - -SPA_POD_TYPE_PROP, &f, - SPA_POD_TYPE_PROP, &f, - PROP_ID_PERIOD_EVENT, SPA_POD_PROP_FLAG_READWRITE | - SPA_POD_PROP_RANGE_NONE, - SPA_POD_TYPE_BOOL, 1, - this->props.period_event, - -SPA_POD_TYPE_PROP, &f, 0), SpaProps); + spa_pod_builder_props (&b, &f[0], + PROP (&f[1], PROP_ID_DEVICE, -SPA_POD_TYPE_STRING, this->props.device, sizeof (this->props.device)), + PROP (&f[1], PROP_ID_DEVICE_NAME, -SPA_POD_TYPE_STRING, this->props.device_name, sizeof (this->props.device_name)), + PROP (&f[1], PROP_ID_CARD_NAME, -SPA_POD_TYPE_STRING, this->props.card_name, sizeof (this->props.card_name)), + PROP_MM (&f[1], PROP_ID_PERIOD_SIZE, SPA_POD_TYPE_INT, this->props.period_size, 1, INT32_MAX), + PROP_MM (&f[1], PROP_ID_PERIODS, SPA_POD_TYPE_INT, this->props.periods, 1, INT32_MAX), + PROP (&f[1], PROP_ID_PERIOD_EVENT, SPA_POD_TYPE_BOOL, this->props.period_event)); + *props = SPA_POD_BUILDER_DEREF (&b, f[0].ref, SpaProps); return SPA_RESULT_OK; } @@ -136,30 +120,12 @@ spa_alsa_sink_node_set_props (SpaNode *node, reset_alsa_sink_props (&this->props); return SPA_RESULT_OK; } else { - SpaPOD *p; - - SPA_POD_OBJECT_BODY_FOREACH (&props->body, props->pod.size, p) { - SpaPODProp *pr; - - if (p->type != SPA_POD_TYPE_PROP) - continue; - - pr = (SpaPODProp *) p; - switch (pr->body.key) { - case PROP_ID_DEVICE: - strncpy (this->props.device, SPA_POD_CONTENTS (SpaPODProp, pr), 63); - break; - case PROP_ID_PERIOD_SIZE: - this->props.period_size = ((SpaPODInt*)&pr->body.value)->value; - break; - case PROP_ID_PERIODS: - this->props.periods = ((SpaPODInt*)&pr->body.value)->value; - break; - case PROP_ID_PERIOD_EVENT: - this->props.period_event = ((SpaPODBool*)&pr->body.value)->value; - break; - } - } + spa_props_query (props, + PROP_ID_DEVICE, -SPA_POD_TYPE_STRING, this->props.device, sizeof (this->props.device), + PROP_ID_PERIOD_SIZE, SPA_POD_TYPE_INT, &this->props.period_size, + PROP_ID_PERIODS, SPA_POD_TYPE_INT, &this->props.periods, + PROP_ID_PERIOD_EVENT, SPA_POD_TYPE_BOOL, &this->props.period_event, + 0); } return SPA_RESULT_OK; } @@ -358,46 +324,30 @@ next: switch (index++) { case 0: - fmt = SPA_MEMBER (buffer, spa_pod_builder_format (&b, - SPA_MEDIA_TYPE_AUDIO, SPA_MEDIA_SUBTYPE_RAW, - SPA_POD_TYPE_PROP, &f[0], - SPA_PROP_ID_AUDIO_FORMAT, SPA_POD_PROP_FLAG_UNSET | SPA_POD_PROP_FLAG_READWRITE | - SPA_POD_PROP_RANGE_ENUM, - SPA_POD_TYPE_INT, 3, - SPA_AUDIO_FORMAT_S16, - SPA_AUDIO_FORMAT_S16, - SPA_AUDIO_FORMAT_S32, - -SPA_POD_TYPE_PROP, &f[0], - SPA_POD_TYPE_PROP, &f[0], - SPA_PROP_ID_AUDIO_RATE, SPA_POD_PROP_FLAG_UNSET | SPA_POD_PROP_FLAG_READWRITE | - SPA_POD_PROP_RANGE_MIN_MAX, - SPA_POD_TYPE_INT, 3, - 44100, - 1, INT32_MAX, - -SPA_POD_TYPE_PROP, &f[0], - SPA_POD_TYPE_PROP, &f[0], - SPA_PROP_ID_AUDIO_CHANNELS, SPA_POD_PROP_FLAG_UNSET | SPA_POD_PROP_FLAG_READWRITE | - SPA_POD_PROP_RANGE_MIN_MAX, - SPA_POD_TYPE_INT, 3, - 2, - 1, INT32_MAX, - -SPA_POD_TYPE_PROP, &f[0], 0), SpaFormat); + spa_pod_builder_format (&b, &f[0], + SPA_MEDIA_TYPE_AUDIO, SPA_MEDIA_SUBTYPE_RAW, + PROP_U_EN (&f[1], SPA_PROP_ID_AUDIO_FORMAT, SPA_POD_TYPE_INT, 3, SPA_AUDIO_FORMAT_S16, + SPA_AUDIO_FORMAT_S16, + SPA_AUDIO_FORMAT_S32), + PROP_U_MM (&f[1], SPA_PROP_ID_AUDIO_RATE, SPA_POD_TYPE_INT, 44100, 1, INT32_MAX), + PROP_U_MM (&f[1], SPA_PROP_ID_AUDIO_CHANNELS, SPA_POD_TYPE_INT, 2, 1, INT32_MAX)); break; case 1: - fmt = SPA_MEMBER (buffer, spa_pod_builder_format (&b, + spa_pod_builder_format (&b, &f[0], SPA_MEDIA_TYPE_AUDIO, SPA_MEDIA_SUBTYPE_AAC, - 0), SpaFormat); + 0); break; default: return SPA_RESULT_ENUM_END; } + fmt = SPA_POD_BUILDER_DEREF (&b, f[0].ref, SpaFormat); spa_pod_builder_init (&b, this->format_buffer, sizeof (this->format_buffer)); if ((res = spa_format_filter (fmt, filter, &b)) != SPA_RESULT_OK) goto next; - *format = SPA_MEMBER (b.data, 0, SpaFormat); + *format = SPA_POD_BUILDER_DEREF (&b, 0, SpaFormat); return SPA_RESULT_OK; } @@ -422,6 +372,8 @@ spa_alsa_sink_node_port_set_format (SpaNode *node, { SpaALSASink *this; SpaResult res; + SpaPODBuilder b = { NULL }; + SpaPODFrame f[2]; if (node == NULL) return SPA_RESULT_INVALID_ARGUMENTS; @@ -453,26 +405,26 @@ spa_alsa_sink_node_port_set_format (SpaNode *node, this->info.latency = (this->period_frames * SPA_NSEC_PER_SEC) / this->rate; this->info.n_params = 3; this->info.params = this->params; - this->params[0] = &this->param_buffers.param; - this->param_buffers.param.type = SPA_ALLOC_PARAM_TYPE_BUFFERS; - this->param_buffers.param.size = sizeof (this->param_buffers); - this->param_buffers.minsize = this->period_frames * this->frame_size; - this->param_buffers.stride = 0; - this->param_buffers.min_buffers = 1; - this->param_buffers.max_buffers = 32; - this->param_buffers.align = 16; - this->params[1] = &this->param_meta.param; - this->param_meta.param.type = SPA_ALLOC_PARAM_TYPE_META_ENABLE; - this->param_meta.param.size = sizeof (this->param_meta); - this->param_meta.type = SPA_META_TYPE_HEADER; - this->params[2] = &this->param_meta_rb.param; - this->param_meta_rb.param.type = SPA_ALLOC_PARAM_TYPE_META_ENABLE; - this->param_meta_rb.param.size = sizeof (this->param_meta_rb); - this->param_meta_rb.type = SPA_META_TYPE_RINGBUFFER; - this->param_meta_rb.minsize = this->period_frames * this->frame_size * 32; - this->param_meta_rb.stride = 0; - this->param_meta_rb.blocks = 1; - this->param_meta_rb.align = 16; + + spa_pod_builder_init (&b, this->params_buffer, sizeof (this->params_buffer)); + spa_pod_builder_object (&b, &f[0], 0, SPA_ALLOC_PARAM_TYPE_BUFFERS, + PROP (&f[1], SPA_ALLOC_PARAM_BUFFERS_SIZE, SPA_POD_TYPE_INT, this->period_frames * this->frame_size), + PROP (&f[1], SPA_ALLOC_PARAM_BUFFERS_STRIDE, SPA_POD_TYPE_INT, 0), + PROP_MM (&f[1], SPA_ALLOC_PARAM_BUFFERS_BUFFERS, SPA_POD_TYPE_INT, 32, 1, 32), + PROP (&f[1], SPA_ALLOC_PARAM_BUFFERS_ALIGN, SPA_POD_TYPE_INT, 16)); + this->params[0] = SPA_POD_BUILDER_DEREF (&b, f[0].ref, SpaAllocParam); + + spa_pod_builder_object (&b, &f[0], 0, SPA_ALLOC_PARAM_TYPE_META_ENABLE, + PROP (&f[1], SPA_ALLOC_PARAM_META_ENABLE_TYPE, SPA_POD_TYPE_INT, SPA_META_TYPE_HEADER)); + this->params[1] = SPA_POD_BUILDER_DEREF (&b, f[0].ref, SpaAllocParam); + + spa_pod_builder_object (&b, &f[0], 0, SPA_ALLOC_PARAM_TYPE_META_ENABLE, + PROP (&f[1], SPA_ALLOC_PARAM_META_ENABLE_TYPE, SPA_POD_TYPE_INT, SPA_META_TYPE_RINGBUFFER), + PROP (&f[1], SPA_ALLOC_PARAM_META_ENABLE_RB_SIZE, SPA_POD_TYPE_INT, this->period_frames * this->frame_size * 32), + PROP (&f[1], SPA_ALLOC_PARAM_META_ENABLE_RB_STRIDE, SPA_POD_TYPE_INT, 0), + PROP (&f[1], SPA_ALLOC_PARAM_META_ENABLE_RB_BLOCKS, SPA_POD_TYPE_INT, 1), + PROP (&f[1], SPA_ALLOC_PARAM_META_ENABLE_RB_ALIGN, SPA_POD_TYPE_INT, 16)); + this->params[2] = SPA_POD_BUILDER_DEREF (&b, f[0].ref, SpaAllocParam); this->info.extra = NULL; this->have_format = true; diff --git a/spa/plugins/alsa/alsa-source.c b/spa/plugins/alsa/alsa-source.c index 81b6bc6e0..8f3f8d86a 100644 --- a/spa/plugins/alsa/alsa-source.c +++ b/spa/plugins/alsa/alsa-source.c @@ -62,13 +62,30 @@ enum { PROP_ID_PERIOD_EVENT, }; +#define PROP(f,key,type,...) \ + SPA_POD_PROP (f,key,SPA_POD_PROP_FLAG_READWRITE,type,1,__VA_ARGS__) +#define PROP_MM(f,key,type,...) \ + SPA_POD_PROP (f,key,SPA_POD_PROP_FLAG_READWRITE | \ + SPA_POD_PROP_RANGE_MIN_MAX,type,3,__VA_ARGS__) +#define PROP_U_MM(f,key,type,...) \ + SPA_POD_PROP (f,key,SPA_POD_PROP_FLAG_READWRITE | \ + SPA_POD_PROP_FLAG_UNSET | \ + SPA_POD_PROP_RANGE_MIN_MAX,type,3,__VA_ARGS__) +#define PROP_EN(f,key,type,n,...) \ + SPA_POD_PROP (f,key,SPA_POD_PROP_FLAG_READWRITE | \ + SPA_POD_PROP_RANGE_ENUM,type,n,__VA_ARGS__) +#define PROP_U_EN(f,key,type,n,...) \ + SPA_POD_PROP (f,key,SPA_POD_PROP_FLAG_READWRITE | \ + SPA_POD_PROP_FLAG_UNSET | \ + SPA_POD_PROP_RANGE_ENUM,type,n,__VA_ARGS__) + static SpaResult spa_alsa_source_node_get_props (SpaNode *node, SpaProps **props) { SpaALSASource *this; SpaPODBuilder b = { NULL, }; - SpaPODFrame f; + SpaPODFrame f[2]; if (node == NULL || props == NULL) return SPA_RESULT_INVALID_ARGUMENTS; @@ -77,45 +94,15 @@ spa_alsa_source_node_get_props (SpaNode *node, spa_pod_builder_init (&b, this->props_buffer, sizeof (this->props_buffer)); - *props = SPA_MEMBER (b.data, spa_pod_builder_props (&b, - SPA_POD_TYPE_PROP, &f, - PROP_ID_DEVICE, SPA_POD_PROP_FLAG_READWRITE | - SPA_POD_PROP_RANGE_NONE, - -SPA_POD_TYPE_STRING, 1, - this->props.device, sizeof (this->props.device), - -SPA_POD_TYPE_PROP, &f, - SPA_POD_TYPE_PROP, &f, - PROP_ID_DEVICE_NAME, SPA_POD_PROP_FLAG_READABLE | - SPA_POD_PROP_RANGE_NONE, - -SPA_POD_TYPE_STRING, 1, - this->props.device_name, sizeof (this->props.device_name), - -SPA_POD_TYPE_PROP, &f, - SPA_POD_TYPE_PROP, &f, - PROP_ID_CARD_NAME, SPA_POD_PROP_FLAG_READABLE | - SPA_POD_PROP_RANGE_NONE, - -SPA_POD_TYPE_STRING, 1, - this->props.card_name, sizeof (this->props.card_name), - -SPA_POD_TYPE_PROP, &f, - SPA_POD_TYPE_PROP, &f, - PROP_ID_PERIOD_SIZE, SPA_POD_PROP_FLAG_READWRITE | - SPA_POD_PROP_RANGE_MIN_MAX, - SPA_POD_TYPE_INT, 3, - this->props.period_size, - 1, INT32_MAX, - -SPA_POD_TYPE_PROP, &f, - SPA_POD_TYPE_PROP, &f, - PROP_ID_PERIODS, SPA_POD_PROP_FLAG_READWRITE | - SPA_POD_PROP_RANGE_MIN_MAX, - SPA_POD_TYPE_INT, 3, - this->props.periods, - 1, INT32_MAX, - -SPA_POD_TYPE_PROP, &f, - SPA_POD_TYPE_PROP, &f, - PROP_ID_PERIOD_EVENT, SPA_POD_PROP_FLAG_READWRITE | - SPA_POD_PROP_RANGE_NONE, - SPA_POD_TYPE_BOOL, 1, - this->props.period_event, - -SPA_POD_TYPE_PROP, &f, 0), SpaProps); + spa_pod_builder_props (&b, &f[0], + PROP (&f[1], PROP_ID_DEVICE, -SPA_POD_TYPE_STRING, this->props.device, sizeof (this->props.device)), + PROP (&f[1], PROP_ID_DEVICE_NAME, -SPA_POD_TYPE_STRING, this->props.device_name, sizeof (this->props.device_name)), + PROP (&f[1], PROP_ID_CARD_NAME, -SPA_POD_TYPE_STRING, this->props.card_name, sizeof (this->props.card_name)), + PROP_MM (&f[1], PROP_ID_PERIOD_SIZE, SPA_POD_TYPE_INT, this->props.period_size, 1, INT32_MAX), + PROP_MM (&f[1], PROP_ID_PERIODS, SPA_POD_TYPE_INT, this->props.periods, 1, INT32_MAX), + PROP (&f[1], PROP_ID_PERIOD_EVENT, SPA_POD_TYPE_BOOL, this->props.period_event)); + + *props = SPA_POD_BUILDER_DEREF (&b, f[0].ref, SpaProps); return SPA_RESULT_OK; } @@ -135,31 +122,12 @@ spa_alsa_source_node_set_props (SpaNode *node, reset_alsa_props (&this->props); return SPA_RESULT_OK; } else { - SpaPOD *p; - - SPA_POD_OBJECT_BODY_FOREACH (&props->body, props->pod.size, p) { - SpaPODProp *pr; - - if (p->type != SPA_POD_TYPE_PROP) - continue; - - pr = (SpaPODProp *) p; - - switch (pr->body.key) { - case PROP_ID_DEVICE: - strncpy (this->props.device, SPA_POD_CONTENTS (SpaPODProp, pr), 63); - break; - case PROP_ID_PERIOD_SIZE: - this->props.period_size = ((SpaPODInt*)&pr->body.value)->value; - break; - case PROP_ID_PERIODS: - this->props.periods = ((SpaPODInt*)&pr->body.value)->value; - break; - case PROP_ID_PERIOD_EVENT: - this->props.period_event = ((SpaPODBool*)&pr->body.value)->value; - break; - } - } + spa_props_query (props, + PROP_ID_DEVICE, -SPA_POD_TYPE_STRING, this->props.device, sizeof (this->props.device), + PROP_ID_PERIOD_SIZE, SPA_POD_TYPE_INT, &this->props.period_size, + PROP_ID_PERIODS, SPA_POD_TYPE_INT, &this->props.periods, + PROP_ID_PERIOD_EVENT, SPA_POD_TYPE_BOOL, &this->props.period_event, + 0); } return SPA_RESULT_OK; @@ -390,38 +358,22 @@ next: switch (index++) { case 0: - fmt = SPA_MEMBER (buffer, spa_pod_builder_format (&b, + spa_pod_builder_format (&b, &f[0], SPA_MEDIA_TYPE_AUDIO, SPA_MEDIA_SUBTYPE_RAW, - SPA_POD_TYPE_PROP, &f[0], - SPA_PROP_ID_AUDIO_FORMAT, SPA_POD_PROP_FLAG_UNSET | SPA_POD_PROP_FLAG_READWRITE | - SPA_POD_PROP_RANGE_ENUM, - SPA_POD_TYPE_INT, 3, - SPA_AUDIO_FORMAT_S16, - SPA_AUDIO_FORMAT_S16, - SPA_AUDIO_FORMAT_S32, - -SPA_POD_TYPE_PROP, &f[0], - SPA_POD_TYPE_PROP, &f[0], - SPA_PROP_ID_AUDIO_RATE, SPA_POD_PROP_FLAG_UNSET | SPA_POD_PROP_FLAG_READWRITE | - SPA_POD_PROP_RANGE_MIN_MAX, - SPA_POD_TYPE_INT, 3, - 44100, - 1, INT32_MAX, - -SPA_POD_TYPE_PROP, &f[0], - SPA_POD_TYPE_PROP, &f[0], - SPA_PROP_ID_AUDIO_CHANNELS, SPA_POD_PROP_FLAG_UNSET | SPA_POD_PROP_FLAG_READWRITE | - SPA_POD_PROP_RANGE_MIN_MAX, - SPA_POD_TYPE_INT, 3, - 2, - 1, INT32_MAX, - -SPA_POD_TYPE_PROP, &f[0], 0), SpaFormat); + PROP_U_EN (&f[1], SPA_PROP_ID_AUDIO_FORMAT, SPA_POD_TYPE_INT, 3, SPA_AUDIO_FORMAT_S16, + SPA_AUDIO_FORMAT_S16, + SPA_AUDIO_FORMAT_S32), + PROP_U_MM (&f[1], SPA_PROP_ID_AUDIO_RATE, SPA_POD_TYPE_INT, 44100, 1, INT32_MAX), + PROP_U_MM (&f[1], SPA_PROP_ID_AUDIO_CHANNELS, SPA_POD_TYPE_INT, 2, 1, INT32_MAX)); break; case 1: - fmt = SPA_MEMBER (buffer, spa_pod_builder_format (&b, + spa_pod_builder_format (&b, &f[0], SPA_MEDIA_TYPE_AUDIO, SPA_MEDIA_SUBTYPE_AAC, - 0), SpaFormat); + 0); default: return SPA_RESULT_ENUM_END; } + fmt = SPA_POD_BUILDER_DEREF (&b, f[0].ref, SpaFormat); spa_pod_builder_init (&b, this->format_buffer, sizeof (this->format_buffer)); @@ -466,6 +418,8 @@ spa_alsa_source_node_port_set_format (SpaNode *node, { SpaALSASource *this; SpaResult res; + SpaPODBuilder b = { NULL }; + SpaPODFrame f[2]; if (node == NULL) return SPA_RESULT_INVALID_ARGUMENTS; @@ -496,18 +450,19 @@ spa_alsa_source_node_port_set_format (SpaNode *node, this->info.latency = (this->period_frames * SPA_NSEC_PER_SEC) / this->rate; this->info.n_params = 2; this->info.params = this->params; - this->params[0] = &this->param_buffers.param; - this->param_buffers.param.type = SPA_ALLOC_PARAM_TYPE_BUFFERS; - this->param_buffers.param.size = sizeof (this->param_buffers); - this->param_buffers.minsize = this->period_frames * this->frame_size; - this->param_buffers.stride = 0; - this->param_buffers.min_buffers = 1; - this->param_buffers.max_buffers = 32; - this->param_buffers.align = 16; - this->params[1] = &this->param_meta.param; - this->param_meta.param.type = SPA_ALLOC_PARAM_TYPE_META_ENABLE; - this->param_meta.param.size = sizeof (this->param_meta); - this->param_meta.type = SPA_META_TYPE_HEADER; + + spa_pod_builder_init (&b, this->params_buffer, sizeof (this->params_buffer)); + spa_pod_builder_object (&b, &f[0], 0, SPA_ALLOC_PARAM_TYPE_BUFFERS, + PROP (&f[1], SPA_ALLOC_PARAM_BUFFERS_SIZE, SPA_POD_TYPE_INT, this->period_frames * this->frame_size), + PROP (&f[1], SPA_ALLOC_PARAM_BUFFERS_STRIDE, SPA_POD_TYPE_INT, 0), + PROP_MM (&f[1], SPA_ALLOC_PARAM_BUFFERS_BUFFERS, SPA_POD_TYPE_INT, 32, 1, 32), + PROP (&f[1], SPA_ALLOC_PARAM_BUFFERS_ALIGN, SPA_POD_TYPE_INT, 16)); + this->params[0] = SPA_POD_BUILDER_DEREF (&b, f[0].ref, SpaAllocParam); + + spa_pod_builder_object (&b, &f[0], 0, SPA_ALLOC_PARAM_TYPE_META_ENABLE, + PROP (&f[1], SPA_ALLOC_PARAM_META_ENABLE_TYPE, SPA_POD_TYPE_INT, SPA_META_TYPE_HEADER)); + this->params[1] = SPA_POD_BUILDER_DEREF (&b, f[0].ref, SpaAllocParam); + this->info.extra = NULL; this->have_format = true; diff --git a/spa/plugins/alsa/alsa-utils.h b/spa/plugins/alsa/alsa-utils.h index 514a42d62..af00294cf 100644 --- a/spa/plugins/alsa/alsa-utils.h +++ b/spa/plugins/alsa/alsa-utils.h @@ -102,9 +102,7 @@ struct _SpaALSAState { SpaPortInfo info; SpaAllocParam *params[3]; - SpaAllocParamBuffers param_buffers; - SpaAllocParamMetaEnable param_meta; - SpaAllocParamMetaEnableRingbuffer param_meta_rb; + uint8_t params_buffer[1024]; void *io; SpaALSABuffer buffers[MAX_BUFFERS]; diff --git a/spa/plugins/audiotestsrc/audiotestsrc.c b/spa/plugins/audiotestsrc/audiotestsrc.c index 856e9997b..1589fdee0 100644 --- a/spa/plugins/audiotestsrc/audiotestsrc.c +++ b/spa/plugins/audiotestsrc/audiotestsrc.c @@ -84,8 +84,7 @@ struct _SpaAudioTestSrc { SpaPortInfo info; SpaAllocParam *params[2]; - SpaAllocParamBuffers param_buffers; - SpaAllocParamMetaEnable param_meta; + uint8_t params_buffer[1024]; SpaPortOutput *output; bool have_format; @@ -131,13 +130,30 @@ reset_audiotestsrc_props (SpaAudioTestSrcProps *props) props->volume = DEFAULT_VOLUME; } +#define PROP(f,key,type,...) \ + SPA_POD_PROP (f,key,SPA_POD_PROP_FLAG_READWRITE,type,1,__VA_ARGS__) +#define PROP_MM(f,key,type,...) \ + SPA_POD_PROP (f,key,SPA_POD_PROP_FLAG_READWRITE | \ + SPA_POD_PROP_RANGE_MIN_MAX,type,3,__VA_ARGS__) +#define PROP_U_MM(f,key,type,...) \ + SPA_POD_PROP (f,key,SPA_POD_PROP_FLAG_READWRITE | \ + SPA_POD_PROP_FLAG_UNSET | \ + SPA_POD_PROP_RANGE_MIN_MAX,type,3,__VA_ARGS__) +#define PROP_EN(f,key,type,n,...) \ + SPA_POD_PROP (f,key,SPA_POD_PROP_FLAG_READWRITE | \ + SPA_POD_PROP_RANGE_ENUM,type,n,__VA_ARGS__) +#define PROP_U_EN(f,key,type,n,...) \ + SPA_POD_PROP (f,key,SPA_POD_PROP_FLAG_READWRITE | \ + SPA_POD_PROP_FLAG_UNSET | \ + SPA_POD_PROP_RANGE_ENUM,type,n,__VA_ARGS__) + static SpaResult spa_audiotestsrc_node_get_props (SpaNode *node, SpaProps **props) { SpaAudioTestSrc *this; SpaPODBuilder b = { NULL, }; - SpaPODFrame f; + SpaPODFrame f[2]; if (node == NULL || props == NULL) return SPA_RESULT_INVALID_ARGUMENTS; @@ -145,38 +161,17 @@ spa_audiotestsrc_node_get_props (SpaNode *node, this = SPA_CONTAINER_OF (node, SpaAudioTestSrc, node); spa_pod_builder_init (&b, this->props_buffer, sizeof (this->props_buffer)); + spa_pod_builder_props (&b, &f[0], + PROP (&f[1], PROP_ID_LIVE, SPA_POD_TYPE_BOOL, this->props.live), + PROP_EN (&f[1], PROP_ID_WAVE, SPA_POD_TYPE_INT, 3, this->props.wave, + wave_val_sine, + wave_val_square), + PROP_MM (&f[1], PROP_ID_FREQ, SPA_POD_TYPE_DOUBLE, this->props.freq, + 0.0, 50000000.0), + PROP_MM (&f[1], PROP_ID_VOLUME, SPA_POD_TYPE_DOUBLE, this->props.volume, + 0.0, 10.0)); - *props = SPA_MEMBER (b.data, spa_pod_builder_props (&b, - SPA_POD_TYPE_PROP, &f, - PROP_ID_LIVE, SPA_POD_PROP_FLAG_READWRITE | - SPA_POD_PROP_RANGE_NONE, - SPA_POD_TYPE_BOOL, 1, - this->props.live, - -SPA_POD_TYPE_PROP, &f, - SPA_POD_TYPE_PROP, &f, - PROP_ID_WAVE, SPA_POD_PROP_FLAG_READWRITE | - SPA_POD_PROP_RANGE_ENUM, - SPA_POD_TYPE_INT, 3, - this->props.wave, - wave_val_sine, - wave_val_square, - -SPA_POD_TYPE_PROP, &f, - SPA_POD_TYPE_PROP, &f, - PROP_ID_FREQ, SPA_POD_PROP_FLAG_READWRITE | - SPA_POD_PROP_RANGE_MIN_MAX, - SPA_POD_TYPE_DOUBLE, 3, - this->props.freq, - 0.0, - 50000000.0, - -SPA_POD_TYPE_PROP, &f, - SPA_POD_TYPE_PROP, &f, - PROP_ID_VOLUME, SPA_POD_PROP_FLAG_READWRITE | - SPA_POD_PROP_RANGE_MIN_MAX, - SPA_POD_TYPE_DOUBLE, 3, - this->props.volume, - 0.0, - 10.0, - -SPA_POD_TYPE_PROP, &f, 0), SpaProps); + *props = SPA_POD_BUILDER_DEREF (&b, f[0].ref, SpaProps); return SPA_RESULT_OK; } @@ -195,31 +190,12 @@ spa_audiotestsrc_node_set_props (SpaNode *node, if (props == NULL) { reset_audiotestsrc_props (&this->props); } else { - SpaPOD *p; - - SPA_POD_OBJECT_BODY_FOREACH (&props->body, props->pod.size, p) { - SpaPODProp *pr; - - if (p->type != SPA_POD_TYPE_PROP) - continue; - - pr = (SpaPODProp *) p; - - switch (pr->body.key) { - case PROP_ID_LIVE: - this->props.live = ((SpaPODBool*)&pr->body.value)->value; - break; - case PROP_ID_WAVE: - this->props.wave = ((SpaPODInt*)&pr->body.value)->value; - break; - case PROP_ID_FREQ: - this->props.freq = ((SpaPODDouble*)&pr->body.value)->value; - break; - case PROP_ID_VOLUME: - this->props.volume = ((SpaPODDouble*)&pr->body.value)->value; - break; - } - } + spa_props_query (props, + PROP_ID_LIVE, SPA_POD_TYPE_BOOL, &this->props.live, + PROP_ID_WAVE, SPA_POD_TYPE_INT, &this->props.wave, + PROP_ID_FREQ, SPA_POD_TYPE_DOUBLE, &this->props.freq, + PROP_ID_VOLUME, SPA_POD_TYPE_DOUBLE, &this->props.volume, + 0); } if (this->props.live) @@ -490,34 +466,18 @@ next: switch (index++) { case 0: - fmt = SPA_MEMBER (buffer, spa_pod_builder_format (&b, + spa_pod_builder_format (&b, &f[0], SPA_MEDIA_TYPE_AUDIO, SPA_MEDIA_SUBTYPE_RAW, - SPA_POD_TYPE_PROP, &f[0], - SPA_PROP_ID_AUDIO_FORMAT, SPA_POD_PROP_FLAG_UNSET | SPA_POD_PROP_FLAG_READWRITE | - SPA_POD_PROP_RANGE_ENUM, - SPA_POD_TYPE_INT, 3, - SPA_AUDIO_FORMAT_S16, - SPA_AUDIO_FORMAT_S16, - SPA_AUDIO_FORMAT_S32, - -SPA_POD_TYPE_PROP, &f[0], - SPA_POD_TYPE_PROP, &f[0], - SPA_PROP_ID_AUDIO_RATE, SPA_POD_PROP_FLAG_UNSET | SPA_POD_PROP_FLAG_READWRITE | - SPA_POD_PROP_RANGE_MIN_MAX, - SPA_POD_TYPE_INT, 3, - 44100, - 1, INT32_MAX, - -SPA_POD_TYPE_PROP, &f[0], - SPA_POD_TYPE_PROP, &f[0], - SPA_PROP_ID_AUDIO_CHANNELS, SPA_POD_PROP_FLAG_UNSET | SPA_POD_PROP_FLAG_READWRITE | - SPA_POD_PROP_RANGE_MIN_MAX, - SPA_POD_TYPE_INT, 3, - 2, - 1, INT32_MAX, - -SPA_POD_TYPE_PROP, &f[0], 0), SpaFormat); + PROP_U_EN (&f[1], SPA_PROP_ID_AUDIO_FORMAT, SPA_POD_TYPE_INT, 3, SPA_AUDIO_FORMAT_S16, + SPA_AUDIO_FORMAT_S16, + SPA_AUDIO_FORMAT_S32), + PROP_U_MM (&f[1], SPA_PROP_ID_AUDIO_RATE, SPA_POD_TYPE_INT, 44100, 1, INT32_MAX), + PROP_U_MM (&f[1], SPA_PROP_ID_AUDIO_CHANNELS, SPA_POD_TYPE_INT, 2, 1, INT32_MAX)); break; default: return SPA_RESULT_ENUM_END; } + fmt = SPA_POD_BUILDER_DEREF (&b, f[0].ref, SpaFormat); spa_pod_builder_init (&b, this->format_buffer, sizeof (this->format_buffer)); @@ -572,23 +532,27 @@ spa_audiotestsrc_node_port_set_format (SpaNode *node, } if (this->have_format) { + SpaPODBuilder b = { NULL }; + SpaPODFrame f[2]; + this->info.maxbuffering = -1; this->info.latency = BYTES_TO_TIME (this, 1024); this->info.n_params = 2; this->info.params = this->params; - this->params[0] = &this->param_buffers.param; - this->param_buffers.param.type = SPA_ALLOC_PARAM_TYPE_BUFFERS; - this->param_buffers.param.size = sizeof (this->param_buffers); - this->param_buffers.minsize = 1024; - this->param_buffers.stride = 1024; - this->param_buffers.min_buffers = 2; - this->param_buffers.max_buffers = 32; - this->param_buffers.align = 16; - this->params[1] = &this->param_meta.param; - this->param_meta.param.type = SPA_ALLOC_PARAM_TYPE_META_ENABLE; - this->param_meta.param.size = sizeof (this->param_meta); - this->param_meta.type = SPA_META_TYPE_HEADER; + + spa_pod_builder_init (&b, this->params_buffer, sizeof (this->params_buffer)); + spa_pod_builder_object (&b, &f[0], 0, SPA_ALLOC_PARAM_TYPE_BUFFERS, + PROP (&f[1], SPA_ALLOC_PARAM_BUFFERS_SIZE, SPA_POD_TYPE_INT, 1024), + PROP (&f[1], SPA_ALLOC_PARAM_BUFFERS_STRIDE, SPA_POD_TYPE_INT, 1024), + PROP_MM (&f[1], SPA_ALLOC_PARAM_BUFFERS_BUFFERS, SPA_POD_TYPE_INT, 32, 2, 32), + PROP (&f[1], SPA_ALLOC_PARAM_BUFFERS_ALIGN, SPA_POD_TYPE_INT, 16)); + this->params[0] = SPA_POD_BUILDER_DEREF (&b, f[0].ref, SpaAllocParam); + + spa_pod_builder_object (&b, &f[0], 0, SPA_ALLOC_PARAM_TYPE_META_ENABLE, + PROP (&f[1], SPA_ALLOC_PARAM_META_ENABLE_TYPE, SPA_POD_TYPE_INT, SPA_META_TYPE_HEADER)); + this->params[1] = SPA_POD_BUILDER_DEREF (&b, f[0].ref, SpaAllocParam); + this->info.extra = NULL; update_state (this, SPA_NODE_STATE_READY); } @@ -606,7 +570,7 @@ spa_audiotestsrc_node_port_get_format (SpaNode *node, { SpaAudioTestSrc *this; SpaPODBuilder b = { NULL, }; - SpaPODFrame f; + SpaPODFrame f[2]; if (node == NULL || format == NULL) return SPA_RESULT_INVALID_ARGUMENTS; @@ -620,24 +584,13 @@ spa_audiotestsrc_node_port_get_format (SpaNode *node, return SPA_RESULT_NO_FORMAT; spa_pod_builder_init (&b, this->format_buffer, sizeof (this->format_buffer)); - - *format = SPA_MEMBER (b.data, spa_pod_builder_format (&b, + spa_pod_builder_format (&b, &f[0], SPA_MEDIA_TYPE_AUDIO, SPA_MEDIA_SUBTYPE_RAW, - SPA_POD_TYPE_PROP, &f, - SPA_PROP_ID_AUDIO_FORMAT, SPA_POD_PROP_FLAG_READWRITE, - SPA_POD_TYPE_INT, 1, - this->current_format.info.raw.format, - -SPA_POD_TYPE_PROP, &f, - SPA_POD_TYPE_PROP, &f, - SPA_PROP_ID_AUDIO_RATE, SPA_POD_PROP_FLAG_READWRITE, - SPA_POD_TYPE_INT, 1, - this->current_format.info.raw.rate, - -SPA_POD_TYPE_PROP, &f, - SPA_POD_TYPE_PROP, &f, - SPA_PROP_ID_AUDIO_CHANNELS, SPA_POD_PROP_FLAG_READWRITE, - SPA_POD_TYPE_INT, 1, - this->current_format.info.raw.channels, - -SPA_POD_TYPE_PROP, &f, 0), SpaFormat); + PROP (&f[1], SPA_PROP_ID_AUDIO_FORMAT, SPA_POD_TYPE_INT, this->current_format.info.raw.format), + PROP (&f[1], SPA_PROP_ID_AUDIO_RATE, SPA_POD_TYPE_INT, this->current_format.info.raw.rate), + PROP (&f[1], SPA_PROP_ID_AUDIO_CHANNELS, SPA_POD_TYPE_INT, this->current_format.info.raw.channels)); + + *format = SPA_POD_BUILDER_DEREF (&b, f[0].ref, SpaFormat); return SPA_RESULT_OK; } diff --git a/spa/plugins/ffmpeg/ffmpeg-dec.c b/spa/plugins/ffmpeg/ffmpeg-dec.c index 50cdd250d..9a0f282f4 100644 --- a/spa/plugins/ffmpeg/ffmpeg-dec.c +++ b/spa/plugins/ffmpeg/ffmpeg-dec.c @@ -47,8 +47,6 @@ typedef struct { bool have_buffers; FFMpegBuffer buffers[MAX_BUFFERS]; SpaPortInfo info; - SpaAllocParam *params[1]; - SpaAllocParamBuffers param_buffers; void *io; } SpaFFMpegPort; @@ -210,12 +208,12 @@ spa_ffmpeg_dec_node_port_enum_formats (SpaNode *node, const SpaFormat *filter, uint32_t index) { - SpaFFMpegDec *this; + //SpaFFMpegDec *this; if (node == NULL || format == NULL) return SPA_RESULT_INVALID_ARGUMENTS; - this = SPA_CONTAINER_OF (node, SpaFFMpegDec, node); + //this = SPA_CONTAINER_OF (node, SpaFFMpegDec, node); if (!IS_VALID_PORT (this, direction, port_id)) return SPA_RESULT_INVALID_PORT; diff --git a/spa/plugins/ffmpeg/ffmpeg-enc.c b/spa/plugins/ffmpeg/ffmpeg-enc.c index 383745a5e..af41292ce 100644 --- a/spa/plugins/ffmpeg/ffmpeg-enc.c +++ b/spa/plugins/ffmpeg/ffmpeg-enc.c @@ -52,8 +52,6 @@ typedef struct { bool have_buffers; FFMpegBuffer buffers[MAX_BUFFERS]; SpaPortInfo info; - SpaAllocParam *params[1]; - SpaAllocParamBuffers param_buffers; void *io; } SpaFFMpegPort; @@ -215,18 +213,18 @@ spa_ffmpeg_enc_node_port_enum_formats (SpaNode *node, const SpaFormat *filter, uint32_t index) { - SpaFFMpegEnc *this; - SpaFFMpegPort *port; + //SpaFFMpegEnc *this; + //SpaFFMpegPort *port; if (node == NULL || format == NULL) return SPA_RESULT_INVALID_ARGUMENTS; - this = SPA_CONTAINER_OF (node, SpaFFMpegEnc, node); + //this = SPA_CONTAINER_OF (node, SpaFFMpegEnc, node); if (!IS_VALID_PORT (this, direction, port_id)) return SPA_RESULT_INVALID_PORT; - port = direction == SPA_DIRECTION_INPUT ? &this->in_ports[port_id] : &this->out_ports[port_id]; + //port = direction == SPA_DIRECTION_INPUT ? &this->in_ports[port_id] : &this->out_ports[port_id]; switch (index) { case 0: diff --git a/spa/plugins/v4l2/v4l2-source.c b/spa/plugins/v4l2/v4l2-source.c index eac1e8383..35e0cb38f 100644 --- a/spa/plugins/v4l2/v4l2-source.c +++ b/spa/plugins/v4l2/v4l2-source.c @@ -100,8 +100,7 @@ typedef struct { SpaPortInfo info; SpaAllocParam *params[2]; - SpaAllocParamBuffers param_buffers; - SpaAllocParamMetaEnable param_meta; + uint8_t params_buffer[1024]; void *io; int64_t last_ticks; @@ -136,6 +135,25 @@ update_state (SpaV4l2Source *this, SpaNodeState state) spa_log_info (this->log, "state: %d", state); this->node.state = state; } + +#define PROP(f,key,type,...) \ + SPA_POD_PROP (f,key,SPA_POD_PROP_FLAG_READWRITE,type,1,__VA_ARGS__) +#define PROP_R(f,key,type,...) \ + SPA_POD_PROP (f,key,SPA_POD_PROP_FLAG_READABLE,type,1,__VA_ARGS__) +#define PROP_MM(f,key,type,...) \ + SPA_POD_PROP (f,key,SPA_POD_PROP_FLAG_READWRITE | \ + SPA_POD_PROP_RANGE_MIN_MAX,type,3,__VA_ARGS__) +#define PROP_U_MM(f,key,type,...) \ + SPA_POD_PROP (f,key,SPA_POD_PROP_FLAG_READWRITE | \ + SPA_POD_PROP_FLAG_UNSET | \ + SPA_POD_PROP_RANGE_MIN_MAX,type,3,__VA_ARGS__) +#define PROP_EN(f,key,type,n,...) \ + SPA_POD_PROP (f,key,SPA_POD_PROP_FLAG_READWRITE | \ + SPA_POD_PROP_RANGE_ENUM,type,n,__VA_ARGS__) +#define PROP_U_EN(f,key,type,n,...) \ + SPA_POD_PROP (f,key,SPA_POD_PROP_FLAG_READWRITE | \ + SPA_POD_PROP_FLAG_UNSET | \ + SPA_POD_PROP_RANGE_ENUM,type,n,__VA_ARGS__) #include "v4l2-utils.c" enum { @@ -151,7 +169,7 @@ spa_v4l2_source_node_get_props (SpaNode *node, { SpaV4l2Source *this; SpaPODBuilder b = { NULL, }; - SpaPODFrame f; + SpaPODFrame f[2]; if (node == NULL || props == NULL) return SPA_RESULT_INVALID_ARGUMENTS; @@ -159,28 +177,11 @@ spa_v4l2_source_node_get_props (SpaNode *node, this = SPA_CONTAINER_OF (node, SpaV4l2Source, node); spa_pod_builder_init (&b, this->props_buffer, sizeof (this->props_buffer)); - - *props = SPA_MEMBER (b.data, spa_pod_builder_props (&b, - SPA_POD_TYPE_PROP, &f, - PROP_ID_DEVICE, SPA_POD_PROP_FLAG_READWRITE | - SPA_POD_PROP_RANGE_NONE, - -SPA_POD_TYPE_STRING, 1, - this->props.device, sizeof (this->props.device), - - -SPA_POD_TYPE_PROP, &f, - SPA_POD_TYPE_PROP, &f, - PROP_ID_DEVICE_NAME, SPA_POD_PROP_FLAG_READABLE | - SPA_POD_PROP_RANGE_NONE, - -SPA_POD_TYPE_STRING, 1, - this->props.device_name, sizeof (this->props.device_name), - - -SPA_POD_TYPE_PROP, &f, - SPA_POD_TYPE_PROP, &f, - PROP_ID_DEVICE_FD, SPA_POD_PROP_FLAG_READABLE | - SPA_POD_PROP_RANGE_NONE, - SPA_POD_TYPE_INT, 1, - this->props.device_fd, - -SPA_POD_TYPE_PROP, &f, 0), SpaProps); + spa_pod_builder_props (&b, &f[0], + PROP (&f[1], PROP_ID_DEVICE, -SPA_POD_TYPE_STRING, this->props.device, sizeof (this->props.device)), + PROP_R (&f[1], PROP_ID_DEVICE_NAME, -SPA_POD_TYPE_STRING, this->props.device_name, sizeof (this->props.device_name)), + PROP_R (&f[1], PROP_ID_DEVICE_FD, SPA_POD_TYPE_INT, this->props.device_fd)); + *props = SPA_POD_BUILDER_DEREF (&b, f[0].ref, SpaProps); return SPA_RESULT_OK; } @@ -200,22 +201,9 @@ spa_v4l2_source_node_set_props (SpaNode *node, reset_v4l2_source_props (&this->props); return SPA_RESULT_OK; } else { - SpaPOD *p; - - SPA_POD_OBJECT_BODY_FOREACH (&props->body, props->pod.size, p) { - SpaPODProp *pr; - - if (p->type != SPA_POD_TYPE_PROP) - continue; - - pr = (SpaPODProp *)p; - - switch (pr->body.key) { - case PROP_ID_DEVICE: - strncpy (this->props.device, SPA_POD_CONTENTS (SpaPODProp, pr), 63); - break; - } - } + spa_props_query (props, + PROP_ID_DEVICE, -SPA_POD_TYPE_STRING, this->props.device, sizeof (this->props.device), + 0); } return SPA_RESULT_OK; } @@ -588,54 +576,23 @@ spa_v4l2_source_node_port_get_format (SpaNode *node, switch (state->current_format.media_subtype) { case SPA_MEDIA_SUBTYPE_RAW: spa_pod_builder_add (&b, - SPA_POD_TYPE_PROP, &f[1], - SPA_PROP_ID_VIDEO_FORMAT, SPA_POD_PROP_FLAG_READWRITE, - SPA_POD_TYPE_INT, 1, - state->current_format.info.raw.format, - -SPA_POD_TYPE_PROP, &f[1], - SPA_POD_TYPE_PROP, &f[1], - SPA_PROP_ID_VIDEO_SIZE, SPA_POD_PROP_FLAG_READWRITE, - SPA_POD_TYPE_RECTANGLE, 1, - state->current_format.info.raw.size.width, - state->current_format.info.raw.size.height, - -SPA_POD_TYPE_PROP, &f[1], - SPA_POD_TYPE_PROP, &f[1], - SPA_PROP_ID_VIDEO_FRAMERATE, SPA_POD_PROP_FLAG_READWRITE, - SPA_POD_TYPE_FRACTION, 1, - state->current_format.info.raw.framerate.num, - state->current_format.info.raw.framerate.denom, - -SPA_POD_TYPE_PROP, &f[1], 0); + PROP (&f[1], SPA_PROP_ID_VIDEO_FORMAT, SPA_POD_TYPE_INT, state->current_format.info.raw.format), + PROP (&f[1], SPA_PROP_ID_VIDEO_SIZE, -SPA_POD_TYPE_RECTANGLE, &state->current_format.info.raw.size), + PROP (&f[1], SPA_PROP_ID_VIDEO_FRAMERATE, -SPA_POD_TYPE_FRACTION, &state->current_format.info.raw.framerate), + 0); break; case SPA_MEDIA_SUBTYPE_MJPG: case SPA_MEDIA_SUBTYPE_JPEG: spa_pod_builder_add (&b, - SPA_POD_TYPE_PROP, &f[1], - SPA_PROP_ID_VIDEO_SIZE, SPA_POD_PROP_FLAG_READWRITE, - SPA_POD_TYPE_RECTANGLE, 1, - state->current_format.info.mjpg.size.width, - state->current_format.info.mjpg.size.height, - -SPA_POD_TYPE_PROP, &f[1], - SPA_POD_TYPE_PROP, &f[1], - SPA_PROP_ID_VIDEO_FRAMERATE, SPA_POD_PROP_FLAG_READWRITE, - SPA_POD_TYPE_FRACTION, 1, - state->current_format.info.mjpg.framerate.num, - state->current_format.info.mjpg.framerate.denom, - -SPA_POD_TYPE_PROP, &f[1], 0); + PROP (&f[1], SPA_PROP_ID_VIDEO_SIZE, -SPA_POD_TYPE_RECTANGLE, &state->current_format.info.mjpg.size), + PROP (&f[1], SPA_PROP_ID_VIDEO_FRAMERATE, -SPA_POD_TYPE_FRACTION, &state->current_format.info.mjpg.framerate), + 0); break; case SPA_MEDIA_SUBTYPE_H264: spa_pod_builder_add (&b, - SPA_POD_TYPE_PROP, &f[1], - SPA_PROP_ID_VIDEO_SIZE, SPA_POD_PROP_FLAG_READWRITE, - SPA_POD_TYPE_RECTANGLE, 1, - state->current_format.info.h264.size.width, - state->current_format.info.h264.size.height, - -SPA_POD_TYPE_PROP, &f[1], - SPA_POD_TYPE_PROP, &f[1], - SPA_PROP_ID_VIDEO_FRAMERATE, SPA_POD_PROP_FLAG_READWRITE, - SPA_POD_TYPE_FRACTION, 1, - state->current_format.info.h264.framerate.num, - state->current_format.info.h264.framerate.denom, - -SPA_POD_TYPE_PROP, &f[1], 0); + PROP (&f[1], SPA_PROP_ID_VIDEO_SIZE, -SPA_POD_TYPE_RECTANGLE, &state->current_format.info.h264.size), + PROP (&f[1], SPA_PROP_ID_VIDEO_FRAMERATE, -SPA_POD_TYPE_FRACTION, &state->current_format.info.h264.framerate), + 0); break; case SPA_MEDIA_SUBTYPE_DV: case SPA_MEDIA_SUBTYPE_MPEGTS: diff --git a/spa/plugins/v4l2/v4l2-utils.c b/spa/plugins/v4l2/v4l2-utils.c index 2a9170598..ef9ae3a2b 100644 --- a/spa/plugins/v4l2/v4l2-utils.c +++ b/spa/plugins/v4l2/v4l2-utils.c @@ -456,7 +456,6 @@ spa_v4l2_enum_format (SpaV4l2Source *this, const FormatInfo *info; SpaPODFrame f[2]; SpaPODProp *prop; - SpaFormat *fmt; SpaPODBuilder b = { state->format_buffer, sizeof (state->format_buffer), }; if (spa_v4l2_open (this) < 0) @@ -605,25 +604,17 @@ have_size: spa_pod_builder_push_format (&b, &f[0], info->media_type, - info->media_subtype), - - fmt = SPA_POD_BUILDER_DEREF (&b, f[0].ref, SpaFormat); + info->media_subtype); if (info->media_subtype == SPA_MEDIA_SUBTYPE_RAW) { spa_pod_builder_add (&b, - SPA_POD_TYPE_PROP, &f[1], - SPA_PROP_ID_VIDEO_FORMAT, SPA_POD_PROP_RANGE_NONE | SPA_POD_PROP_FLAG_READWRITE, - SPA_POD_TYPE_INT, 1, - info->format, - -SPA_POD_TYPE_PROP, &f[1], 0); + PROP (&f[1], SPA_PROP_ID_VIDEO_FORMAT, SPA_POD_TYPE_INT, info->format), + 0); } spa_pod_builder_add (&b, - SPA_POD_TYPE_PROP, &f[1], - SPA_PROP_ID_VIDEO_SIZE, SPA_POD_PROP_RANGE_NONE | SPA_POD_PROP_FLAG_READWRITE, - SPA_POD_TYPE_RECTANGLE, 1, - state->frmsize.discrete.width, - state->frmsize.discrete.height, - -SPA_POD_TYPE_PROP, &f[1], 0); + PROP (&f[1], SPA_PROP_ID_VIDEO_SIZE, SPA_POD_TYPE_RECTANGLE, state->frmsize.discrete.width, + state->frmsize.discrete.height), + 0); spa_pod_builder_push_prop (&b, &f[1], SPA_PROP_ID_VIDEO_FRAMERATE, @@ -729,13 +720,13 @@ have_framerate: spa_pod_builder_pop (&b, &f[1]); spa_pod_builder_pop (&b, &f[0]); - *format = fmt; + *format = SPA_POD_BUILDER_DEREF (&b, f[0].ref, SpaFormat); return SPA_RESULT_OK; } static int -spa_v4l2_set_format (SpaV4l2Source *this, SpaVideoInfo *f, bool try_only) +spa_v4l2_set_format (SpaV4l2Source *this, SpaVideoInfo *format, bool try_only) { SpaV4l2State *state = &this->state[0]; int cmd; @@ -745,28 +736,30 @@ spa_v4l2_set_format (SpaV4l2Source *this, SpaVideoInfo *f, bool try_only) SpaVideoFormat video_format; SpaRectangle *size = NULL; SpaFraction *framerate = NULL; + SpaPODBuilder b = { NULL }; + SpaPODFrame f[2]; CLEAR (fmt); CLEAR (streamparm); fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; streamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - switch (f->media_subtype) { + switch (format->media_subtype) { case SPA_MEDIA_SUBTYPE_RAW: - video_format = f->info.raw.format; - size = &f->info.raw.size; - framerate = &f->info.raw.framerate; + video_format = format->info.raw.format; + size = &format->info.raw.size; + framerate = &format->info.raw.framerate; break; case SPA_MEDIA_SUBTYPE_MJPG: case SPA_MEDIA_SUBTYPE_JPEG: video_format = SPA_VIDEO_FORMAT_ENCODED; - size = &f->info.mjpg.size; - framerate = &f->info.mjpg.framerate; + size = &format->info.mjpg.size; + framerate = &format->info.mjpg.framerate; break; case SPA_MEDIA_SUBTYPE_H264: video_format = SPA_VIDEO_FORMAT_ENCODED; - size = &f->info.h264.size; - framerate = &f->info.h264.framerate; + size = &format->info.h264.size; + framerate = &format->info.h264.framerate; break; case SPA_MEDIA_SUBTYPE_DV: case SPA_MEDIA_SUBTYPE_MPEGTS: @@ -781,13 +774,13 @@ spa_v4l2_set_format (SpaV4l2Source *this, SpaVideoInfo *f, bool try_only) break; } - info = find_format_info_by_media_type (f->media_type, - f->media_subtype, + info = find_format_info_by_media_type (format->media_type, + format->media_subtype, video_format, 0); if (info == NULL || size == NULL || framerate == NULL) { - spa_log_error (state->log, "v4l2: unknown media type %d %d %d", f->media_type, - f->media_subtype, video_format); + spa_log_error (state->log, "v4l2: unknown media type %d %d %d", format->media_type, + format->media_subtype, video_format); return -1; } @@ -847,18 +840,18 @@ spa_v4l2_set_format (SpaV4l2Source *this, SpaVideoInfo *f, bool try_only) state->info.n_params = 2; state->info.params = state->params; - state->params[0] = &state->param_buffers.param; - state->param_buffers.param.type = SPA_ALLOC_PARAM_TYPE_BUFFERS; - state->param_buffers.param.size = sizeof (state->param_buffers); - state->param_buffers.minsize = fmt.fmt.pix.sizeimage; - state->param_buffers.stride = fmt.fmt.pix.bytesperline; - state->param_buffers.min_buffers = 2; - state->param_buffers.max_buffers = MAX_BUFFERS; - state->param_buffers.align = 16; - state->params[1] = &state->param_meta.param; - state->param_meta.param.type = SPA_ALLOC_PARAM_TYPE_META_ENABLE; - state->param_meta.param.size = sizeof (state->param_meta); - state->param_meta.type = SPA_META_TYPE_HEADER; + + spa_pod_builder_init (&b, state->params_buffer, sizeof (state->params_buffer)); + spa_pod_builder_object (&b, &f[0], 0, SPA_ALLOC_PARAM_TYPE_BUFFERS, + PROP (&f[1], SPA_ALLOC_PARAM_BUFFERS_SIZE, SPA_POD_TYPE_INT, fmt.fmt.pix.sizeimage), + PROP (&f[1], SPA_ALLOC_PARAM_BUFFERS_STRIDE, SPA_POD_TYPE_INT, fmt.fmt.pix.bytesperline), + PROP_U_MM (&f[1], SPA_ALLOC_PARAM_BUFFERS_BUFFERS, SPA_POD_TYPE_INT, MAX_BUFFERS, 2, MAX_BUFFERS), + PROP (&f[1], SPA_ALLOC_PARAM_BUFFERS_ALIGN, SPA_POD_TYPE_INT, 16)); + state->params[0] = SPA_POD_BUILDER_DEREF (&b, f[0].ref, SpaAllocParam); + + spa_pod_builder_object (&b, &f[0], 0, SPA_ALLOC_PARAM_TYPE_META_ENABLE, + PROP (&f[1], SPA_ALLOC_PARAM_META_ENABLE_TYPE, SPA_POD_TYPE_INT, SPA_META_TYPE_HEADER)); + state->params[1] = SPA_POD_BUILDER_DEREF (&b, f[0].ref, SpaAllocParam); state->info.extra = NULL; diff --git a/spa/plugins/videotestsrc/draw.c b/spa/plugins/videotestsrc/draw.c index f7563e38f..317588ad6 100644 --- a/spa/plugins/videotestsrc/draw.c +++ b/spa/plugins/videotestsrc/draw.c @@ -162,7 +162,7 @@ drawing_data_init (DrawingData *dd, dd->line = data; dd->width = size->width; dd->height = size->height; - dd->stride = this->param_buffers.stride; + dd->stride = this->stride; return SPA_RESULT_OK; } diff --git a/spa/plugins/videotestsrc/videotestsrc.c b/spa/plugins/videotestsrc/videotestsrc.c index ca8011204..ff9b3f1a8 100644 --- a/spa/plugins/videotestsrc/videotestsrc.c +++ b/spa/plugins/videotestsrc/videotestsrc.c @@ -82,8 +82,8 @@ struct _SpaVideoTestSrc { SpaPortInfo info; SpaAllocParam *params[2]; - SpaAllocParamBuffers param_buffers; - SpaAllocParamMetaEnable param_meta; + uint8_t params_buffer[1024]; + int stride; SpaPortOutput *output; bool have_format; @@ -123,13 +123,30 @@ reset_videotestsrc_props (SpaVideoTestSrcProps *props) props->pattern = DEFAULT_PATTERN; } +#define PROP(f,key,type,...) \ + SPA_POD_PROP (f,key,SPA_POD_PROP_FLAG_READWRITE,type,1,__VA_ARGS__) +#define PROP_MM(f,key,type,...) \ + SPA_POD_PROP (f,key,SPA_POD_PROP_FLAG_READWRITE | \ + SPA_POD_PROP_RANGE_MIN_MAX,type,3,__VA_ARGS__) +#define PROP_U_MM(f,key,type,...) \ + SPA_POD_PROP (f,key,SPA_POD_PROP_FLAG_READWRITE | \ + SPA_POD_PROP_FLAG_UNSET | \ + SPA_POD_PROP_RANGE_MIN_MAX,type,3,__VA_ARGS__) +#define PROP_EN(f,key,type,n,...) \ + SPA_POD_PROP (f,key,SPA_POD_PROP_FLAG_READWRITE | \ + SPA_POD_PROP_RANGE_ENUM,type,n,__VA_ARGS__) +#define PROP_U_EN(f,key,type,n,...) \ + SPA_POD_PROP (f,key,SPA_POD_PROP_FLAG_READWRITE | \ + SPA_POD_PROP_FLAG_UNSET | \ + SPA_POD_PROP_RANGE_ENUM,type,n,__VA_ARGS__) + static SpaResult spa_videotestsrc_node_get_props (SpaNode *node, SpaProps **props) { SpaVideoTestSrc *this; SpaPODBuilder b = { NULL, }; - SpaPODFrame f; + SpaPODFrame f[2]; if (node == NULL || props == NULL) return SPA_RESULT_INVALID_ARGUMENTS; @@ -138,21 +155,14 @@ spa_videotestsrc_node_get_props (SpaNode *node, spa_pod_builder_init (&b, this->props_buffer, sizeof (this->props_buffer)); - *props = SPA_MEMBER (b.data, spa_pod_builder_props (&b, - SPA_POD_TYPE_PROP, &f, - PROP_ID_LIVE, SPA_POD_PROP_FLAG_READWRITE | - SPA_POD_PROP_RANGE_NONE, - SPA_POD_TYPE_BOOL, 1, - this->props.live, - -SPA_POD_TYPE_PROP, &f, - SPA_POD_TYPE_PROP, &f, - PROP_ID_PATTERN, SPA_POD_PROP_FLAG_READWRITE | - SPA_POD_PROP_RANGE_ENUM, - SPA_POD_TYPE_INT, 3, - this->props.pattern, - pattern_val_smpte_snow, - pattern_val_snow, - -SPA_POD_TYPE_PROP, &f, 0), SpaProps); + spa_pod_builder_props (&b, &f[0], + PROP (&f[1], PROP_ID_LIVE, SPA_POD_TYPE_BOOL, this->props.live), + PROP_EN (&f[1], PROP_ID_PATTERN, SPA_POD_TYPE_INT, 3, + this->props.pattern, + pattern_val_smpte_snow, + pattern_val_snow)); + + *props = SPA_POD_BUILDER_DEREF (&b, f[0].ref, SpaProps); return SPA_RESULT_OK; } @@ -171,24 +181,10 @@ spa_videotestsrc_node_set_props (SpaNode *node, if (props == NULL) { reset_videotestsrc_props (&this->props); } else { - SpaPOD *p; - - SPA_POD_OBJECT_BODY_FOREACH (&props->body, props->pod.size, p) { - SpaPODProp *pr; - - if (p->type != SPA_POD_TYPE_PROP) - continue; - - pr = (SpaPODProp *) p; - switch (pr->body.key) { - case PROP_ID_LIVE: - this->props.live = ((SpaPODBool*)&pr->body.value)->value; - break; - case PROP_ID_PATTERN: - this->props.pattern = ((SpaPODInt*)&pr->body.value)->value; - break; - } - } + spa_props_query (props, + PROP_ID_LIVE, SPA_POD_TYPE_BOOL, &this->props.live, + PROP_ID_PATTERN, SPA_POD_TYPE_INT, &this->props.pattern, + 0); } if (this->props.live) @@ -453,37 +449,27 @@ next: switch (index++) { case 0: - fmt = SPA_MEMBER (buffer, spa_pod_builder_format (&b, + spa_pod_builder_format (&b, &f[0], SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW, - SPA_POD_TYPE_PROP, &f[0], - SPA_PROP_ID_VIDEO_FORMAT, SPA_POD_PROP_FLAG_UNSET | SPA_POD_PROP_FLAG_READWRITE | - SPA_POD_PROP_RANGE_ENUM, - SPA_POD_TYPE_INT, 3, - SPA_VIDEO_FORMAT_RGB, - SPA_VIDEO_FORMAT_RGB, - SPA_VIDEO_FORMAT_UYVY, - -SPA_POD_TYPE_PROP, &f[0], - SPA_POD_TYPE_PROP, &f[0], - SPA_PROP_ID_VIDEO_SIZE, SPA_POD_PROP_FLAG_UNSET | SPA_POD_PROP_FLAG_READWRITE | - SPA_POD_PROP_RANGE_MIN_MAX, - SPA_POD_TYPE_RECTANGLE, 3, - 320, 240, - 1, 1, - INT32_MAX, INT32_MAX, - -SPA_POD_TYPE_PROP, &f[0], - SPA_POD_TYPE_PROP, &f[0], - SPA_PROP_ID_VIDEO_FRAMERATE, SPA_POD_PROP_FLAG_UNSET | SPA_POD_PROP_FLAG_READWRITE | - SPA_POD_PROP_RANGE_MIN_MAX, - SPA_POD_TYPE_FRACTION, 3, - 25, 1, - 0, 1, - INT32_MAX, 1, - -SPA_POD_TYPE_PROP, &f[0], 0), SpaFormat); + PROP_U_EN (&f[1], SPA_PROP_ID_VIDEO_FORMAT, SPA_POD_TYPE_INT, 3, + SPA_VIDEO_FORMAT_RGB, + SPA_VIDEO_FORMAT_RGB, + SPA_VIDEO_FORMAT_UYVY), + PROP_U_MM (&f[1], SPA_PROP_ID_VIDEO_SIZE, SPA_POD_TYPE_RECTANGLE, + 320, 240, + 1, 1, + INT32_MAX, INT32_MAX), + PROP_U_MM (&f[1], SPA_PROP_ID_VIDEO_FRAMERATE, SPA_POD_TYPE_FRACTION, + 25, 1, + 0, 1, + INT32_MAX, 1)); break; default: return SPA_RESULT_ENUM_END; } + fmt = SPA_POD_BUILDER_DEREF (&b, f[0].ref, SpaFormat); + spa_pod_builder_init (&b, this->format_buffer, sizeof (this->format_buffer)); if ((res = spa_format_filter (fmt, filter, &b)) != SPA_RESULT_OK) @@ -537,6 +523,8 @@ spa_videotestsrc_node_port_set_format (SpaNode *node, if (this->have_format) { SpaVideoInfoRaw *raw_info = &this->current_format.info.raw; + SpaPODBuilder b = { NULL }; + SpaPODFrame f[2]; switch (raw_info->format) { case SPA_VIDEO_FORMAT_RGB: @@ -554,18 +542,21 @@ spa_videotestsrc_node_port_set_format (SpaNode *node, this->info.n_params = 2; this->info.params = this->params; - this->params[0] = &this->param_buffers.param; - this->param_buffers.param.type = SPA_ALLOC_PARAM_TYPE_BUFFERS; - this->param_buffers.param.size = sizeof (this->param_buffers); - this->param_buffers.stride = this->bpp * raw_info->size.width; - this->param_buffers.minsize = this->param_buffers.stride * raw_info->size.height; - this->param_buffers.min_buffers = 2; - this->param_buffers.max_buffers = 32; - this->param_buffers.align = 16; - this->params[1] = &this->param_meta.param; - this->param_meta.param.type = SPA_ALLOC_PARAM_TYPE_META_ENABLE; - this->param_meta.param.size = sizeof (this->param_meta); - this->param_meta.type = SPA_META_TYPE_HEADER; + + this->stride = SPA_ROUND_UP_N (this->bpp * raw_info->size.width, 4); + + spa_pod_builder_init (&b, this->params_buffer, sizeof (this->params_buffer)); + spa_pod_builder_object (&b, &f[0], 0, SPA_ALLOC_PARAM_TYPE_BUFFERS, + PROP (&f[1], SPA_ALLOC_PARAM_BUFFERS_SIZE, SPA_POD_TYPE_INT, this->stride * raw_info->size.height), + PROP (&f[1], SPA_ALLOC_PARAM_BUFFERS_STRIDE, SPA_POD_TYPE_INT, this->stride), + PROP_U_MM (&f[1], SPA_ALLOC_PARAM_BUFFERS_BUFFERS, SPA_POD_TYPE_INT, 32, 2, 32), + PROP (&f[1], SPA_ALLOC_PARAM_BUFFERS_ALIGN, SPA_POD_TYPE_INT, 16)); + this->params[0] = SPA_POD_BUILDER_DEREF (&b, f[0].ref, SpaAllocParam); + + spa_pod_builder_object (&b, &f[0], 0, SPA_ALLOC_PARAM_TYPE_META_ENABLE, + PROP (&f[1], SPA_ALLOC_PARAM_META_ENABLE_TYPE, SPA_POD_TYPE_INT, SPA_META_TYPE_HEADER)); + this->params[1] = SPA_POD_BUILDER_DEREF (&b, f[0].ref, SpaAllocParam); + this->info.extra = NULL; update_state (this, SPA_NODE_STATE_READY); } @@ -583,7 +574,7 @@ spa_videotestsrc_node_port_get_format (SpaNode *node, { SpaVideoTestSrc *this; SpaPODBuilder b = { NULL, }; - SpaPODFrame f; + SpaPODFrame f[2]; if (node == NULL || format == NULL) return SPA_RESULT_INVALID_ARGUMENTS; @@ -598,25 +589,12 @@ spa_videotestsrc_node_port_get_format (SpaNode *node, spa_pod_builder_init (&b, this->format_buffer, sizeof (this->format_buffer)); - *format = SPA_MEMBER (b.data, spa_pod_builder_format (&b, - SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW, - SPA_POD_TYPE_PROP, &f, - SPA_PROP_ID_VIDEO_FORMAT, SPA_POD_PROP_FLAG_READWRITE, - SPA_POD_TYPE_INT, 1, - this->current_format.info.raw.format, - -SPA_POD_TYPE_PROP, &f, - SPA_POD_TYPE_PROP, &f, - SPA_PROP_ID_VIDEO_SIZE, SPA_POD_PROP_FLAG_READWRITE, - SPA_POD_TYPE_RECTANGLE, 1, - this->current_format.info.raw.size.width, - this->current_format.info.raw.size.height, - -SPA_POD_TYPE_PROP, &f, - SPA_POD_TYPE_PROP, &f, - SPA_PROP_ID_VIDEO_FRAMERATE, SPA_POD_PROP_FLAG_READWRITE, - SPA_POD_TYPE_FRACTION, 1, - this->current_format.info.raw.framerate.num, - this->current_format.info.raw.framerate.denom, - -SPA_POD_TYPE_PROP, &f, 0), SpaFormat); + spa_pod_builder_format (&b, &f[0], + SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW, + PROP (&f[1], SPA_PROP_ID_VIDEO_FORMAT, SPA_POD_TYPE_INT, this->current_format.info.raw.format), + PROP (&f[1], SPA_PROP_ID_VIDEO_SIZE, -SPA_POD_TYPE_RECTANGLE, &this->current_format.info.raw.size), + PROP (&f[1], SPA_PROP_ID_VIDEO_FRAMERATE, -SPA_POD_TYPE_FRACTION, &this->current_format.info.raw.framerate)); + *format = SPA_POD_BUILDER_DEREF (&b, f[0].ref, SpaFormat); return SPA_RESULT_OK; } diff --git a/spa/plugins/volume/volume.c b/spa/plugins/volume/volume.c index 11e8f36d4..5682df868 100644 --- a/spa/plugins/volume/volume.c +++ b/spa/plugins/volume/volume.c @@ -51,8 +51,7 @@ typedef struct { SpaPortInfo info; SpaAllocParam *params[2]; - SpaAllocParamBuffers param_buffers; - SpaAllocParamMetaEnable param_meta; + uint8_t params_buffer[1024]; SpaVolumeBuffer buffers[MAX_BUFFERS]; uint32_t n_buffers; @@ -113,13 +112,28 @@ update_state (SpaVolume *this, SpaNodeState state) this->node.state = state; } +#define PROP(f,key,type,...) \ + SPA_POD_PROP (f,key,SPA_POD_PROP_FLAG_READWRITE,type,1,__VA_ARGS__) +#define PROP_MM(f,key,type,...) \ + SPA_POD_PROP (f,key,SPA_POD_PROP_FLAG_READWRITE | \ + SPA_POD_PROP_RANGE_MIN_MAX,type,3,__VA_ARGS__) +#define PROP_U_MM(f,key,type,...) \ + SPA_POD_PROP (f,key,SPA_POD_PROP_FLAG_READWRITE | \ + SPA_POD_PROP_FLAG_UNSET | \ + SPA_POD_PROP_RANGE_MIN_MAX,type,3,__VA_ARGS__) +#define PROP_U_EN(f,key,type,n,...) \ + SPA_POD_PROP (f,key,SPA_POD_PROP_FLAG_READWRITE | \ + SPA_POD_PROP_FLAG_UNSET | \ + SPA_POD_PROP_RANGE_ENUM,type,n,__VA_ARGS__) + + static SpaResult spa_volume_node_get_props (SpaNode *node, SpaProps **props) { SpaVolume *this; SpaPODBuilder b = { NULL, }; - SpaPODFrame f; + SpaPODFrame f[2]; if (node == NULL || props == NULL) return SPA_RESULT_INVALID_ARGUMENTS; @@ -127,29 +141,18 @@ spa_volume_node_get_props (SpaNode *node, this = SPA_CONTAINER_OF (node, SpaVolume, node); spa_pod_builder_init (&b, this->props_buffer, sizeof (this->props_buffer)); + spa_pod_builder_props (&b, &f[0], + PROP_MM (&f[1], PROP_ID_VOLUME, SPA_POD_TYPE_DOUBLE, this->props.volume, 0.0, 10.0), + PROP (&f[1], PROP_ID_MUTE, SPA_POD_TYPE_BOOL, this->props.mute)); - *props = SPA_MEMBER (b.data, spa_pod_builder_props (&b, - SPA_POD_TYPE_PROP, &f, - PROP_ID_VOLUME, SPA_POD_PROP_FLAG_READWRITE | - SPA_POD_PROP_RANGE_MIN_MAX, - SPA_POD_TYPE_DOUBLE, 3, - this->props.volume, - 0.0, - 10.0, - -SPA_POD_TYPE_PROP, &f, - SPA_POD_TYPE_PROP, &f, - PROP_ID_MUTE, SPA_POD_PROP_FLAG_READWRITE | - SPA_POD_PROP_RANGE_NONE, - SPA_POD_TYPE_BOOL, 1, - this->props.mute, - -SPA_POD_TYPE_PROP, &f, 0), SpaProps); + *props = SPA_POD_BUILDER_DEREF (&b, f[0].ref, SpaProps); return SPA_RESULT_OK; } static SpaResult -spa_volume_node_set_props (SpaNode *node, - const SpaProps *props) +spa_volume_node_set_props (SpaNode *node, + const SpaProps *props) { SpaVolume *this; @@ -161,24 +164,10 @@ spa_volume_node_set_props (SpaNode *node, if (props == NULL) { reset_volume_props (&this->props); } else { - SpaPOD *p; - - SPA_POD_OBJECT_BODY_FOREACH (&props->body, props->pod.size, p) { - SpaPODProp *pr; - - if (p->type != SPA_POD_TYPE_PROP) - continue; - - pr = (SpaPODProp *) p; - switch (pr->body.key) { - case PROP_ID_VOLUME: - this->props.volume = ((SpaPODDouble*)&pr->body.value)->value; - break; - case PROP_ID_MUTE: - this->props.mute = ((SpaPODBool*)&pr->body.value)->value; - break; - } - } + spa_props_query (props, + PROP_ID_VOLUME, SPA_POD_TYPE_DOUBLE, &this->props.volume, + PROP_ID_MUTE, SPA_POD_TYPE_BOOL, &this->props.mute, + 0); } return SPA_RESULT_OK; } @@ -303,7 +292,7 @@ spa_volume_node_port_enum_formats (SpaNode *node, SpaFormat *fmt; uint8_t buffer[1024]; SpaPODBuilder b = { NULL, }; - SpaPODFrame f; + SpaPODFrame f[2]; if (node == NULL || format == NULL) return SPA_RESULT_INVALID_ARGUMENTS; @@ -318,35 +307,19 @@ next: switch (index++) { case 0: - fmt = SPA_MEMBER (buffer, spa_pod_builder_format (&b, - SPA_MEDIA_TYPE_AUDIO, SPA_MEDIA_SUBTYPE_RAW, - SPA_POD_TYPE_PROP, &f, - SPA_PROP_ID_AUDIO_FORMAT, SPA_POD_PROP_FLAG_UNSET | SPA_POD_PROP_FLAG_READWRITE | - SPA_POD_PROP_RANGE_ENUM, - SPA_POD_TYPE_INT, 3, - SPA_AUDIO_FORMAT_S16, - SPA_AUDIO_FORMAT_S16, - SPA_AUDIO_FORMAT_S32, - -SPA_POD_TYPE_PROP, &f, - SPA_POD_TYPE_PROP, &f, - SPA_PROP_ID_AUDIO_RATE, SPA_POD_PROP_FLAG_UNSET | SPA_POD_PROP_FLAG_READWRITE | - SPA_POD_PROP_RANGE_MIN_MAX, - SPA_POD_TYPE_INT, 3, - 44100, - 1, INT32_MAX, - -SPA_POD_TYPE_PROP, &f, - SPA_POD_TYPE_PROP, &f, - SPA_PROP_ID_AUDIO_CHANNELS, SPA_POD_PROP_FLAG_UNSET | SPA_POD_PROP_FLAG_READWRITE | - SPA_POD_PROP_RANGE_MIN_MAX, - SPA_POD_TYPE_INT, 3, - 2, - 1, INT32_MAX, - -SPA_POD_TYPE_PROP, &f, 0), SpaFormat); + spa_pod_builder_format (&b, &f[0], SPA_MEDIA_TYPE_AUDIO, SPA_MEDIA_SUBTYPE_RAW, + PROP_U_EN (&f[1], SPA_PROP_ID_AUDIO_FORMAT, SPA_POD_TYPE_INT, 3, + SPA_AUDIO_FORMAT_S16, + SPA_AUDIO_FORMAT_S16, + SPA_AUDIO_FORMAT_S32), + PROP_U_MM (&f[1], SPA_PROP_ID_AUDIO_RATE, SPA_POD_TYPE_INT, 44100, 1, INT32_MAX), + PROP_U_MM (&f[1], SPA_PROP_ID_AUDIO_CHANNELS, SPA_POD_TYPE_INT, 2, 1, INT32_MAX)); + break; default: return SPA_RESULT_ENUM_END; } - + fmt = SPA_POD_BUILDER_DEREF (&b, f[0].ref, SpaFormat); spa_pod_builder_init (&b, this->format_buffer, sizeof (this->format_buffer)); if ((res = spa_format_filter (fmt, filter, &b)) != SPA_RESULT_OK) @@ -400,23 +373,27 @@ spa_volume_node_port_set_format (SpaNode *node, } if (port->have_format) { + SpaPODBuilder b = { NULL }; + SpaPODFrame f[2]; + port->info.maxbuffering = -1; port->info.latency = 0; port->info.n_params = 2; port->info.params = port->params; - port->params[0] = &port->param_buffers.param; - port->param_buffers.param.type = SPA_ALLOC_PARAM_TYPE_BUFFERS; - port->param_buffers.param.size = sizeof (port->param_buffers); - port->param_buffers.minsize = 16; - port->param_buffers.stride = 16; - port->param_buffers.min_buffers = 2; - port->param_buffers.max_buffers = MAX_BUFFERS; - port->param_buffers.align = 16; - port->params[1] = &port->param_meta.param; - port->param_meta.param.type = SPA_ALLOC_PARAM_TYPE_META_ENABLE; - port->param_meta.param.size = sizeof (port->param_meta); - port->param_meta.type = SPA_META_TYPE_HEADER; + + spa_pod_builder_init (&b, port->params_buffer, sizeof (port->params_buffer)); + spa_pod_builder_object (&b, &f[0], 0, SPA_ALLOC_PARAM_TYPE_BUFFERS, + PROP (&f[1], SPA_ALLOC_PARAM_BUFFERS_SIZE, SPA_POD_TYPE_INT, 16), + PROP (&f[1], SPA_ALLOC_PARAM_BUFFERS_STRIDE, SPA_POD_TYPE_INT, 16), + PROP_U_MM (&f[1], SPA_ALLOC_PARAM_BUFFERS_BUFFERS, SPA_POD_TYPE_INT, MAX_BUFFERS, 2, MAX_BUFFERS), + PROP (&f[1], SPA_ALLOC_PARAM_BUFFERS_ALIGN, SPA_POD_TYPE_INT, 16)); + port->params[0] = SPA_POD_BUILDER_DEREF (&b, f[0].ref, SpaAllocParam); + + spa_pod_builder_object (&b, &f[0], 0, SPA_ALLOC_PARAM_TYPE_META_ENABLE, + PROP (&f[1], SPA_ALLOC_PARAM_META_ENABLE_TYPE, SPA_POD_TYPE_INT, SPA_META_TYPE_HEADER)); + port->params[1] = SPA_POD_BUILDER_DEREF (&b, f[0].ref, SpaAllocParam); + port->info.extra = NULL; update_state (this, SPA_NODE_STATE_READY); } diff --git a/spa/plugins/xv/xv-sink.c b/spa/plugins/xv/xv-sink.c index 0263d44ee..14200a1ec 100644 --- a/spa/plugins/xv/xv-sink.c +++ b/spa/plugins/xv/xv-sink.c @@ -114,13 +114,18 @@ update_state (SpaXvSink *this, SpaNodeState state) this->node.state = state; } +#define PROP(f,key,type,...) \ + SPA_POD_PROP (f,key,SPA_POD_PROP_FLAG_READWRITE,type,1,__VA_ARGS__) +#define PROP_R(f,key,type,...) \ + SPA_POD_PROP (f,key,SPA_POD_PROP_FLAG_READABLE,type,1,__VA_ARGS__) + static SpaResult spa_xv_sink_node_get_props (SpaNode *node, SpaProps **props) { SpaXvSink *this; SpaPODBuilder b = { NULL, }; - SpaPODFrame f; + SpaPODFrame f[2]; if (node == NULL || props == NULL) return SPA_RESULT_INVALID_ARGUMENTS; @@ -128,26 +133,11 @@ spa_xv_sink_node_get_props (SpaNode *node, this = SPA_CONTAINER_OF (node, SpaXvSink, node); spa_pod_builder_init (&b, this->props_buffer, sizeof (this->props_buffer)); - - *props = SPA_MEMBER (b.data, spa_pod_builder_props (&b, - SPA_POD_TYPE_PROP, &f, - PROP_ID_DEVICE, SPA_POD_PROP_FLAG_READWRITE | - SPA_POD_PROP_RANGE_NONE, - -SPA_POD_TYPE_STRING, 1, - this->props.device, sizeof (this->props.device), - -SPA_POD_TYPE_PROP, &f, - SPA_POD_TYPE_PROP, &f, - PROP_ID_DEVICE_NAME, SPA_POD_PROP_FLAG_READABLE | - SPA_POD_PROP_RANGE_NONE, - -SPA_POD_TYPE_STRING, 1, - this->props.device_name, sizeof (this->props.device_name), - -SPA_POD_TYPE_PROP, &f, - SPA_POD_TYPE_PROP, &f, - PROP_ID_DEVICE_FD, SPA_POD_PROP_FLAG_READABLE | - SPA_POD_PROP_RANGE_NONE, - SPA_POD_TYPE_INT, 1, - this->props.device_fd, - -SPA_POD_TYPE_PROP, &f, 0), SpaProps); + spa_pod_builder_props (&b, &f[0], + PROP (&f[1], PROP_ID_DEVICE, -SPA_POD_TYPE_STRING, this->props.device, sizeof (this->props.device)), + PROP_R (&f[1], PROP_ID_DEVICE_NAME, -SPA_POD_TYPE_STRING, this->props.device_name, sizeof (this->props.device_name)), + PROP_R (&f[1], PROP_ID_DEVICE_FD, SPA_POD_TYPE_INT, this->props.device_fd)); + *props = SPA_POD_BUILDER_DEREF (&b, f[0].ref, SpaProps); return SPA_RESULT_OK; } @@ -166,21 +156,9 @@ spa_xv_sink_node_set_props (SpaNode *node, if (props == NULL) { reset_xv_sink_props (&this->props); } else { - SpaPOD *p; - - SPA_POD_OBJECT_BODY_FOREACH (&props->body, props->pod.size, p) { - SpaPODProp *pr; - - if (p->type != SPA_POD_TYPE_PROP) - continue; - - pr = (SpaPODProp *) p; - switch (pr->body.key) { - case PROP_ID_DEVICE: - strncpy (this->props.device, SPA_POD_CONTENTS (SpaPODProp, pr), 63); - break; - } - } + spa_props_query (props, + PROP_ID_DEVICE, -SPA_POD_TYPE_STRING, this->props.device, sizeof (this->props.device), + 0); } return SPA_RESULT_OK; } @@ -301,12 +279,12 @@ spa_xv_sink_node_port_enum_formats (SpaNode *node, const SpaFormat *filter, uint32_t index) { - SpaXvSink *this; + //SpaXvSink *this; if (node == NULL || format == NULL) return SPA_RESULT_INVALID_ARGUMENTS; - this = SPA_CONTAINER_OF (node, SpaXvSink, node); + //this = SPA_CONTAINER_OF (node, SpaXvSink, node); if (!CHECK_PORT (this, direction, port_id)) return SPA_RESULT_INVALID_PORT; diff --git a/spa/tests/test-props.c b/spa/tests/test-props.c index 50f0bcb10..2bab75685 100644 --- a/spa/tests/test-props.c +++ b/spa/tests/test-props.c @@ -123,7 +123,6 @@ main (int argc, char *argv[]) SpaPODFrame frame[4]; uint8_t buffer[1024]; SpaFormat *fmt; - off_t o; spa_pod_builder_init (&b, buffer, sizeof (buffer)); @@ -160,34 +159,34 @@ main (int argc, char *argv[]) spa_pod_builder_init (&b, buffer, sizeof (buffer)); - o = spa_pod_builder_format (&b, + spa_pod_builder_format (&b, &frame[0], SPA_MEDIA_TYPE_VIDEO, SPA_MEDIA_SUBTYPE_RAW, - SPA_POD_TYPE_PROP, &frame[0], + SPA_POD_TYPE_PROP, &frame[1], SPA_PROP_ID_VIDEO_FORMAT, SPA_POD_PROP_FLAG_UNSET | SPA_POD_PROP_RANGE_ENUM, SPA_POD_TYPE_INT, 3, SPA_VIDEO_FORMAT_I420, SPA_VIDEO_FORMAT_I420, SPA_VIDEO_FORMAT_YUY2, - -SPA_POD_TYPE_PROP, &frame[0], - SPA_POD_TYPE_PROP, &frame[0], + -SPA_POD_TYPE_PROP, &frame[1], + SPA_POD_TYPE_PROP, &frame[1], SPA_PROP_ID_VIDEO_SIZE, SPA_POD_PROP_FLAG_UNSET | SPA_POD_PROP_RANGE_MIN_MAX, SPA_POD_TYPE_RECTANGLE, 3, 320, 241, 1, 1, INT32_MAX, INT32_MAX, - -SPA_POD_TYPE_PROP, &frame[0], - SPA_POD_TYPE_PROP, &frame[0], + -SPA_POD_TYPE_PROP, &frame[1], + SPA_POD_TYPE_PROP, &frame[1], SPA_PROP_ID_VIDEO_FRAMERATE, SPA_POD_PROP_FLAG_UNSET | SPA_POD_PROP_RANGE_MIN_MAX, SPA_POD_TYPE_FRACTION, 3, 25, 1, 0, 1, INT32_MAX, 1, - -SPA_POD_TYPE_PROP, &frame[0], 0); + -SPA_POD_TYPE_PROP, &frame[1], 0); - fmt = SPA_MEMBER (buffer, o, SpaFormat); + fmt = SPA_MEMBER (buffer, frame[0].ref, SpaFormat); spa_debug_pod (&fmt->pod); spa_debug_format (fmt); @@ -223,14 +222,25 @@ main (int argc, char *argv[]) -SPA_POD_TYPE_PROP, &frame[1], -SPA_POD_TYPE_OBJECT, &frame[0], 0); - spa_pod_builder_pop (&b, &frame[0]); - fmt = SPA_MEMBER (buffer, o, SpaFormat); + fmt = SPA_MEMBER (buffer, frame[0].ref, SpaFormat); spa_debug_pod (&fmt->pod); spa_debug_format (fmt); spa_debug_pod (&test_format.fmt.pod); spa_debug_format (&test_format.fmt); + { + uint32_t format = 0, match; + SpaFraction frac = { 0, 0 }; + + match = spa_pod_contents_query (&test_format.fmt.pod, sizeof (SpaFormat), + SPA_PROP_ID_VIDEO_FORMAT, SPA_POD_TYPE_INT, &format, + SPA_PROP_ID_VIDEO_FRAMERATE, SPA_POD_TYPE_FRACTION, &frac, + 0); + + printf ("%d %d %d %d\n", match, format, frac.num, frac.denom); + } + return 0; }