work on port-update control message

Serialize format and properties.
Simplify the properties by moving the unset-mask inside the property
structure. We can then also just use the index of the property as the
bit in the mask.
Work on stopping on disconnect
This commit is contained in:
Wim Taymans 2016-08-08 22:10:57 +02:00
parent de53315f6e
commit 0d2f5a1386
24 changed files with 318 additions and 238 deletions

View file

@ -23,11 +23,16 @@ static SpaFormat *
format_copy (SpaFormat *format) format_copy (SpaFormat *format)
{ {
SpaMemory *mem; SpaMemory *mem;
SpaFormat *f;
if (format == NULL) if (format == NULL)
return NULL; return NULL;
mem = spa_memory_alloc_size (format->mem.mem.pool_id, format, format->mem.size); mem = spa_memory_alloc_size (format->mem.mem.pool_id, format, format->mem.size);
f = spa_memory_ensure_ptr (mem);
f->mem.mem = mem->mem;
f->mem.offset = 0;
f->mem.size = format->mem.size;
return spa_memory_ensure_ptr (mem); return spa_memory_ensure_ptr (mem);
} }

View file

@ -864,6 +864,23 @@ unhandle_socket (PinosStream *stream)
} }
} }
typedef struct {
SpaProps props;
uint32_t unset_mask;
char target_node[64];
} PortProps;
static const SpaPropInfo port_props_info[] =
{
{ 0, "pinos.target.node", "The pinos target node",
SPA_PROP_FLAG_READWRITE,
SPA_PROP_TYPE_STRING, 64,
0, NULL,
SPA_PROP_RANGE_TYPE_NONE, 0, NULL,
NULL,
offsetof (PortProps, target_node) },
};
static void static void
do_node_init (PinosStream *stream) do_node_init (PinosStream *stream)
{ {
@ -872,6 +889,7 @@ do_node_init (PinosStream *stream)
SpaControlCmdPortUpdate pu; SpaControlCmdPortUpdate pu;
SpaControlBuilder builder; SpaControlBuilder builder;
SpaControl control; SpaControl control;
PortProps port_props;
control_builder_init (stream, &builder); control_builder_init (stream, &builder);
nu.change_mask = SPA_CONTROL_CMD_NODE_UPDATE_MAX_INPUTS | nu.change_mask = SPA_CONTROL_CMD_NODE_UPDATE_MAX_INPUTS |
@ -881,6 +899,11 @@ do_node_init (PinosStream *stream)
nu.props = NULL; nu.props = NULL;
spa_control_builder_add_cmd (&builder, SPA_CONTROL_CMD_NODE_UPDATE, &nu); spa_control_builder_add_cmd (&builder, SPA_CONTROL_CMD_NODE_UPDATE, &nu);
port_props.props.n_prop_info = SPA_N_ELEMENTS (port_props_info);
port_props.props.prop_info = port_props_info;
strncpy (port_props.target_node, priv->path, 64);
port_props.target_node[63] = '\0';
pu.port_id = 0; pu.port_id = 0;
pu.change_mask = SPA_CONTROL_CMD_PORT_UPDATE_DIRECTION | pu.change_mask = SPA_CONTROL_CMD_PORT_UPDATE_DIRECTION |
SPA_CONTROL_CMD_PORT_UPDATE_POSSIBLE_FORMATS | SPA_CONTROL_CMD_PORT_UPDATE_POSSIBLE_FORMATS |
@ -889,7 +912,7 @@ do_node_init (PinosStream *stream)
pu.direction = priv->direction; pu.direction = priv->direction;
pu.n_possible_formats = priv->possible_formats->len; pu.n_possible_formats = priv->possible_formats->len;
pu.possible_formats = (const SpaFormat **)priv->possible_formats->pdata; pu.possible_formats = (const SpaFormat **)priv->possible_formats->pdata;
pu.props = NULL; pu.props = &port_props.props;
pu.info = &priv->port_info; pu.info = &priv->port_info;
priv->port_info.flags = SPA_PORT_INFO_FLAG_NONE | priv->port_info.flags = SPA_PORT_INFO_FLAG_NONE |
SPA_PORT_INFO_FLAG_CAN_USE_BUFFERS; SPA_PORT_INFO_FLAG_CAN_USE_BUFFERS;
@ -1050,9 +1073,9 @@ pinos_stream_connect (PinosStream *stream,
priv->direction = direction; priv->direction = direction;
g_free (priv->path); g_free (priv->path);
priv->path = g_strdup (port_path); priv->path = g_strdup (port_path);
priv->flags = flags;
if (priv->possible_formats) if (priv->possible_formats)
g_ptr_array_unref (priv->possible_formats); g_ptr_array_unref (priv->possible_formats);
priv->flags = flags;
priv->possible_formats = possible_formats; priv->possible_formats = possible_formats;
stream_set_state (stream, PINOS_STREAM_STATE_CONNECTING, NULL); stream_set_state (stream, PINOS_STREAM_STATE_CONNECTING, NULL);

View file

@ -42,8 +42,6 @@ main (gint argc, gchar *argv[])
props = pinos_properties_new ("test", "test", NULL); props = pinos_properties_new ("test", "test", NULL);
daemon = pinos_daemon_new (props); daemon = pinos_daemon_new (props);
pinos_gst_manager_new (daemon);
factory = pinos_gst_node_factory_new ("gst-node-factory"); factory = pinos_gst_node_factory_new ("gst-node-factory");
pinos_daemon_add_node_factory (daemon, factory); pinos_daemon_add_node_factory (daemon, factory);

View file

@ -55,7 +55,7 @@ convert_1 (GstCapsFeatures *cf, GstStructure *cs)
if (!gst_structure_get_int (cs, "height", &i)) if (!gst_structure_get_int (cs, "height", &i))
goto done; goto done;
f->info.size.height = i; f->info.size.height = i;
f->unset_mask = 0; f->format.props.unset_mask = 0;
res = &f->format; res = &f->format;
} else if (gst_structure_has_name (cs, "audio/x-raw")) { } else if (gst_structure_has_name (cs, "audio/x-raw")) {
@ -81,7 +81,7 @@ convert_1 (GstCapsFeatures *cf, GstStructure *cs)
if (!gst_structure_get_int (cs, "channels", &i)) if (!gst_structure_get_int (cs, "channels", &i))
goto done; goto done;
f->info.channels = i; f->info.channels = i;
f->unset_mask = 0; f->format.props.unset_mask = 0;
res = &f->format; res = &f->format;
} }
@ -150,6 +150,7 @@ gst_caps_from_format (SpaFormat *format)
"format", G_TYPE_STRING, gst_video_format_to_string (f.info.format), "format", G_TYPE_STRING, gst_video_format_to_string (f.info.format),
"width", G_TYPE_INT, f.info.size.width, "width", G_TYPE_INT, f.info.size.width,
"height", G_TYPE_INT, f.info.size.height, "height", G_TYPE_INT, f.info.size.height,
"framerate", GST_TYPE_FRACTION, f.info.framerate.num, f.info.framerate.denom,
NULL); NULL);
} }
} else if (format->media_type == SPA_MEDIA_TYPE_AUDIO) { } else if (format->media_type == SPA_MEDIA_TYPE_AUDIO) {

View file

@ -290,7 +290,7 @@ on_node_event (SpaNode *node, SpaEvent *event, void *user_data)
target = pinos_daemon_find_port (pinos_node_get_daemon (pnode), target = pinos_daemon_find_port (pinos_node_get_daemon (pnode),
pinos_direction_reverse (pa->direction), pinos_direction_reverse (pa->direction),
"/org/pinos/node_8", "/org/pinos/node_1",
NULL, NULL,
NULL, NULL,
&error); &error);

View file

@ -182,6 +182,18 @@ no_node:
} }
} }
static void
on_port_added (PinosNode *node, PinosPort *port, PinosClient *client)
{
pinos_client_add_object (client, G_OBJECT (port));
}
static void
on_port_removed (PinosNode *node, PinosPort *port, PinosClient *client)
{
pinos_client_remove_object (client, G_OBJECT (port));
}
static gboolean static gboolean
handle_create_client_node (PinosDaemon1 *interface, handle_create_client_node (PinosDaemon1 *interface,
GDBusMethodInvocation *invocation, GDBusMethodInvocation *invocation,
@ -216,6 +228,9 @@ handle_create_client_node (PinosDaemon1 *interface,
client = sender_get_client (daemon, sender); client = sender_get_client (daemon, sender);
pinos_client_add_object (client, G_OBJECT (node)); pinos_client_add_object (client, G_OBJECT (node));
g_signal_connect (node, "port-added", (GCallback) on_port_added, client);
g_signal_connect (node, "port-removed", (GCallback) on_port_removed, client);
object_path = pinos_node_get_object_path (PINOS_NODE (node)); object_path = pinos_node_get_object_path (PINOS_NODE (node));
g_debug ("daemon %p: add client-node %p, %s", daemon, node, object_path); g_debug ("daemon %p: add client-node %p, %s", daemon, node, object_path);

View file

@ -174,13 +174,13 @@ pinos_link_set_property (GObject *_object,
break; break;
case PROP_OUTPUT: case PROP_OUTPUT:
priv->output = g_value_dup_object (value); priv->output = g_value_get_object (value);
priv->output_node = priv->output->node->node; priv->output_node = priv->output->node->node;
priv->output_port = priv->output->id; priv->output_port = priv->output->id;
break; break;
case PROP_INPUT: case PROP_INPUT:
priv->input = g_value_dup_object (value); priv->input = g_value_get_object (value);
priv->input_node = priv->input->node->node; priv->input_node = priv->input->node->node;
priv->input_port = priv->input->id; priv->input_port = priv->input->id;
break; break;
@ -277,7 +277,7 @@ do_negotiate (PinosLink *this)
value.type = SPA_PROP_TYPE_FRACTION; value.type = SPA_PROP_TYPE_FRACTION;
value.size = sizeof (SpaFraction); value.size = sizeof (SpaFraction);
value.value = &frac; value.value = &frac;
frac.num = 25; frac.num = 20;
frac.denom = 1; frac.denom = 1;
if ((res = spa_props_set_prop (props, spa_props_index_for_id (props, SPA_PROP_ID_VIDEO_FRAMERATE), &value)) < 0) if ((res = spa_props_set_prop (props, spa_props_index_for_id (props, SPA_PROP_ID_VIDEO_FRAMERATE), &value)) < 0)
return res; return res;
@ -334,12 +334,12 @@ on_activate (PinosPort *port, gpointer user_data)
if (priv->active) if (priv->active)
return TRUE; return TRUE;
priv->active = TRUE;
if (priv->input == port) if (priv->input == port)
pinos_port_activate (priv->output); pinos_port_activate (priv->output);
else else
pinos_port_activate (priv->input); pinos_port_activate (priv->input);
priv->active = TRUE;
if (!priv->negotiated) if (!priv->negotiated)
do_negotiate (this); do_negotiate (this);
@ -367,12 +367,12 @@ on_deactivate (PinosPort *port, gpointer user_data)
if (!priv->active) if (!priv->active)
return TRUE; return TRUE;
priv->active = FALSE;
if (priv->input == port) if (priv->input == port)
pinos_port_deactivate (priv->output); pinos_port_deactivate (priv->output);
else else
pinos_port_deactivate (priv->input); pinos_port_deactivate (priv->input);
priv->active = FALSE;
cmd.type = SPA_COMMAND_STOP; cmd.type = SPA_COMMAND_STOP;
if ((res = spa_node_send_command (priv->input_node, &cmd)) < 0) if ((res = spa_node_send_command (priv->input_node, &cmd)) < 0)

View file

@ -69,6 +69,8 @@ enum
enum enum
{ {
SIGNAL_REMOVE, SIGNAL_REMOVE,
SIGNAL_PORT_ADDED,
SIGNAL_PORT_REMOVED,
LAST_SIGNAL LAST_SIGNAL
}; };
@ -105,6 +107,7 @@ node_add_port (PinosNode *node,
if (port) { if (port) {
g_hash_table_insert (priv->ports, GUINT_TO_POINTER (id), port); g_hash_table_insert (priv->ports, GUINT_TO_POINTER (id), port);
g_signal_connect (port, "remove", (GCallback) do_remove_port, node); g_signal_connect (port, "remove", (GCallback) do_remove_port, node);
g_signal_emit (node, signals[SIGNAL_PORT_ADDED], 0, port);
} }
return port; return port;
} }
@ -114,8 +117,14 @@ node_remove_port (PinosNode *node,
guint id) guint id)
{ {
PinosNodePrivate *priv = node->priv; PinosNodePrivate *priv = node->priv;
PinosPort *port;
g_debug ("node %p: removed port %u", node, id); g_debug ("node %p: removed port %u", node, id);
g_hash_table_remove (priv->ports, GUINT_TO_POINTER (id)); port = g_hash_table_lookup (priv->ports, GUINT_TO_POINTER (id));
if (port) {
g_signal_emit (node, signals[SIGNAL_PORT_REMOVED], 0, port);
g_hash_table_remove (priv->ports, GUINT_TO_POINTER (id));
}
return TRUE; return TRUE;
} }
@ -497,6 +506,26 @@ pinos_node_class_init (PinosNodeClass * klass)
G_TYPE_NONE, G_TYPE_NONE,
0, 0,
G_TYPE_NONE); G_TYPE_NONE);
signals[SIGNAL_PORT_ADDED] = g_signal_new ("port-added",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
0,
NULL,
NULL,
g_cclosure_marshal_generic,
G_TYPE_NONE,
0,
PINOS_TYPE_PORT);
signals[SIGNAL_PORT_REMOVED] = g_signal_new ("port-removed",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
0,
NULL,
NULL,
g_cclosure_marshal_generic,
G_TYPE_NONE,
0,
PINOS_TYPE_PORT);
node_class->set_state = node_set_state; node_class->set_state = node_set_state;
node_class->add_port = node_add_port; node_class->add_port = node_add_port;
@ -522,7 +551,10 @@ pinos_node_init (PinosNode * node)
priv->state = PINOS_NODE_STATE_SUSPENDED; priv->state = PINOS_NODE_STATE_SUSPENDED;
pinos_node1_set_state (priv->iface, PINOS_NODE_STATE_SUSPENDED); pinos_node1_set_state (priv->iface, PINOS_NODE_STATE_SUSPENDED);
priv->ports = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, (GDestroyNotify) g_object_unref); priv->ports = g_hash_table_new_full (g_direct_hash,
g_direct_equal,
NULL,
(GDestroyNotify) g_object_unref);
} }
/** /**

View file

@ -273,8 +273,11 @@ static void
pinos_port_dispose (GObject * object) pinos_port_dispose (GObject * object)
{ {
PinosPort *port = PINOS_PORT (object); PinosPort *port = PINOS_PORT (object);
PinosPortPrivate *priv = port->priv;
g_debug ("port %p: dispose", port); g_debug ("port %p: dispose %d", port, priv->active_count);
if (priv->active_count == 1)
g_signal_emit (port, signals[SIGNAL_DEACTIVATE], 0, NULL);
G_OBJECT_CLASS (pinos_port_parent_class)->dispose (object); G_OBJECT_CLASS (pinos_port_parent_class)->dispose (object);
} }
@ -437,7 +440,7 @@ pinos_port_class_init (PinosPortClass * klass)
static void static void
pinos_port_init (PinosPort * port) pinos_port_init (PinosPort * port)
{ {
PinosPortPrivate *priv = port->priv = PINOS_PORT_GET_PRIVATE (port); port->priv = PINOS_PORT_GET_PRIVATE (port);
g_debug ("port %p: new", port); g_debug ("port %p: new", port);
port->direction = PINOS_DIRECTION_INVALID; port->direction = PINOS_DIRECTION_INVALID;

View file

@ -41,7 +41,6 @@ typedef enum {
struct _SpaAudioRawFormat { struct _SpaAudioRawFormat {
SpaFormat format; SpaFormat format;
uint32_t unset_mask;
SpaAudioRawInfo info; SpaAudioRawInfo info;
}; };

View file

@ -144,9 +144,6 @@ typedef struct {
const SpaPropRangeInfo *range_values; const SpaPropRangeInfo *range_values;
const char **tags; const char **tags;
size_t offset; size_t offset;
size_t mask_offset;
uint32_t unset_mask;
const void *priv;
} SpaPropInfo; } SpaPropInfo;
typedef struct { typedef struct {
@ -160,12 +157,14 @@ typedef struct {
* @n_prop_info: number of elements in @prop_info * @n_prop_info: number of elements in @prop_info
* @prop_info: array of #SpaPropInfo. Contains info about the * @prop_info: array of #SpaPropInfo. Contains info about the
* properties. Can be %NULL when unspecified. * properties. Can be %NULL when unspecified.
* @unset_mask: mask of unset properties
* *
* Generic propertiers. * Generic propertiers.
*/ */
struct _SpaProps { struct _SpaProps {
unsigned int n_prop_info; unsigned int n_prop_info;
const SpaPropInfo *prop_info; const SpaPropInfo *prop_info;
uint32_t unset_mask;
}; };
static inline unsigned int static inline unsigned int

