mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-02 09:01:50 -05:00
remove hardcoded negotiation
Remove the hardcoded negotiation and replace by filtering accepted and possible formats. Not quite correct yet because v4l2 doesn't actually do filtering yet.
This commit is contained in:
parent
f743b00f2c
commit
ad71c82159
4 changed files with 65 additions and 72 deletions
|
|
@ -22,6 +22,7 @@
|
||||||
#include <gio/gio.h>
|
#include <gio/gio.h>
|
||||||
|
|
||||||
#include <spa/include/spa/video/format.h>
|
#include <spa/include/spa/video/format.h>
|
||||||
|
#include <spa/include/spa/debug.h>
|
||||||
|
|
||||||
#include "pinos/client/pinos.h"
|
#include "pinos/client/pinos.h"
|
||||||
#include "pinos/client/enumtypes.h"
|
#include "pinos/client/enumtypes.h"
|
||||||
|
|
@ -241,46 +242,35 @@ do_negotiate (PinosLink *this)
|
||||||
{
|
{
|
||||||
PinosLinkPrivate *priv = this->priv;
|
PinosLinkPrivate *priv = this->priv;
|
||||||
SpaResult res;
|
SpaResult res;
|
||||||
SpaFormat *format;
|
SpaFormat *filter, *format;
|
||||||
SpaProps *props;
|
void *istate = NULL, *ostate = NULL;
|
||||||
uint32_t val;
|
|
||||||
SpaPropValue value;
|
|
||||||
void *state = NULL;
|
|
||||||
SpaFraction frac;
|
|
||||||
SpaRectangle rect;
|
|
||||||
|
|
||||||
g_debug ("link %p: doing set format", this);
|
g_debug ("link %p: doing set format", this);
|
||||||
|
|
||||||
if ((res = spa_node_port_enum_formats (priv->output_node, priv->output_port, &format, NULL, &state)) < 0) {
|
again:
|
||||||
|
if ((res = spa_node_port_enum_formats (priv->input_node,
|
||||||
|
priv->input_port,
|
||||||
|
&filter,
|
||||||
|
NULL,
|
||||||
|
&istate)) < 0) {
|
||||||
g_warning ("error enum formats: %d", res);
|
g_warning ("error enum formats: %d", res);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
spa_debug_format (filter);
|
||||||
|
|
||||||
props = &format->props;
|
if ((res = spa_node_port_enum_formats (priv->output_node,
|
||||||
|
priv->output_port,
|
||||||
value.type = SPA_PROP_TYPE_UINT32;
|
&format,
|
||||||
value.size = sizeof (uint32_t);
|
filter,
|
||||||
value.value = &val;
|
&ostate)) < 0) {
|
||||||
|
if (res == SPA_RESULT_ENUM_END) {
|
||||||
val = SPA_VIDEO_FORMAT_YUY2;
|
ostate = NULL;
|
||||||
if ((res = spa_props_set_prop (props, spa_props_index_for_id (props, SPA_PROP_ID_VIDEO_FORMAT), &value)) < 0)
|
goto again;
|
||||||
return res;
|
}
|
||||||
|
g_warning ("error enum formats: %d", res);
|
||||||
value.type = SPA_PROP_TYPE_RECTANGLE;
|
|
||||||
value.size = sizeof (SpaRectangle);
|
|
||||||
value.value = ▭
|
|
||||||
rect.width = 640;
|
|
||||||
rect.height = 480;
|
|
||||||
if ((res = spa_props_set_prop (props, spa_props_index_for_id (props, SPA_PROP_ID_VIDEO_SIZE), &value)) < 0)
|
|
||||||
return res;
|
|
||||||
|
|
||||||
value.type = SPA_PROP_TYPE_FRACTION;
|
|
||||||
value.size = sizeof (SpaFraction);
|
|
||||||
value.value = &frac;
|
|
||||||
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;
|
return res;
|
||||||
|
}
|
||||||
|
spa_debug_format (format);
|
||||||
|
|
||||||
if ((res = spa_node_port_set_format (priv->output_node, priv->output_port, 0, format)) < 0) {
|
if ((res = spa_node_port_set_format (priv->output_node, priv->output_port, 0, format)) < 0) {
|
||||||
g_warning ("error set format output: %d", res);
|
g_warning ("error set format output: %d", res);
|
||||||
|
|
|
||||||
|
|
@ -106,7 +106,7 @@ typedef struct {
|
||||||
uint32_t change_mask;
|
uint32_t change_mask;
|
||||||
SpaDirection direction;
|
SpaDirection direction;
|
||||||
unsigned int n_possible_formats;
|
unsigned int n_possible_formats;
|
||||||
const SpaFormat **possible_formats;
|
SpaFormat **possible_formats;
|
||||||
const SpaProps *props;
|
const SpaProps *props;
|
||||||
const SpaPortInfo *info;
|
const SpaPortInfo *info;
|
||||||
} SpaControlCmdPortUpdate;
|
} SpaControlCmdPortUpdate;
|
||||||
|
|
|
||||||
|
|
@ -408,7 +408,7 @@ iter_parse_port_update (struct stack_iter *si, SpaControlCmdPortUpdate *pu)
|
||||||
|
|
||||||
if (pu->possible_formats)
|
if (pu->possible_formats)
|
||||||
pu->possible_formats = SPA_MEMBER (p,
|
pu->possible_formats = SPA_MEMBER (p,
|
||||||
SPA_PTR_TO_INT (pu->possible_formats), const SpaFormat *);
|
SPA_PTR_TO_INT (pu->possible_formats), SpaFormat *);
|
||||||
for (i = 0; i < pu->n_possible_formats; i++) {
|
for (i = 0; i < pu->n_possible_formats; i++) {
|
||||||
pu->possible_formats[i] = parse_format (mem, p,
|
pu->possible_formats[i] = parse_format (mem, p,
|
||||||
SPA_PTR_TO_INT (pu->possible_formats[i]));
|
SPA_PTR_TO_INT (pu->possible_formats[i]));
|
||||||
|
|
|
||||||
|
|
@ -49,14 +49,15 @@ typedef struct {
|
||||||
} SpaProxyProps;
|
} SpaProxyProps;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
SpaDirection direction;
|
bool valid;
|
||||||
bool valid;
|
SpaDirection direction;
|
||||||
bool have_format;
|
SpaPortInfo info;
|
||||||
SpaPortInfo info;
|
SpaFormat *format;
|
||||||
SpaPortStatus status;
|
unsigned int n_formats;
|
||||||
SpaFormat formats[2];
|
SpaFormat **formats;
|
||||||
unsigned int n_buffers;
|
SpaPortStatus status;
|
||||||
SpaBuffer **buffers;
|
unsigned int n_buffers;
|
||||||
|
SpaBuffer **buffers;
|
||||||
} SpaProxyPort;
|
} SpaProxyPort;
|
||||||
|
|
||||||
struct _SpaProxy {
|
struct _SpaProxy {
|
||||||
|
|
@ -334,7 +335,9 @@ spa_proxy_node_get_port_ids (SpaNode *node,
|
||||||
static void
|
static void
|
||||||
do_init_port (SpaProxy *this,
|
do_init_port (SpaProxy *this,
|
||||||
uint32_t port_id,
|
uint32_t port_id,
|
||||||
SpaDirection direction)
|
SpaDirection direction,
|
||||||
|
unsigned int n_formats,
|
||||||
|
SpaFormat **formats)
|
||||||
{
|
{
|
||||||
SpaEvent event;
|
SpaEvent event;
|
||||||
SpaProxyPort *port;
|
SpaProxyPort *port;
|
||||||
|
|
@ -344,7 +347,9 @@ do_init_port (SpaProxy *this,
|
||||||
port = &this->ports[port_id];
|
port = &this->ports[port_id];
|
||||||
port->direction = direction;
|
port->direction = direction;
|
||||||
port->valid = true;
|
port->valid = true;
|
||||||
port->have_format = false;
|
port->format = NULL;
|
||||||
|
port->n_formats = n_formats;
|
||||||
|
port->formats = formats;
|
||||||
|
|
||||||
if (direction == SPA_DIRECTION_INPUT)
|
if (direction == SPA_DIRECTION_INPUT)
|
||||||
this->n_inputs++;
|
this->n_inputs++;
|
||||||
|
|
@ -376,7 +381,9 @@ do_uninit_port (SpaProxy *this,
|
||||||
|
|
||||||
port->direction = SPA_DIRECTION_INVALID;
|
port->direction = SPA_DIRECTION_INVALID;
|
||||||
port->valid = false;
|
port->valid = false;
|
||||||
port->have_format = false;
|
if (port->format)
|
||||||
|
spa_format_unref (port->format);
|
||||||
|
port->format = NULL;
|
||||||
|
|
||||||
event.type = SPA_EVENT_TYPE_PORT_REMOVED;
|
event.type = SPA_EVENT_TYPE_PORT_REMOVED;
|
||||||
event.port_id = port_id;
|
event.port_id = port_id;
|
||||||
|
|
@ -400,7 +407,7 @@ spa_proxy_node_add_port (SpaNode *node,
|
||||||
if (!CHECK_FREE_PORT_ID (this, port_id))
|
if (!CHECK_FREE_PORT_ID (this, port_id))
|
||||||
return SPA_RESULT_INVALID_PORT;
|
return SPA_RESULT_INVALID_PORT;
|
||||||
|
|
||||||
do_init_port (this, port_id, direction);
|
do_init_port (this, port_id, direction, 0, NULL);
|
||||||
|
|
||||||
return SPA_RESULT_OK;
|
return SPA_RESULT_OK;
|
||||||
}
|
}
|
||||||
|
|
@ -447,13 +454,10 @@ spa_proxy_node_port_enum_formats (SpaNode *node,
|
||||||
|
|
||||||
index = (*state == NULL ? 0 : *(int*)state);
|
index = (*state == NULL ? 0 : *(int*)state);
|
||||||
|
|
||||||
switch (index) {
|
if (index >= port->n_formats)
|
||||||
case 0:
|
return SPA_RESULT_ENUM_END;
|
||||||
break;
|
|
||||||
default:
|
*format = port->formats[index];
|
||||||
return SPA_RESULT_ENUM_END;
|
|
||||||
}
|
|
||||||
*format = &port->formats[0];
|
|
||||||
*(int*)state = ++index;
|
*(int*)state = ++index;
|
||||||
|
|
||||||
return SPA_RESULT_OK;
|
return SPA_RESULT_OK;
|
||||||
|
|
@ -473,7 +477,7 @@ spa_proxy_node_port_set_format (SpaNode *node,
|
||||||
uint8_t buf[128];
|
uint8_t buf[128];
|
||||||
SpaResult res;
|
SpaResult res;
|
||||||
|
|
||||||
if (node == NULL || node->handle == NULL || format == NULL)
|
if (node == NULL || node->handle == NULL)
|
||||||
return SPA_RESULT_INVALID_ARGUMENTS;
|
return SPA_RESULT_INVALID_ARGUMENTS;
|
||||||
|
|
||||||
this = (SpaProxy *) node->handle;
|
this = (SpaProxy *) node->handle;
|
||||||
|
|
@ -486,9 +490,6 @@ spa_proxy_node_port_set_format (SpaNode *node,
|
||||||
spa_control_builder_init_into (&builder, buf, sizeof (buf), NULL, 0);
|
spa_control_builder_init_into (&builder, buf, sizeof (buf), NULL, 0);
|
||||||
sf.port_id = port_id;
|
sf.port_id = port_id;
|
||||||
sf.format = (SpaFormat *) format;
|
sf.format = (SpaFormat *) format;
|
||||||
|
|
||||||
spa_debug_format (sf.format);
|
|
||||||
|
|
||||||
spa_control_builder_add_cmd (&builder, SPA_CONTROL_CMD_SET_FORMAT, &sf);
|
spa_control_builder_add_cmd (&builder, SPA_CONTROL_CMD_SET_FORMAT, &sf);
|
||||||
spa_control_builder_end (&builder, &control);
|
spa_control_builder_end (&builder, &control);
|
||||||
|
|
||||||
|
|
@ -497,7 +498,11 @@ spa_proxy_node_port_set_format (SpaNode *node,
|
||||||
|
|
||||||
spa_control_clear (&control);
|
spa_control_clear (&control);
|
||||||
|
|
||||||
port->have_format = format != NULL;
|
if (port->format)
|
||||||
|
spa_format_unref (port->format);
|
||||||
|
if (format)
|
||||||
|
spa_format_ref ((SpaFormat *) format);
|
||||||
|
port->format = (SpaFormat *)format;
|
||||||
|
|
||||||
return SPA_RESULT_OK;
|
return SPA_RESULT_OK;
|
||||||
}
|
}
|
||||||
|
|
@ -520,10 +525,10 @@ spa_proxy_node_port_get_format (SpaNode *node,
|
||||||
|
|
||||||
port = &this->ports[port_id];
|
port = &this->ports[port_id];
|
||||||
|
|
||||||
if (!port->have_format)
|
if (!port->format)
|
||||||
return SPA_RESULT_NO_FORMAT;
|
return SPA_RESULT_NO_FORMAT;
|
||||||
|
|
||||||
*format = &port->formats[1];
|
*format = port->format;
|
||||||
|
|
||||||
return SPA_RESULT_OK;
|
return SPA_RESULT_OK;
|
||||||
}
|
}
|
||||||
|
|
@ -585,7 +590,7 @@ spa_proxy_node_port_get_status (SpaNode *node,
|
||||||
|
|
||||||
port = &this->ports[port_id];
|
port = &this->ports[port_id];
|
||||||
|
|
||||||
if (!port->have_format)
|
if (!port->format)
|
||||||
return SPA_RESULT_NO_FORMAT;
|
return SPA_RESULT_NO_FORMAT;
|
||||||
|
|
||||||
*status = &port->status;
|
*status = &port->status;
|
||||||
|
|
@ -720,7 +725,7 @@ spa_proxy_node_port_use_buffers (SpaNode *node,
|
||||||
|
|
||||||
port = &this->ports[port_id];
|
port = &this->ports[port_id];
|
||||||
|
|
||||||
if (!port->have_format)
|
if (!port->format)
|
||||||
return SPA_RESULT_NO_FORMAT;
|
return SPA_RESULT_NO_FORMAT;
|
||||||
|
|
||||||
for (i = 0; i < port->n_buffers; i++)
|
for (i = 0; i < port->n_buffers; i++)
|
||||||
|
|
@ -760,7 +765,7 @@ spa_proxy_node_port_alloc_buffers (SpaNode *node,
|
||||||
|
|
||||||
port = &this->ports[port_id];
|
port = &this->ports[port_id];
|
||||||
|
|
||||||
if (!port->have_format)
|
if (!port->format)
|
||||||
return SPA_RESULT_NO_FORMAT;
|
return SPA_RESULT_NO_FORMAT;
|
||||||
|
|
||||||
return SPA_RESULT_NOT_IMPLEMENTED;
|
return SPA_RESULT_NOT_IMPLEMENTED;
|
||||||
|
|
@ -807,7 +812,7 @@ spa_proxy_node_port_push_input (SpaNode *node,
|
||||||
}
|
}
|
||||||
port = &this->ports[info[i].port_id];
|
port = &this->ports[info[i].port_id];
|
||||||
|
|
||||||
if (!port->have_format) {
|
if (!port->format) {
|
||||||
info[i].status = SPA_RESULT_NO_FORMAT;
|
info[i].status = SPA_RESULT_NO_FORMAT;
|
||||||
have_error = true;
|
have_error = true;
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -867,7 +872,7 @@ spa_proxy_node_port_pull_output (SpaNode *node,
|
||||||
|
|
||||||
port = &this->ports[info[i].port_id];
|
port = &this->ports[info[i].port_id];
|
||||||
|
|
||||||
if (!port->have_format) {
|
if (!port->format) {
|
||||||
info[i].status = SPA_RESULT_NO_FORMAT;
|
info[i].status = SPA_RESULT_NO_FORMAT;
|
||||||
have_error = true;
|
have_error = true;
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -918,7 +923,6 @@ 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,13 +933,12 @@ parse_control (SpaProxy *this,
|
||||||
|
|
||||||
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,
|
||||||
|
pu.n_possible_formats,
|
||||||
|
pu.possible_formats);
|
||||||
} else {
|
} else {
|
||||||
do_uninit_port (this, pu.port_id);
|
do_uninit_port (this, pu.port_id);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue