From bc9eb76a6ec08076cc8808160cad74c53f4498b7 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Tue, 9 Jul 2024 09:23:49 +0200 Subject: [PATCH] v4l2: use a dynamic pod builder to handle larger PropInfo The labels from the vivid driver need more space so use a dynamic builder to make sure we can handle them. See #4063 --- spa/plugins/v4l2/v4l2-utils.c | 39 +++++++++++++++++------------------ 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/spa/plugins/v4l2/v4l2-utils.c b/spa/plugins/v4l2/v4l2-utils.c index 4c583355c..8022680c9 100644 --- a/spa/plugins/v4l2/v4l2-utils.c +++ b/spa/plugins/v4l2/v4l2-utils.c @@ -11,6 +11,8 @@ #include #include +#include +#include #include static int xioctl(int fd, int request, void *arg) @@ -1116,7 +1118,8 @@ spa_v4l2_enum_controls(struct impl *this, int seq, struct spa_v4l2_device *dev = &port->dev; struct v4l2_query_ext_ctrl queryctrl; struct spa_pod *param; - struct spa_pod_builder b = { 0 }; + spa_auto(spa_pod_dynamic_builder) b = { 0 }; + struct spa_pod_builder_state state; uint32_t prop_id, ctrl_id; uint8_t buffer[1024]; int res; @@ -1128,6 +1131,9 @@ spa_v4l2_enum_controls(struct impl *this, int seq, if ((res = spa_v4l2_open(dev, this->props.device)) < 0) return res; + spa_pod_dynamic_builder_init(&b, buffer, sizeof(buffer), 4096); + spa_pod_builder_get_state(&b.b, &state); + result.id = SPA_PARAM_PropInfo; result.next = start; next: @@ -1178,7 +1184,7 @@ spa_v4l2_enum_controls(struct impl *this, int seq, ctrl_id = queryctrl.id & ~next_fl; - spa_pod_builder_init(&b, buffer, sizeof(buffer)); + spa_pod_builder_reset(&b.b, &state); prop_id = control_to_prop_id(this, ctrl_id); @@ -1191,7 +1197,7 @@ spa_v4l2_enum_controls(struct impl *this, int seq, switch (queryctrl.type) { case V4L2_CTRL_TYPE_INTEGER: port->controls[port->n_controls].type = SPA_TYPE_Int; - param = spa_pod_builder_add_object(&b, + param = spa_pod_builder_add_object(&b.b, SPA_TYPE_OBJECT_PropInfo, SPA_PARAM_PropInfo, SPA_PROP_INFO_id, SPA_POD_Id(prop_id), SPA_PROP_INFO_type, SPA_POD_CHOICE_STEP_Int( @@ -1203,7 +1209,7 @@ spa_v4l2_enum_controls(struct impl *this, int seq, break; case V4L2_CTRL_TYPE_BOOLEAN: port->controls[port->n_controls].type = SPA_TYPE_Bool; - param = spa_pod_builder_add_object(&b, + param = spa_pod_builder_add_object(&b.b, SPA_TYPE_OBJECT_PropInfo, SPA_PARAM_PropInfo, SPA_PROP_INFO_id, SPA_POD_Id(prop_id), SPA_PROP_INFO_type, SPA_POD_CHOICE_Bool((bool)queryctrl.default_value), @@ -1212,11 +1218,10 @@ spa_v4l2_enum_controls(struct impl *this, int seq, case V4L2_CTRL_TYPE_MENU: { struct v4l2_querymenu querymenu; - struct spa_pod_builder_state state; port->controls[port->n_controls].type = SPA_TYPE_Int; - spa_pod_builder_push_object(&b, &f[0], SPA_TYPE_OBJECT_PropInfo, SPA_PARAM_PropInfo); - spa_pod_builder_add(&b, + spa_pod_builder_push_object(&b.b, &f[0], SPA_TYPE_OBJECT_PropInfo, SPA_PARAM_PropInfo); + spa_pod_builder_add(&b.b, SPA_PROP_INFO_id, SPA_POD_Id(prop_id), SPA_PROP_INFO_type, SPA_POD_CHOICE_ENUM_Int(1, (int32_t)queryctrl.default_value), SPA_PROP_INFO_description, SPA_POD_String(queryctrl.name), @@ -1225,25 +1230,19 @@ spa_v4l2_enum_controls(struct impl *this, int seq, spa_zero(querymenu); querymenu.id = queryctrl.id; - spa_pod_builder_prop(&b, SPA_PROP_INFO_labels, 0); + spa_pod_builder_prop(&b.b, SPA_PROP_INFO_labels, 0); - spa_pod_builder_get_state(&b, &state); - spa_pod_builder_push_struct(&b, &f[1]); + spa_pod_builder_push_struct(&b.b, &f[1]); for (querymenu.index = queryctrl.minimum; querymenu.index <= queryctrl.maximum; querymenu.index++) { if (xioctl(dev->fd, VIDIOC_QUERYMENU, &querymenu) == 0) { - spa_pod_builder_int(&b, querymenu.index); - spa_pod_builder_string(&b, (const char *)querymenu.name); + spa_pod_builder_int(&b.b, querymenu.index); + spa_pod_builder_string(&b.b, (const char *)querymenu.name); } } - if (spa_pod_builder_pop(&b, &f[1]) == NULL) { - spa_log_warn(this->log, "can't create Control '%s' overflow %d", - queryctrl.name, b.state.offset); - spa_pod_builder_reset(&b, &state); - spa_pod_builder_none(&b); - } - param = spa_pod_builder_pop(&b, &f[0]); + spa_pod_builder_pop(&b.b, &f[1]); + param = spa_pod_builder_pop(&b.b, &f[0]); break; } case V4L2_CTRL_TYPE_INTEGER_MENU: @@ -1258,7 +1257,7 @@ spa_v4l2_enum_controls(struct impl *this, int seq, port->n_controls++; - if (spa_pod_filter(&b, &result.param, param, filter) < 0) + if (spa_pod_filter(&b.b, &result.param, param, filter) < 0) goto next; spa_node_emit_result(&this->hooks, seq, 0, SPA_RESULT_TYPE_NODE_PARAMS, &result);