View file

@ -49,7 +49,6 @@ typedef enum {
struct _SpaVideoRawFormat { struct _SpaVideoRawFormat {
SpaFormat format; SpaFormat format;
uint32_t unset_mask;
SpaVideoRawInfo info; SpaVideoRawInfo info;
}; };

View file

@ -143,63 +143,49 @@ static const SpaPropInfo raw_format_prop_info[] =
sizeof (uint32_t), &default_info.format, sizeof (uint32_t), &default_info.format,
SPA_PROP_RANGE_TYPE_ENUM, SPA_N_ELEMENTS (format_format_range), format_format_range, SPA_PROP_RANGE_TYPE_ENUM, SPA_N_ELEMENTS (format_format_range), format_format_range,
NULL, NULL,
offsetof (SpaAudioRawFormat, info.format), offsetof (SpaAudioRawFormat, info.format) },
offsetof (SpaAudioRawFormat, unset_mask), 1 << 0,
NULL },
{ SPA_PROP_ID_AUDIO_FLAGS, "flags", "Sample Flags", { SPA_PROP_ID_AUDIO_FLAGS, "flags", "Sample Flags",
SPA_PROP_FLAG_READWRITE, SPA_PROP_FLAG_READWRITE,
SPA_PROP_TYPE_UINT32, sizeof (uint32_t), SPA_PROP_TYPE_UINT32, sizeof (uint32_t),
sizeof (uint32_t), &default_info.flags, sizeof (uint32_t), &default_info.flags,
SPA_PROP_RANGE_TYPE_FLAGS, SPA_N_ELEMENTS (flags_range), flags_range, SPA_PROP_RANGE_TYPE_FLAGS, SPA_N_ELEMENTS (flags_range), flags_range,
NULL, NULL,
offsetof (SpaAudioRawFormat, info.flags), offsetof (SpaAudioRawFormat, info.flags) },
offsetof (SpaAudioRawFormat, unset_mask), 1 << 1,
NULL },
{ SPA_PROP_ID_AUDIO_LAYOUT, "layout", "Sample Layout", { SPA_PROP_ID_AUDIO_LAYOUT, "layout", "Sample Layout",
SPA_PROP_FLAG_READWRITE, SPA_PROP_FLAG_READWRITE,
SPA_PROP_TYPE_UINT32, sizeof (uint32_t), SPA_PROP_TYPE_UINT32, sizeof (uint32_t),
sizeof (uint32_t), &default_info.layout, sizeof (uint32_t), &default_info.layout,
SPA_PROP_RANGE_TYPE_ENUM, SPA_N_ELEMENTS (layouts_range), layouts_range, SPA_PROP_RANGE_TYPE_ENUM, SPA_N_ELEMENTS (layouts_range), layouts_range,
NULL, NULL,
offsetof (SpaAudioRawFormat, info.layout), offsetof (SpaAudioRawFormat, info.layout) },
offsetof (SpaAudioRawFormat, unset_mask), 1 << 2,
NULL },
{ SPA_PROP_ID_AUDIO_RATE, "rate", "Audio sample rate", { SPA_PROP_ID_AUDIO_RATE, "rate", "Audio sample rate",
SPA_PROP_FLAG_READWRITE, SPA_PROP_FLAG_READWRITE,
SPA_PROP_TYPE_UINT32, sizeof (uint32_t), SPA_PROP_TYPE_UINT32, sizeof (uint32_t),
sizeof (uint32_t), &default_info.rate, sizeof (uint32_t), &default_info.rate,
SPA_PROP_RANGE_TYPE_MIN_MAX, 2, uint32_range, SPA_PROP_RANGE_TYPE_MIN_MAX, 2, uint32_range,
NULL, NULL,
offsetof (SpaAudioRawFormat, info.rate), offsetof (SpaAudioRawFormat, info.rate) },
offsetof (SpaAudioRawFormat, unset_mask), 1 << 3,
NULL },
{ SPA_PROP_ID_AUDIO_CHANNELS, "channels", "Audio channels", { SPA_PROP_ID_AUDIO_CHANNELS, "channels", "Audio channels",
SPA_PROP_FLAG_READWRITE, SPA_PROP_FLAG_READWRITE,
SPA_PROP_TYPE_UINT32, sizeof (uint32_t), SPA_PROP_TYPE_UINT32, sizeof (uint32_t),
sizeof (uint32_t), &default_info.channels, sizeof (uint32_t), &default_info.channels,
SPA_PROP_RANGE_TYPE_MIN_MAX, 2, uint32_range, SPA_PROP_RANGE_TYPE_MIN_MAX, 2, uint32_range,
NULL, NULL,
offsetof (SpaAudioRawFormat, info.channels), offsetof (SpaAudioRawFormat, info.channels) },
offsetof (SpaAudioRawFormat, unset_mask), 1 << 4,
NULL },
{ SPA_PROP_ID_AUDIO_CHANNEL_MASK, "channel-mask", "Audio channel mask", { SPA_PROP_ID_AUDIO_CHANNEL_MASK, "channel-mask", "Audio channel mask",
SPA_PROP_FLAG_READWRITE, SPA_PROP_FLAG_READWRITE,
SPA_PROP_TYPE_BITMASK, sizeof (uint32_t), SPA_PROP_TYPE_BITMASK, sizeof (uint32_t),
sizeof (uint32_t), &default_info.channel_mask, sizeof (uint32_t), &default_info.channel_mask,
SPA_PROP_RANGE_TYPE_NONE, 0, NULL, SPA_PROP_RANGE_TYPE_NONE, 0, NULL,
NULL, NULL,
offsetof (SpaAudioRawFormat, info.channel_mask), offsetof (SpaAudioRawFormat, info.channel_mask) },
offsetof (SpaAudioRawFormat, unset_mask), 1 << 5,
NULL },
{ SPA_PROP_ID_AUDIO_RAW_INFO, "info", "the SpaAudioRawInfo structure", { SPA_PROP_ID_AUDIO_RAW_INFO, "info", "the SpaAudioRawInfo structure",
SPA_PROP_FLAG_READWRITE, SPA_PROP_FLAG_READWRITE,
SPA_PROP_TYPE_POINTER, sizeof (SpaAudioRawInfo), SPA_PROP_TYPE_POINTER, sizeof (SpaAudioRawInfo),
0, NULL, 0, NULL,
SPA_PROP_RANGE_TYPE_NONE, 0, NULL, SPA_PROP_RANGE_TYPE_NONE, 0, NULL,
NULL, NULL,
offsetof (SpaAudioRawFormat, info), offsetof (SpaAudioRawFormat, info) },
offsetof (SpaAudioRawFormat, unset_mask), ~0,
NULL },
}; };
SpaResult SpaResult
@ -209,7 +195,7 @@ spa_audio_raw_format_init (SpaAudioRawFormat *format)
format->format.media_subtype = SPA_MEDIA_SUBTYPE_RAW; format->format.media_subtype = SPA_MEDIA_SUBTYPE_RAW;
format->format.props.n_prop_info = SPA_N_ELEMENTS (raw_format_prop_info); format->format.props.n_prop_info = SPA_N_ELEMENTS (raw_format_prop_info);
format->format.props.prop_info = raw_format_prop_info; format->format.props.prop_info = raw_format_prop_info;
format->unset_mask = (1 << 0) | (1 << 2) | (1 << 3) | (1 << 4); format->format.props.unset_mask = (1 << 0) | (1 << 2) | (1 << 3) | (1 << 4);
format->info = default_info; format->info = default_info;
return SPA_RESULT_OK; return SPA_RESULT_OK;

