mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-10-29 05:40:27 -04:00
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
This commit is contained in:
parent
b79f77b73d
commit
bc9eb76a6e
1 changed files with 19 additions and 20 deletions
|
|
@ -11,6 +11,8 @@
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
|
|
||||||
|
#include <spa/pod/dynamic.h>
|
||||||
|
#include <spa/utils/cleanup.h>
|
||||||
#include <spa/utils/result.h>
|
#include <spa/utils/result.h>
|
||||||
|
|
||||||
static int xioctl(int fd, int request, void *arg)
|
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 spa_v4l2_device *dev = &port->dev;
|
||||||
struct v4l2_query_ext_ctrl queryctrl;
|
struct v4l2_query_ext_ctrl queryctrl;
|
||||||
struct spa_pod *param;
|
struct spa_pod *param;
|
||||||
struct spa_pod_builder b = { 0 };
|
spa_auto(spa_pod_dynamic_builder) b = { 0 };
|
||||||
|
struct spa_pod_builder_state state;
|
||||||
uint32_t prop_id, ctrl_id;
|
uint32_t prop_id, ctrl_id;
|
||||||
uint8_t buffer[1024];
|
uint8_t buffer[1024];
|
||||||
int res;
|
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)
|
if ((res = spa_v4l2_open(dev, this->props.device)) < 0)
|
||||||
return res;
|
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.id = SPA_PARAM_PropInfo;
|
||||||
result.next = start;
|
result.next = start;
|
||||||
next:
|
next:
|
||||||
|
|
@ -1178,7 +1184,7 @@ spa_v4l2_enum_controls(struct impl *this, int seq,
|
||||||
|
|
||||||
ctrl_id = queryctrl.id & ~next_fl;
|
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);
|
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) {
|
switch (queryctrl.type) {
|
||||||
case V4L2_CTRL_TYPE_INTEGER:
|
case V4L2_CTRL_TYPE_INTEGER:
|
||||||
port->controls[port->n_controls].type = SPA_TYPE_Int;
|
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_TYPE_OBJECT_PropInfo, SPA_PARAM_PropInfo,
|
||||||
SPA_PROP_INFO_id, SPA_POD_Id(prop_id),
|
SPA_PROP_INFO_id, SPA_POD_Id(prop_id),
|
||||||
SPA_PROP_INFO_type, SPA_POD_CHOICE_STEP_Int(
|
SPA_PROP_INFO_type, SPA_POD_CHOICE_STEP_Int(
|
||||||
|
|
@ -1203,7 +1209,7 @@ spa_v4l2_enum_controls(struct impl *this, int seq,
|
||||||
break;
|
break;
|
||||||
case V4L2_CTRL_TYPE_BOOLEAN:
|
case V4L2_CTRL_TYPE_BOOLEAN:
|
||||||
port->controls[port->n_controls].type = SPA_TYPE_Bool;
|
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_TYPE_OBJECT_PropInfo, SPA_PARAM_PropInfo,
|
||||||
SPA_PROP_INFO_id, SPA_POD_Id(prop_id),
|
SPA_PROP_INFO_id, SPA_POD_Id(prop_id),
|
||||||
SPA_PROP_INFO_type, SPA_POD_CHOICE_Bool((bool)queryctrl.default_value),
|
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:
|
case V4L2_CTRL_TYPE_MENU:
|
||||||
{
|
{
|
||||||
struct v4l2_querymenu querymenu;
|
struct v4l2_querymenu querymenu;
|
||||||
struct spa_pod_builder_state state;
|
|
||||||
|
|
||||||
port->controls[port->n_controls].type = SPA_TYPE_Int;
|
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_push_object(&b.b, &f[0], SPA_TYPE_OBJECT_PropInfo, SPA_PARAM_PropInfo);
|
||||||
spa_pod_builder_add(&b,
|
spa_pod_builder_add(&b.b,
|
||||||
SPA_PROP_INFO_id, SPA_POD_Id(prop_id),
|
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_type, SPA_POD_CHOICE_ENUM_Int(1, (int32_t)queryctrl.default_value),
|
||||||
SPA_PROP_INFO_description, SPA_POD_String(queryctrl.name),
|
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);
|
spa_zero(querymenu);
|
||||||
querymenu.id = queryctrl.id;
|
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.b, &f[1]);
|
||||||
spa_pod_builder_push_struct(&b, &f[1]);
|
|
||||||
for (querymenu.index = queryctrl.minimum;
|
for (querymenu.index = queryctrl.minimum;
|
||||||
querymenu.index <= queryctrl.maximum;
|
querymenu.index <= queryctrl.maximum;
|
||||||
querymenu.index++) {
|
querymenu.index++) {
|
||||||
if (xioctl(dev->fd, VIDIOC_QUERYMENU, &querymenu) == 0) {
|
if (xioctl(dev->fd, VIDIOC_QUERYMENU, &querymenu) == 0) {
|
||||||
spa_pod_builder_int(&b, querymenu.index);
|
spa_pod_builder_int(&b.b, querymenu.index);
|
||||||
spa_pod_builder_string(&b, (const char *)querymenu.name);
|
spa_pod_builder_string(&b.b, (const char *)querymenu.name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (spa_pod_builder_pop(&b, &f[1]) == NULL) {
|
spa_pod_builder_pop(&b.b, &f[1]);
|
||||||
spa_log_warn(this->log, "can't create Control '%s' overflow %d",
|
param = spa_pod_builder_pop(&b.b, &f[0]);
|
||||||
queryctrl.name, b.state.offset);
|
|
||||||
spa_pod_builder_reset(&b, &state);
|
|
||||||
spa_pod_builder_none(&b);
|
|
||||||
}
|
|
||||||
param = spa_pod_builder_pop(&b, &f[0]);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case V4L2_CTRL_TYPE_INTEGER_MENU:
|
case V4L2_CTRL_TYPE_INTEGER_MENU:
|
||||||
|
|
@ -1258,7 +1257,7 @@ spa_v4l2_enum_controls(struct impl *this, int seq,
|
||||||
|
|
||||||
port->n_controls++;
|
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;
|
goto next;
|
||||||
|
|
||||||
spa_node_emit_result(&this->hooks, seq, 0, SPA_RESULT_TYPE_NODE_PARAMS, &result);
|
spa_node_emit_result(&this->hooks, seq, 0, SPA_RESULT_TYPE_NODE_PARAMS, &result);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue