mirror of
https://gitlab.freedesktop.org/pipewire/pipewire
synced 2024-09-19 16:01:45 +00:00
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:
parent
de53315f6e
commit
0d2f5a1386
|
@ -23,11 +23,16 @@ static SpaFormat *
|
|||
format_copy (SpaFormat *format)
|
||||
{
|
||||
SpaMemory *mem;
|
||||
SpaFormat *f;
|
||||
|
||||
if (format == NULL)
|
||||
return NULL;
|
||||
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
do_node_init (PinosStream *stream)
|
||||
{
|
||||
|
@ -872,6 +889,7 @@ do_node_init (PinosStream *stream)
|
|||
SpaControlCmdPortUpdate pu;
|
||||
SpaControlBuilder builder;
|
||||
SpaControl control;
|
||||
PortProps port_props;
|
||||
|
||||
control_builder_init (stream, &builder);
|
||||
nu.change_mask = SPA_CONTROL_CMD_NODE_UPDATE_MAX_INPUTS |
|
||||
|
@ -881,6 +899,11 @@ do_node_init (PinosStream *stream)
|
|||
nu.props = NULL;
|
||||
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.change_mask = SPA_CONTROL_CMD_PORT_UPDATE_DIRECTION |
|
||||
SPA_CONTROL_CMD_PORT_UPDATE_POSSIBLE_FORMATS |
|
||||
|
@ -889,7 +912,7 @@ do_node_init (PinosStream *stream)
|
|||
pu.direction = priv->direction;
|
||||
pu.n_possible_formats = priv->possible_formats->len;
|
||||
pu.possible_formats = (const SpaFormat **)priv->possible_formats->pdata;
|
||||
pu.props = NULL;
|
||||
pu.props = &port_props.props;
|
||||
pu.info = &priv->port_info;
|
||||
priv->port_info.flags = SPA_PORT_INFO_FLAG_NONE |
|
||||
SPA_PORT_INFO_FLAG_CAN_USE_BUFFERS;
|
||||
|
@ -1050,9 +1073,9 @@ pinos_stream_connect (PinosStream *stream,
|
|||
priv->direction = direction;
|
||||
g_free (priv->path);
|
||||
priv->path = g_strdup (port_path);
|
||||
priv->flags = flags;
|
||||
if (priv->possible_formats)
|
||||
g_ptr_array_unref (priv->possible_formats);
|
||||
priv->flags = flags;
|
||||
priv->possible_formats = possible_formats;
|
||||
|
||||
stream_set_state (stream, PINOS_STREAM_STATE_CONNECTING, NULL);
|
||||
|
|
|
@ -42,8 +42,6 @@ main (gint argc, gchar *argv[])
|
|||
props = pinos_properties_new ("test", "test", NULL);
|
||||
daemon = pinos_daemon_new (props);
|
||||
|
||||
pinos_gst_manager_new (daemon);
|
||||
|
||||
factory = pinos_gst_node_factory_new ("gst-node-factory");
|
||||
pinos_daemon_add_node_factory (daemon, factory);
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ convert_1 (GstCapsFeatures *cf, GstStructure *cs)
|
|||
if (!gst_structure_get_int (cs, "height", &i))
|
||||
goto done;
|
||||
f->info.size.height = i;
|
||||
f->unset_mask = 0;
|
||||
f->format.props.unset_mask = 0;
|
||||
|
||||
res = &f->format;
|
||||
} 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))
|
||||
goto done;
|
||||
f->info.channels = i;
|
||||
f->unset_mask = 0;
|
||||
f->format.props.unset_mask = 0;
|
||||
|
||||
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),
|
||||
"width", G_TYPE_INT, f.info.size.width,
|
||||
"height", G_TYPE_INT, f.info.size.height,
|
||||
"framerate", GST_TYPE_FRACTION, f.info.framerate.num, f.info.framerate.denom,
|
||||
NULL);
|
||||
}
|
||||
} else if (format->media_type == SPA_MEDIA_TYPE_AUDIO) {
|
||||
|
|
|
@ -290,7 +290,7 @@ on_node_event (SpaNode *node, SpaEvent *event, void *user_data)
|
|||
|
||||
target = pinos_daemon_find_port (pinos_node_get_daemon (pnode),
|
||||
pinos_direction_reverse (pa->direction),
|
||||
"/org/pinos/node_8",
|
||||
"/org/pinos/node_1",
|
||||
NULL,
|
||||
NULL,
|
||||
&error);
|
||||
|
|
|
@ -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
|
||||
handle_create_client_node (PinosDaemon1 *interface,
|
||||
GDBusMethodInvocation *invocation,
|
||||
|
@ -216,6 +228,9 @@ handle_create_client_node (PinosDaemon1 *interface,
|
|||
client = sender_get_client (daemon, sender);
|
||||
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));
|
||||
g_debug ("daemon %p: add client-node %p, %s", daemon, node, object_path);
|
||||
|
||||
|
|
|
@ -174,13 +174,13 @@ pinos_link_set_property (GObject *_object,
|
|||
break;
|
||||
|
||||
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_port = priv->output->id;
|
||||
break;
|
||||
|
||||
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_port = priv->input->id;
|
||||
break;
|
||||
|
@ -277,7 +277,7 @@ do_negotiate (PinosLink *this)
|
|||
value.type = SPA_PROP_TYPE_FRACTION;
|
||||
value.size = sizeof (SpaFraction);
|
||||
value.value = &frac;
|
||||
frac.num = 25;
|
||||
frac.num = 20;
|
||||
frac.denom = 1;
|
||||
if ((res = spa_props_set_prop (props, spa_props_index_for_id (props, SPA_PROP_ID_VIDEO_FRAMERATE), &value)) < 0)
|
||||
return res;
|
||||
|
@ -334,12 +334,12 @@ on_activate (PinosPort *port, gpointer user_data)
|
|||
|
||||
if (priv->active)
|
||||
return TRUE;
|
||||
priv->active = TRUE;
|
||||
|
||||
if (priv->input == port)
|
||||
pinos_port_activate (priv->output);
|
||||
else
|
||||
pinos_port_activate (priv->input);
|
||||
priv->active = TRUE;
|
||||
|
||||
if (!priv->negotiated)
|
||||
do_negotiate (this);
|
||||
|
@ -367,12 +367,12 @@ on_deactivate (PinosPort *port, gpointer user_data)
|
|||
|
||||
if (!priv->active)
|
||||
return TRUE;
|
||||
priv->active = FALSE;
|
||||
|
||||
if (priv->input == port)
|
||||
pinos_port_deactivate (priv->output);
|
||||
else
|
||||
pinos_port_deactivate (priv->input);
|
||||
priv->active = FALSE;
|
||||
|
||||
cmd.type = SPA_COMMAND_STOP;
|
||||
if ((res = spa_node_send_command (priv->input_node, &cmd)) < 0)
|
||||
|
|
|
@ -69,6 +69,8 @@ enum
|
|||
enum
|
||||
{
|
||||
SIGNAL_REMOVE,
|
||||
SIGNAL_PORT_ADDED,
|
||||
SIGNAL_PORT_REMOVED,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
|
@ -105,6 +107,7 @@ node_add_port (PinosNode *node,
|
|||
if (port) {
|
||||
g_hash_table_insert (priv->ports, GUINT_TO_POINTER (id), port);
|
||||
g_signal_connect (port, "remove", (GCallback) do_remove_port, node);
|
||||
g_signal_emit (node, signals[SIGNAL_PORT_ADDED], 0, port);
|
||||
}
|
||||
return port;
|
||||
}
|
||||
|
@ -114,8 +117,14 @@ node_remove_port (PinosNode *node,
|
|||
guint id)
|
||||
{
|
||||
PinosNodePrivate *priv = node->priv;
|
||||
PinosPort *port;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -497,6 +506,26 @@ pinos_node_class_init (PinosNodeClass * klass)
|
|||
G_TYPE_NONE,
|
||||
0,
|
||||
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->add_port = node_add_port;
|
||||
|
@ -522,7 +551,10 @@ pinos_node_init (PinosNode * node)
|
|||
priv->state = 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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -273,8 +273,11 @@ static void
|
|||
pinos_port_dispose (GObject * 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);
|
||||
}
|
||||
|
@ -437,7 +440,7 @@ pinos_port_class_init (PinosPortClass * klass)
|
|||
static void
|
||||
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);
|
||||
port->direction = PINOS_DIRECTION_INVALID;
|
||||
|
|
|
@ -41,7 +41,6 @@ typedef enum {
|
|||
|
||||
struct _SpaAudioRawFormat {
|
||||
SpaFormat format;
|
||||
uint32_t unset_mask;
|
||||
SpaAudioRawInfo info;
|
||||
};
|
||||
|
||||
|
|
|
@ -144,9 +144,6 @@ typedef struct {
|
|||
const SpaPropRangeInfo *range_values;
|
||||
const char **tags;
|
||||
size_t offset;
|
||||
size_t mask_offset;
|
||||
uint32_t unset_mask;
|
||||
const void *priv;
|
||||
} SpaPropInfo;
|
||||
|
||||
typedef struct {
|
||||
|
@ -160,12 +157,14 @@ typedef struct {
|
|||
* @n_prop_info: number of elements in @prop_info
|
||||
* @prop_info: array of #SpaPropInfo. Contains info about the
|
||||
* properties. Can be %NULL when unspecified.
|
||||
* @unset_mask: mask of unset properties
|
||||
*
|
||||
* Generic propertiers.
|
||||
*/
|
||||
struct _SpaProps {
|
||||
unsigned int n_prop_info;
|
||||
const SpaPropInfo *prop_info;
|
||||
uint32_t unset_mask;
|
||||
};
|
||||
|
||||
static inline unsigned int
|
||||
|
|
|
@ -49,7 +49,6 @@ typedef enum {
|
|||
|
||||
struct _SpaVideoRawFormat {
|
||||
SpaFormat format;
|
||||
uint32_t unset_mask;
|
||||
SpaVideoRawInfo info;
|
||||
};
|
||||
|
||||
|
|
|
@ -143,63 +143,49 @@ static const SpaPropInfo raw_format_prop_info[] =
|
|||
sizeof (uint32_t), &default_info.format,
|
||||
SPA_PROP_RANGE_TYPE_ENUM, SPA_N_ELEMENTS (format_format_range), format_format_range,
|
||||
NULL,
|
||||
offsetof (SpaAudioRawFormat, info.format),
|
||||
offsetof (SpaAudioRawFormat, unset_mask), 1 << 0,
|
||||
NULL },
|
||||
offsetof (SpaAudioRawFormat, info.format) },
|
||||
{ SPA_PROP_ID_AUDIO_FLAGS, "flags", "Sample Flags",
|
||||
SPA_PROP_FLAG_READWRITE,
|
||||
SPA_PROP_TYPE_UINT32, sizeof (uint32_t),
|
||||
sizeof (uint32_t), &default_info.flags,
|
||||
SPA_PROP_RANGE_TYPE_FLAGS, SPA_N_ELEMENTS (flags_range), flags_range,
|
||||
NULL,
|
||||
offsetof (SpaAudioRawFormat, info.flags),
|
||||
offsetof (SpaAudioRawFormat, unset_mask), 1 << 1,
|
||||
NULL },
|
||||
offsetof (SpaAudioRawFormat, info.flags) },
|
||||
{ SPA_PROP_ID_AUDIO_LAYOUT, "layout", "Sample Layout",
|
||||
SPA_PROP_FLAG_READWRITE,
|
||||
SPA_PROP_TYPE_UINT32, sizeof (uint32_t),
|
||||
sizeof (uint32_t), &default_info.layout,
|
||||
SPA_PROP_RANGE_TYPE_ENUM, SPA_N_ELEMENTS (layouts_range), layouts_range,
|
||||
NULL,
|
||||
offsetof (SpaAudioRawFormat, info.layout),
|
||||
offsetof (SpaAudioRawFormat, unset_mask), 1 << 2,
|
||||
NULL },
|
||||
offsetof (SpaAudioRawFormat, info.layout) },
|
||||
{ SPA_PROP_ID_AUDIO_RATE, "rate", "Audio sample rate",
|
||||
SPA_PROP_FLAG_READWRITE,
|
||||
SPA_PROP_TYPE_UINT32, sizeof (uint32_t),
|
||||
sizeof (uint32_t), &default_info.rate,
|
||||
SPA_PROP_RANGE_TYPE_MIN_MAX, 2, uint32_range,
|
||||
NULL,
|
||||
offsetof (SpaAudioRawFormat, info.rate),
|
||||
offsetof (SpaAudioRawFormat, unset_mask), 1 << 3,
|
||||
NULL },
|
||||
offsetof (SpaAudioRawFormat, info.rate) },
|
||||
{ SPA_PROP_ID_AUDIO_CHANNELS, "channels", "Audio channels",
|
||||
SPA_PROP_FLAG_READWRITE,
|
||||
SPA_PROP_TYPE_UINT32, sizeof (uint32_t),
|
||||
sizeof (uint32_t), &default_info.channels,
|
||||
SPA_PROP_RANGE_TYPE_MIN_MAX, 2, uint32_range,
|
||||
NULL,
|
||||
offsetof (SpaAudioRawFormat, info.channels),
|
||||
offsetof (SpaAudioRawFormat, unset_mask), 1 << 4,
|
||||
NULL },
|
||||
offsetof (SpaAudioRawFormat, info.channels) },
|
||||
{ SPA_PROP_ID_AUDIO_CHANNEL_MASK, "channel-mask", "Audio channel mask",
|
||||
SPA_PROP_FLAG_READWRITE,
|
||||
SPA_PROP_TYPE_BITMASK, sizeof (uint32_t),
|
||||
sizeof (uint32_t), &default_info.channel_mask,
|
||||
SPA_PROP_RANGE_TYPE_NONE, 0, NULL,
|
||||
NULL,
|
||||
offsetof (SpaAudioRawFormat, info.channel_mask),
|
||||
offsetof (SpaAudioRawFormat, unset_mask), 1 << 5,
|
||||
NULL },
|
||||
offsetof (SpaAudioRawFormat, info.channel_mask) },
|
||||
{ SPA_PROP_ID_AUDIO_RAW_INFO, "info", "the SpaAudioRawInfo structure",
|
||||
SPA_PROP_FLAG_READWRITE,
|
||||
SPA_PROP_TYPE_POINTER, sizeof (SpaAudioRawInfo),
|
||||
0, NULL,
|
||||
SPA_PROP_RANGE_TYPE_NONE, 0, NULL,
|
||||
NULL,
|
||||
offsetof (SpaAudioRawFormat, info),
|
||||
offsetof (SpaAudioRawFormat, unset_mask), ~0,
|
||||
NULL },
|
||||
offsetof (SpaAudioRawFormat, info) },
|
||||
};
|
||||
|
||||
SpaResult
|
||||
|
@ -209,7 +195,7 @@ spa_audio_raw_format_init (SpaAudioRawFormat *format)
|
|||
format->format.media_subtype = SPA_MEDIA_SUBTYPE_RAW;
|
||||
format->format.props.n_prop_info = SPA_N_ELEMENTS (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;
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
|
|
|
@ -340,24 +340,15 @@ spa_control_iter_get_data (SpaControlIter *iter, size_t *size)
|
|||
return si->data;
|
||||
}
|
||||
|
||||
static void
|
||||
iter_parse_set_format (struct stack_iter *si, SpaControlCmdSetFormat *cmd)
|
||||
static SpaProps *
|
||||
parse_props (SpaMemory *mem, void *p, off_t offset)
|
||||
{
|
||||
uint32_t *p = si->data;
|
||||
SpaProps *tp;
|
||||
unsigned int i, j;
|
||||
SpaPropInfo *pi;
|
||||
SpaPropRangeInfo *ri;
|
||||
SpaMemory *mem;
|
||||
|
||||
cmd->port_id = *p++;
|
||||
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 = SPA_MEMBER (p, offset, SpaProps);
|
||||
tp->prop_info = SPA_MEMBER (tp, SPA_PTR_TO_INT (tp->prop_info), SpaPropInfo);
|
||||
|
||||
/* 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);
|
||||
}
|
||||
}
|
||||
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
|
||||
spa_control_iter_parse_cmd (SpaControlIter *iter,
|
||||
|
@ -402,9 +451,7 @@ spa_control_iter_parse_cmd (SpaControlIter *iter,
|
|||
break;
|
||||
|
||||
case SPA_CONTROL_CMD_PORT_UPDATE:
|
||||
if (si->size < sizeof (SpaControlCmdPortUpdate))
|
||||
return SPA_RESULT_ERROR;
|
||||
memcpy (command, si->data, sizeof (SpaControlCmdPortUpdate));
|
||||
iter_parse_port_update (si, command);
|
||||
break;
|
||||
|
||||
case SPA_CONTROL_CMD_PORT_REMOVED:
|
||||
|
@ -449,10 +496,8 @@ spa_control_iter_parse_cmd (SpaControlIter *iter,
|
|||
break;
|
||||
|
||||
case SPA_CONTROL_CMD_SET_FORMAT:
|
||||
{
|
||||
iter_parse_set_format (si, command);
|
||||
break;
|
||||
}
|
||||
|
||||
case SPA_CONTROL_CMD_SET_PROPERTY:
|
||||
fprintf (stderr, "implement iter of %d\n", si->cmd);
|
||||
|
@ -735,6 +780,9 @@ calc_props_len (const SpaProps *props)
|
|||
SpaPropInfo *pi;
|
||||
SpaPropRangeInfo *ri;
|
||||
|
||||
if (props == NULL)
|
||||
return 0;
|
||||
|
||||
/* props and unset mask */
|
||||
len = sizeof (SpaProps) + sizeof (uint32_t);
|
||||
for (i = 0; i < props->n_prop_info; i++) {
|
||||
|
@ -757,59 +805,22 @@ calc_props_len (const SpaProps *props)
|
|||
}
|
||||
|
||||
static size_t
|
||||
calc_format_len (const SpaFormat *format)
|
||||
{
|
||||
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)
|
||||
write_props (void *p, const SpaProps *props, off_t offset)
|
||||
{
|
||||
size_t len, slen;
|
||||
unsigned int i, j;
|
||||
void *p, *base;
|
||||
SpaFormat *tf;
|
||||
SpaProps *tp;
|
||||
const SpaProps *sp;
|
||||
SpaPropInfo *pi, *bpi;
|
||||
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 */
|
||||
/* port_id + format + mask */
|
||||
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));
|
||||
/* write propinfo array */
|
||||
bpi = pi = SPA_MEMBER (tp, SPA_PTR_TO_INT (tp->prop_info), SpaPropInfo);
|
||||
for (i = 0; i < tp->n_prop_info; i++) {
|
||||
memcpy (pi, &sp->prop_info[i], sizeof (SpaPropInfo));
|
||||
pi->mask_offset = sizeof (SpaFormat);
|
||||
pi->priv = NULL;
|
||||
memcpy (pi, &props->prop_info[i], sizeof (SpaPropInfo));
|
||||
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++) {
|
||||
pi->range_values = SPA_INT_TO_PTR (SPA_PTRDIFF (ri, tp));
|
||||
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++;
|
||||
}
|
||||
pi++;
|
||||
|
@ -883,7 +894,7 @@ builder_add_set_format (struct stack_builder *sb, SpaControlCmdSetFormat *sf)
|
|||
pi = bpi;
|
||||
for (i = 0; i < tp->n_prop_info; i++) {
|
||||
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);
|
||||
p += pi->maxsize;
|
||||
} else {
|
||||
|
@ -891,6 +902,95 @@ builder_add_set_format (struct stack_builder *sb, SpaControlCmdSetFormat *sf)
|
|||
}
|
||||
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));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -248,7 +248,7 @@ print_value (const SpaPropInfo *info, int size, const void *value)
|
|||
fprintf (stderr, "%" PRIu16, *(uint16_t *)value);
|
||||
break;
|
||||
case SPA_PROP_TYPE_INT32:
|
||||
fprintf (stderr, stderr, "%" PRIi32, *(int32_t *)value);
|
||||
fprintf (stderr, "%" PRIi32, *(int32_t *)value);
|
||||
break;
|
||||
case SPA_PROP_TYPE_UINT32:
|
||||
fprintf (stderr, "%" PRIu32, *(uint32_t *)value);
|
||||
|
|
|
@ -47,10 +47,8 @@ spa_props_set_prop (SpaProps *props,
|
|||
if (info->offset != 0)
|
||||
memcpy ((uint8_t*)props + info->offset, value->value, value->size);
|
||||
|
||||
if (info->mask_offset != 0) {
|
||||
uint32_t *mask = (uint32_t *)((uint8_t *)props + info->mask_offset);
|
||||
*mask &= ~info->unset_mask;
|
||||
}
|
||||
props->unset_mask &= ~(1 << index);
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
|
@ -71,11 +69,9 @@ spa_props_get_prop (const SpaProps *props,
|
|||
if ((info->flags & SPA_PROP_FLAG_READABLE) == 0)
|
||||
return SPA_RESULT_INVALID_PROPERTY_ACCESS;
|
||||
|
||||
if (info->mask_offset != 0) {
|
||||
uint32_t *mask = (uint32_t *)((uint8_t *)props + info->mask_offset);
|
||||
if ((*mask & info->unset_mask))
|
||||
return SPA_RESULT_PROPERTY_UNSET;
|
||||
}
|
||||
if (props->unset_mask & (1 << index))
|
||||
return SPA_RESULT_PROPERTY_UNSET;
|
||||
|
||||
value->type = info->type;
|
||||
value->size = info->maxsize;
|
||||
if (info->offset != 0)
|
||||
|
@ -109,10 +105,8 @@ spa_props_copy (const SpaProps *src,
|
|||
|
||||
if (info->offset)
|
||||
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);
|
||||
*mask &= ~info->unset_mask;
|
||||
}
|
||||
|
||||
dest->unset_mask &= ~(1 << i);
|
||||
}
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
|
|
@ -345,135 +345,105 @@ static const SpaPropInfo raw_format_prop_info[] =
|
|||
sizeof (uint32_t), &default_info.format,
|
||||
SPA_PROP_RANGE_TYPE_ENUM, SPA_N_ELEMENTS (format_range), format_range,
|
||||
NULL,
|
||||
offsetof (SpaVideoRawFormat, info.format),
|
||||
offsetof (SpaVideoRawFormat, unset_mask), 1 << 0,
|
||||
NULL },
|
||||
offsetof (SpaVideoRawFormat, info.format) },
|
||||
{ SPA_PROP_ID_VIDEO_SIZE, "size", "Video size",
|
||||
SPA_PROP_FLAG_READWRITE,
|
||||
SPA_PROP_TYPE_RECTANGLE, sizeof (SpaRectangle),
|
||||
sizeof (SpaRectangle), &default_info.size,
|
||||
SPA_PROP_RANGE_TYPE_MIN_MAX, 2, size_range,
|
||||
NULL,
|
||||
offsetof (SpaVideoRawFormat, info.size),
|
||||
offsetof (SpaVideoRawFormat, unset_mask), 1 << 1,
|
||||
NULL },
|
||||
offsetof (SpaVideoRawFormat, info.size) },
|
||||
{ SPA_PROP_ID_VIDEO_FRAMERATE, "framerate", "Video framerate",
|
||||
SPA_PROP_FLAG_READWRITE,
|
||||
SPA_PROP_TYPE_FRACTION, sizeof (SpaFraction),
|
||||
sizeof (SpaFraction), &default_info.framerate,
|
||||
SPA_PROP_RANGE_TYPE_MIN_MAX, 2, framerate_range,
|
||||
NULL,
|
||||
offsetof (SpaVideoRawFormat, info.framerate),
|
||||
offsetof (SpaVideoRawFormat, unset_mask), 1 << 2,
|
||||
NULL },
|
||||
offsetof (SpaVideoRawFormat, info.framerate) },
|
||||
{ SPA_PROP_ID_VIDEO_MAX_FRAMERATE, "max-framerate", "Video max framerate",
|
||||
SPA_PROP_FLAG_READWRITE | SPA_PROP_FLAG_OPTIONAL,
|
||||
SPA_PROP_TYPE_FRACTION, sizeof (SpaFraction),
|
||||
sizeof (SpaFraction), &default_info.max_framerate,
|
||||
SPA_PROP_RANGE_TYPE_MIN_MAX, 2, framerate_range,
|
||||
NULL,
|
||||
offsetof (SpaVideoRawFormat, info.max_framerate),
|
||||
offsetof (SpaVideoRawFormat, unset_mask), 1 << 3,
|
||||
NULL },
|
||||
offsetof (SpaVideoRawFormat, info.max_framerate) },
|
||||
{ SPA_PROP_ID_VIDEO_VIEWS, "views", "Video number of views",
|
||||
SPA_PROP_FLAG_READWRITE | SPA_PROP_FLAG_OPTIONAL,
|
||||
SPA_PROP_TYPE_UINT32, sizeof (uint32_t),
|
||||
sizeof (uint32_t), &default_info.views,
|
||||
SPA_PROP_RANGE_TYPE_MIN_MAX, 2, uint32_range,
|
||||
NULL,
|
||||
offsetof (SpaVideoRawFormat, info.views),
|
||||
offsetof (SpaVideoRawFormat, unset_mask), 1 << 4,
|
||||
NULL },
|
||||
offsetof (SpaVideoRawFormat, info.views) },
|
||||
{ SPA_PROP_ID_VIDEO_INTERLACE_MODE, "interlace-mode", "Interlace mode",
|
||||
SPA_PROP_FLAG_READWRITE | SPA_PROP_FLAG_OPTIONAL,
|
||||
SPA_PROP_TYPE_UINT32, sizeof (uint32_t),
|
||||
sizeof (uint32_t), &default_info.interlace_mode,
|
||||
SPA_PROP_RANGE_TYPE_ENUM, SPA_N_ELEMENTS (interlace_mode_range), interlace_mode_range,
|
||||
NULL,
|
||||
offsetof (SpaVideoRawFormat, info.interlace_mode),
|
||||
offsetof (SpaVideoRawFormat, unset_mask), 1 << 5,
|
||||
NULL },
|
||||
offsetof (SpaVideoRawFormat, info.interlace_mode) },
|
||||
{ SPA_PROP_ID_VIDEO_PIXEL_ASPECT_RATIO, "pixel-aspect-ratio", "Video pixel aspect ratio",
|
||||
SPA_PROP_FLAG_READWRITE | SPA_PROP_FLAG_OPTIONAL,
|
||||
SPA_PROP_TYPE_FRACTION, sizeof (SpaFraction),
|
||||
sizeof (SpaFraction), &default_info.pixel_aspect_ratio,
|
||||
SPA_PROP_RANGE_TYPE_MIN_MAX, 2, framerate_range,
|
||||
NULL,
|
||||
offsetof (SpaVideoRawFormat, info.pixel_aspect_ratio),
|
||||
offsetof (SpaVideoRawFormat, unset_mask), 1 << 6,
|
||||
NULL },
|
||||
offsetof (SpaVideoRawFormat, info.pixel_aspect_ratio) },
|
||||
{ SPA_PROP_ID_VIDEO_MULTIVIEW_MODE, "multiview-mode", "Multiview mode",
|
||||
SPA_PROP_FLAG_READWRITE | SPA_PROP_FLAG_OPTIONAL,
|
||||
SPA_PROP_TYPE_UINT32, sizeof (uint32_t),
|
||||
sizeof (uint32_t), &default_info.multiview_mode,
|
||||
SPA_PROP_RANGE_TYPE_ENUM, SPA_N_ELEMENTS (multiview_mode_range), multiview_mode_range,
|
||||
NULL,
|
||||
offsetof (SpaVideoRawFormat, info.multiview_mode),
|
||||
offsetof (SpaVideoRawFormat, unset_mask), 1 << 7,
|
||||
NULL },
|
||||
offsetof (SpaVideoRawFormat, info.multiview_mode) },
|
||||
{ SPA_PROP_ID_VIDEO_MULTIVIEW_FLAGS, "multiview-flags", "Multiview flags",
|
||||
SPA_PROP_FLAG_READWRITE | SPA_PROP_FLAG_OPTIONAL,
|
||||
SPA_PROP_TYPE_UINT32, sizeof (uint32_t),
|
||||
sizeof (uint32_t), &default_info.multiview_flags,
|
||||
SPA_PROP_RANGE_TYPE_FLAGS, SPA_N_ELEMENTS (multiview_flags_range), multiview_flags_range,
|
||||
NULL,
|
||||
offsetof (SpaVideoRawFormat, info.multiview_flags),
|
||||
offsetof (SpaVideoRawFormat, unset_mask), 1 << 8,
|
||||
NULL },
|
||||
offsetof (SpaVideoRawFormat, info.multiview_flags) },
|
||||
{ SPA_PROP_ID_VIDEO_CHROMA_SITE, "chroma-site", "Chroma site",
|
||||
SPA_PROP_FLAG_READWRITE | SPA_PROP_FLAG_OPTIONAL,
|
||||
SPA_PROP_TYPE_UINT32, sizeof (uint32_t),
|
||||
sizeof (uint32_t), &default_info.chroma_site,
|
||||
SPA_PROP_RANGE_TYPE_FLAGS, SPA_N_ELEMENTS (chroma_site_range), chroma_site_range,
|
||||
NULL,
|
||||
offsetof (SpaVideoRawFormat, info.chroma_site),
|
||||
offsetof (SpaVideoRawFormat, unset_mask), 1 << 9,
|
||||
NULL },
|
||||
offsetof (SpaVideoRawFormat, info.chroma_site) },
|
||||
{ SPA_PROP_ID_VIDEO_COLOR_RANGE, "color-range", "Color range",
|
||||
SPA_PROP_FLAG_READWRITE | SPA_PROP_FLAG_OPTIONAL,
|
||||
SPA_PROP_TYPE_UINT32, sizeof (uint32_t),
|
||||
sizeof (uint32_t), &default_info.color_range,
|
||||
SPA_PROP_RANGE_TYPE_ENUM, SPA_N_ELEMENTS (color_range_range), color_range_range,
|
||||
NULL,
|
||||
offsetof (SpaVideoRawFormat, info.color_range),
|
||||
offsetof (SpaVideoRawFormat, unset_mask), 1 << 10,
|
||||
NULL },
|
||||
offsetof (SpaVideoRawFormat, info.color_range) },
|
||||
{ SPA_PROP_ID_VIDEO_COLOR_MATRIX, "color-matrix", "Color matrix",
|
||||
SPA_PROP_FLAG_READWRITE | SPA_PROP_FLAG_OPTIONAL,
|
||||
SPA_PROP_TYPE_UINT32, sizeof (uint32_t),
|
||||
sizeof (uint32_t), &default_info.color_matrix,
|
||||
SPA_PROP_RANGE_TYPE_ENUM, SPA_N_ELEMENTS (color_matrix_range), color_matrix_range,
|
||||
NULL,
|
||||
offsetof (SpaVideoRawFormat, info.color_matrix),
|
||||
offsetof (SpaVideoRawFormat, unset_mask), 1 << 11,
|
||||
NULL },
|
||||
offsetof (SpaVideoRawFormat, info.color_matrix) },
|
||||
{ SPA_PROP_ID_VIDEO_TRANSFER_FUNCTION, "transfer-function", "Transfer function",
|
||||
SPA_PROP_FLAG_READWRITE | SPA_PROP_FLAG_OPTIONAL,
|
||||
SPA_PROP_TYPE_UINT32, sizeof (uint32_t),
|
||||
sizeof (uint32_t), &default_info.transfer_function,
|
||||
SPA_PROP_RANGE_TYPE_ENUM, SPA_N_ELEMENTS (transfer_function_range), transfer_function_range,
|
||||
NULL,
|
||||
offsetof (SpaVideoRawFormat, info.transfer_function),
|
||||
offsetof (SpaVideoRawFormat, unset_mask), 1 << 12,
|
||||
NULL },
|
||||
offsetof (SpaVideoRawFormat, info.transfer_function) },
|
||||
{ SPA_PROP_ID_VIDEO_COLOR_PRIMARIES, "color-primaries", "Color primaries",
|
||||
SPA_PROP_FLAG_READWRITE | SPA_PROP_FLAG_OPTIONAL,
|
||||
SPA_PROP_TYPE_UINT32, sizeof (uint32_t),
|
||||
sizeof (uint32_t), &default_info.color_primaries,
|
||||
SPA_PROP_RANGE_TYPE_ENUM, SPA_N_ELEMENTS (color_primaries_range), color_primaries_range,
|
||||
NULL,
|
||||
offsetof (SpaVideoRawFormat, info.color_primaries),
|
||||
offsetof (SpaVideoRawFormat, unset_mask), 1 << 13,
|
||||
NULL },
|
||||
offsetof (SpaVideoRawFormat, info.color_primaries) },
|
||||
{ SPA_PROP_ID_VIDEO_RAW_INFO, "info", "the SpaVideoRawInfo structure",
|
||||
SPA_PROP_FLAG_READWRITE | SPA_PROP_FLAG_OPTIONAL,
|
||||
SPA_PROP_TYPE_POINTER, sizeof (SpaVideoRawInfo),
|
||||
0, NULL,
|
||||
SPA_PROP_RANGE_TYPE_NONE, 0, NULL,
|
||||
NULL,
|
||||
offsetof (SpaVideoRawFormat, info),
|
||||
offsetof (SpaVideoRawFormat, unset_mask), ~0,
|
||||
NULL },
|
||||
offsetof (SpaVideoRawFormat, info) },
|
||||
};
|
||||
|
||||
SpaResult
|
||||
|
@ -483,7 +453,7 @@ spa_video_raw_format_init (SpaVideoRawFormat *format)
|
|||
format->format.media_subtype = SPA_MEDIA_SUBTYPE_RAW;
|
||||
format->format.props.n_prop_info = SPA_N_ELEMENTS (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;
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
|
@ -549,8 +519,6 @@ spa_video_raw_fill_prop_info (SpaPropInfo *info,
|
|||
if (raw_format_prop_info[i].id == id) {
|
||||
memcpy (info, &raw_format_prop_info[i], sizeof (SpaPropInfo));
|
||||
info->offset = offset;
|
||||
info->mask_offset = 0;
|
||||
info->unset_mask = 0;
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -124,54 +124,42 @@ static const SpaPropInfo prop_info[] =
|
|||
strlen (default_device)+1, default_device,
|
||||
SPA_PROP_RANGE_TYPE_NONE, 0, NULL,
|
||||
NULL,
|
||||
offsetof (SpaALSASinkProps, device),
|
||||
0, 0,
|
||||
NULL },
|
||||
offsetof (SpaALSASinkProps, device) },
|
||||
{ PROP_ID_DEVICE_NAME, "device-name", "Human-readable name of the sound device",
|
||||
SPA_PROP_FLAG_READABLE,
|
||||
SPA_PROP_TYPE_STRING, 127,
|
||||
0, NULL,
|
||||
SPA_PROP_RANGE_TYPE_NONE, 0, NULL,
|
||||
NULL,
|
||||
offsetof (SpaALSASinkProps, device_name),
|
||||
0, 0,
|
||||
NULL },
|
||||
offsetof (SpaALSASinkProps, device_name) },
|
||||
{ PROP_ID_CARD_NAME, "card-name", "Human-readable name of the sound card",
|
||||
SPA_PROP_FLAG_READABLE,
|
||||
SPA_PROP_TYPE_STRING, 127,
|
||||
0, NULL,
|
||||
SPA_PROP_RANGE_TYPE_NONE, 0, NULL,
|
||||
NULL,
|
||||
offsetof (SpaALSASinkProps, card_name),
|
||||
0, 0,
|
||||
NULL },
|
||||
offsetof (SpaALSASinkProps, card_name) },
|
||||
{ PROP_ID_BUFFER_TIME, "buffer-time", "The total size of the buffer in time",
|
||||
SPA_PROP_FLAG_READWRITE,
|
||||
SPA_PROP_TYPE_UINT32, sizeof (uint32_t),
|
||||
sizeof (uint32_t), &default_buffer_time,
|
||||
SPA_PROP_RANGE_TYPE_MIN_MAX, 2, uint32_range,
|
||||
NULL,
|
||||
offsetof (SpaALSASinkProps, buffer_time),
|
||||
0, 0,
|
||||
NULL },
|
||||
offsetof (SpaALSASinkProps, buffer_time) },
|
||||
{ PROP_ID_PERIOD_TIME, "period-time", "The size of a period in time",
|
||||
SPA_PROP_FLAG_READWRITE,
|
||||
SPA_PROP_TYPE_UINT32, sizeof (uint32_t),
|
||||
sizeof (uint32_t), &default_period_time,
|
||||
SPA_PROP_RANGE_TYPE_MIN_MAX, 2, uint32_range,
|
||||
NULL,
|
||||
offsetof (SpaALSASinkProps, period_time),
|
||||
0, 0,
|
||||
NULL },
|
||||
offsetof (SpaALSASinkProps, period_time) },
|
||||
{ PROP_ID_PERIOD_EVENT, "period-event", "Generate an event each period",
|
||||
SPA_PROP_FLAG_READWRITE,
|
||||
SPA_PROP_TYPE_BOOL, sizeof (bool),
|
||||
sizeof (bool), &default_period_event,
|
||||
SPA_PROP_RANGE_TYPE_NONE, 0, NULL,
|
||||
NULL,
|
||||
offsetof (SpaALSASinkProps, period_event),
|
||||
0, 0,
|
||||
NULL },
|
||||
offsetof (SpaALSASinkProps, period_event) },
|
||||
};
|
||||
|
||||
static SpaResult
|
||||
|
|
|
@ -90,27 +90,21 @@ static const SpaPropInfo prop_info[] =
|
|||
sizeof (uint32_t), &default_wave,
|
||||
SPA_PROP_RANGE_TYPE_ENUM, SPA_N_ELEMENTS (wave_range), wave_range,
|
||||
NULL,
|
||||
offsetof (SpaAudioTestSrcProps, wave),
|
||||
0, 0,
|
||||
NULL },
|
||||
offsetof (SpaAudioTestSrcProps, wave) },
|
||||
{ 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_TYPE_DOUBLE, sizeof (double),
|
||||
sizeof (double), &default_freq,
|
||||
SPA_PROP_RANGE_TYPE_MIN_MAX, 2, freq_range,
|
||||
NULL,
|
||||
offsetof (SpaAudioTestSrcProps, freq),
|
||||
0, 0,
|
||||
NULL },
|
||||
offsetof (SpaAudioTestSrcProps, freq) },
|
||||
{ PROP_ID_VOLUME, "volume", "The Volume factor",
|
||||
SPA_PROP_FLAG_READWRITE,
|
||||
SPA_PROP_TYPE_DOUBLE, sizeof (double),
|
||||
sizeof (double), &default_volume,
|
||||
SPA_PROP_RANGE_TYPE_MIN_MAX, 2, volume_range,
|
||||
NULL,
|
||||
offsetof (SpaAudioTestSrcProps, volume),
|
||||
0, 0,
|
||||
NULL },
|
||||
offsetof (SpaAudioTestSrcProps, volume) },
|
||||
};
|
||||
|
||||
static void
|
||||
|
|
|
@ -90,9 +90,7 @@ static const SpaPropInfo prop_info[PROP_ID_LAST] =
|
|||
sizeof (int), NULL,
|
||||
SPA_PROP_RANGE_TYPE_NONE, 0, NULL,
|
||||
NULL,
|
||||
offsetof (SpaProxyProps, socketfd),
|
||||
0, 0,
|
||||
NULL },
|
||||
offsetof (SpaProxyProps, socketfd) },
|
||||
};
|
||||
|
||||
static void
|
||||
|
@ -920,6 +918,7 @@ parse_control (SpaProxy *this,
|
|||
{
|
||||
SpaControlCmdPortUpdate pu;
|
||||
SpaProxyPort *port;
|
||||
unsigned int i;
|
||||
|
||||
fprintf (stderr, "proxy %p: got port update %d\n", this, cmd);
|
||||
if (spa_control_iter_parse_cmd (&it, &pu) < 0)
|
||||
|
@ -929,6 +928,12 @@ parse_control (SpaProxy *this,
|
|||
break;
|
||||
|
||||
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) {
|
||||
do_init_port (this, pu.port_id, pu.direction);
|
||||
} else {
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
|
||||
typedef struct _SpaV4l2Source SpaV4l2Source;
|
||||
|
||||
static const char default_device[] = "/dev/video1";
|
||||
static const char default_device[] = "/dev/video0";
|
||||
|
||||
typedef struct {
|
||||
SpaProps props;
|
||||
|
@ -66,7 +66,6 @@ typedef struct _V4l2Format V4l2Format;
|
|||
|
||||
struct _V4l2Format {
|
||||
SpaFormat fmt;
|
||||
uint32_t unset_mask;
|
||||
SpaVideoFormat format;
|
||||
SpaRectangle size;
|
||||
SpaFraction framerate;
|
||||
|
@ -146,27 +145,21 @@ static const SpaPropInfo prop_info[] =
|
|||
strlen (default_device)+1, default_device,
|
||||
SPA_PROP_RANGE_TYPE_NONE, 0, NULL,
|
||||
NULL,
|
||||
offsetof (SpaV4l2SourceProps, device),
|
||||
0, 0,
|
||||
NULL },
|
||||
offsetof (SpaV4l2SourceProps, device) },
|
||||
{ PROP_ID_DEVICE_NAME, "device-name", "Human-readable name of the device",
|
||||
SPA_PROP_FLAG_READABLE,
|
||||
SPA_PROP_TYPE_STRING, 127,
|
||||
0, NULL,
|
||||
SPA_PROP_RANGE_TYPE_NONE, 0, NULL,
|
||||
NULL,
|
||||
offsetof (SpaV4l2SourceProps, device_name),
|
||||
0, 0,
|
||||
NULL },
|
||||
offsetof (SpaV4l2SourceProps, device_name) },
|
||||
{ PROP_ID_DEVICE_FD, "device-fd", "Device file descriptor",
|
||||
SPA_PROP_FLAG_READABLE,
|
||||
SPA_PROP_TYPE_UINT32, sizeof (uint32_t),
|
||||
0, NULL,
|
||||
SPA_PROP_RANGE_TYPE_NONE, 0, NULL,
|
||||
NULL,
|
||||
offsetof (SpaV4l2SourceProps, device_fd),
|
||||
0, 0,
|
||||
NULL },
|
||||
offsetof (SpaV4l2SourceProps, device_fd) },
|
||||
};
|
||||
|
||||
static SpaResult
|
||||
|
@ -347,20 +340,12 @@ spa_v4l2_format_init (V4l2Format *f)
|
|||
spa_video_raw_fill_prop_info (&f->infos[0],
|
||||
SPA_PROP_ID_VIDEO_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_PROP_ID_VIDEO_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_PROP_ID_VIDEO_FRAMERATE,
|
||||
offsetof (V4l2Format, framerate));
|
||||
f->infos[2].mask_offset = offsetof (V4l2Format, unset_mask);
|
||||
f->infos[2].unset_mask = 1 << 2;
|
||||
}
|
||||
|
||||
static SpaResult
|
||||
|
|
|
@ -279,13 +279,12 @@ again:
|
|||
fmt->fmt.media_subtype = info->media_subtype;
|
||||
fmt->fmt.props.prop_info = fmt->infos;
|
||||
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) {
|
||||
spa_video_raw_fill_prop_info (&fmt->infos[pi],
|
||||
SPA_PROP_ID_VIDEO_FORMAT,
|
||||
offsetof (V4l2Format, format));
|
||||
fmt->infos[pi].mask_offset = offsetof (V4l2Format, unset_mask);
|
||||
fmt->format = info->format;
|
||||
pi = ++fmt->fmt.props.n_prop_info;
|
||||
}
|
||||
|
@ -293,7 +292,6 @@ again:
|
|||
spa_video_raw_fill_prop_info (&fmt->infos[pi],
|
||||
SPA_PROP_ID_VIDEO_SIZE,
|
||||
offsetof (V4l2Format, size));
|
||||
fmt->infos[pi].mask_offset = offsetof (V4l2Format, unset_mask);
|
||||
fmt->size.width = state->frmsize.discrete.width;
|
||||
fmt->size.height = state->frmsize.discrete.height;
|
||||
pi = ++fmt->fmt.props.n_prop_info;
|
||||
|
@ -301,7 +299,6 @@ again:
|
|||
spa_video_raw_fill_prop_info (&fmt->infos[pi],
|
||||
SPA_PROP_ID_VIDEO_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_values = fmt->ranges;
|
||||
fmt->infos[pi].n_range_values = 0;
|
||||
|
@ -328,8 +325,7 @@ again:
|
|||
i = ++state->frmival.index;
|
||||
}
|
||||
fmt->infos[pi].n_range_values = i;
|
||||
fmt->infos[pi].unset_mask = 1 << i;
|
||||
fmt->unset_mask |= fmt->infos[pi].unset_mask;
|
||||
fmt->fmt.props.unset_mask |= 1 << pi;
|
||||
pi = ++fmt->fmt.props.n_prop_info;
|
||||
|
||||
*format = &state->format[0].fmt;
|
||||
|
|
|
@ -81,18 +81,14 @@ static const SpaPropInfo prop_info[] =
|
|||
sizeof (double), &default_volume,
|
||||
SPA_PROP_RANGE_TYPE_MIN_MAX, 2, volume_range,
|
||||
NULL,
|
||||
offsetof (SpaVolumeProps, volume),
|
||||
0, 0,
|
||||
NULL },
|
||||
offsetof (SpaVolumeProps, volume) },
|
||||
{ PROP_ID_MUTE, "mute", "Mute",
|
||||
SPA_PROP_FLAG_READWRITE,
|
||||
SPA_PROP_TYPE_BOOL, sizeof (bool),
|
||||
sizeof (bool), &default_mute,
|
||||
SPA_PROP_RANGE_TYPE_NONE, 0, NULL,
|
||||
NULL,
|
||||
offsetof (SpaVolumeProps, mute),
|
||||
0, 0,
|
||||
NULL },
|
||||
offsetof (SpaVolumeProps, mute) },
|
||||
};
|
||||
|
||||
static void
|
||||
|
|
|
@ -103,27 +103,21 @@ static const SpaPropInfo prop_info[] =
|
|||
strlen (default_device)+1, default_device,
|
||||
SPA_PROP_RANGE_TYPE_NONE, 0, NULL,
|
||||
NULL,
|
||||
offsetof (SpaXvSinkProps, device),
|
||||
0, 0,
|
||||
NULL },
|
||||
offsetof (SpaXvSinkProps, device) },
|
||||
{ PROP_ID_DEVICE_NAME, "device-name", "Human-readable name of the device",
|
||||
SPA_PROP_FLAG_READABLE,
|
||||
SPA_PROP_TYPE_STRING, 127,
|
||||
0, NULL,
|
||||
SPA_PROP_RANGE_TYPE_NONE, 0, NULL,
|
||||
NULL,
|
||||
offsetof (SpaXvSinkProps, device_name),
|
||||
0, 0,
|
||||
NULL },
|
||||
offsetof (SpaXvSinkProps, device_name) },
|
||||
{ PROP_ID_DEVICE_FD, "device-fd", "Device file descriptor",
|
||||
SPA_PROP_FLAG_READABLE,
|
||||
SPA_PROP_TYPE_UINT32, sizeof (uint32_t),
|
||||
0, NULL,
|
||||
SPA_PROP_RANGE_TYPE_NONE, 0, NULL,
|
||||
NULL,
|
||||
offsetof (SpaXvSinkProps, device_fd),
|
||||
0, 0,
|
||||
NULL },
|
||||
offsetof (SpaXvSinkProps, device_fd) },
|
||||
};
|
||||
|
||||
static SpaResult
|
||||
|
|
Loading…
Reference in a new issue