View file

@ -340,24 +340,15 @@ spa_control_iter_get_data (SpaControlIter *iter, size_t *size)
return si->data; return si->data;
} }
static void static SpaProps *
iter_parse_set_format (struct stack_iter *si, SpaControlCmdSetFormat *cmd) parse_props (SpaMemory *mem, void *p, off_t offset)
{ {
uint32_t *p = si->data;
SpaProps *tp; SpaProps *tp;
unsigned int i, j; unsigned int i, j;
SpaPropInfo *pi; SpaPropInfo *pi;
SpaPropRangeInfo *ri; SpaPropRangeInfo *ri;
SpaMemory *mem;
cmd->port_id = *p++; tp = SPA_MEMBER (p, offset, SpaProps);
mem = spa_memory_alloc_size (SPA_MEMORY_POOL_LOCAL, p, si->size - 4);
cmd->format = spa_memory_ensure_ptr (mem);
cmd->format->mem.mem = mem->mem;
cmd->format->mem.offset = 0;
cmd->format->mem.size = mem->size;
tp = (SpaProps *) &cmd->format->props;
tp->prop_info = SPA_MEMBER (tp, SPA_PTR_TO_INT (tp->prop_info), SpaPropInfo); tp->prop_info = SPA_MEMBER (tp, SPA_PTR_TO_INT (tp->prop_info), SpaPropInfo);
/* now fix all the pointers */ /* now fix all the pointers */
@ -382,8 +373,66 @@ iter_parse_set_format (struct stack_iter *si, SpaControlCmdSetFormat *cmd)
ri->value = SPA_MEMBER (tp, SPA_PTR_TO_INT (ri->value), void); ri->value = SPA_MEMBER (tp, SPA_PTR_TO_INT (ri->value), void);
} }
} }
return tp;
} }
static SpaFormat *
parse_format (SpaMemory *mem, void *p, off_t offset)
{
SpaFormat *f;
if (offset == 0)
return NULL;
f = SPA_MEMBER (p, offset, SpaFormat);
f->mem.mem = mem->mem;
f->mem.offset = offset;
f->mem.size = mem->size - offset;
parse_props (mem, f, offsetof (SpaFormat, props));
return f;
}
static void
iter_parse_port_update (struct stack_iter *si, SpaControlCmdPortUpdate *pu)
{
void *p;
SpaMemory *mem;
unsigned int i;
memcpy (pu, si->data, sizeof (SpaControlCmdPortUpdate));
mem = spa_memory_alloc_size (SPA_MEMORY_POOL_LOCAL, si->data, si->size);
p = spa_memory_ensure_ptr (mem);
if (pu->possible_formats)
pu->possible_formats = SPA_MEMBER (p,
SPA_PTR_TO_INT (pu->possible_formats), const SpaFormat *);
for (i = 0; i < pu->n_possible_formats; i++) {
pu->possible_formats[i] = parse_format (mem, p,
SPA_PTR_TO_INT (pu->possible_formats[i]));
}
if (pu->props)
pu->props = parse_props (mem, p, SPA_PTR_TO_INT (pu->props));
if (pu->info)
pu->info = SPA_MEMBER (p, SPA_PTR_TO_INT (pu->info), SpaPortInfo);
}
static void
iter_parse_set_format (struct stack_iter *si, SpaControlCmdSetFormat *cmd)
{
void *p;
SpaMemory *mem;
memcpy (cmd, si->data, sizeof (SpaControlCmdSetFormat));
mem = spa_memory_alloc_size (SPA_MEMORY_POOL_LOCAL, si->data, si->size);
p = spa_memory_ensure_ptr (mem);
cmd->format = parse_format (mem, p, SPA_PTR_TO_INT (cmd->format));
}
SpaResult SpaResult
spa_control_iter_parse_cmd (SpaControlIter *iter, spa_control_iter_parse_cmd (SpaControlIter *iter,
@ -402,9 +451,7 @@ spa_control_iter_parse_cmd (SpaControlIter *iter,
break; break;
case SPA_CONTROL_CMD_PORT_UPDATE: case SPA_CONTROL_CMD_PORT_UPDATE:
if (si->size < sizeof (SpaControlCmdPortUpdate)) iter_parse_port_update (si, command);
return SPA_RESULT_ERROR;
memcpy (command, si->data, sizeof (SpaControlCmdPortUpdate));
break; break;
case SPA_CONTROL_CMD_PORT_REMOVED: case SPA_CONTROL_CMD_PORT_REMOVED:
@ -449,10 +496,8 @@ spa_control_iter_parse_cmd (SpaControlIter *iter,
break; break;
case SPA_CONTROL_CMD_SET_FORMAT: case SPA_CONTROL_CMD_SET_FORMAT:
{
iter_parse_set_format (si, command); iter_parse_set_format (si, command);
break; break;
}
case SPA_CONTROL_CMD_SET_PROPERTY: case SPA_CONTROL_CMD_SET_PROPERTY:
fprintf (stderr, "implement iter of %d\n", si->cmd); fprintf (stderr, "implement iter of %d\n", si->cmd);
@ -735,6 +780,9 @@ calc_props_len (const SpaProps *props)
SpaPropInfo *pi; SpaPropInfo *pi;
SpaPropRangeInfo *ri; SpaPropRangeInfo *ri;
if (props == NULL)
return 0;
/* props and unset mask */ /* props and unset mask */
len = sizeof (SpaProps) + sizeof (uint32_t); len = sizeof (SpaProps) + sizeof (uint32_t);
for (i = 0; i < props->n_prop_info; i++) { for (i = 0; i < props->n_prop_info; i++) {
@ -757,59 +805,22 @@ calc_props_len (const SpaProps *props)
} }
static size_t static size_t
calc_format_len (const SpaFormat *format) write_props (void *p, const SpaProps *props, off_t offset)
{
return calc_props_len (&format->props) - sizeof (SpaProps) + sizeof (SpaFormat);
}
static void
builder_add_port_update (struct stack_builder *sb, SpaControlCmdPortUpdate *pu)
{
size_t len;
void *base;
/* calc len */
len = sizeof (SpaControlCmdPortUpdate);
base = builder_add_cmd (sb, SPA_CONTROL_CMD_PORT_UPDATE, len);
memcpy (base, pu, sizeof (SpaControlCmdPortUpdate));
/* FIXME add more things */
}
static void
builder_add_set_format (struct stack_builder *sb, SpaControlCmdSetFormat *sf)
{ {
size_t len, slen; size_t len, slen;
unsigned int i, j; unsigned int i, j;
void *p, *base;
SpaFormat *tf;
SpaProps *tp; SpaProps *tp;
const SpaProps *sp;
SpaPropInfo *pi, *bpi; SpaPropInfo *pi, *bpi;
SpaPropRangeInfo *ri, *bri; SpaPropRangeInfo *ri, *bri;
sp = &sf->format->props; tp = p;
memcpy (tp, props, sizeof (SpaProps));
tp->prop_info = SPA_INT_TO_PTR (offset + sizeof (uint32_t));
/* calculate length */ /* write propinfo array */
/* port_id + format + mask */ bpi = pi = SPA_MEMBER (tp, SPA_PTR_TO_INT (tp->prop_info), SpaPropInfo);
len = sizeof (uint32_t) + calc_format_len (sf->format);
base = builder_add_cmd (sb, SPA_CONTROL_CMD_SET_FORMAT, len);
memcpy (base, &sf->port_id, sizeof (uint32_t));
tf = SPA_MEMBER (base, sizeof (uint32_t), SpaFormat);
tf->media_type = sf->format->media_type;
tf->media_subtype = sf->format->media_subtype;
tp = SPA_MEMBER (tf, offsetof (SpaFormat, props), SpaProps);
tp->n_prop_info = sp->n_prop_info;
tp->prop_info = SPA_INT_TO_PTR (sizeof (SpaFormat) + sizeof (uint32_t));
/* write propinfo array, adjust offset of mask */
bpi = pi = (SpaPropInfo *) ((uint8_t *)tp + sizeof (SpaFormat) + sizeof (uint32_t));
for (i = 0; i < tp->n_prop_info; i++) { for (i = 0; i < tp->n_prop_info; i++) {
memcpy (pi, &sp->prop_info[i], sizeof (SpaPropInfo)); memcpy (pi, &props->prop_info[i], sizeof (SpaPropInfo));
pi->mask_offset = sizeof (SpaFormat);
pi->priv = NULL;
pi++; pi++;
} }
bri = ri = (SpaPropRangeInfo *) pi; bri = ri = (SpaPropRangeInfo *) pi;
@ -818,7 +829,7 @@ builder_add_set_format (struct stack_builder *sb, SpaControlCmdSetFormat *sf)
for (i = 0; i < tp->n_prop_info; i++) { for (i = 0; i < tp->n_prop_info; i++) {
pi->range_values = SPA_INT_TO_PTR (SPA_PTRDIFF (ri, tp)); pi->range_values = SPA_INT_TO_PTR (SPA_PTRDIFF (ri, tp));
for (j = 0; j < pi->n_range_values; j++) { for (j = 0; j < pi->n_range_values; j++) {
memcpy (ri, &sp->prop_info[i].range_values[j], sizeof (SpaPropRangeInfo)); memcpy (ri, &props->prop_info[i].range_values[j], sizeof (SpaPropRangeInfo));
ri++; ri++;
} }
pi++; pi++;
@ -883,7 +894,7 @@ builder_add_set_format (struct stack_builder *sb, SpaControlCmdSetFormat *sf)
pi = bpi; pi = bpi;
for (i = 0; i < tp->n_prop_info; i++) { for (i = 0; i < tp->n_prop_info; i++) {
if (pi->offset) { if (pi->offset) {
memcpy (p, SPA_MEMBER (sp, pi->offset, void), pi->maxsize); memcpy (p, SPA_MEMBER (props, pi->offset, void), pi->maxsize);
pi->offset = SPA_PTRDIFF (p, tp); pi->offset = SPA_PTRDIFF (p, tp);
p += pi->maxsize; p += pi->maxsize;
} else { } else {
@ -891,6 +902,95 @@ builder_add_set_format (struct stack_builder *sb, SpaControlCmdSetFormat *sf)
} }
pi++; pi++;
} }
len = SPA_PTRDIFF (p, tp);
return len;
}
static size_t
calc_format_len (const SpaFormat *format)
{
if (format == NULL)
return 0;
return calc_props_len (&format->props) - sizeof (SpaProps) + sizeof (SpaFormat);
}
static size_t
write_format (void *p, const SpaFormat *format)
{
SpaFormat *tf;
tf = p;
tf->media_type = format->media_type;
tf->media_subtype = format->media_subtype;
p = SPA_MEMBER (tf, offsetof (SpaFormat, props), void);
return write_props (p, &format->props, sizeof (SpaFormat));
}
static void
builder_add_port_update (struct stack_builder *sb, SpaControlCmdPortUpdate *pu)
{
size_t len;
void *p, *base;
int i;
SpaFormat **bfa;
SpaControlCmdPortUpdate *d;
/* calc len */
len = sizeof (SpaControlCmdPortUpdate);
len += pu->n_possible_formats * sizeof (SpaFormat *);
for (i = 0; i < pu->n_possible_formats; i++)
len += calc_format_len (pu->possible_formats[i]);
len += calc_props_len (pu->props);
base = builder_add_cmd (sb, SPA_CONTROL_CMD_PORT_UPDATE, len);
memcpy (base, pu, sizeof (SpaControlCmdPortUpdate));
d = base;
p = SPA_MEMBER (d, sizeof (SpaControlCmdPortUpdate), void);
bfa = p;
if (pu->n_possible_formats)
d->possible_formats = SPA_INT_TO_PTR (SPA_PTRDIFF (p, base));
else
d->possible_formats = 0;
p = SPA_MEMBER (p, sizeof (SpaFormat*) * pu->n_possible_formats, void);
for (i = 0; i < pu->n_possible_formats; i++) {
len = write_format (p, pu->possible_formats[i]);
bfa[i] = SPA_INT_TO_PTR (SPA_PTRDIFF (p, base));
p = SPA_MEMBER (p, len, void);
}
if (pu->props) {
len = write_props (p, pu->props, sizeof (SpaProps));
d->props = SPA_INT_TO_PTR (SPA_PTRDIFF (p, base));
p = SPA_MEMBER (p, len, void);
} else {
d->props = 0;
}
/* FIXME add more things */
}
static void
builder_add_set_format (struct stack_builder *sb, SpaControlCmdSetFormat *sf)
{
size_t len;
void *p, *base;
/* calculate length */
/* port_id + format + mask */
len = sizeof (SpaControlCmdSetFormat) + calc_format_len (sf->format);
base = builder_add_cmd (sb, SPA_CONTROL_CMD_SET_FORMAT, len);
memcpy (base, sf, sizeof (SpaControlCmdSetFormat));
sf = base;
p = SPA_MEMBER (sf, sizeof (SpaControlCmdSetFormat), void);
len = write_format (p, sf->format);
sf->format = SPA_INT_TO_PTR (SPA_PTRDIFF (p, sf));
} }
/** /**

View file

@ -248,7 +248,7 @@ print_value (const SpaPropInfo *info, int size, const void *value)
fprintf (stderr, "%" PRIu16, *(uint16_t *)value); fprintf (stderr, "%" PRIu16, *(uint16_t *)value);
break; break;
case SPA_PROP_TYPE_INT32: case SPA_PROP_TYPE_INT32:
fprintf (stderr, stderr, "%" PRIi32, *(int32_t *)value); fprintf (stderr, "%" PRIi32, *(int32_t *)value);
break; break;
case SPA_PROP_TYPE_UINT32: case SPA_PROP_TYPE_UINT32:
fprintf (stderr, "%" PRIu32, *(uint32_t *)value); fprintf (stderr, "%" PRIu32, *(uint32_t *)value);

View file

@ -47,10 +47,8 @@ spa_props_set_prop (SpaProps *props,
if (info->offset != 0) if (info->offset != 0)
memcpy ((uint8_t*)props + info->offset, value->value, value->size); memcpy ((uint8_t*)props + info->offset, value->value, value->size);
if (info->mask_offset != 0) { props->unset_mask &= ~(1 << index);
uint32_t *mask = (uint32_t *)((uint8_t *)props + info->mask_offset);
*mask &= ~info->unset_mask;
}
return SPA_RESULT_OK; return SPA_RESULT_OK;
} }
@ -71,11 +69,9 @@ spa_props_get_prop (const SpaProps *props,
if ((info->flags & SPA_PROP_FLAG_READABLE) == 0) if ((info->flags & SPA_PROP_FLAG_READABLE) == 0)
return SPA_RESULT_INVALID_PROPERTY_ACCESS; return SPA_RESULT_INVALID_PROPERTY_ACCESS;
if (info->mask_offset != 0) { if (props->unset_mask & (1 << index))
uint32_t *mask = (uint32_t *)((uint8_t *)props + info->mask_offset); return SPA_RESULT_PROPERTY_UNSET;
if ((*mask & info->unset_mask))
return SPA_RESULT_PROPERTY_UNSET;
}
value->type = info->type; value->type = info->type;
value->size = info->maxsize; value->size = info->maxsize;
if (info->offset != 0) if (info->offset != 0)
@ -109,10 +105,8 @@ spa_props_copy (const SpaProps *src,
if (info->offset) if (info->offset)
memcpy ((uint8_t*)dest + info->offset, value.value, value.size); memcpy ((uint8_t*)dest + info->offset, value.value, value.size);
if (info->mask_offset != 0) {
uint32_t *mask = (uint32_t *)((uint8_t *)dest + info->mask_offset); dest->unset_mask &= ~(1 << i);
*mask &= ~info->unset_mask;
}
} }
return SPA_RESULT_OK; return SPA_RESULT_OK;
} }

View file

@ -345,135 +345,105 @@ static const SpaPropInfo raw_format_prop_info[] =
sizeof (uint32_t), &default_info.format, sizeof (uint32_t), &default_info.format,
SPA_PROP_RANGE_TYPE_ENUM, SPA_N_ELEMENTS (format_range), format_range, SPA_PROP_RANGE_TYPE_ENUM, SPA_N_ELEMENTS (format_range), format_range,
NULL, NULL,
offsetof (SpaVideoRawFormat, info.format), offsetof (SpaVideoRawFormat, info.format) },
offsetof (SpaVideoRawFormat, unset_mask), 1 << 0,
NULL },
{ SPA_PROP_ID_VIDEO_SIZE, "size", "Video size", { SPA_PROP_ID_VIDEO_SIZE, "size", "Video size",
SPA_PROP_FLAG_READWRITE, SPA_PROP_FLAG_READWRITE,
SPA_PROP_TYPE_RECTANGLE, sizeof (SpaRectangle), SPA_PROP_TYPE_RECTANGLE, sizeof (SpaRectangle),
sizeof (SpaRectangle), &default_info.size, sizeof (SpaRectangle), &default_info.size,
SPA_PROP_RANGE_TYPE_MIN_MAX, 2, size_range, SPA_PROP_RANGE_TYPE_MIN_MAX, 2, size_range,
NULL, NULL,
offsetof (SpaVideoRawFormat, info.size), offsetof (SpaVideoRawFormat, info.size) },
offsetof (SpaVideoRawFormat, unset_mask), 1 << 1,
NULL },
{ SPA_PROP_ID_VIDEO_FRAMERATE, "framerate", "Video framerate", { SPA_PROP_ID_VIDEO_FRAMERATE, "framerate", "Video framerate",
SPA_PROP_FLAG_READWRITE, SPA_PROP_FLAG_READWRITE,
SPA_PROP_TYPE_FRACTION, sizeof (SpaFraction), SPA_PROP_TYPE_FRACTION, sizeof (SpaFraction),
sizeof (SpaFraction), &default_info.framerate, sizeof (SpaFraction), &default_info.framerate,
SPA_PROP_RANGE_TYPE_MIN_MAX, 2, framerate_range, SPA_PROP_RANGE_TYPE_MIN_MAX, 2, framerate_range,
NULL, NULL,
offsetof (SpaVideoRawFormat, info.framerate), offsetof (SpaVideoRawFormat, info.framerate) },
offsetof (SpaVideoRawFormat, unset_mask), 1 << 2,
NULL },
{ SPA_PROP_ID_VIDEO_MAX_FRAMERATE, "max-framerate", "Video max framerate", { SPA_PROP_ID_VIDEO_MAX_FRAMERATE, "max-framerate", "Video max framerate",
SPA_PROP_FLAG_READWRITE | SPA_PROP_FLAG_OPTIONAL, SPA_PROP_FLAG_READWRITE | SPA_PROP_FLAG_OPTIONAL,
SPA_PROP_TYPE_FRACTION, sizeof (SpaFraction), SPA_PROP_TYPE_FRACTION, sizeof (SpaFraction),
sizeof (SpaFraction), &default_info.max_framerate, sizeof (SpaFraction), &default_info.max_framerate,
SPA_PROP_RANGE_TYPE_MIN_MAX, 2, framerate_range, SPA_PROP_RANGE_TYPE_MIN_MAX, 2, framerate_range,
NULL, NULL,
offsetof (SpaVideoRawFormat, info.max_framerate), offsetof (SpaVideoRawFormat, info.max_framerate) },
offsetof (SpaVideoRawFormat, unset_mask), 1 << 3,
NULL },
{ SPA_PROP_ID_VIDEO_VIEWS, "views", "Video number of views", { SPA_PROP_ID_VIDEO_VIEWS, "views", "Video number of views",
SPA_PROP_FLAG_READWRITE | SPA_PROP_FLAG_OPTIONAL, SPA_PROP_FLAG_READWRITE | SPA_PROP_FLAG_OPTIONAL,
SPA_PROP_TYPE_UINT32, sizeof (uint32_t), SPA_PROP_TYPE_UINT32, sizeof (uint32_t),
sizeof (uint32_t), &default_info.views, sizeof (uint32_t), &default_info.views,
SPA_PROP_RANGE_TYPE_MIN_MAX, 2, uint32_range, SPA_PROP_RANGE_TYPE_MIN_MAX, 2, uint32_range,
NULL, NULL,
offsetof (SpaVideoRawFormat, info.views), offsetof (SpaVideoRawFormat, info.views) },
offsetof (SpaVideoRawFormat, unset_mask), 1 << 4,
NULL },
{ SPA_PROP_ID_VIDEO_INTERLACE_MODE, "interlace-mode", "Interlace mode", { SPA_PROP_ID_VIDEO_INTERLACE_MODE, "interlace-mode", "Interlace mode",
SPA_PROP_FLAG_READWRITE | SPA_PROP_FLAG_OPTIONAL, SPA_PROP_FLAG_READWRITE | SPA_PROP_FLAG_OPTIONAL,
SPA_PROP_TYPE_UINT32, sizeof (uint32_t), SPA_PROP_TYPE_UINT32, sizeof (uint32_t),
sizeof (uint32_t), &default_info.interlace_mode, sizeof (uint32_t), &default_info.interlace_mode,
SPA_PROP_RANGE_TYPE_ENUM, SPA_N_ELEMENTS (interlace_mode_range), interlace_mode_range, SPA_PROP_RANGE_TYPE_ENUM, SPA_N_ELEMENTS (interlace_mode_range), interlace_mode_range,
NULL, NULL,
offsetof (SpaVideoRawFormat, info.interlace_mode), offsetof (SpaVideoRawFormat, info.interlace_mode) },
offsetof (SpaVideoRawFormat, unset_mask), 1 << 5,
NULL },
{ SPA_PROP_ID_VIDEO_PIXEL_ASPECT_RATIO, "pixel-aspect-ratio", "Video pixel aspect ratio", { SPA_PROP_ID_VIDEO_PIXEL_ASPECT_RATIO, "pixel-aspect-ratio", "Video pixel aspect ratio",
SPA_PROP_FLAG_READWRITE | SPA_PROP_FLAG_OPTIONAL, SPA_PROP_FLAG_READWRITE | SPA_PROP_FLAG_OPTIONAL,
SPA_PROP_TYPE_FRACTION, sizeof (SpaFraction), SPA_PROP_TYPE_FRACTION, sizeof (SpaFraction),
sizeof (SpaFraction), &default_info.pixel_aspect_ratio, sizeof (SpaFraction), &default_info.pixel_aspect_ratio,
SPA_PROP_RANGE_TYPE_MIN_MAX, 2, framerate_range, SPA_PROP_RANGE_TYPE_MIN_MAX, 2, framerate_range,
NULL, NULL,
offsetof (SpaVideoRawFormat, info.pixel_aspect_ratio), offsetof (SpaVideoRawFormat, info.pixel_aspect_ratio) },
offsetof (SpaVideoRawFormat, unset_mask), 1 << 6,
NULL },
{ SPA_PROP_ID_VIDEO_MULTIVIEW_MODE, "multiview-mode", "Multiview mode", { SPA_PROP_ID_VIDEO_MULTIVIEW_MODE, "multiview-mode", "Multiview mode",
SPA_PROP_FLAG_READWRITE | SPA_PROP_FLAG_OPTIONAL, SPA_PROP_FLAG_READWRITE | SPA_PROP_FLAG_OPTIONAL,
SPA_PROP_TYPE_UINT32, sizeof (uint32_t), SPA_PROP_TYPE_UINT32, sizeof (uint32_t),
sizeof (uint32_t), &default_info.multiview_mode, sizeof (uint32_t), &default_info.multiview_mode,
SPA_PROP_RANGE_TYPE_ENUM, SPA_N_ELEMENTS (multiview_mode_range), multiview_mode_range, SPA_PROP_RANGE_TYPE_ENUM, SPA_N_ELEMENTS (multiview_mode_range), multiview_mode_range,
NULL, NULL,
offsetof (SpaVideoRawFormat, info.multiview_mode), offsetof (SpaVideoRawFormat, info.multiview_mode) },
offsetof (SpaVideoRawFormat, unset_mask), 1 << 7,
NULL },
{ SPA_PROP_ID_VIDEO_MULTIVIEW_FLAGS, "multiview-flags", "Multiview flags", { SPA_PROP_ID_VIDEO_MULTIVIEW_FLAGS, "multiview-flags", "Multiview flags",
SPA_PROP_FLAG_READWRITE | SPA_PROP_FLAG_OPTIONAL, SPA_PROP_FLAG_READWRITE | SPA_PROP_FLAG_OPTIONAL,
SPA_PROP_TYPE_UINT32, sizeof (uint32_t), SPA_PROP_TYPE_UINT32, sizeof (uint32_t),
sizeof (uint32_t), &default_info.multiview_flags, sizeof (uint32_t), &default_info.multiview_flags,
SPA_PROP_RANGE_TYPE_FLAGS, SPA_N_ELEMENTS (multiview_flags_range), multiview_flags_range, SPA_PROP_RANGE_TYPE_FLAGS, SPA_N_ELEMENTS (multiview_flags_range), multiview_flags_range,
NULL, NULL,
offsetof (SpaVideoRawFormat, info.multiview_flags), offsetof (SpaVideoRawFormat, info.multiview_flags) },
offsetof (SpaVideoRawFormat, unset_mask), 1 << 8,
NULL },
{ SPA_PROP_ID_VIDEO_CHROMA_SITE, "chroma-site", "Chroma site", { SPA_PROP_ID_VIDEO_CHROMA_SITE, "chroma-site", "Chroma site",
SPA_PROP_FLAG_READWRITE | SPA_PROP_FLAG_OPTIONAL, SPA_PROP_FLAG_READWRITE | SPA_PROP_FLAG_OPTIONAL,
SPA_PROP_TYPE_UINT32, sizeof (uint32_t), SPA_PROP_TYPE_UINT32, sizeof (uint32_t),
sizeof (uint32_t), &default_info.chroma_site, sizeof (uint32_t), &default_info.chroma_site,
SPA_PROP_RANGE_TYPE_FLAGS, SPA_N_ELEMENTS (chroma_site_range), chroma_site_range, SPA_PROP_RANGE_TYPE_FLAGS, SPA_N_ELEMENTS (chroma_site_range), chroma_site_range,
NULL, NULL,
offsetof (SpaVideoRawFormat, info.chroma_site), offsetof (SpaVideoRawFormat, info.chroma_site) },
offsetof (SpaVideoRawFormat, unset_mask), 1 << 9,
NULL },
{ SPA_PROP_ID_VIDEO_COLOR_RANGE, "color-range", "Color range", { SPA_PROP_ID_VIDEO_COLOR_RANGE, "color-range", "Color range",
SPA_PROP_FLAG_READWRITE | SPA_PROP_FLAG_OPTIONAL, SPA_PROP_FLAG_READWRITE | SPA_PROP_FLAG_OPTIONAL,
SPA_PROP_TYPE_UINT32, sizeof (uint32_t), SPA_PROP_TYPE_UINT32, sizeof (uint32_t),
sizeof (uint32_t), &default_info.color_range, sizeof (uint32_t), &default_info.color_range,
SPA_PROP_RANGE_TYPE_ENUM, SPA_N_ELEMENTS (color_range_range), color_range_range, SPA_PROP_RANGE_TYPE_ENUM, SPA_N_ELEMENTS (color_range_range), color_range_range,
NULL, NULL,
offsetof (SpaVideoRawFormat, info.color_range), offsetof (SpaVideoRawFormat, info.color_range) },
offsetof (SpaVideoRawFormat, unset_mask), 1 << 10,
NULL },
{ SPA_PROP_ID_VIDEO_COLOR_MATRIX, "color-matrix", "Color matrix", { SPA_PROP_ID_VIDEO_COLOR_MATRIX, "color-matrix", "Color matrix",
SPA_PROP_FLAG_READWRITE | SPA_PROP_FLAG_OPTIONAL, SPA_PROP_FLAG_READWRITE | SPA_PROP_FLAG_OPTIONAL,
SPA_PROP_TYPE_UINT32, sizeof (uint32_t), SPA_PROP_TYPE_UINT32, sizeof (uint32_t),
sizeof (uint32_t), &default_info.color_matrix, sizeof (uint32_t), &default_info.color_matrix,
SPA_PROP_RANGE_TYPE_ENUM, SPA_N_ELEMENTS (color_matrix_range), color_matrix_range, SPA_PROP_RANGE_TYPE_ENUM, SPA_N_ELEMENTS (color_matrix_range), color_matrix_range,
NULL, NULL,
offsetof (SpaVideoRawFormat, info.color_matrix), offsetof (SpaVideoRawFormat, info.color_matrix) },
offsetof (SpaVideoRawFormat, unset_mask), 1 << 11,
NULL },
{ SPA_PROP_ID_VIDEO_TRANSFER_FUNCTION, "transfer-function", "Transfer function", { SPA_PROP_ID_VIDEO_TRANSFER_FUNCTION, "transfer-function", "Transfer function",
SPA_PROP_FLAG_READWRITE | SPA_PROP_FLAG_OPTIONAL, SPA_PROP_FLAG_READWRITE | SPA_PROP_FLAG_OPTIONAL,
SPA_PROP_TYPE_UINT32, sizeof (uint32_t), SPA_PROP_TYPE_UINT32, sizeof (uint32_t),
sizeof (uint32_t), &default_info.transfer_function, sizeof (uint32_t), &default_info.transfer_function,
SPA_PROP_RANGE_TYPE_ENUM, SPA_N_ELEMENTS (transfer_function_range), transfer_function_range, SPA_PROP_RANGE_TYPE_ENUM, SPA_N_ELEMENTS (transfer_function_range), transfer_function_range,
NULL, NULL,
offsetof (SpaVideoRawFormat, info.transfer_function), offsetof (SpaVideoRawFormat, info.transfer_function) },
offsetof (SpaVideoRawFormat, unset_mask), 1 << 12,
NULL },
{ SPA_PROP_ID_VIDEO_COLOR_PRIMARIES, "color-primaries", "Color primaries", { SPA_PROP_ID_VIDEO_COLOR_PRIMARIES, "color-primaries", "Color primaries",
SPA_PROP_FLAG_READWRITE | SPA_PROP_FLAG_OPTIONAL, SPA_PROP_FLAG_READWRITE | SPA_PROP_FLAG_OPTIONAL,
SPA_PROP_TYPE_UINT32, sizeof (uint32_t), SPA_PROP_TYPE_UINT32, sizeof (uint32_t),
sizeof (uint32_t), &default_info.color_primaries, sizeof (uint32_t), &default_info.color_primaries,
SPA_PROP_RANGE_TYPE_ENUM, SPA_N_ELEMENTS (color_primaries_range), color_primaries_range, SPA_PROP_RANGE_TYPE_ENUM, SPA_N_ELEMENTS (color_primaries_range), color_primaries_range,
NULL, NULL,
offsetof (SpaVideoRawFormat, info.color_primaries), offsetof (SpaVideoRawFormat, info.color_primaries) },
offsetof (SpaVideoRawFormat, unset_mask), 1 << 13,
NULL },
{ SPA_PROP_ID_VIDEO_RAW_INFO, "info", "the SpaVideoRawInfo structure", { SPA_PROP_ID_VIDEO_RAW_INFO, "info", "the SpaVideoRawInfo structure",
SPA_PROP_FLAG_READWRITE | SPA_PROP_FLAG_OPTIONAL, SPA_PROP_FLAG_READWRITE | SPA_PROP_FLAG_OPTIONAL,
SPA_PROP_TYPE_POINTER, sizeof (SpaVideoRawInfo), SPA_PROP_TYPE_POINTER, sizeof (SpaVideoRawInfo),
0, NULL, 0, NULL,
SPA_PROP_RANGE_TYPE_NONE, 0, NULL, SPA_PROP_RANGE_TYPE_NONE, 0, NULL,
NULL, NULL,
offsetof (SpaVideoRawFormat, info), offsetof (SpaVideoRawFormat, info) },
offsetof (SpaVideoRawFormat, unset_mask), ~0,
NULL },
}; };
SpaResult SpaResult
@ -483,7 +453,7 @@ spa_video_raw_format_init (SpaVideoRawFormat *format)
format->format.media_subtype = SPA_MEDIA_SUBTYPE_RAW; format->format.media_subtype = SPA_MEDIA_SUBTYPE_RAW;
format->format.props.n_prop_info = SPA_N_ELEMENTS (raw_format_prop_info); format->format.props.n_prop_info = SPA_N_ELEMENTS (raw_format_prop_info);
format->format.props.prop_info = raw_format_prop_info; format->format.props.prop_info = raw_format_prop_info;
format->unset_mask = (1 << 14)-1; format->format.props.unset_mask = (1 << 14)-1;
format->info = default_info; format->info = default_info;
return SPA_RESULT_OK; return SPA_RESULT_OK;
@ -549,8 +519,6 @@ spa_video_raw_fill_prop_info (SpaPropInfo *info,
if (raw_format_prop_info[i].id == id) { if (raw_format_prop_info[i].id == id) {
memcpy (info, &raw_format_prop_info[i], sizeof (SpaPropInfo)); memcpy (info, &raw_format_prop_info[i], sizeof (SpaPropInfo));
info->offset = offset; info->offset = offset;
info->mask_offset = 0;
info->unset_mask = 0;
return SPA_RESULT_OK; return SPA_RESULT_OK;
} }
} }

View file

@ -124,54 +124,42 @@ static const SpaPropInfo prop_info[] =
strlen (default_device)+1, default_device, strlen (default_device)+1, default_device,
SPA_PROP_RANGE_TYPE_NONE, 0, NULL, SPA_PROP_RANGE_TYPE_NONE, 0, NULL,
NULL, NULL,
offsetof (SpaALSASinkProps, device), offsetof (SpaALSASinkProps, device) },
0, 0,
NULL },
{ PROP_ID_DEVICE_NAME, "device-name", "Human-readable name of the sound device", { PROP_ID_DEVICE_NAME, "device-name", "Human-readable name of the sound device",
SPA_PROP_FLAG_READABLE, SPA_PROP_FLAG_READABLE,
SPA_PROP_TYPE_STRING, 127, SPA_PROP_TYPE_STRING, 127,
0, NULL, 0, NULL,
SPA_PROP_RANGE_TYPE_NONE, 0, NULL, SPA_PROP_RANGE_TYPE_NONE, 0, NULL,
NULL, NULL,
offsetof (SpaALSASinkProps, device_name), offsetof (SpaALSASinkProps, device_name) },
0, 0,
NULL },
{ PROP_ID_CARD_NAME, "card-name", "Human-readable name of the sound card", { PROP_ID_CARD_NAME, "card-name", "Human-readable name of the sound card",
SPA_PROP_FLAG_READABLE, SPA_PROP_FLAG_READABLE,
SPA_PROP_TYPE_STRING, 127, SPA_PROP_TYPE_STRING, 127,
0, NULL, 0, NULL,
SPA_PROP_RANGE_TYPE_NONE, 0, NULL, SPA_PROP_RANGE_TYPE_NONE, 0, NULL,
NULL, NULL,
offsetof (SpaALSASinkProps, card_name), offsetof (SpaALSASinkProps, card_name) },
0, 0,
NULL },
{ PROP_ID_BUFFER_TIME, "buffer-time", "The total size of the buffer in time", { PROP_ID_BUFFER_TIME, "buffer-time", "The total size of the buffer in time",
SPA_PROP_FLAG_READWRITE, SPA_PROP_FLAG_READWRITE,
SPA_PROP_TYPE_UINT32, sizeof (uint32_t), SPA_PROP_TYPE_UINT32, sizeof (uint32_t),
sizeof (uint32_t), &default_buffer_time, sizeof (uint32_t), &default_buffer_time,
SPA_PROP_RANGE_TYPE_MIN_MAX, 2, uint32_range, SPA_PROP_RANGE_TYPE_MIN_MAX, 2, uint32_range,
NULL, NULL,
offsetof (SpaALSASinkProps, buffer_time), offsetof (SpaALSASinkProps, buffer_time) },
0, 0,
NULL },
{ PROP_ID_PERIOD_TIME, "period-time", "The size of a period in time", { PROP_ID_PERIOD_TIME, "period-time", "The size of a period in time",
SPA_PROP_FLAG_READWRITE, SPA_PROP_FLAG_READWRITE,
SPA_PROP_TYPE_UINT32, sizeof (uint32_t), SPA_PROP_TYPE_UINT32, sizeof (uint32_t),
sizeof (uint32_t), &default_period_time, sizeof (uint32_t), &default_period_time,
SPA_PROP_RANGE_TYPE_MIN_MAX, 2, uint32_range, SPA_PROP_RANGE_TYPE_MIN_MAX, 2, uint32_range,
NULL, NULL,
offsetof (SpaALSASinkProps, period_time), offsetof (SpaALSASinkProps, period_time) },
0, 0,
NULL },
{ PROP_ID_PERIOD_EVENT, "period-event", "Generate an event each period", { PROP_ID_PERIOD_EVENT, "period-event", "Generate an event each period",
SPA_PROP_FLAG_READWRITE, SPA_PROP_FLAG_READWRITE,
SPA_PROP_TYPE_BOOL, sizeof (bool), SPA_PROP_TYPE_BOOL, sizeof (bool),
sizeof (bool), &default_period_event, sizeof (bool), &default_period_event,
SPA_PROP_RANGE_TYPE_NONE, 0, NULL, SPA_PROP_RANGE_TYPE_NONE, 0, NULL,
NULL, NULL,
offsetof (SpaALSASinkProps, period_event), offsetof (SpaALSASinkProps, period_event) },
0, 0,
NULL },
}; };
static SpaResult static SpaResult

View file

@ -90,27 +90,21 @@ static const SpaPropInfo prop_info[] =
sizeof (uint32_t), &default_wave, sizeof (uint32_t), &default_wave,
SPA_PROP_RANGE_TYPE_ENUM, SPA_N_ELEMENTS (wave_range), wave_range, SPA_PROP_RANGE_TYPE_ENUM, SPA_N_ELEMENTS (wave_range), wave_range,
NULL, NULL,
offsetof (SpaAudioTestSrcProps, wave), offsetof (SpaAudioTestSrcProps, wave) },
0, 0,
NULL },
{ PROP_ID_FREQ, "freq", "Frequency of test signal. The sample rate needs to be at least 4 times higher", { PROP_ID_FREQ, "freq", "Frequency of test signal. The sample rate needs to be at least 4 times higher",
SPA_PROP_FLAG_READWRITE, SPA_PROP_FLAG_READWRITE,
SPA_PROP_TYPE_DOUBLE, sizeof (double), SPA_PROP_TYPE_DOUBLE, sizeof (double),
sizeof (double), &default_freq, sizeof (double), &default_freq,
SPA_PROP_RANGE_TYPE_MIN_MAX, 2, freq_range, SPA_PROP_RANGE_TYPE_MIN_MAX, 2, freq_range,
NULL, NULL,
offsetof (SpaAudioTestSrcProps, freq), offsetof (SpaAudioTestSrcProps, freq) },
0, 0,
NULL },
{ PROP_ID_VOLUME, "volume", "The Volume factor", { PROP_ID_VOLUME, "volume", "The Volume factor",
SPA_PROP_FLAG_READWRITE, SPA_PROP_FLAG_READWRITE,
SPA_PROP_TYPE_DOUBLE, sizeof (double), SPA_PROP_TYPE_DOUBLE, sizeof (double),
sizeof (double), &default_volume, sizeof (double), &default_volume,
SPA_PROP_RANGE_TYPE_MIN_MAX, 2, volume_range, SPA_PROP_RANGE_TYPE_MIN_MAX, 2, volume_range,
NULL, NULL,
offsetof (SpaAudioTestSrcProps, volume), offsetof (SpaAudioTestSrcProps, volume) },
0, 0,
NULL },
}; };
static void static void

View file

@ -90,9 +90,7 @@ static const SpaPropInfo prop_info[PROP_ID_LAST] =
sizeof (int), NULL, sizeof (int), NULL,
SPA_PROP_RANGE_TYPE_NONE, 0, NULL, SPA_PROP_RANGE_TYPE_NONE, 0, NULL,
NULL, NULL,
offsetof (SpaProxyProps, socketfd), offsetof (SpaProxyProps, socketfd) },
0, 0,
NULL },
}; };
static void static void
@ -920,6 +918,7 @@ parse_control (SpaProxy *this,
{ {
SpaControlCmdPortUpdate pu; SpaControlCmdPortUpdate pu;
SpaProxyPort *port; SpaProxyPort *port;
unsigned int i;
fprintf (stderr, "proxy %p: got port update %d\n", this, cmd); fprintf (stderr, "proxy %p: got port update %d\n", this, cmd);
if (spa_control_iter_parse_cmd (&it, &pu) < 0) if (spa_control_iter_parse_cmd (&it, &pu) < 0)
@ -929,6 +928,12 @@ parse_control (SpaProxy *this,
break; break;
port = &this->ports[pu.port_id]; port = &this->ports[pu.port_id];
for (i = 0; i < pu.n_possible_formats; i++)
spa_debug_format (pu.possible_formats[i]);
spa_debug_props (pu.props, true);
if (!port->valid && pu.direction != SPA_DIRECTION_INVALID) { if (!port->valid && pu.direction != SPA_DIRECTION_INVALID) {
do_init_port (this, pu.port_id, pu.direction); do_init_port (this, pu.port_id, pu.direction);
} else { } else {

View file

@ -31,7 +31,7 @@
typedef struct _SpaV4l2Source SpaV4l2Source; typedef struct _SpaV4l2Source SpaV4l2Source;
static const char default_device[] = "/dev/video1"; static const char default_device[] = "/dev/video0";
typedef struct { typedef struct {
SpaProps props; SpaProps props;
@ -66,7 +66,6 @@ typedef struct _V4l2Format V4l2Format;
struct _V4l2Format { struct _V4l2Format {
SpaFormat fmt; SpaFormat fmt;
uint32_t unset_mask;
SpaVideoFormat format; SpaVideoFormat format;
SpaRectangle size; SpaRectangle size;
SpaFraction framerate; SpaFraction framerate;
@ -146,27 +145,21 @@ static const SpaPropInfo prop_info[] =
strlen (default_device)+1, default_device, strlen (default_device)+1, default_device,
SPA_PROP_RANGE_TYPE_NONE, 0, NULL, SPA_PROP_RANGE_TYPE_NONE, 0, NULL,
NULL, NULL,
offsetof (SpaV4l2SourceProps, device), offsetof (SpaV4l2SourceProps, device) },
0, 0,
NULL },
{ PROP_ID_DEVICE_NAME, "device-name", "Human-readable name of the device", { PROP_ID_DEVICE_NAME, "device-name", "Human-readable name of the device",
SPA_PROP_FLAG_READABLE, SPA_PROP_FLAG_READABLE,
SPA_PROP_TYPE_STRING, 127, SPA_PROP_TYPE_STRING, 127,
0, NULL, 0, NULL,
SPA_PROP_RANGE_TYPE_NONE, 0, NULL, SPA_PROP_RANGE_TYPE_NONE, 0, NULL,
NULL, NULL,
offsetof (SpaV4l2SourceProps, device_name), offsetof (SpaV4l2SourceProps, device_name) },
0, 0,
NULL },
{ PROP_ID_DEVICE_FD, "device-fd", "Device file descriptor", { PROP_ID_DEVICE_FD, "device-fd", "Device file descriptor",
SPA_PROP_FLAG_READABLE, SPA_PROP_FLAG_READABLE,
SPA_PROP_TYPE_UINT32, sizeof (uint32_t), SPA_PROP_TYPE_UINT32, sizeof (uint32_t),
0, NULL, 0, NULL,
SPA_PROP_RANGE_TYPE_NONE, 0, NULL, SPA_PROP_RANGE_TYPE_NONE, 0, NULL,
NULL, NULL,
offsetof (SpaV4l2SourceProps, device_fd), offsetof (SpaV4l2SourceProps, device_fd) },
0, 0,
NULL },
}; };
static SpaResult static SpaResult
@ -347,20 +340,12 @@ spa_v4l2_format_init (V4l2Format *f)
spa_video_raw_fill_prop_info (&f->infos[0], spa_video_raw_fill_prop_info (&f->infos[0],
SPA_PROP_ID_VIDEO_FORMAT, SPA_PROP_ID_VIDEO_FORMAT,
offsetof (V4l2Format, format)); offsetof (V4l2Format, format));
f->infos[0].mask_offset = offsetof (V4l2Format, unset_mask);
f->infos[0].unset_mask = 1 << 0;
spa_video_raw_fill_prop_info (&f->infos[1], spa_video_raw_fill_prop_info (&f->infos[1],
SPA_PROP_ID_VIDEO_SIZE, SPA_PROP_ID_VIDEO_SIZE,
offsetof (V4l2Format, size)); offsetof (V4l2Format, size));
f->infos[1].mask_offset = offsetof (V4l2Format, unset_mask);
f->infos[1].unset_mask = 1 << 1;
spa_video_raw_fill_prop_info (&f->infos[2], spa_video_raw_fill_prop_info (&f->infos[2],
SPA_PROP_ID_VIDEO_FRAMERATE, SPA_PROP_ID_VIDEO_FRAMERATE,
offsetof (V4l2Format, framerate)); offsetof (V4l2Format, framerate));
f->infos[2].mask_offset = offsetof (V4l2Format, unset_mask);
f->infos[2].unset_mask = 1 << 2;
} }
static SpaResult static SpaResult

View file

@ -279,13 +279,12 @@ again:
fmt->fmt.media_subtype = info->media_subtype; fmt->fmt.media_subtype = info->media_subtype;
fmt->fmt.props.prop_info = fmt->infos; fmt->fmt.props.prop_info = fmt->infos;
fmt->fmt.props.n_prop_info = pi = 0; fmt->fmt.props.n_prop_info = pi = 0;
fmt->unset_mask = 0; fmt->fmt.props.unset_mask = 0;
if (info->media_subtype == SPA_MEDIA_SUBTYPE_RAW) { if (info->media_subtype == SPA_MEDIA_SUBTYPE_RAW) {
spa_video_raw_fill_prop_info (&fmt->infos[pi], spa_video_raw_fill_prop_info (&fmt->infos[pi],
SPA_PROP_ID_VIDEO_FORMAT, SPA_PROP_ID_VIDEO_FORMAT,
offsetof (V4l2Format, format)); offsetof (V4l2Format, format));
fmt->infos[pi].mask_offset = offsetof (V4l2Format, unset_mask);
fmt->format = info->format; fmt->format = info->format;
pi = ++fmt->fmt.props.n_prop_info; pi = ++fmt->fmt.props.n_prop_info;
} }
@ -293,7 +292,6 @@ again:
spa_video_raw_fill_prop_info (&fmt->infos[pi], spa_video_raw_fill_prop_info (&fmt->infos[pi],
SPA_PROP_ID_VIDEO_SIZE, SPA_PROP_ID_VIDEO_SIZE,
offsetof (V4l2Format, size)); offsetof (V4l2Format, size));
fmt->infos[pi].mask_offset = offsetof (V4l2Format, unset_mask);
fmt->size.width = state->frmsize.discrete.width; fmt->size.width = state->frmsize.discrete.width;
fmt->size.height = state->frmsize.discrete.height; fmt->size.height = state->frmsize.discrete.height;
pi = ++fmt->fmt.props.n_prop_info; pi = ++fmt->fmt.props.n_prop_info;
@ -301,7 +299,6 @@ again:
spa_video_raw_fill_prop_info (&fmt->infos[pi], spa_video_raw_fill_prop_info (&fmt->infos[pi],
SPA_PROP_ID_VIDEO_FRAMERATE, SPA_PROP_ID_VIDEO_FRAMERATE,
offsetof (V4l2Format, framerate)); offsetof (V4l2Format, framerate));
fmt->infos[pi].mask_offset = offsetof (V4l2Format, unset_mask);
fmt->infos[pi].range_type = SPA_PROP_RANGE_TYPE_ENUM; fmt->infos[pi].range_type = SPA_PROP_RANGE_TYPE_ENUM;
fmt->infos[pi].range_values = fmt->ranges; fmt->infos[pi].range_values = fmt->ranges;
fmt->infos[pi].n_range_values = 0; fmt->infos[pi].n_range_values = 0;
@ -328,8 +325,7 @@ again:
i = ++state->frmival.index; i = ++state->frmival.index;
} }
fmt->infos[pi].n_range_values = i; fmt->infos[pi].n_range_values = i;
fmt->infos[pi].unset_mask = 1 << i; fmt->fmt.props.unset_mask |= 1 << pi;
fmt->unset_mask |= fmt->infos[pi].unset_mask;
pi = ++fmt->fmt.props.n_prop_info; pi = ++fmt->fmt.props.n_prop_info;
*format = &state->format[0].fmt; *format = &state->format[0].fmt;

View file

@ -81,18 +81,14 @@ static const SpaPropInfo prop_info[] =
sizeof (double), &default_volume, sizeof (double), &default_volume,
SPA_PROP_RANGE_TYPE_MIN_MAX, 2, volume_range, SPA_PROP_RANGE_TYPE_MIN_MAX, 2, volume_range,
NULL, NULL,
offsetof (SpaVolumeProps, volume), offsetof (SpaVolumeProps, volume) },
0, 0,
NULL },
{ PROP_ID_MUTE, "mute", "Mute", { PROP_ID_MUTE, "mute", "Mute",
SPA_PROP_FLAG_READWRITE, SPA_PROP_FLAG_READWRITE,
SPA_PROP_TYPE_BOOL, sizeof (bool), SPA_PROP_TYPE_BOOL, sizeof (bool),
sizeof (bool), &default_mute, sizeof (bool), &default_mute,
SPA_PROP_RANGE_TYPE_NONE, 0, NULL, SPA_PROP_RANGE_TYPE_NONE, 0, NULL,
NULL, NULL,
offsetof (SpaVolumeProps, mute), offsetof (SpaVolumeProps, mute) },
0, 0,
NULL },
}; };
static void static void

View file

@ -103,27 +103,21 @@ static const SpaPropInfo prop_info[] =
strlen (default_device)+1, default_device, strlen (default_device)+1, default_device,
SPA_PROP_RANGE_TYPE_NONE, 0, NULL, SPA_PROP_RANGE_TYPE_NONE, 0, NULL,
NULL, NULL,
offsetof (SpaXvSinkProps, device), offsetof (SpaXvSinkProps, device) },
0, 0,
NULL },
{ PROP_ID_DEVICE_NAME, "device-name", "Human-readable name of the device", { PROP_ID_DEVICE_NAME, "device-name", "Human-readable name of the device",
SPA_PROP_FLAG_READABLE, SPA_PROP_FLAG_READABLE,
SPA_PROP_TYPE_STRING, 127, SPA_PROP_TYPE_STRING, 127,
0, NULL, 0, NULL,
SPA_PROP_RANGE_TYPE_NONE, 0, NULL, SPA_PROP_RANGE_TYPE_NONE, 0, NULL,
NULL, NULL,
offsetof (SpaXvSinkProps, device_name), offsetof (SpaXvSinkProps, device_name) },
0, 0,
NULL },
{ PROP_ID_DEVICE_FD, "device-fd", "Device file descriptor", { PROP_ID_DEVICE_FD, "device-fd", "Device file descriptor",
SPA_PROP_FLAG_READABLE, SPA_PROP_FLAG_READABLE,
SPA_PROP_TYPE_UINT32, sizeof (uint32_t), SPA_PROP_TYPE_UINT32, sizeof (uint32_t),
0, NULL, 0, NULL,
SPA_PROP_RANGE_TYPE_NONE, 0, NULL, SPA_PROP_RANGE_TYPE_NONE, 0, NULL,
NULL, NULL,
offsetof (SpaXvSinkProps, device_fd), offsetof (SpaXvSinkProps, device_fd) },
0, 0,
NULL },
}; };
static SpaResult static SpaResult