mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-03 09:01:54 -05:00
Unify props, params and formats
Make enum_params and set_param to configure properties, format and other parameters. This allows us to remove some duplicate code and make the properties and parameters much more extensible. Use the object id to mark the id of the parameter. Remove the spa_format and spa_props. We can now make the client-node easier by merging the various format methods into the params. Make the stream API more powerful now that we can pass params around.
This commit is contained in:
parent
b6ee67905d
commit
f3bca48398
87 changed files with 3773 additions and 3580 deletions
|
|
@ -1,7 +1,7 @@
|
|||
#load-module libpipewire-module-protocol-dbus
|
||||
load-module libpipewire-module-protocol-native
|
||||
load-module libpipewire-module-suspend-on-idle
|
||||
#load-module libpipewire-module-spa-monitor alsa/libspa-alsa alsa-monitor alsa
|
||||
load-module libpipewire-module-spa-monitor alsa/libspa-alsa alsa-monitor alsa
|
||||
load-module libpipewire-module-spa-monitor v4l2/libspa-v4l2 v4l2-monitor v4l2
|
||||
#load-module libpipewire-module-spa-node videotestsrc/libspa-videotestsrc videotestsrc videotestsrc Spa:POD:Object:Props:patternType=Spa:POD:Object:Props:patternType:snow
|
||||
load-module libpipewire-module-autolink
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@
|
|||
#include <spa/type-map.h>
|
||||
#include <spa/format-utils.h>
|
||||
#include <spa/video/format-utils.h>
|
||||
#include <spa/format-builder.h>
|
||||
#include <spa/props.h>
|
||||
#include <spa/lib/debug.h>
|
||||
|
||||
|
|
@ -90,7 +89,6 @@ struct data {
|
|||
struct spa_video_info_raw format;
|
||||
int32_t stride;
|
||||
|
||||
uint8_t params_buffer[1024];
|
||||
struct spa_param *params[2];
|
||||
|
||||
struct spa_buffer *buffers[32];
|
||||
|
|
@ -223,27 +221,42 @@ static int impl_port_set_io(struct spa_node *node, enum spa_direction direction,
|
|||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
static int impl_port_enum_formats(struct spa_node *node, enum spa_direction direction, uint32_t port_id,
|
||||
struct spa_format **format,
|
||||
const struct spa_format *filter,
|
||||
uint32_t index)
|
||||
static int impl_port_get_info(struct spa_node *node, enum spa_direction direction, uint32_t port_id,
|
||||
const struct spa_port_info **info)
|
||||
{
|
||||
struct data *d = SPA_CONTAINER_OF(node, struct data, impl_node);
|
||||
|
||||
d->port_info.flags = SPA_PORT_INFO_FLAG_CAN_USE_BUFFERS;
|
||||
d->port_info.rate = 0;
|
||||
d->port_info.props = NULL;
|
||||
|
||||
*info = &d->port_info;
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
static int port_enum_formats(struct spa_node *node,
|
||||
enum spa_direction direction, uint32_t port_id,
|
||||
uint32_t *index,
|
||||
const struct spa_pod_object *filter,
|
||||
struct spa_pod_builder *builder)
|
||||
{
|
||||
struct data *d = SPA_CONTAINER_OF(node, struct data, impl_node);
|
||||
struct spa_pod_builder b = SPA_POD_BUILDER_INIT(d->buffer, sizeof(d->buffer));
|
||||
struct spa_pod_frame f[2];
|
||||
SDL_RendererInfo info;
|
||||
int i, c;
|
||||
|
||||
if (index != 0)
|
||||
if (*index != 0)
|
||||
return SPA_RESULT_ENUM_END;
|
||||
|
||||
SDL_GetRendererInfo(d->renderer, &info);
|
||||
|
||||
spa_pod_builder_push_format(&b, &f[0], d->type.format,
|
||||
d->type.media_type.video,
|
||||
d->type.media_subtype.raw);
|
||||
spa_pod_builder_push_object(builder, &f[0],
|
||||
d->t->param.idEnumFormat, d->type.format);
|
||||
spa_pod_builder_id(builder, d->type.media_type.video);
|
||||
spa_pod_builder_id(builder, d->type.media_subtype.raw);
|
||||
|
||||
spa_pod_builder_push_prop(&b, &f[1], d->type.format_video.format,
|
||||
spa_pod_builder_push_prop(builder, &f[1], d->type.format_video.format,
|
||||
SPA_POD_PROP_FLAG_UNSET |
|
||||
SPA_POD_PROP_RANGE_ENUM);
|
||||
for (i = 0, c = 0; i < info.num_texture_formats; i++) {
|
||||
|
|
@ -251,18 +264,18 @@ static int impl_port_enum_formats(struct spa_node *node, enum spa_direction dire
|
|||
if (id == 0)
|
||||
continue;
|
||||
if (c++ == 0)
|
||||
spa_pod_builder_id(&b, id);
|
||||
spa_pod_builder_id(&b, id);
|
||||
spa_pod_builder_id(builder, id);
|
||||
spa_pod_builder_id(builder, id);
|
||||
}
|
||||
for (i = 0; i < SPA_N_ELEMENTS(video_formats); i++) {
|
||||
uint32_t id =
|
||||
*SPA_MEMBER(&d->type.video_format, video_formats[i].id,
|
||||
uint32_t);
|
||||
if (id != d->type.video_format.UNKNOWN)
|
||||
spa_pod_builder_id(&b, id);
|
||||
spa_pod_builder_id(builder, id);
|
||||
}
|
||||
spa_pod_builder_pop(&b, &f[1]);
|
||||
spa_pod_builder_add(&b,
|
||||
spa_pod_builder_pop(builder, &f[1]);
|
||||
spa_pod_builder_add(builder,
|
||||
":", d->type.format_video.size, "Rru", &SPA_RECTANGLE(WIDTH, HEIGHT),
|
||||
2, &SPA_RECTANGLE(1,1),
|
||||
&SPA_RECTANGLE(info.max_texture_width,
|
||||
|
|
@ -271,27 +284,106 @@ static int impl_port_enum_formats(struct spa_node *node, enum spa_direction dire
|
|||
2, &SPA_FRACTION(0,1),
|
||||
&SPA_FRACTION(30,1),
|
||||
NULL);
|
||||
spa_pod_builder_pop(&b, &f[0]);
|
||||
*format = SPA_POD_BUILDER_DEREF(&b, f[0].ref, struct spa_format);
|
||||
spa_pod_builder_pop(builder, &f[0]);
|
||||
|
||||
spa_debug_format(*format);
|
||||
(*index)++;
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
static int impl_port_set_format(struct spa_node *node, enum spa_direction direction, uint32_t port_id,
|
||||
uint32_t flags, const struct spa_format *format)
|
||||
static int port_get_format(struct spa_node *node,
|
||||
enum spa_direction direction, uint32_t port_id,
|
||||
uint32_t *index,
|
||||
const struct spa_pod_object *filter,
|
||||
struct spa_pod_builder *builder)
|
||||
{
|
||||
struct data *d = SPA_CONTAINER_OF(node, struct data, impl_node);
|
||||
|
||||
if (*index != 0 || d->format.format == 0)
|
||||
return SPA_RESULT_ENUM_END;
|
||||
|
||||
spa_pod_builder_object(builder,
|
||||
d->t->param.idFormat, d->type.format,
|
||||
"I", d->type.media_type.video,
|
||||
"I", d->type.media_subtype.raw,
|
||||
":", d->type.format_video.format, "I", d->format.format,
|
||||
":", d->type.format_video.size, "R", &d->format.size,
|
||||
":", d->type.format_video.framerate, "F", &d->format.framerate);
|
||||
|
||||
(*index)++;
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
static int impl_port_enum_params(struct spa_node *node,
|
||||
enum spa_direction direction, uint32_t port_id,
|
||||
uint32_t id, uint32_t *index,
|
||||
const struct spa_pod_object *filter,
|
||||
struct spa_pod_builder *builder)
|
||||
{
|
||||
struct data *d = SPA_CONTAINER_OF(node, struct data, impl_node);
|
||||
struct pw_type *t = d->t;
|
||||
struct spa_pod_builder b = { NULL };
|
||||
|
||||
if (id == t->param.idList) {
|
||||
uint32_t list[] = { t->param.idEnumFormat,
|
||||
t->param.idFormat,
|
||||
t->param.idBuffers,
|
||||
t->param.idMeta };
|
||||
|
||||
if (*index < SPA_N_ELEMENTS(list))
|
||||
spa_pod_builder_object(builder,
|
||||
id, t->param.List,
|
||||
":", t->param.listId, "I", list[*index]);
|
||||
else
|
||||
return SPA_RESULT_ENUM_END;
|
||||
}
|
||||
else if (id == t->param.idEnumFormat) {
|
||||
return port_enum_formats(node, direction, port_id, index, filter, builder);
|
||||
}
|
||||
else if (id == t->param.idFormat) {
|
||||
return port_get_format(node, direction, port_id, index, filter, builder);
|
||||
}
|
||||
else if (id == t->param.idBuffers) {
|
||||
if (*index != 0)
|
||||
return SPA_RESULT_ENUM_END;
|
||||
|
||||
spa_pod_builder_object(builder,
|
||||
id, t->param_alloc_buffers.Buffers,
|
||||
":", t->param_alloc_buffers.size, "i", d->stride * d->format.size.height,
|
||||
":", t->param_alloc_buffers.stride, "i", d->stride,
|
||||
":", t->param_alloc_buffers.buffers, "iru", 32,
|
||||
2, 2, 32,
|
||||
":", t->param_alloc_buffers.align, "i", 16);
|
||||
}
|
||||
else if (id == t->param.idMeta) {
|
||||
if (*index != 0)
|
||||
return SPA_RESULT_ENUM_END;
|
||||
|
||||
spa_pod_builder_object(builder,
|
||||
id, t->param_alloc_meta_enable.MetaEnable,
|
||||
":", t->param_alloc_meta_enable.type, "I", t->meta.Header,
|
||||
":", t->param_alloc_meta_enable.size, "i", sizeof(struct spa_meta_header));
|
||||
}
|
||||
else
|
||||
return SPA_RESULT_UNKNOWN_PARAM;
|
||||
|
||||
(*index)++;
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
static int port_set_format(struct spa_node *node,
|
||||
enum spa_direction direction, uint32_t port_id,
|
||||
uint32_t flags, const struct spa_pod_object *format)
|
||||
{
|
||||
struct data *d = SPA_CONTAINER_OF(node, struct data, impl_node);
|
||||
Uint32 sdl_format;
|
||||
void *dest;
|
||||
|
||||
if (format == NULL)
|
||||
return SPA_RESULT_OK;
|
||||
|
||||
spa_debug_format(format);
|
||||
spa_debug_pod(&format->pod, SPA_DEBUG_FLAG_FORMAT);
|
||||
|
||||
spa_format_video_raw_parse(format, &d->format, &d->type.format_video);
|
||||
|
||||
|
|
@ -307,64 +399,22 @@ static int impl_port_set_format(struct spa_node *node, enum spa_direction direct
|
|||
SDL_LockTexture(d->texture, NULL, &dest, &d->stride);
|
||||
SDL_UnlockTexture(d->texture);
|
||||
|
||||
spa_pod_builder_init(&b, d->params_buffer, sizeof(d->params_buffer));
|
||||
d->params[0] = spa_pod_builder_param(&b,
|
||||
t->param_alloc_buffers.Buffers,
|
||||
":", t->param_alloc_buffers.size, "i", d->stride * d->format.size.height,
|
||||
":", t->param_alloc_buffers.stride, "i", d->stride,
|
||||
":", t->param_alloc_buffers.buffers, "iru", 32,
|
||||
2, 2, 32,
|
||||
":", t->param_alloc_buffers.align, "i", 16);
|
||||
|
||||
d->params[1] = spa_pod_builder_param(&b,
|
||||
t->param_alloc_meta_enable.MetaEnable,
|
||||
":", t->param_alloc_meta_enable.type, "I", t->meta.Header,
|
||||
":", t->param_alloc_meta_enable.size, "i", sizeof(struct spa_meta_header));
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
static int impl_port_get_format(struct spa_node *node, enum spa_direction direction, uint32_t port_id,
|
||||
const struct spa_format **format)
|
||||
static int impl_port_set_param(struct spa_node *node,
|
||||
enum spa_direction direction, uint32_t port_id,
|
||||
uint32_t id, uint32_t flags,
|
||||
const struct spa_pod_object *param)
|
||||
{
|
||||
struct data *d = SPA_CONTAINER_OF(node, struct data, impl_node);
|
||||
struct spa_pod_builder b = SPA_POD_BUILDER_INIT(d->buffer, sizeof(d->buffer));
|
||||
struct pw_type *t = d->t;
|
||||
|
||||
*format = spa_pod_builder_format(&b, d->type.format,
|
||||
d->type.media_type.video,
|
||||
d->type.media_subtype.raw,
|
||||
":", d->type.format_video.format, "I", d->format.format,
|
||||
":", d->type.format_video.size, "R", &d->format.size,
|
||||
":", d->type.format_video.framerate, "F", &d->format.framerate);
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
static int impl_port_get_info(struct spa_node *node, enum spa_direction direction, uint32_t port_id,
|
||||
const struct spa_port_info **info)
|
||||
{
|
||||
struct data *d = SPA_CONTAINER_OF(node, struct data, impl_node);
|
||||
|
||||
d->port_info.flags = SPA_PORT_INFO_FLAG_CAN_USE_BUFFERS;
|
||||
d->port_info.rate = 0;
|
||||
d->port_info.props = NULL;
|
||||
|
||||
*info = &d->port_info;
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
static int impl_port_enum_params(struct spa_node *node, enum spa_direction direction, uint32_t port_id,
|
||||
uint32_t index, struct spa_param **param)
|
||||
{
|
||||
struct data *d = SPA_CONTAINER_OF(node, struct data, impl_node);
|
||||
|
||||
if (index >= 2)
|
||||
return SPA_RESULT_ENUM_END;
|
||||
|
||||
*param = d->params[index];
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
if (id == t->param.idFormat) {
|
||||
return port_set_format(node, direction, port_id, flags, param);
|
||||
}
|
||||
else
|
||||
return SPA_RESULT_UNKNOWN_PARAM;
|
||||
}
|
||||
|
||||
static int impl_port_use_buffers(struct spa_node *node, enum spa_direction direction, uint32_t port_id,
|
||||
|
|
@ -443,11 +493,9 @@ static const struct spa_node impl_node = {
|
|||
.get_n_ports = impl_get_n_ports,
|
||||
.get_port_ids = impl_get_port_ids,
|
||||
.port_set_io = impl_port_set_io,
|
||||
.port_enum_formats = impl_port_enum_formats,
|
||||
.port_set_format = impl_port_set_format,
|
||||
.port_get_format = impl_port_get_format,
|
||||
.port_get_info = impl_port_get_info,
|
||||
.port_enum_params = impl_port_enum_params,
|
||||
.port_set_param = impl_port_set_param,
|
||||
.port_use_buffers = impl_port_use_buffers,
|
||||
.process_input = impl_node_process_input,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@
|
|||
#include <spa/type-map.h>
|
||||
#include <spa/format-utils.h>
|
||||
#include <spa/audio/format-utils.h>
|
||||
#include <spa/format-builder.h>
|
||||
#include <spa/props.h>
|
||||
#include <spa/lib/debug.h>
|
||||
|
||||
|
|
@ -88,8 +87,6 @@ struct data {
|
|||
|
||||
struct spa_audio_info_raw format;
|
||||
|
||||
uint8_t params_buffer[1024];
|
||||
|
||||
struct buffer buffers[32];
|
||||
int n_buffers;
|
||||
struct spa_list empty;
|
||||
|
|
@ -141,62 +138,6 @@ static int impl_port_set_io(struct spa_node *node, enum spa_direction direction,
|
|||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
static int impl_port_enum_formats(struct spa_node *node, enum spa_direction direction, uint32_t port_id,
|
||||
struct spa_format **format,
|
||||
const struct spa_format *filter,
|
||||
uint32_t index)
|
||||
{
|
||||
struct data *d = SPA_CONTAINER_OF(node, struct data, impl_node);
|
||||
struct spa_pod_builder b = SPA_POD_BUILDER_INIT(d->buffer, sizeof(d->buffer));
|
||||
|
||||
if (index != 0)
|
||||
return SPA_RESULT_ENUM_END;
|
||||
|
||||
*format = spa_pod_builder_format(&b, d->type.format,
|
||||
d->type.media_type.audio, d->type.media_subtype.raw,
|
||||
":", d->type.format_audio.format, "I", d->type.audio_format.S16,
|
||||
":", d->type.format_audio.channels, "i", 2,
|
||||
":", d->type.format_audio.rate, "i", 44100);
|
||||
|
||||
spa_debug_format(*format);
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
static int impl_port_set_format(struct spa_node *node, enum spa_direction direction, uint32_t port_id,
|
||||
uint32_t flags, const struct spa_format *format)
|
||||
{
|
||||
struct data *d = SPA_CONTAINER_OF(node, struct data, impl_node);
|
||||
|
||||
if (format == NULL)
|
||||
return SPA_RESULT_OK;
|
||||
|
||||
spa_debug_format(format);
|
||||
|
||||
if (spa_format_audio_raw_parse(format, &d->format, &d->type.format_audio) < 0)
|
||||
return SPA_RESULT_INVALID_MEDIA_TYPE;
|
||||
|
||||
if (d->format.format != d->type.audio_format.S16)
|
||||
return SPA_RESULT_ERROR;
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
static int impl_port_get_format(struct spa_node *node, enum spa_direction direction, uint32_t port_id,
|
||||
const struct spa_format **format)
|
||||
{
|
||||
struct data *d = SPA_CONTAINER_OF(node, struct data, impl_node);
|
||||
struct spa_pod_builder b = SPA_POD_BUILDER_INIT(d->buffer, sizeof(d->buffer));
|
||||
|
||||
*format = spa_pod_builder_format(&b, d->type.format,
|
||||
d->type.media_type.audio, d->type.media_subtype.raw,
|
||||
":", d->type.format_audio.format, "I", d->format.format,
|
||||
":", d->type.format_audio.channels, "i", d->format.channels,
|
||||
":", d->type.format_audio.rate, "i", d->format.rate);
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
static int impl_port_get_info(struct spa_node *node, enum spa_direction direction, uint32_t port_id,
|
||||
const struct spa_port_info **info)
|
||||
{
|
||||
|
|
@ -211,49 +152,166 @@ static int impl_port_get_info(struct spa_node *node, enum spa_direction directio
|
|||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
static int impl_port_enum_params(struct spa_node *node, enum spa_direction direction, uint32_t port_id,
|
||||
uint32_t index, struct spa_param **param)
|
||||
static int port_enum_formats(struct spa_node *node,
|
||||
enum spa_direction direction, uint32_t port_id,
|
||||
uint32_t *index,
|
||||
const struct spa_pod_object *filter,
|
||||
struct spa_pod_builder *builder)
|
||||
{
|
||||
struct data *d = SPA_CONTAINER_OF(node, struct data, impl_node);
|
||||
|
||||
if (*index != 0)
|
||||
return SPA_RESULT_ENUM_END;
|
||||
|
||||
spa_pod_builder_object(builder,
|
||||
d->t->param.idEnumFormat, d->type.format,
|
||||
"I", d->type.media_type.audio,
|
||||
"I", d->type.media_subtype.raw,
|
||||
":", d->type.format_audio.format, "I", d->type.audio_format.S16,
|
||||
":", d->type.format_audio.channels, "i", 2,
|
||||
":", d->type.format_audio.rate, "i", 44100);
|
||||
|
||||
(*index)++;
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
static int port_get_format(struct spa_node *node,
|
||||
enum spa_direction direction, uint32_t port_id,
|
||||
uint32_t *index,
|
||||
const struct spa_pod_object *filter,
|
||||
struct spa_pod_builder *builder)
|
||||
{
|
||||
struct data *d = SPA_CONTAINER_OF(node, struct data, impl_node);
|
||||
|
||||
if (*index != 0)
|
||||
return SPA_RESULT_ENUM_END;
|
||||
|
||||
if (d->format.format == 0)
|
||||
return SPA_RESULT_ENUM_END;
|
||||
|
||||
spa_pod_builder_object(builder,
|
||||
d->t->param.idFormat, d->type.format,
|
||||
"I", d->type.media_type.audio,
|
||||
"I", d->type.media_subtype.raw,
|
||||
":", d->type.format_audio.format, "I", d->format.format,
|
||||
":", d->type.format_audio.channels, "i", d->format.channels,
|
||||
":", d->type.format_audio.rate, "i", d->format.rate);
|
||||
|
||||
(*index)++;
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
static int impl_port_enum_params(struct spa_node *node,
|
||||
enum spa_direction direction, uint32_t port_id,
|
||||
uint32_t id, uint32_t *index,
|
||||
const struct spa_pod_object *filter,
|
||||
struct spa_pod_builder *builder)
|
||||
{
|
||||
struct data *d = SPA_CONTAINER_OF(node, struct data, impl_node);
|
||||
struct pw_type *t = d->t;
|
||||
struct spa_pod_builder b = { NULL };
|
||||
|
||||
spa_pod_builder_init(&b, d->params_buffer, sizeof(d->params_buffer));
|
||||
if (id == t->param.idList) {
|
||||
uint32_t list[] = { t->param.idEnumFormat,
|
||||
t->param.idFormat,
|
||||
t->param.idBuffers,
|
||||
t->param.idMeta };
|
||||
|
||||
switch (index) {
|
||||
case 0:
|
||||
*param = spa_pod_builder_param(&b,
|
||||
t->param_alloc_buffers.Buffers,
|
||||
if (*index < SPA_N_ELEMENTS(list))
|
||||
spa_pod_builder_object(builder,
|
||||
id, t->param.List,
|
||||
":", t->param.listId, "I", list[*index]);
|
||||
else
|
||||
return SPA_RESULT_ENUM_END;
|
||||
}
|
||||
else if (id == t->param.idEnumFormat) {
|
||||
return port_enum_formats(node, direction, port_id, index, filter, builder);
|
||||
}
|
||||
else if (id == t->param.idFormat) {
|
||||
return port_get_format(node, direction, port_id, index, filter, builder);
|
||||
}
|
||||
else if (id == t->param.idBuffers) {
|
||||
if (*index > 0)
|
||||
return SPA_RESULT_ENUM_END;
|
||||
|
||||
spa_pod_builder_object(builder,
|
||||
id, t->param_alloc_buffers.Buffers,
|
||||
":", t->param_alloc_buffers.size, "iru", 1024,
|
||||
2, 32, 4096,
|
||||
":", t->param_alloc_buffers.stride, "i", 0,
|
||||
":", t->param_alloc_buffers.buffers, "iru", 2,
|
||||
2, 2, 32,
|
||||
":", t->param_alloc_buffers.align, "i", 16);
|
||||
break;
|
||||
case 1:
|
||||
*param = spa_pod_builder_param(&b,
|
||||
t->param_alloc_meta_enable.MetaEnable,
|
||||
":", t->param_alloc_meta_enable.type, "I", t->meta.Header,
|
||||
":", t->param_alloc_meta_enable.size, "i", sizeof(struct spa_meta_header));
|
||||
break;
|
||||
case 2:
|
||||
*param = spa_pod_builder_param(&b,
|
||||
t->param_alloc_meta_enable.MetaEnable,
|
||||
":", t->param_alloc_meta_enable.type, "I", t->meta.Ringbuffer,
|
||||
":", t->param_alloc_meta_enable.size, "i", sizeof(struct spa_meta_ringbuffer),
|
||||
":", t->param_alloc_meta_enable.ringbufferSize, "ir", 1024 * 4,
|
||||
2, 16 * 4, INT32_MAX / 4,
|
||||
":", t->param_alloc_meta_enable.ringbufferStride, "i", 0,
|
||||
":", t->param_alloc_meta_enable.ringbufferBlocks, "i", 1,
|
||||
":", t->param_alloc_meta_enable.ringbufferAlign, "i", 16);
|
||||
break;
|
||||
default:
|
||||
return SPA_RESULT_ENUM_END;
|
||||
}
|
||||
else if (id == t->param.idMeta) {
|
||||
switch (*index) {
|
||||
case 0:
|
||||
spa_pod_builder_object(builder,
|
||||
id, t->param_alloc_meta_enable.MetaEnable,
|
||||
":", t->param_alloc_meta_enable.type, "I", t->meta.Header,
|
||||
":", t->param_alloc_meta_enable.size, "i", sizeof(struct spa_meta_header));
|
||||
break;
|
||||
case 1:
|
||||
spa_pod_builder_object(builder,
|
||||
id, t->param_alloc_meta_enable.MetaEnable,
|
||||
":", t->param_alloc_meta_enable.type, "I", t->meta.Ringbuffer,
|
||||
":", t->param_alloc_meta_enable.size, "i", sizeof(struct spa_meta_ringbuffer),
|
||||
":", t->param_alloc_meta_enable.ringbufferSize, "ir", 1024 * 4,
|
||||
2, 16 * 4, INT32_MAX / 4,
|
||||
":", t->param_alloc_meta_enable.ringbufferStride, "i", 0,
|
||||
":", t->param_alloc_meta_enable.ringbufferBlocks, "i", 1,
|
||||
":", t->param_alloc_meta_enable.ringbufferAlign, "i", 16);
|
||||
break;
|
||||
default:
|
||||
return SPA_RESULT_ENUM_END;
|
||||
}
|
||||
}
|
||||
else
|
||||
return SPA_RESULT_UNKNOWN_PARAM;
|
||||
|
||||
(*index)++;
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
static int port_set_format(struct spa_node *node,
|
||||
enum spa_direction direction, uint32_t port_id,
|
||||
uint32_t flags, const struct spa_pod_object *format)
|
||||
{
|
||||
struct data *d = SPA_CONTAINER_OF(node, struct data, impl_node);
|
||||
|
||||
if (format == NULL) {
|
||||
d->format.format = 0;
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
spa_debug_pod(&format->pod, SPA_DEBUG_FLAG_FORMAT);
|
||||
|
||||
if (spa_format_audio_raw_parse(format, &d->format, &d->type.format_audio) < 0)
|
||||
return SPA_RESULT_INVALID_MEDIA_TYPE;
|
||||
|
||||
if (d->format.format != d->type.audio_format.S16)
|
||||
return SPA_RESULT_ERROR;
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
static int impl_port_set_param(struct spa_node *node,
|
||||
enum spa_direction direction, uint32_t port_id,
|
||||
uint32_t id, uint32_t flags,
|
||||
const struct spa_pod_object *param)
|
||||
{
|
||||
struct data *d = SPA_CONTAINER_OF(node, struct data, impl_node);
|
||||
struct pw_type *t = d->t;
|
||||
|
||||
if (id == t->param.idFormat) {
|
||||
return port_set_format(node, direction, port_id, flags, param);
|
||||
}
|
||||
else
|
||||
return SPA_RESULT_UNKNOWN_PARAM;
|
||||
}
|
||||
|
||||
static int impl_port_use_buffers(struct spa_node *node, enum spa_direction direction, uint32_t port_id,
|
||||
struct spa_buffer **buffers, uint32_t n_buffers)
|
||||
{
|
||||
|
|
@ -378,11 +436,9 @@ static const struct spa_node impl_node = {
|
|||
.get_n_ports = impl_get_n_ports,
|
||||
.get_port_ids = impl_get_port_ids,
|
||||
.port_set_io = impl_port_set_io,
|
||||
.port_enum_formats = impl_port_enum_formats,
|
||||
.port_set_format = impl_port_set_format,
|
||||
.port_get_format = impl_port_get_format,
|
||||
.port_get_info = impl_port_get_info,
|
||||
.port_enum_params = impl_port_enum_params,
|
||||
.port_set_param = impl_port_set_param,
|
||||
.port_use_buffers = impl_port_use_buffers,
|
||||
.port_reuse_buffer = impl_port_reuse_buffer,
|
||||
.process_output = impl_node_process_output,
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@
|
|||
#include <spa/type-map.h>
|
||||
#include <spa/format-utils.h>
|
||||
#include <spa/video/format-utils.h>
|
||||
#include <spa/format-builder.h>
|
||||
#include <spa/props.h>
|
||||
#include <spa/lib/debug.h>
|
||||
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@
|
|||
#include <spa/type-map.h>
|
||||
#include <spa/format-utils.h>
|
||||
#include <spa/video/format-utils.h>
|
||||
#include <spa/format-builder.h>
|
||||
#include <spa/props.h>
|
||||
#include <spa/lib/debug.h>
|
||||
|
||||
|
|
@ -85,14 +84,9 @@ struct data {
|
|||
const struct spa_node_callbacks *callbacks;
|
||||
void *callbacks_data;
|
||||
|
||||
uint8_t buffer[1024];
|
||||
|
||||
struct spa_video_info_raw format;
|
||||
int32_t stride;
|
||||
|
||||
uint8_t params_buffer[1024];
|
||||
struct spa_param *params[2];
|
||||
|
||||
struct spa_buffer *buffers[32];
|
||||
int n_buffers;
|
||||
};
|
||||
|
|
@ -223,27 +217,42 @@ static int impl_port_set_io(struct spa_node *node, enum spa_direction direction,
|
|||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
static int impl_port_enum_formats(struct spa_node *node, enum spa_direction direction, uint32_t port_id,
|
||||
struct spa_format **format,
|
||||
const struct spa_format *filter,
|
||||
uint32_t index)
|
||||
static int impl_port_get_info(struct spa_node *node, enum spa_direction direction, uint32_t port_id,
|
||||
const struct spa_port_info **info)
|
||||
{
|
||||
struct data *d = SPA_CONTAINER_OF(node, struct data, impl_node);
|
||||
|
||||
d->port_info.flags = SPA_PORT_INFO_FLAG_CAN_USE_BUFFERS;
|
||||
d->port_info.rate = 0;
|
||||
d->port_info.props = NULL;
|
||||
|
||||
*info = &d->port_info;
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
static int port_enum_formats(struct spa_node *node,
|
||||
enum spa_direction direction, uint32_t port_id,
|
||||
uint32_t *index,
|
||||
const struct spa_pod_object *filter,
|
||||
struct spa_pod_builder *builder)
|
||||
{
|
||||
struct data *d = SPA_CONTAINER_OF(node, struct data, impl_node);
|
||||
struct spa_pod_builder b = SPA_POD_BUILDER_INIT(d->buffer, sizeof(d->buffer));
|
||||
struct spa_pod_frame f[2];
|
||||
SDL_RendererInfo info;
|
||||
int i, c;
|
||||
|
||||
if (index != 0)
|
||||
if (*index != 0)
|
||||
return SPA_RESULT_ENUM_END;
|
||||
|
||||
SDL_GetRendererInfo(d->renderer, &info);
|
||||
|
||||
spa_pod_builder_push_format(&b, &f[0], d->type.format,
|
||||
d->type.media_type.video,
|
||||
d->type.media_subtype.raw);
|
||||
spa_pod_builder_push_object(builder, &f[0],
|
||||
d->t->param.idEnumFormat, d->type.format);
|
||||
spa_pod_builder_id(builder, d->type.media_type.video);
|
||||
spa_pod_builder_id(builder, d->type.media_subtype.raw);
|
||||
|
||||
spa_pod_builder_push_prop(&b, &f[1], d->type.format_video.format,
|
||||
spa_pod_builder_push_prop(builder, &f[1], d->type.format_video.format,
|
||||
SPA_POD_PROP_FLAG_UNSET |
|
||||
SPA_POD_PROP_RANGE_ENUM);
|
||||
for (i = 0, c = 0; i < info.num_texture_formats; i++) {
|
||||
|
|
@ -251,19 +260,19 @@ static int impl_port_enum_formats(struct spa_node *node, enum spa_direction dire
|
|||
if (id == 0)
|
||||
continue;
|
||||
if (c++ == 0)
|
||||
spa_pod_builder_id(&b, id);
|
||||
spa_pod_builder_id(&b, id);
|
||||
spa_pod_builder_id(builder, id);
|
||||
spa_pod_builder_id(builder, id);
|
||||
}
|
||||
for (i = 0; i < SPA_N_ELEMENTS(video_formats); i++) {
|
||||
uint32_t id =
|
||||
*SPA_MEMBER(&d->type.video_format, video_formats[i].id,
|
||||
uint32_t);
|
||||
if (id != d->type.video_format.UNKNOWN)
|
||||
spa_pod_builder_id(&b, id);
|
||||
spa_pod_builder_id(builder, id);
|
||||
}
|
||||
spa_pod_builder_pop(&b, &f[1]);
|
||||
spa_pod_builder_pop(builder, &f[1]);
|
||||
|
||||
spa_pod_builder_add(&b,
|
||||
spa_pod_builder_add(builder,
|
||||
":", d->type.format_video.size, "Rru", &SPA_RECTANGLE(WIDTH, HEIGHT),
|
||||
2, &SPA_RECTANGLE(1,1),
|
||||
&SPA_RECTANGLE(info.max_texture_width,
|
||||
|
|
@ -272,28 +281,64 @@ static int impl_port_enum_formats(struct spa_node *node, enum spa_direction dire
|
|||
2, &SPA_FRACTION(0,1),
|
||||
&SPA_FRACTION(30,1),
|
||||
NULL);
|
||||
spa_pod_builder_pop(&b, &f[0]);
|
||||
*format = SPA_POD_BUILDER_DEREF(&b, f[0].ref, struct spa_format);
|
||||
spa_pod_builder_pop(builder, &f[0]);
|
||||
|
||||
spa_debug_format(*format);
|
||||
(*index)++;
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
static int impl_port_set_format(struct spa_node *node, enum spa_direction direction, uint32_t port_id,
|
||||
uint32_t flags, const struct spa_format *format)
|
||||
static int impl_port_enum_params(struct spa_node *node,
|
||||
enum spa_direction direction, uint32_t port_id,
|
||||
uint32_t id, uint32_t *index,
|
||||
const struct spa_pod_object *filter,
|
||||
struct spa_pod_builder *builder)
|
||||
{
|
||||
struct data *d = SPA_CONTAINER_OF(node, struct data, impl_node);
|
||||
struct pw_type *t = d->t;
|
||||
struct spa_pod_builder b = { NULL };
|
||||
|
||||
if (id == t->param.idEnumFormat) {
|
||||
return port_enum_formats(node, direction, port_id, index, filter, builder);
|
||||
}
|
||||
else if (id == t->param.idBuffers) {
|
||||
if (*index > 0)
|
||||
return SPA_RESULT_ENUM_END;
|
||||
|
||||
spa_pod_builder_object(builder,
|
||||
id, t->param_alloc_buffers.Buffers,
|
||||
":", t->param_alloc_buffers.size, "i", d->stride * d->format.size.height,
|
||||
":", t->param_alloc_buffers.stride, "i", d->stride,
|
||||
":", t->param_alloc_buffers.buffers, "iru", 2,
|
||||
2, 1, 32,
|
||||
":", t->param_alloc_buffers.align, "i", 16);
|
||||
}
|
||||
else if (id == t->param.idMeta) {
|
||||
if (*index > 0)
|
||||
return SPA_RESULT_ENUM_END;
|
||||
|
||||
spa_pod_builder_object(builder,
|
||||
id, t->param_alloc_meta_enable.MetaEnable,
|
||||
":", t->param_alloc_meta_enable.type, "I", t->meta.Header,
|
||||
":", t->param_alloc_meta_enable.size, "i", sizeof(struct spa_meta_header));
|
||||
}
|
||||
else
|
||||
return SPA_RESULT_UNKNOWN_PARAM;
|
||||
|
||||
(*index)++;
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
static int port_set_format(struct spa_node *node, enum spa_direction direction, uint32_t port_id,
|
||||
uint32_t flags, const struct spa_pod_object *format)
|
||||
{
|
||||
struct data *d = SPA_CONTAINER_OF(node, struct data, impl_node);
|
||||
Uint32 sdl_format;
|
||||
void *dest;
|
||||
|
||||
if (format == NULL) {
|
||||
if (format == NULL)
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
spa_debug_format(format);
|
||||
spa_debug_pod(&format->pod, SPA_DEBUG_FLAG_FORMAT);
|
||||
|
||||
spa_format_video_raw_parse(format, &d->format, &d->type.format_video);
|
||||
|
||||
|
|
@ -309,48 +354,22 @@ static int impl_port_set_format(struct spa_node *node, enum spa_direction direct
|
|||
SDL_LockTexture(d->texture, NULL, &dest, &d->stride);
|
||||
SDL_UnlockTexture(d->texture);
|
||||
|
||||
spa_pod_builder_init(&b, d->params_buffer, sizeof(d->params_buffer));
|
||||
d->params[0] = spa_pod_builder_param(&b,
|
||||
t->param_alloc_buffers.Buffers,
|
||||
":", t->param_alloc_buffers.size, "i", d->stride * d->format.size.height,
|
||||
":", t->param_alloc_buffers.stride, "i", d->stride,
|
||||
":", t->param_alloc_buffers.buffers, "iru", 2,
|
||||
2, 1, 32,
|
||||
":", t->param_alloc_buffers.align, "i", 16);
|
||||
|
||||
d->params[1] = spa_pod_builder_param(&b,
|
||||
t->param_alloc_meta_enable.MetaEnable,
|
||||
":", t->param_alloc_meta_enable.type, "I", t->meta.Header,
|
||||
":", t->param_alloc_meta_enable.size, "i", sizeof(struct spa_meta_header));
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
static int impl_port_get_info(struct spa_node *node, enum spa_direction direction, uint32_t port_id,
|
||||
const struct spa_port_info **info)
|
||||
static int impl_port_set_param(struct spa_node *node,
|
||||
enum spa_direction direction, uint32_t port_id,
|
||||
uint32_t id, uint32_t flags,
|
||||
const struct spa_pod_object *param)
|
||||
{
|
||||
struct data *d = SPA_CONTAINER_OF(node, struct data, impl_node);
|
||||
struct pw_type *t = d->t;
|
||||
|
||||
d->port_info.flags = SPA_PORT_INFO_FLAG_CAN_USE_BUFFERS;
|
||||
d->port_info.rate = 0;
|
||||
d->port_info.props = NULL;
|
||||
|
||||
*info = &d->port_info;
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
static int impl_port_enum_params(struct spa_node *node, enum spa_direction direction, uint32_t port_id,
|
||||
uint32_t index, struct spa_param **param)
|
||||
{
|
||||
struct data *d = SPA_CONTAINER_OF(node, struct data, impl_node);
|
||||
|
||||
if (index >= 2)
|
||||
return SPA_RESULT_ENUM_END;
|
||||
|
||||
*param = d->params[index];
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
if (id == t->param.idFormat) {
|
||||
return port_set_format(node, direction, port_id, flags, param);
|
||||
}
|
||||
else
|
||||
return SPA_RESULT_UNKNOWN_PARAM;
|
||||
}
|
||||
|
||||
static int impl_port_use_buffers(struct spa_node *node, enum spa_direction direction, uint32_t port_id,
|
||||
|
|
@ -425,10 +444,9 @@ static const struct spa_node impl_node = {
|
|||
.get_n_ports = impl_get_n_ports,
|
||||
.get_port_ids = impl_get_port_ids,
|
||||
.port_set_io = impl_port_set_io,
|
||||
.port_enum_formats = impl_port_enum_formats,
|
||||
.port_set_format = impl_port_set_format,
|
||||
.port_get_info = impl_port_get_info,
|
||||
.port_enum_params = impl_port_enum_params,
|
||||
.port_set_param = impl_port_set_param,
|
||||
.port_use_buffers = impl_port_use_buffers,
|
||||
.process_input = impl_node_process_input,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@
|
|||
#include <spa/type-map.h>
|
||||
#include <spa/format-utils.h>
|
||||
#include <spa/video/format-utils.h>
|
||||
#include <spa/format-builder.h>
|
||||
#include <spa/props.h>
|
||||
#include <spa/lib/debug.h>
|
||||
|
||||
|
|
@ -34,6 +33,7 @@
|
|||
struct type {
|
||||
uint32_t format;
|
||||
uint32_t props;
|
||||
struct spa_type_param param;
|
||||
struct spa_type_meta meta;
|
||||
struct spa_type_data data;
|
||||
struct spa_type_media_type media_type;
|
||||
|
|
@ -46,6 +46,7 @@ static inline void init_type(struct type *type, struct spa_type_map *map)
|
|||
{
|
||||
type->format = spa_type_map_get_id(map, SPA_TYPE__Format);
|
||||
type->props = spa_type_map_get_id(map, SPA_TYPE__Props);
|
||||
spa_type_param_map(map, &type->param);
|
||||
spa_type_meta_map(map, &type->meta);
|
||||
spa_type_data_map(map, &type->data);
|
||||
spa_type_media_type_map(map, &type->media_type);
|
||||
|
|
@ -234,28 +235,26 @@ static Uint32 id_to_sdl_format(struct data *data, uint32_t id)
|
|||
}
|
||||
|
||||
static void
|
||||
on_stream_format_changed(void *_data, struct spa_format *format)
|
||||
on_stream_format_changed(void *_data, struct spa_pod_object *format)
|
||||
{
|
||||
struct data *data = _data;
|
||||
struct pw_stream *stream = data->stream;
|
||||
struct pw_type *t = data->t;
|
||||
struct spa_pod_builder b = { NULL };
|
||||
struct spa_param *params[2];
|
||||
struct spa_pod_object *params[2];
|
||||
Uint32 sdl_format;
|
||||
void *d;
|
||||
|
||||
if (format == NULL) {
|
||||
pw_stream_finish_format(stream, SPA_RESULT_OK, NULL, 0);
|
||||
pw_stream_finish_format(stream, SPA_RESULT_OK, 0, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
spa_debug_format(format);
|
||||
|
||||
spa_format_video_raw_parse(format, &data->format, &data->type.format_video);
|
||||
|
||||
sdl_format = id_to_sdl_format(data, data->format.format);
|
||||
if (sdl_format == SDL_PIXELFORMAT_UNKNOWN) {
|
||||
pw_stream_finish_format(stream, SPA_RESULT_ERROR, NULL, 0);
|
||||
pw_stream_finish_format(stream, SPA_RESULT_ERROR, 0, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -268,20 +267,20 @@ on_stream_format_changed(void *_data, struct spa_format *format)
|
|||
SDL_UnlockTexture(data->texture);
|
||||
|
||||
spa_pod_builder_init(&b, data->params_buffer, sizeof(data->params_buffer));
|
||||
params[0] = spa_pod_builder_param(&b,
|
||||
t->param_alloc_buffers.Buffers,
|
||||
params[0] = spa_pod_builder_object(&b,
|
||||
t->param.idBuffers, t->param_alloc_buffers.Buffers,
|
||||
":", t->param_alloc_buffers.size, "i", data->stride * data->format.size.height,
|
||||
":", t->param_alloc_buffers.stride, "i", data->stride,
|
||||
":", t->param_alloc_buffers.buffers, "iru", 32,
|
||||
2, 2, 32,
|
||||
":", t->param_alloc_buffers.align, "i", 16);
|
||||
|
||||
params[1] = spa_pod_builder_param(&b,
|
||||
t->param_alloc_meta_enable.MetaEnable,
|
||||
params[1] = spa_pod_builder_object(&b,
|
||||
t->param.idMeta, t->param_alloc_meta_enable.MetaEnable,
|
||||
":", t->param_alloc_meta_enable.type, "I", t->meta.Header,
|
||||
":", t->param_alloc_meta_enable.size, "i", sizeof(struct spa_meta_header));
|
||||
|
||||
pw_stream_finish_format(stream, SPA_RESULT_OK, params, 2);
|
||||
pw_stream_finish_format(stream, SPA_RESULT_OK, 2, params);
|
||||
}
|
||||
|
||||
static const struct pw_stream_events stream_events = {
|
||||
|
|
@ -304,7 +303,7 @@ static void on_state_changed(void *_data, enum pw_remote_state old, enum pw_remo
|
|||
|
||||
case PW_REMOTE_STATE_CONNECTED:
|
||||
{
|
||||
const struct spa_format *formats[1];
|
||||
const struct spa_pod_object *params[1];
|
||||
uint8_t buffer[1024];
|
||||
struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buffer, sizeof(buffer));
|
||||
struct spa_pod_frame f[2];
|
||||
|
|
@ -318,9 +317,10 @@ static void on_state_changed(void *_data, enum pw_remote_state old, enum pw_remo
|
|||
|
||||
SDL_GetRendererInfo(data->renderer, &info);
|
||||
|
||||
spa_pod_builder_push_format(&b, &f[0], data->type.format,
|
||||
data->type.media_type.video,
|
||||
data->type.media_subtype.raw);
|
||||
spa_pod_builder_push_object(&b, &f[0],
|
||||
data->type.param.idEnumFormat, data->type.format);
|
||||
spa_pod_builder_id(&b, data->type.media_type.video);
|
||||
spa_pod_builder_id(&b, data->type.media_subtype.raw);
|
||||
|
||||
spa_pod_builder_push_prop(&b, &f[1], data->type.format_video.format,
|
||||
SPA_POD_PROP_FLAG_UNSET |
|
||||
|
|
@ -351,10 +351,10 @@ static void on_state_changed(void *_data, enum pw_remote_state old, enum pw_remo
|
|||
&SPA_RECTANGLE(30,1),
|
||||
NULL);
|
||||
spa_pod_builder_pop(&b, &f[0]);
|
||||
formats[0] = SPA_POD_BUILDER_DEREF(&b, f[0].ref, struct spa_format);
|
||||
params[0] = SPA_POD_BUILDER_DEREF(&b, f[0].ref, struct spa_pod_object);
|
||||
|
||||
printf("supported formats:\n");
|
||||
spa_debug_format(formats[0]);
|
||||
spa_debug_pod(¶ms[0]->pod, SPA_DEBUG_FLAG_FORMAT);
|
||||
|
||||
pw_stream_add_listener(data->stream,
|
||||
&data->stream_listener,
|
||||
|
|
@ -363,8 +363,9 @@ static void on_state_changed(void *_data, enum pw_remote_state old, enum pw_remo
|
|||
|
||||
pw_stream_connect(data->stream,
|
||||
PW_DIRECTION_INPUT,
|
||||
PW_STREAM_MODE_BUFFER,
|
||||
data->path, PW_STREAM_FLAG_AUTOCONNECT | PW_STREAM_FLAG_INACTIVE, 1, formats);
|
||||
data->path,
|
||||
PW_STREAM_FLAG_AUTOCONNECT | PW_STREAM_FLAG_INACTIVE,
|
||||
1, params);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@
|
|||
#include <spa/type-map.h>
|
||||
#include <spa/format-utils.h>
|
||||
#include <spa/video/format-utils.h>
|
||||
#include <spa/format-builder.h>
|
||||
#include <spa/props.h>
|
||||
#include <spa/lib/debug.h>
|
||||
|
||||
|
|
@ -34,6 +33,7 @@
|
|||
struct type {
|
||||
uint32_t format;
|
||||
uint32_t props;
|
||||
struct spa_type_param param;
|
||||
struct spa_type_meta meta;
|
||||
struct spa_type_data data;
|
||||
struct spa_type_media_type media_type;
|
||||
|
|
@ -46,6 +46,7 @@ static inline void init_type(struct type *type, struct spa_type_map *map)
|
|||
{
|
||||
type->format = spa_type_map_get_id(map, SPA_TYPE__Format);
|
||||
type->props = spa_type_map_get_id(map, SPA_TYPE__Props);
|
||||
spa_type_param_map(map, &type->param);
|
||||
spa_type_meta_map(map, &type->meta);
|
||||
spa_type_data_map(map, &type->data);
|
||||
spa_type_media_type_map(map, &type->media_type);
|
||||
|
|
@ -166,16 +167,16 @@ static void on_stream_state_changed(void *_data, enum pw_stream_state old, enum
|
|||
}
|
||||
|
||||
static void
|
||||
on_stream_format_changed(void *_data, struct spa_format *format)
|
||||
on_stream_format_changed(void *_data, struct spa_pod_object *format)
|
||||
{
|
||||
struct data *data = _data;
|
||||
struct pw_stream *stream = data->stream;
|
||||
struct pw_type *t = data->t;
|
||||
struct spa_pod_builder b = { NULL };
|
||||
struct spa_param *params[2];
|
||||
struct spa_pod_object *params[2];
|
||||
|
||||
if (format == NULL) {
|
||||
pw_stream_finish_format(stream, SPA_RESULT_OK, NULL, 0);
|
||||
pw_stream_finish_format(stream, SPA_RESULT_OK, 0, NULL);
|
||||
return;
|
||||
}
|
||||
spa_format_video_raw_parse(format, &data->format, &data->type.format_video);
|
||||
|
|
@ -183,20 +184,20 @@ on_stream_format_changed(void *_data, struct spa_format *format)
|
|||
data->stride = SPA_ROUND_UP_N(data->format.size.width * BPP, 4);
|
||||
|
||||
spa_pod_builder_init(&b, data->params_buffer, sizeof(data->params_buffer));
|
||||
params[0] = spa_pod_builder_param(&b,
|
||||
t->param_alloc_buffers.Buffers,
|
||||
params[0] = spa_pod_builder_object(&b,
|
||||
t->param.idBuffers, t->param_alloc_buffers.Buffers,
|
||||
":", t->param_alloc_buffers.size, "i", data->stride * data->format.size.height,
|
||||
":", t->param_alloc_buffers.stride, "i", data->stride,
|
||||
":", t->param_alloc_buffers.buffers, "iru", 2,
|
||||
2, 1, 32,
|
||||
":", t->param_alloc_buffers.align, "i", 16);
|
||||
|
||||
params[1] = spa_pod_builder_param(&b,
|
||||
t->param_alloc_meta_enable.MetaEnable,
|
||||
params[1] = spa_pod_builder_object(&b,
|
||||
t->param.idMeta, t->param_alloc_meta_enable.MetaEnable,
|
||||
":", t->param_alloc_meta_enable.type, "I", t->meta.Header,
|
||||
":", t->param_alloc_meta_enable.size, "i", sizeof(struct spa_meta_header));
|
||||
|
||||
pw_stream_finish_format(stream, SPA_RESULT_OK, params, 2);
|
||||
pw_stream_finish_format(stream, SPA_RESULT_OK, 2, params);
|
||||
}
|
||||
|
||||
static const struct pw_stream_events stream_events = {
|
||||
|
|
@ -218,7 +219,7 @@ static void on_state_changed(void *_data, enum pw_remote_state old, enum pw_remo
|
|||
|
||||
case PW_REMOTE_STATE_CONNECTED:
|
||||
{
|
||||
const struct spa_format *formats[1];
|
||||
const struct spa_pod_object *params[1];
|
||||
uint8_t buffer[1024];
|
||||
struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buffer, sizeof(buffer));
|
||||
|
||||
|
|
@ -227,8 +228,10 @@ static void on_state_changed(void *_data, enum pw_remote_state old, enum pw_remo
|
|||
|
||||
data->stream = pw_stream_new(remote, "video-src", NULL);
|
||||
|
||||
formats[0] = spa_pod_builder_format(&b, data->type.format,
|
||||
data->type.media_type.video, data->type.media_subtype.raw,
|
||||
params[0] = spa_pod_builder_object(&b,
|
||||
data->type.param.idEnumFormat, data->type.format,
|
||||
"I", data->type.media_type.video,
|
||||
"I", data->type.media_subtype.raw,
|
||||
":", data->type.format_video.format, "I", data->type.video_format.RGB,
|
||||
":", data->type.format_video.size, "Rru", &SPA_RECTANGLE(320, 240),
|
||||
2, &SPA_RECTANGLE(1, 1),
|
||||
|
|
@ -242,8 +245,8 @@ static void on_state_changed(void *_data, enum pw_remote_state old, enum pw_remo
|
|||
|
||||
pw_stream_connect(data->stream,
|
||||
PW_DIRECTION_OUTPUT,
|
||||
PW_STREAM_MODE_BUFFER,
|
||||
NULL, PW_STREAM_FLAG_NONE, 1, formats);
|
||||
NULL, PW_STREAM_FLAG_NONE,
|
||||
1, params);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -182,21 +182,22 @@ struct pw_client_node_proxy_methods {
|
|||
/**
|
||||
* Update the node ports and properties
|
||||
*
|
||||
* Update the maximum number of ports and the properties of the
|
||||
* Update the maximum number of ports and the params of the
|
||||
* client node.
|
||||
* \param change_mask bitfield with changed parameters
|
||||
* \param max_input_ports new max input ports
|
||||
* \param max_output_ports new max output ports
|
||||
* \param props new properties
|
||||
* \param params new params
|
||||
*/
|
||||
void (*update) (void *object,
|
||||
#define PW_CLIENT_NODE_UPDATE_MAX_INPUTS (1 << 0)
|
||||
#define PW_CLIENT_NODE_UPDATE_MAX_OUTPUTS (1 << 1)
|
||||
#define PW_CLIENT_NODE_UPDATE_PROPS (1 << 2)
|
||||
#define PW_CLIENT_NODE_UPDATE_PARAMS (1 << 2)
|
||||
uint32_t change_mask,
|
||||
uint32_t max_input_ports,
|
||||
uint32_t max_output_ports,
|
||||
const struct spa_props *props);
|
||||
uint32_t n_params,
|
||||
const struct spa_pod_object **params);
|
||||
|
||||
/**
|
||||
* Update a node port
|
||||
|
|
@ -205,9 +206,6 @@ struct pw_client_node_proxy_methods {
|
|||
* \param direction the direction of the port
|
||||
* \param port_id the port id to update
|
||||
* \param change_mask a bitfield of changed items
|
||||
* \param n_possible_formats number of possible formats
|
||||
* \param possible_formats array of possible formats on the port
|
||||
* \param format the current format on the port
|
||||
* \param n_params number of port parameters
|
||||
* \param params array of port parameters
|
||||
* \param info port information
|
||||
|
|
@ -215,19 +213,14 @@ struct pw_client_node_proxy_methods {
|
|||
void (*port_update) (void *object,
|
||||
enum spa_direction direction,
|
||||
uint32_t port_id,
|
||||
#define PW_CLIENT_NODE_PORT_UPDATE_POSSIBLE_FORMATS (1 << 0)
|
||||
#define PW_CLIENT_NODE_PORT_UPDATE_FORMAT (1 << 1)
|
||||
#define PW_CLIENT_NODE_PORT_UPDATE_PARAMS (1 << 2)
|
||||
#define PW_CLIENT_NODE_PORT_UPDATE_INFO (1 << 3)
|
||||
#define PW_CLIENT_NODE_PORT_UPDATE_PARAMS (1 << 0)
|
||||
#define PW_CLIENT_NODE_PORT_UPDATE_INFO (1 << 1)
|
||||
uint32_t change_mask,
|
||||
uint32_t n_possible_formats,
|
||||
const struct spa_format **possible_formats,
|
||||
const struct spa_format *format,
|
||||
uint32_t n_params,
|
||||
const struct spa_param **params,
|
||||
const struct spa_pod_object **params,
|
||||
const struct spa_port_info *info);
|
||||
/**
|
||||
* Activate of deactivate the node
|
||||
* Activate or deactivate the node
|
||||
*/
|
||||
void (*set_active) (void *object, bool active);
|
||||
/**
|
||||
|
|
@ -252,12 +245,14 @@ pw_client_node_proxy_update(struct pw_client_node_proxy *p,
|
|||
uint32_t change_mask,
|
||||
uint32_t max_input_ports,
|
||||
uint32_t max_output_ports,
|
||||
const struct spa_props *props)
|
||||
uint32_t n_params,
|
||||
const struct spa_pod_object **params)
|
||||
{
|
||||
pw_proxy_do((struct pw_proxy*)p, struct pw_client_node_proxy_methods, update, change_mask,
|
||||
max_input_ports,
|
||||
max_output_ports,
|
||||
props);
|
||||
n_params,
|
||||
params);
|
||||
}
|
||||
|
||||
static inline void
|
||||
|
|
@ -265,19 +260,13 @@ pw_client_node_proxy_port_update(struct pw_client_node_proxy *p,
|
|||
enum spa_direction direction,
|
||||
uint32_t port_id,
|
||||
uint32_t change_mask,
|
||||
uint32_t n_possible_formats,
|
||||
const struct spa_format **possible_formats,
|
||||
const struct spa_format *format,
|
||||
uint32_t n_params,
|
||||
const struct spa_param **params,
|
||||
const struct spa_pod_object **params,
|
||||
const struct spa_port_info *info)
|
||||
{
|
||||
pw_proxy_do((struct pw_proxy*)p, struct pw_client_node_proxy_methods, port_update, direction,
|
||||
port_id,
|
||||
change_mask,
|
||||
n_possible_formats,
|
||||
possible_formats,
|
||||
format,
|
||||
n_params,
|
||||
params,
|
||||
info);
|
||||
|
|
@ -302,18 +291,17 @@ pw_client_node_proxy_destroy(struct pw_client_node_proxy *p)
|
|||
}
|
||||
|
||||
|
||||
#define PW_CLIENT_NODE_PROXY_EVENT_TRANSPORT 0
|
||||
#define PW_CLIENT_NODE_PROXY_EVENT_SET_PROPS 1
|
||||
#define PW_CLIENT_NODE_PROXY_EVENT_EVENT 2
|
||||
#define PW_CLIENT_NODE_PROXY_EVENT_ADD_PORT 3
|
||||
#define PW_CLIENT_NODE_PROXY_EVENT_REMOVE_PORT 4
|
||||
#define PW_CLIENT_NODE_PROXY_EVENT_SET_FORMAT 5
|
||||
#define PW_CLIENT_NODE_PROXY_EVENT_SET_PARAM 6
|
||||
#define PW_CLIENT_NODE_PROXY_EVENT_ADD_MEM 7
|
||||
#define PW_CLIENT_NODE_PROXY_EVENT_USE_BUFFERS 8
|
||||
#define PW_CLIENT_NODE_PROXY_EVENT_NODE_COMMAND 9
|
||||
#define PW_CLIENT_NODE_PROXY_EVENT_PORT_COMMAND 10
|
||||
#define PW_CLIENT_NODE_PROXY_EVENT_NUM 11
|
||||
#define PW_CLIENT_NODE_PROXY_EVENT_TRANSPORT 0
|
||||
#define PW_CLIENT_NODE_PROXY_EVENT_SET_PARAM 1
|
||||
#define PW_CLIENT_NODE_PROXY_EVENT_EVENT 2
|
||||
#define PW_CLIENT_NODE_PROXY_EVENT_COMMAND 3
|
||||
#define PW_CLIENT_NODE_PROXY_EVENT_ADD_PORT 4
|
||||
#define PW_CLIENT_NODE_PROXY_EVENT_REMOVE_PORT 5
|
||||
#define PW_CLIENT_NODE_PROXY_EVENT_PORT_SET_PARAM 6
|
||||
#define PW_CLIENT_NODE_PROXY_EVENT_PORT_ADD_MEM 7
|
||||
#define PW_CLIENT_NODE_PROXY_EVENT_PORT_USE_BUFFERS 8
|
||||
#define PW_CLIENT_NODE_PROXY_EVENT_PORT_COMMAND 9
|
||||
#define PW_CLIENT_NODE_PROXY_EVENT_NUM 10
|
||||
|
||||
/** \ref pw_client_node events */
|
||||
struct pw_client_node_proxy_events {
|
||||
|
|
@ -342,15 +330,24 @@ struct pw_client_node_proxy_events {
|
|||
* this event is sent
|
||||
*
|
||||
* \param seq a sequence number
|
||||
* \param props the props to set
|
||||
* \param id the id of the parameter
|
||||
* \param flags parameter flags
|
||||
* \param param the param to set
|
||||
*/
|
||||
void (*set_props) (void *object,
|
||||
uint32_t seq,
|
||||
const struct spa_props *props);
|
||||
void (*set_param) (void *object, uint32_t seq,
|
||||
uint32_t id, uint32_t flags,
|
||||
const struct spa_pod_object *param);
|
||||
/**
|
||||
* Receive an event from the client node
|
||||
* \param event the received event */
|
||||
void (*event) (void *object, const struct spa_event *event);
|
||||
/**
|
||||
* Notify of a new node command
|
||||
*
|
||||
* \param seq a sequence number
|
||||
* \param command the command
|
||||
*/
|
||||
void (*command) (void *object, uint32_t seq, const struct spa_command *command);
|
||||
/**
|
||||
* A new port was added to the node
|
||||
*
|
||||
|
|
@ -376,34 +373,22 @@ struct pw_client_node_proxy_events {
|
|||
uint32_t seq,
|
||||
enum spa_direction direction,
|
||||
uint32_t port_id);
|
||||
/**
|
||||
* A format was configured on the port
|
||||
*
|
||||
* \param seq a sequence number
|
||||
* \param direction a port direction
|
||||
* \param port_id the port id
|
||||
* \param flags flags used when setting the format
|
||||
* \param format the new format
|
||||
*/
|
||||
void (*set_format) (void *object,
|
||||
uint32_t seq,
|
||||
enum spa_direction direction,
|
||||
uint32_t port_id,
|
||||
uint32_t flags,
|
||||
const struct spa_format *format);
|
||||
/**
|
||||
* A parameter was configured on the port
|
||||
*
|
||||
* \param seq a sequence number
|
||||
* \param direction a port direction
|
||||
* \param port_id the port id
|
||||
* \param id the id of the parameter
|
||||
* \param flags flags used when setting the param
|
||||
* \param param the new param
|
||||
*/
|
||||
void (*set_param) (void *object,
|
||||
uint32_t seq,
|
||||
enum spa_direction direction,
|
||||
uint32_t port_id,
|
||||
const struct spa_param *param);
|
||||
void (*port_set_param) (void *object,
|
||||
uint32_t seq,
|
||||
enum spa_direction direction,
|
||||
uint32_t port_id,
|
||||
uint32_t id, uint32_t flags,
|
||||
const struct spa_pod_object *param);
|
||||
/**
|
||||
* Memory was added for a port
|
||||
*
|
||||
|
|
@ -416,15 +401,15 @@ struct pw_client_node_proxy_events {
|
|||
* \param offset valid offset of mapped memory from \a memfd
|
||||
* \param size valid size of mapped memory from \a memfd
|
||||
*/
|
||||
void (*add_mem) (void *object,
|
||||
enum spa_direction direction,
|
||||
uint32_t port_id,
|
||||
uint32_t mem_id,
|
||||
uint32_t type,
|
||||
int memfd,
|
||||
uint32_t flags,
|
||||
uint32_t offset,
|
||||
uint32_t size);
|
||||
void (*port_add_mem) (void *object,
|
||||
enum spa_direction direction,
|
||||
uint32_t port_id,
|
||||
uint32_t mem_id,
|
||||
uint32_t type,
|
||||
int memfd,
|
||||
uint32_t flags,
|
||||
uint32_t offset,
|
||||
uint32_t size);
|
||||
/**
|
||||
* Notify the port of buffers
|
||||
*
|
||||
|
|
@ -434,19 +419,12 @@ struct pw_client_node_proxy_events {
|
|||
* \param n_buffer the number of buffers
|
||||
* \param buffers and array of buffer descriptions
|
||||
*/
|
||||
void (*use_buffers) (void *object,
|
||||
uint32_t seq,
|
||||
enum spa_direction direction,
|
||||
uint32_t port_id,
|
||||
uint32_t n_buffers,
|
||||
struct pw_client_node_buffer *buffers);
|
||||
/**
|
||||
* Notify of a new node command
|
||||
*
|
||||
* \param seq a sequence number
|
||||
* \param command the command
|
||||
*/
|
||||
void (*node_command) (void *object, uint32_t seq, const struct spa_command *command);
|
||||
void (*port_use_buffers) (void *object,
|
||||
uint32_t seq,
|
||||
enum spa_direction direction,
|
||||
uint32_t port_id,
|
||||
uint32_t n_buffers,
|
||||
struct pw_client_node_buffer *buffers);
|
||||
/**
|
||||
* Notify of a new port command
|
||||
*
|
||||
|
|
@ -470,17 +448,26 @@ pw_client_node_proxy_add_listener(struct pw_client_node_proxy *p,
|
|||
pw_proxy_add_proxy_listener((struct pw_proxy*)p, listener, events, data);
|
||||
}
|
||||
|
||||
#define pw_client_node_resource_transport(r,...) pw_resource_notify(r,struct pw_client_node_proxy_events,transport,__VA_ARGS__)
|
||||
#define pw_client_node_resource_set_props(r,...) pw_resource_notify(r,struct pw_client_node_proxy_events,props,__VA_ARGS__)
|
||||
#define pw_client_node_resource_event(r,...) pw_resource_notify(r,struct pw_client_node_proxy_events,event,__VA_ARGS__)
|
||||
#define pw_client_node_resource_add_port(r,...) pw_resource_notify(r,struct pw_client_node_proxy_events,add_port,__VA_ARGS__)
|
||||
#define pw_client_node_resource_remove_port(r,...) pw_resource_notify(r,struct pw_client_node_proxy_events,remove_port,__VA_ARGS__)
|
||||
#define pw_client_node_resource_set_format(r,...) pw_resource_notify(r,struct pw_client_node_proxy_events,set_format,__VA_ARGS__)
|
||||
#define pw_client_node_resource_set_param(r,...) pw_resource_notify(r,struct pw_client_node_proxy_events,set_param,__VA_ARGS__)
|
||||
#define pw_client_node_resource_add_mem(r,...) pw_resource_notify(r,struct pw_client_node_proxy_events,add_mem,__VA_ARGS__)
|
||||
#define pw_client_node_resource_use_buffers(r,...) pw_resource_notify(r,struct pw_client_node_proxy_events,use_buffers,__VA_ARGS__)
|
||||
#define pw_client_node_resource_node_command(r,...) pw_resource_notify(r,struct pw_client_node_proxy_events,node_command,__VA_ARGS__)
|
||||
#define pw_client_node_resource_port_command(r,...) pw_resource_notify(r,struct pw_client_node_proxy_events,port_command,__VA_ARGS__)
|
||||
#define pw_client_node_resource_transport(r,...) \
|
||||
pw_resource_notify(r,struct pw_client_node_proxy_events,transport,__VA_ARGS__)
|
||||
#define pw_client_node_resource_set_param(r,...) \
|
||||
pw_resource_notify(r,struct pw_client_node_proxy_events,set_param,__VA_ARGS__)
|
||||
#define pw_client_node_resource_event(r,...) \
|
||||
pw_resource_notify(r,struct pw_client_node_proxy_events,event,__VA_ARGS__)
|
||||
#define pw_client_node_resource_command(r,...) \
|
||||
pw_resource_notify(r,struct pw_client_node_proxy_events,command,__VA_ARGS__)
|
||||
#define pw_client_node_resource_add_port(r,...) \
|
||||
pw_resource_notify(r,struct pw_client_node_proxy_events,add_port,__VA_ARGS__)
|
||||
#define pw_client_node_resource_remove_port(r,...) \
|
||||
pw_resource_notify(r,struct pw_client_node_proxy_events,remove_port,__VA_ARGS__)
|
||||
#define pw_client_node_resource_port_set_param(r,...) \
|
||||
pw_resource_notify(r,struct pw_client_node_proxy_events,port_set_param,__VA_ARGS__)
|
||||
#define pw_client_node_resource_port_add_mem(r,...) \
|
||||
pw_resource_notify(r,struct pw_client_node_proxy_events,port_add_mem,__VA_ARGS__)
|
||||
#define pw_client_node_resource_port_use_buffers(r,...) \
|
||||
pw_resource_notify(r,struct pw_client_node_proxy_events,port_use_buffers,__VA_ARGS__)
|
||||
#define pw_client_node_resource_port_command(r,...) \
|
||||
pw_resource_notify(r,struct pw_client_node_proxy_events,port_command,__VA_ARGS__)
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
|
|
|||
|
|
@ -207,16 +207,20 @@ new_node (GstPipeWireDeviceProvider *self, const struct pw_node_info *info, uint
|
|||
if (info->max_input_ports > 0 && info->max_output_ports == 0) {
|
||||
type = GST_PIPEWIRE_DEVICE_TYPE_SINK;
|
||||
|
||||
for (i = 0; i < info->n_input_formats; i++) {
|
||||
GstCaps *c1 = gst_caps_from_format (info->input_formats[i], t->map);
|
||||
for (i = 0; i < info->n_input_params; i++) {
|
||||
if (info->input_params[i]->body.id != t->param.idEnumFormat)
|
||||
continue;
|
||||
GstCaps *c1 = gst_caps_from_format (info->input_params[i], t->map);
|
||||
if (c1)
|
||||
gst_caps_append (caps, c1);
|
||||
}
|
||||
}
|
||||
else if (info->max_output_ports > 0 && info->max_input_ports == 0) {
|
||||
type = GST_PIPEWIRE_DEVICE_TYPE_SOURCE;
|
||||
for (i = 0; i < info->n_output_formats; i++) {
|
||||
GstCaps *c1 = gst_caps_from_format (info->output_formats[i], t->map);
|
||||
for (i = 0; i < info->n_output_params; i++) {
|
||||
if (info->output_params[i]->body.id != t->param.idEnumFormat)
|
||||
continue;
|
||||
GstCaps *c1 = gst_caps_from_format (info->output_params[i], t->map);
|
||||
if (c1)
|
||||
gst_caps_append (caps, c1);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@
|
|||
#include <gst/video/video.h>
|
||||
#include <gst/audio/audio.h>
|
||||
|
||||
#include <spa/format-builder.h>
|
||||
#include <spa/pod-builder.h>
|
||||
#include <spa/video/format-utils.h>
|
||||
#include <spa/audio/format-utils.h>
|
||||
|
||||
|
|
@ -542,7 +542,7 @@ write_pod (struct spa_pod_builder *b, uint32_t ref, const void *data, uint32_t s
|
|||
return ref;
|
||||
}
|
||||
|
||||
static struct spa_format *
|
||||
static struct spa_pod_object *
|
||||
convert_1 (GstCapsFeatures *cf, GstStructure *cs)
|
||||
{
|
||||
ConvertData d;
|
||||
|
|
@ -557,9 +557,9 @@ convert_1 (GstCapsFeatures *cf, GstStructure *cs)
|
|||
|
||||
d.b.write = write_pod;
|
||||
|
||||
spa_pod_builder_push_format (&d.b, &f, type.format,
|
||||
*d.type->media_type,
|
||||
*d.type->media_subtype);
|
||||
spa_pod_builder_push_object (&d.b, &f, 0, type.format);
|
||||
spa_pod_builder_id(&d.b, *d.type->media_type);
|
||||
spa_pod_builder_id(&d.b, *d.type->media_subtype);
|
||||
|
||||
if (*d.type->media_type == type.media_type.video)
|
||||
handle_video_fields (&d);
|
||||
|
|
@ -568,15 +568,15 @@ convert_1 (GstCapsFeatures *cf, GstStructure *cs)
|
|||
|
||||
spa_pod_builder_pop (&d.b, &f);
|
||||
|
||||
return SPA_MEMBER (d.b.data, 0, struct spa_format);
|
||||
return SPA_MEMBER (d.b.data, 0, struct spa_pod_object);
|
||||
}
|
||||
|
||||
struct spa_format *
|
||||
struct spa_pod_object *
|
||||
gst_caps_to_format (GstCaps *caps, guint index, struct spa_type_map *map)
|
||||
{
|
||||
GstCapsFeatures *f;
|
||||
GstStructure *s;
|
||||
struct spa_format *res;
|
||||
struct spa_pod_object *res;
|
||||
|
||||
g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
|
||||
g_return_val_if_fail (gst_caps_is_fixed (caps), NULL);
|
||||
|
|
@ -596,7 +596,7 @@ foreach_func (GstCapsFeatures *features,
|
|||
GstStructure *structure,
|
||||
GPtrArray *array)
|
||||
{
|
||||
struct spa_format *fmt;
|
||||
struct spa_pod_object *fmt;
|
||||
|
||||
if ((fmt = convert_1 (features, structure)))
|
||||
g_ptr_array_insert (array, -1, fmt);
|
||||
|
|
@ -794,7 +794,7 @@ handle_fraction_prop (struct spa_pod_prop *prop, const char *key, GstCaps *res)
|
|||
}
|
||||
}
|
||||
GstCaps *
|
||||
gst_caps_from_format (const struct spa_format *format, struct spa_type_map *map)
|
||||
gst_caps_from_format (const struct spa_pod_object *format, struct spa_type_map *map)
|
||||
{
|
||||
GstCaps *res = NULL;
|
||||
uint32_t media_type, media_subtype;
|
||||
|
|
@ -802,13 +802,13 @@ gst_caps_from_format (const struct spa_format *format, struct spa_type_map *map)
|
|||
|
||||
ensure_types(map);
|
||||
|
||||
media_type = SPA_FORMAT_MEDIA_TYPE (format);
|
||||
media_subtype = SPA_FORMAT_MEDIA_SUBTYPE (format);
|
||||
spa_pod_object_parse(format, "I", &media_type,
|
||||
"I", &media_subtype);
|
||||
|
||||
if (media_type == type.media_type.video) {
|
||||
if (media_subtype == type.media_subtype.raw) {
|
||||
res = gst_caps_new_empty_simple ("video/x-raw");
|
||||
if ((prop = spa_format_find_prop (format, type.format_video.format))) {
|
||||
if ((prop = spa_pod_object_find_prop (format, type.format_video.format))) {
|
||||
handle_id_prop (prop, "format", res);
|
||||
}
|
||||
}
|
||||
|
|
@ -821,13 +821,13 @@ gst_caps_from_format (const struct spa_format *format, struct spa_type_map *map)
|
|||
"alignment", G_TYPE_STRING, "au",
|
||||
NULL);
|
||||
}
|
||||
if ((prop = spa_format_find_prop (format, type.format_video.size))) {
|
||||
if ((prop = spa_pod_object_find_prop (format, type.format_video.size))) {
|
||||
handle_rect_prop (prop, "width", "height", res);
|
||||
}
|
||||
if ((prop = spa_format_find_prop (format, type.format_video.framerate))) {
|
||||
if ((prop = spa_pod_object_find_prop (format, type.format_video.framerate))) {
|
||||
handle_fraction_prop (prop, "framerate", res);
|
||||
}
|
||||
if ((prop = spa_format_find_prop (format, type.format_video.max_framerate))) {
|
||||
if ((prop = spa_pod_object_find_prop (format, type.format_video.max_framerate))) {
|
||||
handle_fraction_prop (prop, "max-framerate", res);
|
||||
}
|
||||
} else if (media_type == type.media_type.audio) {
|
||||
|
|
@ -835,13 +835,13 @@ gst_caps_from_format (const struct spa_format *format, struct spa_type_map *map)
|
|||
res = gst_caps_new_simple ("audio/x-raw",
|
||||
"layout", G_TYPE_STRING, "interleaved",
|
||||
NULL);
|
||||
if ((prop = spa_format_find_prop (format, type.format_audio.format))) {
|
||||
if ((prop = spa_pod_object_find_prop (format, type.format_audio.format))) {
|
||||
handle_id_prop (prop, "format", res);
|
||||
}
|
||||
if ((prop = spa_format_find_prop (format, type.format_audio.rate))) {
|
||||
if ((prop = spa_pod_object_find_prop (format, type.format_audio.rate))) {
|
||||
handle_int_prop (prop, "rate", res);
|
||||
}
|
||||
if ((prop = spa_format_find_prop (format, type.format_audio.channels))) {
|
||||
if ((prop = spa_pod_object_find_prop (format, type.format_audio.channels))) {
|
||||
handle_int_prop (prop, "channels", res);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,10 +27,10 @@
|
|||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
struct spa_format * gst_caps_to_format (GstCaps *caps, guint index, struct spa_type_map *map);
|
||||
GPtrArray * gst_caps_to_format_all (GstCaps *caps, struct spa_type_map *map);
|
||||
struct spa_pod_object * gst_caps_to_format (GstCaps *caps, guint index, struct spa_type_map *map);
|
||||
GPtrArray * gst_caps_to_format_all (GstCaps *caps, struct spa_type_map *map);
|
||||
|
||||
GstCaps * gst_caps_from_format (const struct spa_format *format, struct spa_type_map *map);
|
||||
GstCaps * gst_caps_from_format (const struct spa_pod_object *format, struct spa_type_map *map);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
|
|
|||
|
|
@ -228,7 +228,7 @@ pool_activated (GstPipeWirePool *pool, GstPipeWireSink *sink)
|
|||
guint size;
|
||||
guint min_buffers;
|
||||
guint max_buffers;
|
||||
struct spa_param *port_params[3];
|
||||
struct spa_pod_object *port_params[3];
|
||||
struct spa_pod_builder b = { NULL };
|
||||
uint8_t buffer[1024];
|
||||
struct spa_pod_frame f[1];
|
||||
|
|
@ -237,7 +237,7 @@ pool_activated (GstPipeWirePool *pool, GstPipeWireSink *sink)
|
|||
gst_buffer_pool_config_get_params (config, &caps, &size, &min_buffers, &max_buffers);
|
||||
|
||||
spa_pod_builder_init (&b, buffer, sizeof (buffer));
|
||||
spa_pod_builder_push_param (&b, &f[0], t->param_alloc_buffers.Buffers);
|
||||
spa_pod_builder_push_object (&b, &f[0], t->param.idBuffers, t->param_alloc_buffers.Buffers);
|
||||
if (size == 0)
|
||||
spa_pod_builder_add (&b,
|
||||
":", t->param_alloc_buffers.size, "iru", 0, SPA_PROP_RANGE(0, INT32_MAX), NULL);
|
||||
|
|
@ -253,15 +253,15 @@ pool_activated (GstPipeWirePool *pool, GstPipeWireSink *sink)
|
|||
":", t->param_alloc_buffers.align, "i", 16,
|
||||
NULL);
|
||||
spa_pod_builder_pop (&b, &f[0]);
|
||||
port_params[0] = SPA_POD_BUILDER_DEREF (&b, f[0].ref, struct spa_param);
|
||||
port_params[0] = SPA_POD_BUILDER_DEREF (&b, f[0].ref, struct spa_pod_object);
|
||||
|
||||
port_params[1] = spa_pod_builder_param (&b,
|
||||
t->param_alloc_meta_enable.MetaEnable,
|
||||
port_params[1] = spa_pod_builder_object (&b,
|
||||
t->param.idMeta, t->param_alloc_meta_enable.MetaEnable,
|
||||
":", t->param_alloc_meta_enable.type, "I", t->meta.Header,
|
||||
":", t->param_alloc_meta_enable.size, "i", sizeof (struct spa_meta_header));
|
||||
|
||||
port_params[2] = spa_pod_builder_param (&b,
|
||||
t->param_alloc_meta_enable.MetaEnable,
|
||||
port_params[2] = spa_pod_builder_object (&b,
|
||||
t->param.idMeta, t->param_alloc_meta_enable.MetaEnable,
|
||||
":", t->param_alloc_meta_enable.type, "I", t->meta.Ringbuffer,
|
||||
":", t->param_alloc_meta_enable.size, "i", sizeof (struct spa_meta_ringbuffer),
|
||||
":", t->param_alloc_meta_enable.ringbufferSize, "i", size * SPA_MAX (4,
|
||||
|
|
@ -271,7 +271,7 @@ pool_activated (GstPipeWirePool *pool, GstPipeWireSink *sink)
|
|||
":", t->param_alloc_meta_enable.ringbufferAlign, "i", 16);
|
||||
|
||||
pw_thread_loop_lock (sink->main_loop);
|
||||
pw_stream_finish_format (sink->stream, SPA_RESULT_OK, port_params, 2);
|
||||
pw_stream_finish_format (sink->stream, SPA_RESULT_OK, 2, port_params);
|
||||
pw_thread_loop_unlock (sink->main_loop);
|
||||
}
|
||||
|
||||
|
|
@ -586,7 +586,7 @@ on_state_changed (void *data, enum pw_stream_state old, enum pw_stream_state sta
|
|||
}
|
||||
|
||||
static void
|
||||
on_format_changed (void *data, struct spa_format *format)
|
||||
on_format_changed (void *data, struct spa_pod_object *format)
|
||||
{
|
||||
GstPipeWireSink *pwsink = data;
|
||||
|
||||
|
|
@ -621,11 +621,10 @@ gst_pipewire_sink_setcaps (GstBaseSink * bsink, GstCaps * caps)
|
|||
|
||||
pw_stream_connect (pwsink->stream,
|
||||
PW_DIRECTION_OUTPUT,
|
||||
PW_STREAM_MODE_BUFFER,
|
||||
pwsink->path,
|
||||
flags,
|
||||
possible->len,
|
||||
(const struct spa_format **) possible->pdata);
|
||||
(const struct spa_pod_object **) possible->pdata);
|
||||
|
||||
while (TRUE) {
|
||||
state = pw_stream_get_state (pwsink->stream, &error);
|
||||
|
|
|
|||
|
|
@ -663,11 +663,10 @@ gst_pipewire_src_negotiate (GstBaseSrc * basesrc)
|
|||
GST_DEBUG_OBJECT (basesrc, "connect capture with path %s", pwsrc->path);
|
||||
pw_stream_connect (pwsrc->stream,
|
||||
PW_DIRECTION_INPUT,
|
||||
PW_STREAM_MODE_BUFFER,
|
||||
pwsrc->path,
|
||||
PW_STREAM_FLAG_AUTOCONNECT,
|
||||
possible->len,
|
||||
(const struct spa_format **)possible->pdata);
|
||||
(const struct spa_pod_object **)possible->pdata);
|
||||
g_ptr_array_free (possible, TRUE);
|
||||
|
||||
while (TRUE) {
|
||||
|
|
@ -729,8 +728,8 @@ connect_error:
|
|||
#define SPA_PROP_RANGE(min,max) 2,min,max
|
||||
|
||||
static void
|
||||
on_format_changed (void *data,
|
||||
struct spa_format *format)
|
||||
on_format_changed (void *data,
|
||||
struct spa_pod_object *format)
|
||||
{
|
||||
GstPipeWireSrc *pwsrc = data;
|
||||
GstCaps *caps;
|
||||
|
|
@ -740,7 +739,7 @@ on_format_changed (void *data,
|
|||
|
||||
if (format == NULL) {
|
||||
GST_DEBUG_OBJECT (pwsrc, "clear format");
|
||||
pw_stream_finish_format (pwsrc->stream, SPA_RESULT_OK, NULL, 0);
|
||||
pw_stream_finish_format (pwsrc->stream, SPA_RESULT_OK, 0, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -750,28 +749,28 @@ on_format_changed (void *data,
|
|||
gst_caps_unref (caps);
|
||||
|
||||
if (res) {
|
||||
struct spa_param *params[2];
|
||||
struct spa_pod_object *params[2];
|
||||
struct spa_pod_builder b = { NULL };
|
||||
uint8_t buffer[512];
|
||||
|
||||
spa_pod_builder_init (&b, buffer, sizeof (buffer));
|
||||
params[0] = spa_pod_builder_param (&b,
|
||||
t->param_alloc_buffers.Buffers,
|
||||
params[0] = spa_pod_builder_object (&b,
|
||||
0, t->param_alloc_buffers.Buffers,
|
||||
":", t->param_alloc_buffers.size, "ir", 0, SPA_PROP_RANGE(0, INT32_MAX),
|
||||
":", t->param_alloc_buffers.stride, "ir", 0, SPA_PROP_RANGE(0, INT32_MAX),
|
||||
":", t->param_alloc_buffers.buffers, "ir", 16, SPA_PROP_RANGE(1, INT32_MAX),
|
||||
":", t->param_alloc_buffers.align, "i", 16);
|
||||
|
||||
params[1] = spa_pod_builder_param (&b,
|
||||
t->param_alloc_meta_enable.MetaEnable,
|
||||
params[1] = spa_pod_builder_object (&b,
|
||||
0, t->param_alloc_meta_enable.MetaEnable,
|
||||
":", t->param_alloc_meta_enable.type, "I", t->meta.Header,
|
||||
":", t->param_alloc_meta_enable.size, "i", sizeof (struct spa_meta_header));
|
||||
|
||||
GST_DEBUG_OBJECT (pwsrc, "doing finish format");
|
||||
pw_stream_finish_format (pwsrc->stream, SPA_RESULT_OK, params, 2);
|
||||
pw_stream_finish_format (pwsrc->stream, SPA_RESULT_OK, 2, params);
|
||||
} else {
|
||||
GST_WARNING_OBJECT (pwsrc, "finish format with error");
|
||||
pw_stream_finish_format (pwsrc->stream, SPA_RESULT_INVALID_MEDIA_TYPE, NULL, 0);
|
||||
pw_stream_finish_format (pwsrc->stream, SPA_RESULT_INVALID_MEDIA_TYPE, 0, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
#include "pipewire/link.h"
|
||||
#include "pipewire/log.h"
|
||||
#include "pipewire/module.h"
|
||||
#include "pipewire/private.h"
|
||||
|
||||
struct impl {
|
||||
struct pw_core *core;
|
||||
|
|
|
|||
|
|
@ -29,7 +29,6 @@
|
|||
#include <sys/eventfd.h>
|
||||
|
||||
#include "spa/node.h"
|
||||
#include "spa/format-builder.h"
|
||||
#include "spa/lib/format.h"
|
||||
|
||||
#include "pipewire/pipewire.h"
|
||||
|
|
@ -73,11 +72,10 @@ struct proxy_buffer {
|
|||
struct proxy_port {
|
||||
bool valid;
|
||||
struct spa_port_info info;
|
||||
struct spa_format *format;
|
||||
uint32_t n_formats;
|
||||
struct spa_format **formats;
|
||||
|
||||
bool have_format;
|
||||
uint32_t n_params;
|
||||
struct spa_param **params;
|
||||
struct spa_pod_object **params;
|
||||
struct spa_port_io *io;
|
||||
|
||||
uint32_t n_buffers;
|
||||
|
|
@ -108,6 +106,9 @@ struct proxy {
|
|||
struct proxy_port in_ports[MAX_INPUTS];
|
||||
struct proxy_port out_ports[MAX_OUTPUTS];
|
||||
|
||||
uint32_t n_params;
|
||||
struct spa_pod_object **params;
|
||||
|
||||
uint8_t format_buffer[1024];
|
||||
uint32_t seq;
|
||||
};
|
||||
|
|
@ -145,14 +146,51 @@ static int clear_buffers(struct proxy *this, struct proxy_port *port)
|
|||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
static int spa_proxy_node_get_props(struct spa_node *node, struct spa_props **props)
|
||||
static int spa_proxy_node_enum_params(struct spa_node *node,
|
||||
uint32_t id, uint32_t *index,
|
||||
const struct spa_pod_object *filter,
|
||||
struct spa_pod_builder *builder)
|
||||
{
|
||||
return SPA_RESULT_NOT_IMPLEMENTED;
|
||||
struct proxy *this;
|
||||
|
||||
spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
|
||||
spa_return_val_if_fail(index != NULL, SPA_RESULT_INVALID_ARGUMENTS);
|
||||
spa_return_val_if_fail(builder != NULL, SPA_RESULT_INVALID_ARGUMENTS);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct proxy, node);
|
||||
|
||||
while (true) {
|
||||
struct spa_pod_object *param;
|
||||
|
||||
if (*index >= this->n_params)
|
||||
return SPA_RESULT_ENUM_END;
|
||||
|
||||
param = this->params[(*index)++];
|
||||
|
||||
if (param->body.id == id) {
|
||||
spa_pod_builder_primitive(builder, ¶m->pod);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
static int spa_proxy_node_set_props(struct spa_node *node, const struct spa_props *props)
|
||||
static int spa_proxy_node_set_param(struct spa_node *node, uint32_t id, uint32_t flags,
|
||||
const struct spa_pod_object *param)
|
||||
{
|
||||
return SPA_RESULT_NOT_IMPLEMENTED;
|
||||
struct proxy *this;
|
||||
|
||||
if (node == NULL)
|
||||
return SPA_RESULT_INVALID_ARGUMENTS;
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct proxy, node);
|
||||
|
||||
if (this->resource == NULL)
|
||||
return SPA_RESULT_OK;
|
||||
|
||||
pw_client_node_resource_set_param(this->resource, this->seq, id, flags, param);
|
||||
|
||||
return SPA_RESULT_RETURN_ASYNC(this->seq++);
|
||||
}
|
||||
|
||||
static inline void do_flush(struct proxy *this)
|
||||
|
|
@ -180,10 +218,10 @@ static int spa_proxy_node_send_command(struct spa_node *node, const struct spa_c
|
|||
t = this->impl->t;
|
||||
|
||||
if (SPA_COMMAND_TYPE(command) == t->command_node.ClockUpdate) {
|
||||
pw_client_node_resource_node_command(this->resource, this->seq++, command);
|
||||
pw_client_node_resource_command(this->resource, this->seq++, command);
|
||||
} else {
|
||||
/* send start */
|
||||
pw_client_node_resource_node_command(this->resource, this->seq, command);
|
||||
pw_client_node_resource_command(this->resource, this->seq, command);
|
||||
res = SPA_RESULT_RETURN_ASYNC(this->seq++);
|
||||
}
|
||||
return res;
|
||||
|
|
@ -267,15 +305,12 @@ do_update_port(struct proxy *this,
|
|||
enum spa_direction direction,
|
||||
uint32_t port_id,
|
||||
uint32_t change_mask,
|
||||
uint32_t n_possible_formats,
|
||||
const struct spa_format **possible_formats,
|
||||
const struct spa_format *format,
|
||||
uint32_t n_params,
|
||||
const struct spa_param **params,
|
||||
const struct spa_pod_object **params,
|
||||
const struct spa_port_info *info)
|
||||
{
|
||||
struct proxy_port *port;
|
||||
uint32_t i;
|
||||
struct pw_type *t = this->impl->t;
|
||||
|
||||
if (direction == SPA_DIRECTION_INPUT) {
|
||||
port = &this->in_ports[port_id];
|
||||
|
|
@ -283,31 +318,23 @@ do_update_port(struct proxy *this,
|
|||
port = &this->out_ports[port_id];
|
||||
}
|
||||
|
||||
if (change_mask & PW_CLIENT_NODE_PORT_UPDATE_POSSIBLE_FORMATS) {
|
||||
spa_log_info(this->log, "proxy %p: %d formats", this, n_possible_formats);
|
||||
for (i = 0; i < port->n_formats; i++)
|
||||
free(port->formats[i]);
|
||||
port->n_formats = n_possible_formats;
|
||||
port->formats =
|
||||
realloc(port->formats, port->n_formats * sizeof(struct spa_format *));
|
||||
for (i = 0; i < port->n_formats; i++)
|
||||
port->formats[i] = spa_format_copy(possible_formats[i]);
|
||||
}
|
||||
if (change_mask & PW_CLIENT_NODE_PORT_UPDATE_FORMAT) {
|
||||
spa_log_info(this->log, "proxy %p: update format %p", this, format);
|
||||
if (port->format)
|
||||
free(port->format);
|
||||
port->format = spa_format_copy(format);
|
||||
}
|
||||
|
||||
if (change_mask & PW_CLIENT_NODE_PORT_UPDATE_PARAMS) {
|
||||
int i;
|
||||
|
||||
port->have_format = false;
|
||||
|
||||
spa_log_info(this->log, "proxy %p: update %d params", this, n_params);
|
||||
for (i = 0; i < port->n_params; i++)
|
||||
free(port->params[i]);
|
||||
port->n_params = n_params;
|
||||
port->params = realloc(port->params, port->n_params * sizeof(struct spa_param *));
|
||||
for (i = 0; i < port->n_params; i++)
|
||||
port->params[i] = spa_param_copy(params[i]);
|
||||
port->params = realloc(port->params, port->n_params * sizeof(struct spa_pod_object *));
|
||||
|
||||
for (i = 0; i < port->n_params; i++) {
|
||||
port->params[i] = spa_pod_object_copy(params[i]);
|
||||
if (port->params[i]->body.id == t->param.idFormat)
|
||||
port->have_format = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (change_mask & PW_CLIENT_NODE_PORT_UPDATE_INFO && info)
|
||||
|
|
@ -315,7 +342,7 @@ do_update_port(struct proxy *this,
|
|||
|
||||
if (!port->valid) {
|
||||
spa_log_info(this->log, "proxy %p: adding port %d", this, port_id);
|
||||
port->format = NULL;
|
||||
port->have_format = false;
|
||||
port->valid = true;
|
||||
|
||||
if (direction == SPA_DIRECTION_INPUT)
|
||||
|
|
@ -332,10 +359,8 @@ clear_port(struct proxy *this,
|
|||
do_update_port(this,
|
||||
direction,
|
||||
port_id,
|
||||
PW_CLIENT_NODE_PORT_UPDATE_POSSIBLE_FORMATS |
|
||||
PW_CLIENT_NODE_PORT_UPDATE_FORMAT |
|
||||
PW_CLIENT_NODE_PORT_UPDATE_PARAMS |
|
||||
PW_CLIENT_NODE_PORT_UPDATE_INFO, 0, NULL, NULL, 0, NULL, NULL);
|
||||
PW_CLIENT_NODE_PORT_UPDATE_INFO, 0, NULL, NULL);
|
||||
clear_buffers(this, port);
|
||||
}
|
||||
|
||||
|
|
@ -394,101 +419,6 @@ spa_proxy_node_remove_port(struct spa_node *node, enum spa_direction direction,
|
|||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
static int
|
||||
spa_proxy_node_port_enum_formats(struct spa_node *node,
|
||||
enum spa_direction direction,
|
||||
uint32_t port_id,
|
||||
struct spa_format **format,
|
||||
const struct spa_format *filter,
|
||||
uint32_t index)
|
||||
{
|
||||
struct proxy *this;
|
||||
struct proxy_port *port;
|
||||
struct spa_format *fmt;
|
||||
struct spa_pod_builder b = { NULL, };
|
||||
int res;
|
||||
uint32_t count, match = 0;
|
||||
|
||||
if (node == NULL || format == NULL)
|
||||
return SPA_RESULT_INVALID_ARGUMENTS;
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct proxy, node);
|
||||
|
||||
if (!CHECK_PORT(this, direction, port_id))
|
||||
return SPA_RESULT_INVALID_PORT;
|
||||
|
||||
port =
|
||||
direction == SPA_DIRECTION_INPUT ? &this->in_ports[port_id] : &this->out_ports[port_id];
|
||||
|
||||
count = match = filter ? 0 : index;
|
||||
|
||||
next:
|
||||
if (count >= port->n_formats)
|
||||
return SPA_RESULT_ENUM_END;
|
||||
|
||||
fmt = port->formats[count++];
|
||||
|
||||
spa_pod_builder_init(&b, this->format_buffer, sizeof(this->format_buffer));
|
||||
|
||||
if ((res = spa_format_filter(fmt, filter, &b)) != SPA_RESULT_OK || match++ != index)
|
||||
goto next;
|
||||
|
||||
*format = SPA_POD_BUILDER_DEREF(&b, 0, struct spa_format);
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
static int
|
||||
spa_proxy_node_port_set_format(struct spa_node *node,
|
||||
enum spa_direction direction,
|
||||
uint32_t port_id, uint32_t flags, const struct spa_format *format)
|
||||
{
|
||||
struct proxy *this;
|
||||
|
||||
if (node == NULL)
|
||||
return SPA_RESULT_INVALID_ARGUMENTS;
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct proxy, node);
|
||||
|
||||
if (!CHECK_PORT(this, direction, port_id))
|
||||
return SPA_RESULT_INVALID_PORT;
|
||||
|
||||
if (this->resource == NULL)
|
||||
return SPA_RESULT_OK;
|
||||
|
||||
pw_client_node_resource_set_format(this->resource,
|
||||
this->seq, direction, port_id, flags, format);
|
||||
|
||||
return SPA_RESULT_RETURN_ASYNC(this->seq++);
|
||||
}
|
||||
|
||||
static int
|
||||
spa_proxy_node_port_get_format(struct spa_node *node,
|
||||
enum spa_direction direction,
|
||||
uint32_t port_id, const struct spa_format **format)
|
||||
{
|
||||
struct proxy *this;
|
||||
struct proxy_port *port;
|
||||
|
||||
if (node == NULL || format == NULL)
|
||||
return SPA_RESULT_INVALID_ARGUMENTS;
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct proxy, node);
|
||||
|
||||
if (!CHECK_PORT(this, direction, port_id))
|
||||
return SPA_RESULT_INVALID_PORT;
|
||||
|
||||
port =
|
||||
direction == SPA_DIRECTION_INPUT ? &this->in_ports[port_id] : &this->out_ports[port_id];
|
||||
|
||||
if (!port->format)
|
||||
return SPA_RESULT_NO_FORMAT;
|
||||
|
||||
*format = port->format;
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
static int
|
||||
spa_proxy_node_port_get_info(struct spa_node *node,
|
||||
enum spa_direction direction,
|
||||
|
|
@ -515,14 +445,17 @@ spa_proxy_node_port_get_info(struct spa_node *node,
|
|||
|
||||
static int
|
||||
spa_proxy_node_port_enum_params(struct spa_node *node,
|
||||
enum spa_direction direction,
|
||||
uint32_t port_id, uint32_t index, struct spa_param **param)
|
||||
enum spa_direction direction, uint32_t port_id,
|
||||
uint32_t id, uint32_t *index,
|
||||
const struct spa_pod_object *filter,
|
||||
struct spa_pod_builder *builder)
|
||||
{
|
||||
struct proxy *this;
|
||||
struct proxy_port *port;
|
||||
|
||||
spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
|
||||
spa_return_val_if_fail(param != NULL, SPA_RESULT_INVALID_ARGUMENTS);
|
||||
spa_return_val_if_fail(index != NULL, SPA_RESULT_INVALID_ARGUMENTS);
|
||||
spa_return_val_if_fail(builder != NULL, SPA_RESULT_INVALID_ARGUMENTS);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct proxy, node);
|
||||
|
||||
|
|
@ -531,20 +464,48 @@ spa_proxy_node_port_enum_params(struct spa_node *node,
|
|||
port =
|
||||
direction == SPA_DIRECTION_INPUT ? &this->in_ports[port_id] : &this->out_ports[port_id];
|
||||
|
||||
if (index >= port->n_params)
|
||||
return SPA_RESULT_ENUM_END;
|
||||
while (true) {
|
||||
struct spa_pod_object *param;
|
||||
|
||||
*param = port->params[index];
|
||||
if (*index >= port->n_params)
|
||||
return SPA_RESULT_ENUM_END;
|
||||
|
||||
param = port->params[(*index)++];
|
||||
|
||||
if (param->body.id == id) {
|
||||
spa_pod_builder_primitive(builder, ¶m->pod);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
static int
|
||||
spa_proxy_node_port_set_param(struct spa_node *node,
|
||||
enum spa_direction direction,
|
||||
uint32_t port_id, const struct spa_param *param)
|
||||
enum spa_direction direction, uint32_t port_id,
|
||||
uint32_t id, uint32_t flags,
|
||||
const struct spa_pod_object *param)
|
||||
{
|
||||
return SPA_RESULT_NOT_IMPLEMENTED;
|
||||
struct proxy *this;
|
||||
|
||||
if (node == NULL)
|
||||
return SPA_RESULT_INVALID_ARGUMENTS;
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct proxy, node);
|
||||
|
||||
if (!CHECK_PORT(this, direction, port_id))
|
||||
return SPA_RESULT_INVALID_PORT;
|
||||
|
||||
if (this->resource == NULL)
|
||||
return SPA_RESULT_OK;
|
||||
|
||||
pw_client_node_resource_port_set_param(this->resource,
|
||||
this->seq,
|
||||
direction, port_id,
|
||||
id, flags,
|
||||
param);
|
||||
|
||||
return SPA_RESULT_RETURN_ASYNC(this->seq++);
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
@ -597,7 +558,7 @@ spa_proxy_node_port_use_buffers(struct spa_node *node,
|
|||
port =
|
||||
direction == SPA_DIRECTION_INPUT ? &this->in_ports[port_id] : &this->out_ports[port_id];
|
||||
|
||||
if (!port->format)
|
||||
if (!port->have_format)
|
||||
return SPA_RESULT_NO_FORMAT;
|
||||
|
||||
clear_buffers(this, port);
|
||||
|
|
@ -633,12 +594,12 @@ spa_proxy_node_port_use_buffers(struct spa_node *node,
|
|||
mb[i].offset = 0;
|
||||
mb[i].size = msh->size;
|
||||
|
||||
pw_client_node_resource_add_mem(this->resource,
|
||||
direction,
|
||||
port_id,
|
||||
mb[i].mem_id,
|
||||
t->data.MemFd,
|
||||
msh->fd, msh->flags, msh->offset, msh->size);
|
||||
pw_client_node_resource_port_add_mem(this->resource,
|
||||
direction,
|
||||
port_id,
|
||||
mb[i].mem_id,
|
||||
t->data.MemFd,
|
||||
msh->fd, msh->flags, msh->offset, msh->size);
|
||||
|
||||
for (j = 0; j < buffers[i]->n_metas; j++) {
|
||||
memcpy(&b->buffer.metas[j], &buffers[i]->metas[j], sizeof(struct spa_meta));
|
||||
|
|
@ -651,13 +612,13 @@ spa_proxy_node_port_use_buffers(struct spa_node *node,
|
|||
|
||||
if (d->type == t->data.DmaBuf ||
|
||||
d->type == t->data.MemFd) {
|
||||
pw_client_node_resource_add_mem(this->resource,
|
||||
direction,
|
||||
port_id,
|
||||
n_mem,
|
||||
d->type,
|
||||
d->fd,
|
||||
d->flags, d->mapoffset, d->maxsize);
|
||||
pw_client_node_resource_port_add_mem(this->resource,
|
||||
direction,
|
||||
port_id,
|
||||
n_mem,
|
||||
d->type,
|
||||
d->fd,
|
||||
d->flags, d->mapoffset, d->maxsize);
|
||||
b->buffer.datas[j].type = t->data.Id;
|
||||
b->buffer.datas[j].data = SPA_UINT32_TO_PTR(n_mem);
|
||||
n_mem++;
|
||||
|
|
@ -672,8 +633,10 @@ spa_proxy_node_port_use_buffers(struct spa_node *node,
|
|||
}
|
||||
}
|
||||
|
||||
pw_client_node_resource_use_buffers(this->resource,
|
||||
this->seq, direction, port_id, n_buffers, mb);
|
||||
pw_client_node_resource_port_use_buffers(this->resource,
|
||||
this->seq,
|
||||
direction, port_id,
|
||||
n_buffers, mb);
|
||||
|
||||
return SPA_RESULT_RETURN_ASYNC(this->seq++);
|
||||
}
|
||||
|
|
@ -682,7 +645,7 @@ static int
|
|||
spa_proxy_node_port_alloc_buffers(struct spa_node *node,
|
||||
enum spa_direction direction,
|
||||
uint32_t port_id,
|
||||
struct spa_param **params,
|
||||
struct spa_pod_object **params,
|
||||
uint32_t n_params,
|
||||
struct spa_buffer **buffers,
|
||||
uint32_t *n_buffers)
|
||||
|
|
@ -701,7 +664,7 @@ spa_proxy_node_port_alloc_buffers(struct spa_node *node,
|
|||
port =
|
||||
direction == SPA_DIRECTION_INPUT ? &this->in_ports[port_id] : &this->out_ports[port_id];
|
||||
|
||||
if (!port->format)
|
||||
if (!port->have_format)
|
||||
return SPA_RESULT_NO_FORMAT;
|
||||
|
||||
return SPA_RESULT_NOT_IMPLEMENTED;
|
||||
|
|
@ -874,7 +837,9 @@ static void
|
|||
client_node_update(void *data,
|
||||
uint32_t change_mask,
|
||||
uint32_t max_input_ports,
|
||||
uint32_t max_output_ports, const struct spa_props *props)
|
||||
uint32_t max_output_ports,
|
||||
uint32_t n_params,
|
||||
const struct spa_pod_object **params)
|
||||
{
|
||||
struct impl *impl = data;
|
||||
struct proxy *this = &impl->proxy;
|
||||
|
|
@ -883,7 +848,18 @@ client_node_update(void *data,
|
|||
this->max_inputs = max_input_ports;
|
||||
if (change_mask & PW_CLIENT_NODE_UPDATE_MAX_OUTPUTS)
|
||||
this->max_outputs = max_output_ports;
|
||||
if (change_mask & PW_CLIENT_NODE_UPDATE_PARAMS) {
|
||||
int i;
|
||||
spa_log_info(this->log, "proxy %p: update %d params", this, n_params);
|
||||
|
||||
for (i = 0; i < this->n_params; i++)
|
||||
free(this->params[i]);
|
||||
this->n_params = n_params;
|
||||
this->params = realloc(this->params, this->n_params * sizeof(struct spa_pod_object *));
|
||||
|
||||
for (i = 0; i < this->n_params; i++)
|
||||
this->params[i] = spa_pod_object_copy(params[i]);
|
||||
}
|
||||
spa_log_info(this->log, "proxy %p: got node update max_in %u, max_out %u", this,
|
||||
this->max_inputs, this->max_outputs);
|
||||
}
|
||||
|
|
@ -893,11 +869,9 @@ client_node_port_update(void *data,
|
|||
enum spa_direction direction,
|
||||
uint32_t port_id,
|
||||
uint32_t change_mask,
|
||||
uint32_t n_possible_formats,
|
||||
const struct spa_format **possible_formats,
|
||||
const struct spa_format *format,
|
||||
uint32_t n_params,
|
||||
const struct spa_param **params, const struct spa_port_info *info)
|
||||
const struct spa_pod_object **params,
|
||||
const struct spa_port_info *info)
|
||||
{
|
||||
struct impl *impl = data;
|
||||
struct proxy *this = &impl->proxy;
|
||||
|
|
@ -916,8 +890,7 @@ client_node_port_update(void *data,
|
|||
direction,
|
||||
port_id,
|
||||
change_mask,
|
||||
n_possible_formats,
|
||||
possible_formats, format, n_params, params, info);
|
||||
n_params, params, info);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -979,17 +952,14 @@ static void proxy_on_data_fd_events(struct spa_source *source)
|
|||
static const struct spa_node proxy_node = {
|
||||
SPA_VERSION_NODE,
|
||||
NULL,
|
||||
spa_proxy_node_get_props,
|
||||
spa_proxy_node_set_props,
|
||||
spa_proxy_node_enum_params,
|
||||
spa_proxy_node_set_param,
|
||||
spa_proxy_node_send_command,
|
||||
spa_proxy_node_set_callbacks,
|
||||
spa_proxy_node_get_n_ports,
|
||||
spa_proxy_node_get_port_ids,
|
||||
spa_proxy_node_add_port,
|
||||
spa_proxy_node_remove_port,
|
||||
spa_proxy_node_port_enum_formats,
|
||||
spa_proxy_node_port_set_format,
|
||||
spa_proxy_node_port_get_format,
|
||||
spa_proxy_node_port_get_info,
|
||||
spa_proxy_node_port_enum_params,
|
||||
spa_proxy_node_port_set_param,
|
||||
|
|
|
|||
|
|
@ -51,18 +51,27 @@ static void
|
|||
client_node_marshal_update(void *object,
|
||||
uint32_t change_mask,
|
||||
uint32_t max_input_ports,
|
||||
uint32_t max_output_ports, const struct spa_props *props)
|
||||
uint32_t max_output_ports,
|
||||
uint32_t n_params,
|
||||
const struct spa_pod_object **params)
|
||||
{
|
||||
struct pw_proxy *proxy = object;
|
||||
struct spa_pod_builder *b;
|
||||
int i;
|
||||
|
||||
b = pw_protocol_native_begin_proxy(proxy, PW_CLIENT_NODE_PROXY_METHOD_UPDATE);
|
||||
|
||||
spa_pod_builder_struct(b,
|
||||
"i", change_mask,
|
||||
"i", max_input_ports,
|
||||
"i", max_output_ports,
|
||||
"P", props);
|
||||
spa_pod_builder_add(b,
|
||||
"[",
|
||||
"i", change_mask,
|
||||
"i", max_input_ports,
|
||||
"i", max_output_ports,
|
||||
"i", n_params, NULL);
|
||||
|
||||
for (i = 0; i < n_params; i++)
|
||||
spa_pod_builder_add(b, "P", params[i], NULL);
|
||||
|
||||
spa_pod_builder_add(b, "]", NULL);
|
||||
|
||||
pw_protocol_native_end_proxy(proxy, b);
|
||||
}
|
||||
|
|
@ -72,11 +81,9 @@ client_node_marshal_port_update(void *object,
|
|||
enum spa_direction direction,
|
||||
uint32_t port_id,
|
||||
uint32_t change_mask,
|
||||
uint32_t n_possible_formats,
|
||||
const struct spa_format **possible_formats,
|
||||
const struct spa_format *format,
|
||||
uint32_t n_params,
|
||||
const struct spa_param **params, const struct spa_port_info *info)
|
||||
const struct spa_pod_object **params,
|
||||
const struct spa_port_info *info)
|
||||
{
|
||||
struct pw_proxy *proxy = object;
|
||||
struct spa_pod_builder *b;
|
||||
|
|
@ -89,13 +96,6 @@ client_node_marshal_port_update(void *object,
|
|||
"i", direction,
|
||||
"i", port_id,
|
||||
"i", change_mask,
|
||||
"i", n_possible_formats, NULL);
|
||||
|
||||
for (i = 0; i < n_possible_formats; i++)
|
||||
spa_pod_builder_add(b, "P", possible_formats[i], NULL);
|
||||
|
||||
spa_pod_builder_add(b,
|
||||
"P", format,
|
||||
"i", n_params, NULL);
|
||||
|
||||
for (i = 0; i < n_params; i++)
|
||||
|
|
@ -149,21 +149,57 @@ static void client_node_marshal_destroy(void *object)
|
|||
pw_protocol_native_end_proxy(proxy, b);
|
||||
}
|
||||
|
||||
static bool client_node_demarshal_set_props(void *object, void *data, size_t size)
|
||||
static bool client_node_demarshal_transport(void *object, void *data, size_t size)
|
||||
{
|
||||
struct pw_proxy *proxy = object;
|
||||
struct spa_pod_parser prs;
|
||||
uint32_t seq;
|
||||
const struct spa_props *props = NULL;
|
||||
uint32_t node_id, ridx, widx, memfd_idx;
|
||||
int readfd, writefd;
|
||||
struct pw_client_node_transport_info info;
|
||||
struct pw_client_node_transport *transport;
|
||||
|
||||
spa_pod_parser_init(&prs, data, size, 0);
|
||||
if (spa_pod_parser_get(&prs,
|
||||
"["
|
||||
"i", &node_id,
|
||||
"i", &ridx,
|
||||
"i", &widx,
|
||||
"i", &memfd_idx,
|
||||
"i", &info.offset,
|
||||
"i", &info.size, NULL) < 0)
|
||||
return false;
|
||||
|
||||
readfd = pw_protocol_native_get_proxy_fd(proxy, ridx);
|
||||
writefd = pw_protocol_native_get_proxy_fd(proxy, widx);
|
||||
info.memfd = pw_protocol_native_get_proxy_fd(proxy, memfd_idx);
|
||||
|
||||
if (readfd == -1 || writefd == -1 || info.memfd == -1)
|
||||
return false;
|
||||
|
||||
transport = pw_client_node_transport_new_from_info(&info);
|
||||
|
||||
pw_proxy_notify(proxy, struct pw_client_node_proxy_events, transport, node_id,
|
||||
readfd, writefd, transport);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool client_node_demarshal_set_param(void *object, void *data, size_t size)
|
||||
{
|
||||
struct pw_proxy *proxy = object;
|
||||
struct spa_pod_parser prs;
|
||||
uint32_t seq, id, flags;
|
||||
const struct spa_pod_object *param = NULL;
|
||||
|
||||
spa_pod_parser_init(&prs, data, size, 0);
|
||||
if (spa_pod_parser_get(&prs,
|
||||
"["
|
||||
"i", &seq,
|
||||
"O", &props, NULL) < 0)
|
||||
"I", &id,
|
||||
"i", &flags,
|
||||
"O", ¶m, NULL) < 0)
|
||||
return false;
|
||||
|
||||
pw_proxy_notify(proxy, struct pw_client_node_proxy_events, set_props, seq, props);
|
||||
pw_proxy_notify(proxy, struct pw_client_node_proxy_events, set_param, seq, id, flags, param);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -181,6 +217,24 @@ static bool client_node_demarshal_event_event(void *object, void *data, size_t s
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool client_node_demarshal_command(void *object, void *data, size_t size)
|
||||
{
|
||||
struct pw_proxy *proxy = object;
|
||||
struct spa_pod_parser prs;
|
||||
const struct spa_command *command;
|
||||
uint32_t seq;
|
||||
|
||||
spa_pod_parser_init(&prs, data, size, 0);
|
||||
if (spa_pod_parser_get(&prs,
|
||||
"["
|
||||
"i", &seq,
|
||||
"O", &command, NULL) < 0)
|
||||
return false;
|
||||
|
||||
pw_proxy_notify(proxy, struct pw_client_node_proxy_events, command, seq, command);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool client_node_demarshal_add_port(void *object, void *data, size_t size)
|
||||
{
|
||||
struct pw_proxy *proxy = object;
|
||||
|
|
@ -217,12 +271,12 @@ static bool client_node_demarshal_remove_port(void *object, void *data, size_t s
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool client_node_demarshal_set_format(void *object, void *data, size_t size)
|
||||
static bool client_node_demarshal_port_set_param(void *object, void *data, size_t size)
|
||||
{
|
||||
struct pw_proxy *proxy = object;
|
||||
struct spa_pod_parser prs;
|
||||
uint32_t seq, direction, port_id, flags;
|
||||
const struct spa_format *format = NULL;
|
||||
uint32_t seq, direction, port_id, id, flags;
|
||||
const struct spa_pod_object *param = NULL;
|
||||
|
||||
spa_pod_parser_init(&prs, data, size, 0);
|
||||
if (spa_pod_parser_get(&prs,
|
||||
|
|
@ -230,36 +284,17 @@ static bool client_node_demarshal_set_format(void *object, void *data, size_t si
|
|||
"i", &seq,
|
||||
"i", &direction,
|
||||
"i", &port_id,
|
||||
"I", &id,
|
||||
"i", &flags,
|
||||
"O", &format, NULL) < 0)
|
||||
return false;
|
||||
|
||||
pw_proxy_notify(proxy, struct pw_client_node_proxy_events, set_format, seq, direction, port_id,
|
||||
flags, format);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool client_node_demarshal_set_param(void *object, void *data, size_t size)
|
||||
{
|
||||
struct pw_proxy *proxy = object;
|
||||
struct spa_pod_parser prs;
|
||||
uint32_t seq, direction, port_id;
|
||||
const struct spa_param *param = NULL;
|
||||
|
||||
spa_pod_parser_init(&prs, data, size, 0);
|
||||
if (spa_pod_parser_get(&prs,
|
||||
"["
|
||||
"i", &seq,
|
||||
"i", &direction,
|
||||
"i", &port_id,
|
||||
"O", ¶m, NULL) < 0)
|
||||
return false;
|
||||
|
||||
pw_proxy_notify(proxy, struct pw_client_node_proxy_events, set_param, seq, direction, port_id, param);
|
||||
pw_proxy_notify(proxy, struct pw_client_node_proxy_events, port_set_param,
|
||||
seq, direction, port_id, id, flags, param);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool client_node_demarshal_add_mem(void *object, void *data, size_t size)
|
||||
static bool client_node_demarshal_port_add_mem(void *object, void *data, size_t size)
|
||||
{
|
||||
struct pw_proxy *proxy = object;
|
||||
struct spa_pod_parser prs;
|
||||
|
|
@ -281,7 +316,7 @@ static bool client_node_demarshal_add_mem(void *object, void *data, size_t size)
|
|||
|
||||
memfd = pw_protocol_native_get_proxy_fd(proxy, memfd_idx);
|
||||
|
||||
pw_proxy_notify(proxy, struct pw_client_node_proxy_events, add_mem, direction,
|
||||
pw_proxy_notify(proxy, struct pw_client_node_proxy_events, port_add_mem, direction,
|
||||
port_id,
|
||||
mem_id,
|
||||
type,
|
||||
|
|
@ -289,7 +324,7 @@ static bool client_node_demarshal_add_mem(void *object, void *data, size_t size)
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool client_node_demarshal_use_buffers(void *object, void *data, size_t size)
|
||||
static bool client_node_demarshal_port_use_buffers(void *object, void *data, size_t size)
|
||||
{
|
||||
struct pw_proxy *proxy = object;
|
||||
struct spa_pod_parser prs;
|
||||
|
|
@ -345,31 +380,13 @@ static bool client_node_demarshal_use_buffers(void *object, void *data, size_t s
|
|||
d->data = SPA_UINT32_TO_PTR(data_id);
|
||||
}
|
||||
}
|
||||
pw_proxy_notify(proxy, struct pw_client_node_proxy_events, use_buffers, seq,
|
||||
pw_proxy_notify(proxy, struct pw_client_node_proxy_events, port_use_buffers, seq,
|
||||
direction,
|
||||
port_id,
|
||||
n_buffers, buffers);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool client_node_demarshal_node_command(void *object, void *data, size_t size)
|
||||
{
|
||||
struct pw_proxy *proxy = object;
|
||||
struct spa_pod_parser prs;
|
||||
const struct spa_command *command;
|
||||
uint32_t seq;
|
||||
|
||||
spa_pod_parser_init(&prs, data, size, 0);
|
||||
if (spa_pod_parser_get(&prs,
|
||||
"["
|
||||
"i", &seq,
|
||||
"O", &command, NULL) < 0)
|
||||
return false;
|
||||
|
||||
pw_proxy_notify(proxy, struct pw_client_node_proxy_events, node_command, seq, command);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool client_node_demarshal_port_command(void *object, void *data, size_t size)
|
||||
{
|
||||
struct pw_proxy *proxy = object;
|
||||
|
|
@ -391,51 +408,42 @@ static bool client_node_demarshal_port_command(void *object, void *data, size_t
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool client_node_demarshal_transport(void *object, void *data, size_t size)
|
||||
static void client_node_marshal_transport(void *object, uint32_t node_id, int readfd, int writefd,
|
||||
struct pw_client_node_transport *transport)
|
||||
{
|
||||
struct pw_proxy *proxy = object;
|
||||
struct spa_pod_parser prs;
|
||||
uint32_t node_id, ridx, widx, memfd_idx;
|
||||
int readfd, writefd;
|
||||
struct pw_resource *resource = object;
|
||||
struct spa_pod_builder *b;
|
||||
struct pw_client_node_transport_info info;
|
||||
struct pw_client_node_transport *transport;
|
||||
|
||||
spa_pod_parser_init(&prs, data, size, 0);
|
||||
if (spa_pod_parser_get(&prs,
|
||||
"["
|
||||
"i", &node_id,
|
||||
"i", &ridx,
|
||||
"i", &widx,
|
||||
"i", &memfd_idx,
|
||||
"i", &info.offset,
|
||||
"i", &info.size, NULL) < 0)
|
||||
return false;
|
||||
pw_client_node_transport_get_info(transport, &info);
|
||||
|
||||
readfd = pw_protocol_native_get_proxy_fd(proxy, ridx);
|
||||
writefd = pw_protocol_native_get_proxy_fd(proxy, widx);
|
||||
info.memfd = pw_protocol_native_get_proxy_fd(proxy, memfd_idx);
|
||||
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_TRANSPORT);
|
||||
|
||||
if (readfd == -1 || writefd == -1 || info.memfd == -1)
|
||||
return false;
|
||||
spa_pod_builder_struct(b,
|
||||
"i", node_id,
|
||||
"i", pw_protocol_native_add_resource_fd(resource, readfd),
|
||||
"i", pw_protocol_native_add_resource_fd(resource, writefd),
|
||||
"i", pw_protocol_native_add_resource_fd(resource, info.memfd),
|
||||
"i", info.offset,
|
||||
"i", info.size);
|
||||
|
||||
transport = pw_client_node_transport_new_from_info(&info);
|
||||
|
||||
pw_proxy_notify(proxy, struct pw_client_node_proxy_events, transport, node_id,
|
||||
readfd, writefd, transport);
|
||||
return true;
|
||||
pw_protocol_native_end_resource(resource, b);
|
||||
}
|
||||
|
||||
static void
|
||||
client_node_marshal_set_props(void *object, uint32_t seq, const struct spa_props *props)
|
||||
client_node_marshal_set_param(void *object, uint32_t seq, uint32_t id, uint32_t flags,
|
||||
const struct spa_pod_object *param)
|
||||
{
|
||||
struct pw_resource *resource = object;
|
||||
struct spa_pod_builder *b;
|
||||
|
||||
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_SET_PROPS);
|
||||
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_SET_PARAM);
|
||||
|
||||
spa_pod_builder_struct(b,
|
||||
"i", seq,
|
||||
"P", props);
|
||||
"I", id,
|
||||
"i", flags,
|
||||
"P", param);
|
||||
|
||||
pw_protocol_native_end_resource(resource, b);
|
||||
}
|
||||
|
|
@ -452,6 +460,19 @@ static void client_node_marshal_event_event(void *object, const struct spa_event
|
|||
pw_protocol_native_end_resource(resource, b);
|
||||
}
|
||||
|
||||
static void
|
||||
client_node_marshal_command(void *object, uint32_t seq, const struct spa_command *command)
|
||||
{
|
||||
struct pw_resource *resource = object;
|
||||
struct spa_pod_builder *b;
|
||||
|
||||
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_COMMAND);
|
||||
|
||||
spa_pod_builder_struct(b, "i", seq, "P", command);
|
||||
|
||||
pw_protocol_native_end_resource(resource, b);
|
||||
}
|
||||
|
||||
static void
|
||||
client_node_marshal_add_port(void *object,
|
||||
uint32_t seq, enum spa_direction direction, uint32_t port_id)
|
||||
|
|
@ -487,61 +508,42 @@ client_node_marshal_remove_port(void *object,
|
|||
}
|
||||
|
||||
static void
|
||||
client_node_marshal_set_format(void *object,
|
||||
uint32_t seq,
|
||||
enum spa_direction direction,
|
||||
uint32_t port_id,
|
||||
uint32_t flags,
|
||||
const struct spa_format *format)
|
||||
client_node_marshal_port_set_param(void *object,
|
||||
uint32_t seq,
|
||||
enum spa_direction direction,
|
||||
uint32_t port_id,
|
||||
uint32_t id,
|
||||
uint32_t flags,
|
||||
const struct spa_pod_object *param)
|
||||
{
|
||||
struct pw_resource *resource = object;
|
||||
struct spa_pod_builder *b;
|
||||
|
||||
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_SET_FORMAT);
|
||||
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_PORT_SET_PARAM);
|
||||
|
||||
spa_pod_builder_struct(b,
|
||||
"i", seq,
|
||||
"i", direction,
|
||||
"i", port_id,
|
||||
"I", id,
|
||||
"i", flags,
|
||||
"P", format);
|
||||
|
||||
pw_protocol_native_end_resource(resource, b);
|
||||
}
|
||||
|
||||
static void
|
||||
client_node_marshal_set_param(void *object,
|
||||
uint32_t seq,
|
||||
enum spa_direction direction,
|
||||
uint32_t port_id,
|
||||
const struct spa_param *param)
|
||||
{
|
||||
struct pw_resource *resource = object;
|
||||
struct spa_pod_builder *b;
|
||||
|
||||
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_SET_PARAM);
|
||||
|
||||
spa_pod_builder_struct(b,
|
||||
"i", seq,
|
||||
"i", direction,
|
||||
"i", port_id,
|
||||
"P", param);
|
||||
|
||||
pw_protocol_native_end_resource(resource, b);
|
||||
}
|
||||
|
||||
static void
|
||||
client_node_marshal_add_mem(void *object,
|
||||
enum spa_direction direction,
|
||||
uint32_t port_id,
|
||||
uint32_t mem_id,
|
||||
uint32_t type,
|
||||
int memfd, uint32_t flags, uint32_t offset, uint32_t size)
|
||||
client_node_marshal_port_add_mem(void *object,
|
||||
enum spa_direction direction,
|
||||
uint32_t port_id,
|
||||
uint32_t mem_id,
|
||||
uint32_t type,
|
||||
int memfd, uint32_t flags, uint32_t offset, uint32_t size)
|
||||
{
|
||||
struct pw_resource *resource = object;
|
||||
struct spa_pod_builder *b;
|
||||
|
||||
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_ADD_MEM);
|
||||
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_PORT_ADD_MEM);
|
||||
|
||||
spa_pod_builder_struct(b,
|
||||
"i", direction,
|
||||
|
|
@ -557,17 +559,17 @@ client_node_marshal_add_mem(void *object,
|
|||
}
|
||||
|
||||
static void
|
||||
client_node_marshal_use_buffers(void *object,
|
||||
uint32_t seq,
|
||||
enum spa_direction direction,
|
||||
uint32_t port_id,
|
||||
uint32_t n_buffers, struct pw_client_node_buffer *buffers)
|
||||
client_node_marshal_port_use_buffers(void *object,
|
||||
uint32_t seq,
|
||||
enum spa_direction direction,
|
||||
uint32_t port_id,
|
||||
uint32_t n_buffers, struct pw_client_node_buffer *buffers)
|
||||
{
|
||||
struct pw_resource *resource = object;
|
||||
struct spa_pod_builder *b;
|
||||
uint32_t i, j;
|
||||
|
||||
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_USE_BUFFERS);
|
||||
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_PORT_USE_BUFFERS);
|
||||
|
||||
spa_pod_builder_add(b,
|
||||
"[",
|
||||
|
|
@ -608,19 +610,6 @@ client_node_marshal_use_buffers(void *object,
|
|||
pw_protocol_native_end_resource(resource, b);
|
||||
}
|
||||
|
||||
static void
|
||||
client_node_marshal_node_command(void *object, uint32_t seq, const struct spa_command *command)
|
||||
{
|
||||
struct pw_resource *resource = object;
|
||||
struct spa_pod_builder *b;
|
||||
|
||||
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_NODE_COMMAND);
|
||||
|
||||
spa_pod_builder_struct(b, "i", seq, "P", command);
|
||||
|
||||
pw_protocol_native_end_resource(resource, b);
|
||||
}
|
||||
|
||||
static void
|
||||
client_node_marshal_port_command(void *object,
|
||||
uint32_t direction,
|
||||
|
|
@ -640,28 +629,6 @@ client_node_marshal_port_command(void *object,
|
|||
pw_protocol_native_end_resource(resource, b);
|
||||
}
|
||||
|
||||
static void client_node_marshal_transport(void *object, uint32_t node_id, int readfd, int writefd,
|
||||
struct pw_client_node_transport *transport)
|
||||
{
|
||||
struct pw_resource *resource = object;
|
||||
struct spa_pod_builder *b;
|
||||
struct pw_client_node_transport_info info;
|
||||
|
||||
pw_client_node_transport_get_info(transport, &info);
|
||||
|
||||
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_TRANSPORT);
|
||||
|
||||
spa_pod_builder_struct(b,
|
||||
"i", node_id,
|
||||
"i", pw_protocol_native_add_resource_fd(resource, readfd),
|
||||
"i", pw_protocol_native_add_resource_fd(resource, writefd),
|
||||
"i", pw_protocol_native_add_resource_fd(resource, info.memfd),
|
||||
"i", info.offset,
|
||||
"i", info.size);
|
||||
|
||||
pw_protocol_native_end_resource(resource, b);
|
||||
}
|
||||
|
||||
|
||||
static bool client_node_demarshal_done(void *object, void *data, size_t size)
|
||||
{
|
||||
|
|
@ -684,8 +651,9 @@ static bool client_node_demarshal_update(void *object, void *data, size_t size)
|
|||
{
|
||||
struct pw_resource *resource = object;
|
||||
struct spa_pod_parser prs;
|
||||
uint32_t change_mask, max_input_ports, max_output_ports;
|
||||
const struct spa_props *props;
|
||||
uint32_t change_mask, max_input_ports, max_output_ports, n_params;
|
||||
const struct spa_pod_object **params;
|
||||
int i;
|
||||
|
||||
spa_pod_parser_init(&prs, data, size, 0);
|
||||
if (spa_pod_parser_get(&prs,
|
||||
|
|
@ -693,13 +661,19 @@ static bool client_node_demarshal_update(void *object, void *data, size_t size)
|
|||
"i", &change_mask,
|
||||
"i", &max_input_ports,
|
||||
"i", &max_output_ports,
|
||||
"O", &props, NULL) < 0)
|
||||
"i", &n_params, NULL) < 0)
|
||||
return false;
|
||||
|
||||
params = alloca(n_params * sizeof(struct spa_pod_object *));
|
||||
for (i = 0; i < n_params; i++)
|
||||
if (spa_pod_parser_get(&prs, "O", ¶ms[i], NULL) < 0)
|
||||
return false;
|
||||
|
||||
pw_resource_do(resource, struct pw_client_node_proxy_methods, update, change_mask,
|
||||
max_input_ports,
|
||||
max_output_ports,
|
||||
props);
|
||||
n_params,
|
||||
params);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -707,9 +681,8 @@ static bool client_node_demarshal_port_update(void *object, void *data, size_t s
|
|||
{
|
||||
struct pw_resource *resource = object;
|
||||
struct spa_pod_parser prs;
|
||||
uint32_t i, direction, port_id, change_mask, n_possible_formats, n_params;
|
||||
const struct spa_param **params = NULL;
|
||||
const struct spa_format **possible_formats = NULL, *format = NULL;
|
||||
uint32_t i, direction, port_id, change_mask, n_params;
|
||||
const struct spa_pod_object **params = NULL;
|
||||
struct spa_port_info info, *infop = NULL;
|
||||
struct spa_pod *ipod;
|
||||
|
||||
|
|
@ -719,18 +692,10 @@ static bool client_node_demarshal_port_update(void *object, void *data, size_t s
|
|||
"i", &direction,
|
||||
"i", &port_id,
|
||||
"i", &change_mask,
|
||||
"i", &n_possible_formats, NULL) < 0)
|
||||
"i", &n_params, NULL) < 0)
|
||||
return false;
|
||||
|
||||
possible_formats = alloca(n_possible_formats * sizeof(struct spa_format *));
|
||||
for (i = 0; i < n_possible_formats; i++)
|
||||
if (spa_pod_parser_get(&prs, "O", &possible_formats[i], NULL) < 0)
|
||||
return false;
|
||||
|
||||
if (spa_pod_parser_get(&prs, "O", &format, "i", &n_params, NULL) < 0)
|
||||
return false;
|
||||
|
||||
params = alloca(n_params * sizeof(struct spa_param *));
|
||||
params = alloca(n_params * sizeof(struct spa_pod_object *));
|
||||
for (i = 0; i < n_params; i++)
|
||||
if (spa_pod_parser_get(&prs, "O", ¶ms[i], NULL) < 0)
|
||||
return false;
|
||||
|
|
@ -753,9 +718,6 @@ static bool client_node_demarshal_port_update(void *object, void *data, size_t s
|
|||
pw_resource_do(resource, struct pw_client_node_proxy_methods, port_update, direction,
|
||||
port_id,
|
||||
change_mask,
|
||||
n_possible_formats,
|
||||
possible_formats,
|
||||
format,
|
||||
n_params,
|
||||
params, infop);
|
||||
return true;
|
||||
|
|
@ -828,29 +790,27 @@ static const struct pw_protocol_native_demarshal pw_protocol_native_client_node_
|
|||
static const struct pw_client_node_proxy_events pw_protocol_native_client_node_event_marshal = {
|
||||
PW_VERSION_CLIENT_NODE_PROXY_EVENTS,
|
||||
&client_node_marshal_transport,
|
||||
&client_node_marshal_set_props,
|
||||
&client_node_marshal_set_param,
|
||||
&client_node_marshal_event_event,
|
||||
&client_node_marshal_command,
|
||||
&client_node_marshal_add_port,
|
||||
&client_node_marshal_remove_port,
|
||||
&client_node_marshal_set_format,
|
||||
&client_node_marshal_set_param,
|
||||
&client_node_marshal_add_mem,
|
||||
&client_node_marshal_use_buffers,
|
||||
&client_node_marshal_node_command,
|
||||
&client_node_marshal_port_set_param,
|
||||
&client_node_marshal_port_add_mem,
|
||||
&client_node_marshal_port_use_buffers,
|
||||
&client_node_marshal_port_command,
|
||||
};
|
||||
|
||||
static const struct pw_protocol_native_demarshal pw_protocol_native_client_node_event_demarshal[] = {
|
||||
{ &client_node_demarshal_transport, 0 },
|
||||
{ &client_node_demarshal_set_props, PW_PROTOCOL_NATIVE_REMAP },
|
||||
{ &client_node_demarshal_set_param, PW_PROTOCOL_NATIVE_REMAP },
|
||||
{ &client_node_demarshal_event_event, PW_PROTOCOL_NATIVE_REMAP },
|
||||
{ &client_node_demarshal_command, PW_PROTOCOL_NATIVE_REMAP },
|
||||
{ &client_node_demarshal_add_port, 0 },
|
||||
{ &client_node_demarshal_remove_port, 0 },
|
||||
{ &client_node_demarshal_set_format, PW_PROTOCOL_NATIVE_REMAP },
|
||||
{ &client_node_demarshal_set_param, PW_PROTOCOL_NATIVE_REMAP },
|
||||
{ &client_node_demarshal_add_mem, PW_PROTOCOL_NATIVE_REMAP },
|
||||
{ &client_node_demarshal_use_buffers, PW_PROTOCOL_NATIVE_REMAP },
|
||||
{ &client_node_demarshal_node_command, PW_PROTOCOL_NATIVE_REMAP },
|
||||
{ &client_node_demarshal_port_set_param, PW_PROTOCOL_NATIVE_REMAP },
|
||||
{ &client_node_demarshal_port_add_mem, PW_PROTOCOL_NATIVE_REMAP },
|
||||
{ &client_node_demarshal_port_use_buffers, PW_PROTOCOL_NATIVE_REMAP },
|
||||
{ &client_node_demarshal_port_command, PW_PROTOCOL_NATIVE_REMAP },
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -434,7 +434,7 @@ do_create_link(void *data,
|
|||
uint32_t output_port_id,
|
||||
uint32_t input_node_id,
|
||||
uint32_t input_port_id,
|
||||
const struct spa_format *filter,
|
||||
const struct spa_pod_object *filter,
|
||||
const struct spa_dict *props,
|
||||
uint32_t new_id)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1291,7 +1291,9 @@ static bool on_global(void *data, struct pw_global *global)
|
|||
const char *str;
|
||||
char *error;
|
||||
struct pw_port *in_port, *out_port;
|
||||
struct spa_props *props;
|
||||
uint32_t index = 0;
|
||||
uint8_t buf[2048];
|
||||
struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buf, sizeof(buf));
|
||||
|
||||
if (pw_global_get_type(global) != impl->t->node)
|
||||
return true;
|
||||
|
|
@ -1323,10 +1325,11 @@ static bool on_global(void *data, struct pw_global *global)
|
|||
return true;
|
||||
}
|
||||
|
||||
if (spa_node_get_props(node->node, &props) == SPA_RESULT_OK) {
|
||||
if (spa_node_enum_params(node->node, SPA_ID_INVALID, &index, NULL, &b) == SPA_RESULT_OK) {
|
||||
int min_latency = -1;
|
||||
struct spa_pod_object *props = SPA_POD_BUILDER_DEREF(&b, 0, struct spa_pod_object);
|
||||
|
||||
spa_props_parse(props,
|
||||
spa_pod_object_parse(props,
|
||||
":", impl->prop_min_latency, "?i", &min_latency, NULL);
|
||||
|
||||
if (min_latency != -1)
|
||||
|
|
|
|||
|
|
@ -30,7 +30,6 @@
|
|||
|
||||
#include <spa/node.h>
|
||||
#include <spa/hook.h>
|
||||
#include <spa/format-builder.h>
|
||||
#include <spa/lib/format.h>
|
||||
#include <spa/audio/format-utils.h>
|
||||
|
||||
|
|
@ -47,6 +46,7 @@
|
|||
|
||||
struct type {
|
||||
uint32_t format;
|
||||
struct spa_type_param param;
|
||||
struct spa_type_data data;
|
||||
struct spa_type_media_type media_type;
|
||||
struct spa_type_media_subtype media_subtype;
|
||||
|
|
@ -58,6 +58,7 @@ struct type {
|
|||
static inline void init_type(struct type *type, struct spa_type_map *map)
|
||||
{
|
||||
type->format = spa_type_map_get_id(map, SPA_TYPE__Format);
|
||||
spa_type_param_map(map, &type->param);
|
||||
spa_type_data_map(map, &type->data);
|
||||
spa_type_media_type_map(map, &type->media_type);
|
||||
spa_type_media_subtype_map(map, &type->media_subtype);
|
||||
|
|
@ -121,12 +122,17 @@ struct port_data {
|
|||
|
||||
/** \endcond */
|
||||
|
||||
static int node_get_props(struct spa_node *node, struct spa_props **props)
|
||||
static int node_enum_params(struct spa_node *node,
|
||||
uint32_t id, uint32_t *index,
|
||||
const struct spa_pod_object *filter,
|
||||
struct spa_pod_builder *builder)
|
||||
{
|
||||
return SPA_RESULT_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
static int node_set_props(struct spa_node *node, const struct spa_props *props)
|
||||
static int node_set_param(struct spa_node *node,
|
||||
uint32_t id, uint32_t flags,
|
||||
const struct spa_pod_object *param)
|
||||
{
|
||||
return SPA_RESULT_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
|
@ -368,16 +374,17 @@ static int port_set_io(struct spa_node *node, enum spa_direction direction, uint
|
|||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
static int port_enum_formats(struct spa_node *node, enum spa_direction direction, uint32_t port_id,
|
||||
struct spa_format **format,
|
||||
const struct spa_format *filter,
|
||||
uint32_t index)
|
||||
static int port_enum_formats(struct spa_node *node,
|
||||
enum spa_direction direction, uint32_t port_id,
|
||||
uint32_t *index,
|
||||
const struct spa_pod_object *filter,
|
||||
struct spa_pod_builder *builder)
|
||||
{
|
||||
struct node_data *nd = SPA_CONTAINER_OF(node, struct node_data, node_impl);
|
||||
struct port_data *pd = nd->port_data[direction][port_id];
|
||||
struct type *t = &pd->node->type;
|
||||
struct spa_pod_builder b = { NULL, };
|
||||
struct spa_format *fmt;
|
||||
struct spa_pod_object *fmt;
|
||||
uint8_t buffer[4096];
|
||||
int res;
|
||||
struct jack_engine_control *ctrl = pd->node->node.server->engine_control;
|
||||
|
|
@ -389,55 +396,39 @@ static int port_enum_formats(struct spa_node *node, enum spa_direction direction
|
|||
|
||||
if (pd->port.jack_port) {
|
||||
if (pd->port.jack_port->type_id == 0) {
|
||||
fmt = spa_pod_builder_format(&b,
|
||||
t->format,
|
||||
t->media_type.audio, t->media_subtype.raw,
|
||||
fmt = spa_pod_builder_object(&b,
|
||||
t->param.idEnumFormat, t->format,
|
||||
"I", t->media_type.audio,
|
||||
"I", t->media_subtype.raw,
|
||||
":", t->format_audio.format, "I", t->audio_format.F32,
|
||||
":", t->format_audio.rate, "i", ctrl->sample_rate,
|
||||
":", t->format_audio.channels, "i", 1);
|
||||
}
|
||||
else if (pd->port.jack_port->type_id == 1) {
|
||||
fmt = spa_pod_builder_format(&b,
|
||||
t->format,
|
||||
t->media_type.audio, t->media_subtype_audio.midi);
|
||||
fmt = spa_pod_builder_object(&b,
|
||||
t->param.idEnumFormat, t->format,
|
||||
"I", t->media_type.audio,
|
||||
"I", t->media_subtype_audio.midi);
|
||||
}
|
||||
else
|
||||
return SPA_RESULT_ENUM_END;
|
||||
}
|
||||
else {
|
||||
fmt = spa_pod_builder_format(&b,
|
||||
t->format,
|
||||
t->media_type.audio, t->media_subtype.raw,
|
||||
fmt = spa_pod_builder_object(&b,
|
||||
t->param.idEnumFormat, t->format,
|
||||
"I", t->media_type.audio,
|
||||
"I", t->media_subtype.raw,
|
||||
":", t->format_audio.format, "I", t->audio_format.S16,
|
||||
":", t->format_audio.rate, "i", ctrl->sample_rate,
|
||||
":", t->format_audio.channels, "i", 2);
|
||||
}
|
||||
|
||||
spa_pod_builder_init(&b, pd->buffer, sizeof(pd->buffer));
|
||||
if ((res = spa_format_filter(fmt, filter, &b)) < 0)
|
||||
if ((res = spa_pod_object_filter(fmt, filter, builder)) < 0)
|
||||
return res;
|
||||
|
||||
*format = SPA_POD_BUILDER_DEREF(&b, 0, struct spa_format);
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
static int port_set_format(struct spa_node *node, enum spa_direction direction, uint32_t port_id,
|
||||
uint32_t flags, const struct spa_format *format)
|
||||
{
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
static int port_get_format(struct spa_node *node, enum spa_direction direction, uint32_t port_id,
|
||||
const struct spa_format **format)
|
||||
{
|
||||
int res;
|
||||
struct spa_format *fmt;
|
||||
res = port_enum_formats(node, direction, port_id, &fmt, NULL, 0);
|
||||
*format = fmt;
|
||||
return res;
|
||||
}
|
||||
|
||||
static int port_get_info(struct spa_node *node, enum spa_direction direction, uint32_t port_id,
|
||||
const struct spa_port_info **info)
|
||||
{
|
||||
|
|
@ -455,14 +446,31 @@ static int port_get_info(struct spa_node *node, enum spa_direction direction, ui
|
|||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
static int port_enum_params(struct spa_node *node, enum spa_direction direction, uint32_t port_id,
|
||||
uint32_t index, struct spa_param **param)
|
||||
static int port_enum_params(struct spa_node *node,
|
||||
enum spa_direction direction, uint32_t port_id,
|
||||
uint32_t id, uint32_t *index,
|
||||
const struct spa_pod_object *filter,
|
||||
struct spa_pod_builder *builder)
|
||||
{
|
||||
struct node_data *nd = SPA_CONTAINER_OF(node, struct node_data, node_impl);
|
||||
struct type *t = &nd->type;
|
||||
|
||||
if (id == t->param.idEnumFormat) {
|
||||
return port_enum_formats(node, direction, port_id, index, filter, builder);
|
||||
}
|
||||
else if (id == t->param.idFormat) {
|
||||
return port_enum_formats(node, direction, port_id, index, filter, builder);
|
||||
}
|
||||
else
|
||||
return SPA_RESULT_UNKNOWN_PARAM;
|
||||
|
||||
return SPA_RESULT_ENUM_END;
|
||||
}
|
||||
|
||||
static int port_set_param(struct spa_node *node, enum spa_direction direction, uint32_t port_id,
|
||||
const struct spa_param *param)
|
||||
static int port_set_param(struct spa_node *node,
|
||||
enum spa_direction direction, uint32_t port_id,
|
||||
uint32_t id, uint32_t flags,
|
||||
const struct spa_pod_object *param)
|
||||
{
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
|
@ -501,7 +509,7 @@ static int port_use_buffers(struct spa_node *node, enum spa_direction direction,
|
|||
}
|
||||
|
||||
static int port_alloc_buffers(struct spa_node *node, enum spa_direction direction, uint32_t port_id,
|
||||
struct spa_param **params, uint32_t n_params,
|
||||
struct spa_pod_object **params, uint32_t n_params,
|
||||
struct spa_buffer **buffers, uint32_t *n_buffers)
|
||||
{
|
||||
struct node_data *nd = SPA_CONTAINER_OF(node, struct node_data, node_impl);
|
||||
|
|
@ -551,17 +559,14 @@ static int port_send_command(struct spa_node *node, enum spa_direction direction
|
|||
static const struct spa_node driver_impl = {
|
||||
SPA_VERSION_NODE,
|
||||
NULL,
|
||||
.get_props = node_get_props,
|
||||
.set_props = node_set_props,
|
||||
.enum_params = node_enum_params,
|
||||
.set_param = node_set_param,
|
||||
.send_command = node_send_command,
|
||||
.set_callbacks = node_set_callbacks,
|
||||
.get_n_ports = node_get_n_ports,
|
||||
.get_port_ids = node_get_port_ids,
|
||||
.add_port = node_add_port,
|
||||
.remove_port = node_remove_port,
|
||||
.port_enum_formats = port_enum_formats,
|
||||
.port_set_format = port_set_format,
|
||||
.port_get_format = port_get_format,
|
||||
.port_get_info = port_get_info,
|
||||
.port_enum_params = port_enum_params,
|
||||
.port_set_param = port_set_param,
|
||||
|
|
@ -577,17 +582,14 @@ static const struct spa_node driver_impl = {
|
|||
static const struct spa_node node_impl = {
|
||||
SPA_VERSION_NODE,
|
||||
NULL,
|
||||
.get_props = node_get_props,
|
||||
.set_props = node_set_props,
|
||||
.enum_params = node_enum_params,
|
||||
.set_param = node_set_param,
|
||||
.send_command = node_send_command,
|
||||
.set_callbacks = node_set_callbacks,
|
||||
.get_n_ports = node_get_n_ports,
|
||||
.get_port_ids = node_get_port_ids,
|
||||
.add_port = node_add_port,
|
||||
.remove_port = node_remove_port,
|
||||
.port_enum_formats = port_enum_formats,
|
||||
.port_set_format = port_set_format,
|
||||
.port_get_format = port_get_format,
|
||||
.port_get_info = port_get_info,
|
||||
.port_enum_params = port_enum_params,
|
||||
.port_set_param = port_set_param,
|
||||
|
|
|
|||
|
|
@ -99,6 +99,7 @@ struct client_data {
|
|||
static bool pod_remap_data(uint32_t type, void *body, uint32_t size, struct pw_map *types)
|
||||
{
|
||||
void *t;
|
||||
|
||||
switch (type) {
|
||||
case SPA_POD_TYPE_ID:
|
||||
if ((t = pw_map_lookup(types, *(int32_t *) body)) == NULL)
|
||||
|
|
@ -131,6 +132,11 @@ static bool pod_remap_data(uint32_t type, void *body, uint32_t size, struct pw_m
|
|||
struct spa_pod_object_body *b = body;
|
||||
struct spa_pod *p;
|
||||
|
||||
if ((t = pw_map_lookup(types, b->id)) != NULL)
|
||||
b->id = PW_MAP_PTR_TO_ID(t);
|
||||
else
|
||||
b->id = SPA_ID_INVALID;
|
||||
|
||||
if ((t = pw_map_lookup(types, b->type)) == NULL)
|
||||
return false;
|
||||
b->type = PW_MAP_PTR_TO_ID(t);
|
||||
|
|
@ -211,7 +217,7 @@ process_messages(struct client_data *data)
|
|||
if (!pod_remap_data(SPA_POD_TYPE_STRUCT, message, size, &client->types))
|
||||
goto invalid_message;
|
||||
|
||||
if (!demarshal[opcode].func (resource, message, size))
|
||||
if (!demarshal[opcode].func(resource, message, size))
|
||||
goto invalid_message;
|
||||
}
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -322,7 +322,7 @@ pw_protocol_native_connection_get_next(struct pw_protocol_native_connection *con
|
|||
|
||||
if (debug_messages) {
|
||||
printf("<<<<<<<<< in: %d %d %zd\n", *dest_id, *opcode, len);
|
||||
spa_debug_pod((struct spa_pod *)data);
|
||||
spa_debug_pod((struct spa_pod *)data, 0);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
@ -428,7 +428,7 @@ pw_protocol_native_connection_end(struct pw_protocol_native_connection *conn,
|
|||
|
||||
if (debug_messages) {
|
||||
printf(">>>>>>>>> out: %d %d %d\n", impl->dest_id, impl->opcode, size);
|
||||
spa_debug_pod((struct spa_pod *)p);
|
||||
spa_debug_pod((struct spa_pod *)p, 0);
|
||||
}
|
||||
spa_hook_list_call(&conn->listener_list, struct pw_protocol_native_connection_events, need_flush);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ core_marshal_create_link(void *object,
|
|||
uint32_t output_port_id,
|
||||
uint32_t input_node_id,
|
||||
uint32_t input_port_id,
|
||||
const struct spa_format *filter,
|
||||
const struct spa_pod_object *filter,
|
||||
const struct spa_dict *props,
|
||||
uint32_t new_id)
|
||||
{
|
||||
|
|
@ -463,7 +463,7 @@ static bool core_demarshal_create_link(void *object, void *data, size_t size)
|
|||
struct spa_pod_parser prs;
|
||||
uint32_t new_id, i;
|
||||
uint32_t output_node_id, output_port_id, input_node_id, input_port_id;
|
||||
struct spa_format *filter = NULL;
|
||||
struct spa_pod_object *filter = NULL;
|
||||
struct spa_dict props;
|
||||
|
||||
spa_pod_parser_init(&prs, data, size, 0);
|
||||
|
|
@ -703,18 +703,18 @@ static void node_marshal_info(void *object, struct pw_node_info *info)
|
|||
"s", info->name,
|
||||
"i", info->max_input_ports,
|
||||
"i", info->n_input_ports,
|
||||
"i", info->n_input_formats, NULL);
|
||||
"i", info->n_input_params, NULL);
|
||||
|
||||
for (i = 0; i < info->n_input_formats; i++)
|
||||
spa_pod_builder_add(b, "P", info->input_formats[i], NULL);
|
||||
for (i = 0; i < info->n_input_params; i++)
|
||||
spa_pod_builder_add(b, "P", info->input_params[i], NULL);
|
||||
|
||||
spa_pod_builder_add(b,
|
||||
"i", info->max_output_ports,
|
||||
"i", info->n_output_ports,
|
||||
"i", info->n_output_formats, 0);
|
||||
"i", info->n_output_params, 0);
|
||||
|
||||
for (i = 0; i < info->n_output_formats; i++)
|
||||
spa_pod_builder_add(b, "P", info->output_formats[i], NULL);
|
||||
for (i = 0; i < info->n_output_params; i++)
|
||||
spa_pod_builder_add(b, "P", info->output_params[i], NULL);
|
||||
|
||||
n_items = info->props ? info->props->n_items : 0;
|
||||
|
||||
|
|
@ -748,23 +748,23 @@ static bool node_demarshal_info(void *object, void *data, size_t size)
|
|||
"s", &info.name,
|
||||
"i", &info.max_input_ports,
|
||||
"i", &info.n_input_ports,
|
||||
"i", &info.n_input_formats, NULL) < 0)
|
||||
"i", &info.n_input_params, NULL) < 0)
|
||||
return false;
|
||||
|
||||
info.input_formats = alloca(info.n_input_formats * sizeof(struct spa_format *));
|
||||
for (i = 0; i < info.n_input_formats; i++)
|
||||
if (spa_pod_parser_get(&prs, "P", &info.input_formats[i], NULL) < 0)
|
||||
info.input_params = alloca(info.n_input_params * sizeof(struct spa_pod_object *));
|
||||
for (i = 0; i < info.n_input_params; i++)
|
||||
if (spa_pod_parser_get(&prs, "P", &info.input_params[i], NULL) < 0)
|
||||
return false;
|
||||
|
||||
if (spa_pod_parser_get(&prs,
|
||||
"i", &info.max_output_ports,
|
||||
"i", &info.n_output_ports,
|
||||
"i", &info.n_output_formats, NULL) < 0)
|
||||
"i", &info.n_output_params, NULL) < 0)
|
||||
return false;
|
||||
|
||||
info.output_formats = alloca(info.n_output_formats * sizeof(struct spa_format *));
|
||||
for (i = 0; i < info.n_output_formats; i++)
|
||||
if (spa_pod_parser_get(&prs, "P", &info.output_formats[i], NULL) < 0)
|
||||
info.output_params = alloca(info.n_output_params * sizeof(struct spa_pod_object *));
|
||||
for (i = 0; i < info.n_output_params; i++)
|
||||
if (spa_pod_parser_get(&prs, "P", &info.output_params[i], NULL) < 0)
|
||||
return false;
|
||||
|
||||
if (spa_pod_parser_get(&prs,
|
||||
|
|
|
|||
|
|
@ -154,15 +154,19 @@ static int
|
|||
setup_props(struct pw_core *core, struct spa_node *spa_node, struct pw_properties *pw_props)
|
||||
{
|
||||
int res;
|
||||
struct spa_props *props;
|
||||
struct spa_pod_object *props;
|
||||
void *state = NULL;
|
||||
const char *key;
|
||||
struct pw_type *t = pw_core_get_type(core);
|
||||
uint32_t index = 0;
|
||||
uint8_t buf[2048];
|
||||
struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buf, sizeof(buf));
|
||||
|
||||
if ((res = spa_node_get_props(spa_node, &props)) != SPA_RESULT_OK) {
|
||||
if ((res = spa_node_enum_params(spa_node, t->param.idProps, &index, NULL, &b)) != SPA_RESULT_OK) {
|
||||
pw_log_debug("spa_node_get_props failed: %d", res);
|
||||
return SPA_RESULT_ERROR;
|
||||
}
|
||||
props = SPA_POD_BUILDER_DEREF(&b, 0, struct spa_pod_object);
|
||||
|
||||
while ((key = pw_properties_iterate(pw_props, &state))) {
|
||||
struct spa_pod_prop *prop;
|
||||
|
|
@ -175,7 +179,7 @@ setup_props(struct pw_core *core, struct spa_node *spa_node, struct pw_propertie
|
|||
if (id == SPA_ID_INVALID)
|
||||
continue;
|
||||
|
||||
if ((prop = spa_pod_object_find_prop(&props->object, id))) {
|
||||
if ((prop = spa_pod_object_find_prop(props, id))) {
|
||||
const char *value = pw_properties_get(pw_props, key);
|
||||
|
||||
pw_log_info("configure prop %s", key);
|
||||
|
|
@ -213,7 +217,7 @@ setup_props(struct pw_core *core, struct spa_node *spa_node, struct pw_propertie
|
|||
}
|
||||
}
|
||||
|
||||
if ((res = spa_node_set_props(spa_node, props)) != SPA_RESULT_OK) {
|
||||
if ((res = spa_node_set_param(spa_node, t->param.idProps, 0, props)) != SPA_RESULT_OK) {
|
||||
pw_log_debug("spa_node_set_props failed: %d", res);
|
||||
return SPA_RESULT_ERROR;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -229,7 +229,7 @@ core_create_link(void *object,
|
|||
uint32_t output_port_id,
|
||||
uint32_t input_node_id,
|
||||
uint32_t input_port_id,
|
||||
const struct spa_format *filter,
|
||||
const struct spa_pod_object *filter,
|
||||
const struct spa_dict *props,
|
||||
uint32_t new_id)
|
||||
{
|
||||
|
|
@ -625,7 +625,7 @@ struct pw_port *pw_core_find_port(struct pw_core *core,
|
|||
uint32_t id,
|
||||
struct pw_properties *props,
|
||||
uint32_t n_format_filters,
|
||||
struct spa_format **format_filters,
|
||||
struct spa_pod_object **format_filters,
|
||||
char **error)
|
||||
{
|
||||
struct pw_port *best = NULL;
|
||||
|
|
@ -658,6 +658,8 @@ struct pw_port *pw_core_find_port(struct pw_core *core,
|
|||
}
|
||||
} else {
|
||||
struct pw_port *p, *pin, *pout;
|
||||
uint8_t buf[4096];
|
||||
struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buf, sizeof(buf));
|
||||
|
||||
p = pw_node_get_free_port(n, pw_direction_reverse(other_port->direction));
|
||||
if (p == NULL)
|
||||
|
|
@ -675,11 +677,13 @@ struct pw_port *pw_core_find_port(struct pw_core *core,
|
|||
pout,
|
||||
pin,
|
||||
props,
|
||||
n_format_filters, format_filters, error) == NULL) {
|
||||
n_format_filters,
|
||||
format_filters,
|
||||
&b,
|
||||
error) < 0) {
|
||||
free(*error);
|
||||
continue;
|
||||
}
|
||||
|
||||
best = p;
|
||||
}
|
||||
}
|
||||
|
|
@ -705,18 +709,19 @@ struct pw_port *pw_core_find_port(struct pw_core *core,
|
|||
*
|
||||
* \memberof pw_core
|
||||
*/
|
||||
struct spa_format *pw_core_find_format(struct pw_core *core,
|
||||
struct pw_port *output,
|
||||
struct pw_port *input,
|
||||
struct pw_properties *props,
|
||||
uint32_t n_format_filters,
|
||||
struct spa_format **format_filters,
|
||||
char **error)
|
||||
int pw_core_find_format(struct pw_core *core,
|
||||
struct pw_port *output,
|
||||
struct pw_port *input,
|
||||
struct pw_properties *props,
|
||||
uint32_t n_format_filters,
|
||||
struct spa_pod_object **format_filters,
|
||||
struct spa_pod_builder *builder,
|
||||
char **error)
|
||||
{
|
||||
uint32_t out_state, in_state;
|
||||
int res;
|
||||
struct spa_format *filter = NULL, *format;
|
||||
uint32_t iidx = 0, oidx = 0;
|
||||
struct pw_type *t = &core->type;
|
||||
|
||||
out_state = output->state;
|
||||
in_state = input->state;
|
||||
|
|
@ -731,60 +736,71 @@ struct spa_format *pw_core_find_format(struct pw_core *core,
|
|||
|
||||
if (in_state == PW_PORT_STATE_CONFIGURE && out_state > PW_PORT_STATE_CONFIGURE) {
|
||||
/* only input needs format */
|
||||
if ((res = spa_node_port_get_format(output->node->node, output->direction, output->port_id,
|
||||
(const struct spa_format **) &format)) < 0) {
|
||||
if ((res = spa_node_port_enum_params(output->node->node,
|
||||
output->direction, output->port_id,
|
||||
t->param.idFormat, &oidx,
|
||||
NULL, builder)) < 0) {
|
||||
asprintf(error, "error get output format: %d", res);
|
||||
goto error;
|
||||
}
|
||||
} else if (out_state == PW_PORT_STATE_CONFIGURE && in_state > PW_PORT_STATE_CONFIGURE) {
|
||||
/* only output needs format */
|
||||
if ((res = spa_node_port_get_format(input->node->node, input->direction, input->port_id,
|
||||
(const struct spa_format **) &format)) < 0) {
|
||||
if ((res = spa_node_port_enum_params(input->node->node,
|
||||
input->direction, input->port_id,
|
||||
t->param.idFormat, &iidx,
|
||||
NULL, builder)) < 0) {
|
||||
asprintf(error, "error get input format: %d", res);
|
||||
goto error;
|
||||
}
|
||||
} else if (in_state == PW_PORT_STATE_CONFIGURE && out_state == PW_PORT_STATE_CONFIGURE) {
|
||||
struct spa_pod_builder fb = { 0 };
|
||||
uint8_t fbuf[4096];
|
||||
struct spa_pod_object *format;
|
||||
again:
|
||||
/* both ports need a format */
|
||||
pw_log_debug("core %p: do enum input %d", core, iidx);
|
||||
if ((res = spa_node_port_enum_formats(input->node->node, input->direction, input->port_id,
|
||||
&filter, NULL, iidx)) < 0) {
|
||||
if (res == SPA_RESULT_ENUM_END && iidx != 0) {
|
||||
spa_pod_builder_init(&fb, fbuf, sizeof(fbuf));
|
||||
if ((res = spa_node_port_enum_params(input->node->node,
|
||||
input->direction, input->port_id,
|
||||
t->param.idEnumFormat, &iidx,
|
||||
NULL, &fb)) < 0) {
|
||||
if (res == SPA_RESULT_ENUM_END && iidx == 0) {
|
||||
asprintf(error, "error input enum formats: %d", res);
|
||||
goto error;
|
||||
}
|
||||
asprintf(error, "no more input formats");
|
||||
goto error;
|
||||
}
|
||||
pw_log_debug("enum output %d with filter: %p", oidx, filter);
|
||||
format = SPA_POD_BUILDER_DEREF(&fb, 0, struct spa_pod_object);
|
||||
pw_log_debug("enum output %d with filter: %p", oidx, format);
|
||||
if (pw_log_level_enabled(SPA_LOG_LEVEL_DEBUG))
|
||||
spa_debug_format(filter);
|
||||
spa_debug_pod(&format->pod, SPA_DEBUG_FLAG_FORMAT);
|
||||
|
||||
if ((res = spa_node_port_enum_formats(output->node->node, output->direction, output->port_id,
|
||||
&format, filter, oidx)) < 0) {
|
||||
if ((res = spa_node_port_enum_params(output->node->node,
|
||||
output->direction, output->port_id,
|
||||
t->param.idEnumFormat, &oidx,
|
||||
format, builder)) < 0) {
|
||||
if (res == SPA_RESULT_ENUM_END) {
|
||||
oidx = 0;
|
||||
iidx++;
|
||||
goto again;
|
||||
}
|
||||
asprintf(error, "error output enum formats: %d", res);
|
||||
goto error;
|
||||
}
|
||||
format = SPA_POD_BUILDER_DEREF(&fb, 0, struct spa_pod_object);
|
||||
|
||||
pw_log_debug("Got filtered:");
|
||||
if (pw_log_level_enabled(SPA_LOG_LEVEL_DEBUG))
|
||||
spa_debug_format(format);
|
||||
|
||||
spa_format_fixate(format);
|
||||
spa_debug_pod(&format->pod, SPA_DEBUG_FLAG_FORMAT);
|
||||
} else {
|
||||
res = SPA_RESULT_ERROR;
|
||||
asprintf(error, "error node state");
|
||||
goto error;
|
||||
}
|
||||
if (format == NULL) {
|
||||
asprintf(error, "error get format");
|
||||
goto error;
|
||||
}
|
||||
return format;
|
||||
return res;
|
||||
|
||||
error:
|
||||
return NULL;
|
||||
return res;
|
||||
}
|
||||
|
||||
/** Find a factory by name
|
||||
|
|
|
|||
|
|
@ -159,26 +159,6 @@ bool pw_core_for_each_global(struct pw_core *core,
|
|||
/** Find a core global by id */
|
||||
struct pw_global *pw_core_find_global(struct pw_core *core, uint32_t id);
|
||||
|
||||
/** Find a good format between 2 ports */
|
||||
struct spa_format *
|
||||
pw_core_find_format(struct pw_core *core,
|
||||
struct pw_port *output,
|
||||
struct pw_port *input,
|
||||
struct pw_properties *props,
|
||||
uint32_t n_format_filters,
|
||||
struct spa_format **format_filters,
|
||||
char **error);
|
||||
|
||||
/** Find a ports compatible with \a other_port and the format filters */
|
||||
struct pw_port *
|
||||
pw_core_find_port(struct pw_core *core,
|
||||
struct pw_port *other_port,
|
||||
uint32_t id,
|
||||
struct pw_properties *props,
|
||||
uint32_t n_format_filters,
|
||||
struct spa_format **format_filters,
|
||||
char **error);
|
||||
|
||||
/** Find a factory by name */
|
||||
struct pw_factory *
|
||||
pw_core_find_factory(struct pw_core *core, const char *name);
|
||||
|
|
|
|||
|
|
@ -157,7 +157,7 @@ struct pw_core_proxy_methods {
|
|||
uint32_t output_port_id,
|
||||
uint32_t input_node_id,
|
||||
uint32_t input_port_id,
|
||||
const struct spa_format *filter,
|
||||
const struct spa_pod_object *filter,
|
||||
const struct spa_dict *props,
|
||||
uint32_t new_id);
|
||||
};
|
||||
|
|
@ -209,7 +209,7 @@ pw_core_proxy_create_link(struct pw_core_proxy *core,
|
|||
uint32_t output_port_id,
|
||||
uint32_t input_node_id,
|
||||
uint32_t input_port_id,
|
||||
const struct spa_format *filter,
|
||||
const struct spa_pod_object *filter,
|
||||
const struct spa_dict *prop,
|
||||
size_t user_data_size)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -199,40 +199,40 @@ struct pw_node_info *pw_node_info_update(struct pw_node_info *info,
|
|||
info->max_input_ports = update->max_input_ports;
|
||||
info->n_input_ports = update->n_input_ports;
|
||||
}
|
||||
if (update->change_mask & PW_NODE_CHANGE_MASK_INPUT_FORMATS) {
|
||||
for (i = 0; i < info->n_input_formats; i++)
|
||||
free(info->input_formats[i]);
|
||||
info->n_input_formats = update->n_input_formats;
|
||||
if (info->n_input_formats)
|
||||
info->input_formats =
|
||||
realloc(info->input_formats,
|
||||
info->n_input_formats * sizeof(struct spa_format *));
|
||||
if (update->change_mask & PW_NODE_CHANGE_MASK_INPUT_PARAMS) {
|
||||
for (i = 0; i < info->n_input_params; i++)
|
||||
free(info->input_params[i]);
|
||||
info->n_input_params = update->n_input_params;
|
||||
if (info->n_input_params)
|
||||
info->input_params =
|
||||
realloc(info->input_params,
|
||||
info->n_input_params * sizeof(struct spa_pod_object *));
|
||||
else {
|
||||
free(info->input_formats);
|
||||
info->input_formats = NULL;
|
||||
free(info->input_params);
|
||||
info->input_params = NULL;
|
||||
}
|
||||
for (i = 0; i < info->n_input_formats; i++) {
|
||||
info->input_formats[i] = spa_format_copy(update->input_formats[i]);
|
||||
for (i = 0; i < info->n_input_params; i++) {
|
||||
info->input_params[i] = spa_pod_object_copy(update->input_params[i]);
|
||||
}
|
||||
}
|
||||
if (update->change_mask & PW_NODE_CHANGE_MASK_OUTPUT_PORTS) {
|
||||
info->max_output_ports = update->max_output_ports;
|
||||
info->n_output_ports = update->n_output_ports;
|
||||
}
|
||||
if (update->change_mask & PW_NODE_CHANGE_MASK_OUTPUT_FORMATS) {
|
||||
for (i = 0; i < info->n_output_formats; i++)
|
||||
free(info->output_formats[i]);
|
||||
info->n_output_formats = update->n_output_formats;
|
||||
if (info->n_output_formats)
|
||||
info->output_formats =
|
||||
realloc(info->output_formats,
|
||||
info->n_output_formats * sizeof(struct spa_format *));
|
||||
if (update->change_mask & PW_NODE_CHANGE_MASK_OUTPUT_PARAMS) {
|
||||
for (i = 0; i < info->n_output_params; i++)
|
||||
free(info->output_params[i]);
|
||||
info->n_output_params = update->n_output_params;
|
||||
if (info->n_output_params)
|
||||
info->output_params =
|
||||
realloc(info->output_params,
|
||||
info->n_output_params * sizeof(struct spa_pod_object *));
|
||||
else {
|
||||
free(info->output_formats);
|
||||
info->output_formats = NULL;
|
||||
free(info->output_params);
|
||||
info->output_params = NULL;
|
||||
}
|
||||
for (i = 0; i < info->n_output_formats; i++) {
|
||||
info->output_formats[i] = spa_format_copy(update->output_formats[i]);
|
||||
for (i = 0; i < info->n_output_params; i++) {
|
||||
info->output_params[i] = spa_pod_object_copy(update->output_params[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -256,15 +256,15 @@ void pw_node_info_free(struct pw_node_info *info)
|
|||
|
||||
if (info->name)
|
||||
free((void *) info->name);
|
||||
if (info->input_formats) {
|
||||
for (i = 0; i < info->n_input_formats; i++)
|
||||
free(info->input_formats[i]);
|
||||
free(info->input_formats);
|
||||
if (info->input_params) {
|
||||
for (i = 0; i < info->n_input_params; i++)
|
||||
free(info->input_params[i]);
|
||||
free(info->input_params);
|
||||
}
|
||||
if (info->output_formats) {
|
||||
for (i = 0; i < info->n_output_formats; i++)
|
||||
free(info->output_formats[i]);
|
||||
free(info->output_formats);
|
||||
if (info->output_params) {
|
||||
for (i = 0; i < info->n_output_params; i++)
|
||||
free(info->output_params[i]);
|
||||
free(info->output_params);
|
||||
}
|
||||
if (info->error)
|
||||
free((void *) info->error);
|
||||
|
|
@ -414,7 +414,7 @@ struct pw_link_info *pw_link_info_update(struct pw_link_info *info,
|
|||
if (update->change_mask & PW_LINK_CHANGE_MASK_FORMAT) {
|
||||
if (info->format)
|
||||
free(info->format);
|
||||
info->format = spa_format_copy(update->format);
|
||||
info->format = spa_pod_object_copy(update->format);
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -143,21 +143,21 @@ struct pw_node_info {
|
|||
uint32_t id; /**< id of the global */
|
||||
#define PW_NODE_CHANGE_MASK_NAME (1 << 0)
|
||||
#define PW_NODE_CHANGE_MASK_INPUT_PORTS (1 << 1)
|
||||
#define PW_NODE_CHANGE_MASK_INPUT_FORMATS (1 << 2)
|
||||
#define PW_NODE_CHANGE_MASK_INPUT_PARAMS (1 << 2)
|
||||
#define PW_NODE_CHANGE_MASK_OUTPUT_PORTS (1 << 3)
|
||||
#define PW_NODE_CHANGE_MASK_OUTPUT_FORMATS (1 << 4)
|
||||
#define PW_NODE_CHANGE_MASK_OUTPUT_PARAMS (1 << 4)
|
||||
#define PW_NODE_CHANGE_MASK_STATE (1 << 5)
|
||||
#define PW_NODE_CHANGE_MASK_PROPS (1 << 6)
|
||||
uint64_t change_mask; /**< bitfield of changed fields since last call */
|
||||
const char *name; /**< name the node, suitable for display */
|
||||
uint32_t max_input_ports; /**< maximum number of inputs */
|
||||
uint32_t n_input_ports; /**< number of inputs */
|
||||
uint32_t n_input_formats; /**< number of input formats */
|
||||
struct spa_format **input_formats; /**< array of input formats */
|
||||
uint32_t n_input_params; /**< number of input params */
|
||||
struct spa_pod_object **input_params; /**< array of input params */
|
||||
uint32_t max_output_ports; /**< maximum number of outputs */
|
||||
uint32_t n_output_ports; /**< number of outputs */
|
||||
uint32_t n_output_formats; /**< number of output formats */
|
||||
struct spa_format **output_formats; /**< array of output formats */
|
||||
uint32_t n_output_params; /**< number of output params */
|
||||
struct spa_pod_object **output_params; /**< array of output params */
|
||||
enum pw_node_state state; /**< the current state of the node */
|
||||
const char *error; /**< an error reason if \a state is error */
|
||||
struct spa_dict *props; /**< the properties of the node */
|
||||
|
|
@ -200,7 +200,7 @@ struct pw_link_info {
|
|||
uint32_t output_port_id; /**< output port id */
|
||||
uint32_t input_node_id; /**< server side input node id */
|
||||
uint32_t input_port_id; /**< input port id */
|
||||
struct spa_format *format; /**< format over link */
|
||||
struct spa_pod_object *format; /**< format over link */
|
||||
struct spa_dict *props; /**< the properties of the link */
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ struct impl {
|
|||
|
||||
struct pw_work_queue *work;
|
||||
|
||||
struct spa_format *format_filter;
|
||||
struct spa_pod_object *format_filter;
|
||||
struct pw_properties *properties;
|
||||
|
||||
struct spa_hook input_port_listener;
|
||||
|
|
@ -115,11 +115,15 @@ static int do_negotiate(struct pw_link *this, uint32_t in_state, uint32_t out_st
|
|||
{
|
||||
struct impl *impl = SPA_CONTAINER_OF(this, struct impl, this);
|
||||
int res = SPA_RESULT_ERROR, res2;
|
||||
struct spa_format *format, *current;
|
||||
struct spa_pod_object *format = NULL, *current;
|
||||
char *error = NULL;
|
||||
struct pw_resource *resource;
|
||||
bool changed = true;
|
||||
struct pw_port *input, *output;
|
||||
uint8_t buffer[4096];
|
||||
struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buffer, sizeof(buffer));
|
||||
struct pw_type *t = &this->core->type;
|
||||
uint32_t index = 0;
|
||||
|
||||
if (in_state != PW_PORT_STATE_CONFIGURE && out_state != PW_PORT_STATE_CONFIGURE)
|
||||
return SPA_RESULT_OK;
|
||||
|
|
@ -129,19 +133,22 @@ static int do_negotiate(struct pw_link *this, uint32_t in_state, uint32_t out_st
|
|||
input = this->input;
|
||||
output = this->output;
|
||||
|
||||
format = pw_core_find_format(this->core, output, input, NULL, 0, NULL, &error);
|
||||
if (format == NULL)
|
||||
if ((res = pw_core_find_format(this->core, output, input, NULL, 0, NULL, &b, &error)) < 0)
|
||||
goto error;
|
||||
|
||||
format = spa_format_copy(format);
|
||||
format = spa_pod_object_copy(SPA_POD_BUILDER_DEREF(&b, 0, struct spa_pod_object));
|
||||
spa_pod_object_fixate(format);
|
||||
|
||||
if (out_state > PW_PORT_STATE_CONFIGURE && output->node->info.state == PW_NODE_STATE_IDLE) {
|
||||
if ((res = spa_node_port_get_format(output->node->node, output->direction, output->port_id,
|
||||
(const struct spa_format **) ¤t)) < 0) {
|
||||
if ((res = spa_node_port_enum_params(output->node->node,
|
||||
output->direction, output->port_id,
|
||||
t->param.idFormat, &index,
|
||||
NULL, &b)) < 0) {
|
||||
asprintf(&error, "error get output format: %d", res);
|
||||
goto error;
|
||||
}
|
||||
if (spa_format_compare(current, format) < 0) {
|
||||
current = SPA_POD_BUILDER_DEREF(&b, 0, struct spa_pod_object);
|
||||
if (spa_pod_object_compare(current, format) < 0) {
|
||||
pw_log_debug("link %p: output format change, renegotiate", this);
|
||||
pw_node_set_state(output->node, PW_NODE_STATE_SUSPENDED);
|
||||
out_state = PW_PORT_STATE_CONFIGURE;
|
||||
|
|
@ -152,12 +159,15 @@ static int do_negotiate(struct pw_link *this, uint32_t in_state, uint32_t out_st
|
|||
}
|
||||
}
|
||||
if (in_state > PW_PORT_STATE_CONFIGURE && input->node->info.state == PW_NODE_STATE_IDLE) {
|
||||
if ((res = spa_node_port_get_format(input->node->node, input->direction, input->port_id,
|
||||
(const struct spa_format **) ¤t)) < 0) {
|
||||
if ((res = spa_node_port_enum_params(input->node->node,
|
||||
input->direction, input->port_id,
|
||||
t->param.idFormat, &index,
|
||||
NULL, &b)) < 0) {
|
||||
asprintf(&error, "error get input format: %d", res);
|
||||
goto error;
|
||||
}
|
||||
if (spa_format_compare(current, format) < 0) {
|
||||
current = SPA_POD_BUILDER_DEREF(&b, 0, struct spa_pod_object);
|
||||
if (spa_pod_object_compare(current, format) < 0) {
|
||||
pw_log_debug("link %p: input format change, renegotiate", this);
|
||||
pw_node_set_state(input->node, PW_NODE_STATE_SUSPENDED);
|
||||
in_state = PW_PORT_STATE_CONFIGURE;
|
||||
|
|
@ -170,11 +180,13 @@ static int do_negotiate(struct pw_link *this, uint32_t in_state, uint32_t out_st
|
|||
|
||||
pw_log_debug("link %p: doing set format %p", this, format);
|
||||
if (pw_log_level_enabled(SPA_LOG_LEVEL_DEBUG))
|
||||
spa_debug_format(format);
|
||||
spa_debug_pod(&format->pod, SPA_DEBUG_FLAG_FORMAT);
|
||||
|
||||
if (out_state == PW_PORT_STATE_CONFIGURE) {
|
||||
pw_log_debug("link %p: doing set format on output", this);
|
||||
if ((res = pw_port_set_format(output, SPA_PORT_FORMAT_FLAG_NEAREST, format)) < 0) {
|
||||
if ((res = pw_port_set_param(output,
|
||||
t->param.idFormat, SPA_NODE_PARAM_FLAG_NEAREST,
|
||||
format)) < 0) {
|
||||
asprintf(&error, "error set output format: %d", res);
|
||||
goto error;
|
||||
}
|
||||
|
|
@ -184,7 +196,9 @@ static int do_negotiate(struct pw_link *this, uint32_t in_state, uint32_t out_st
|
|||
}
|
||||
if (in_state == PW_PORT_STATE_CONFIGURE) {
|
||||
pw_log_debug("link %p: doing set format on input", this);
|
||||
if ((res2 = pw_port_set_format(input, SPA_PORT_FORMAT_FLAG_NEAREST, format)) < 0) {
|
||||
if ((res2 = pw_port_set_param(input,
|
||||
t->param.idFormat, SPA_NODE_PARAM_FLAG_NEAREST,
|
||||
format)) < 0) {
|
||||
asprintf(&error, "error set input format: %d", res2);
|
||||
goto error;
|
||||
}
|
||||
|
|
@ -215,28 +229,28 @@ static int do_negotiate(struct pw_link *this, uint32_t in_state, uint32_t out_st
|
|||
return res;
|
||||
}
|
||||
|
||||
static struct spa_param *find_param(struct spa_param **params, int n_params, uint32_t type)
|
||||
static struct spa_pod_object *find_param(struct spa_pod_object **params, int n_params, uint32_t type)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < n_params; i++) {
|
||||
if (spa_pod_is_object_type(¶ms[i]->object.pod, type))
|
||||
if (spa_pod_is_object_type(¶ms[i]->pod, type))
|
||||
return params[i];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct spa_param *find_meta_enable(struct pw_core *core, struct spa_param **params,
|
||||
static struct spa_pod_object *find_meta_enable(struct pw_core *core, struct spa_pod_object **params,
|
||||
int n_params, uint32_t type)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < n_params; i++) {
|
||||
if (spa_pod_is_object_type
|
||||
(¶ms[i]->object.pod, core->type.param_alloc_meta_enable.MetaEnable)) {
|
||||
(¶ms[i]->pod, core->type.param_alloc_meta_enable.MetaEnable)) {
|
||||
uint32_t qtype;
|
||||
|
||||
if (spa_param_parse(params[i],
|
||||
if (spa_pod_object_parse(params[i],
|
||||
":", core->type.param_alloc_meta_enable.type, "I", &qtype, NULL) < 0)
|
||||
continue;
|
||||
|
||||
|
|
@ -250,7 +264,7 @@ static struct spa_param *find_meta_enable(struct pw_core *core, struct spa_param
|
|||
static struct spa_buffer **alloc_buffers(struct pw_link *this,
|
||||
uint32_t n_buffers,
|
||||
uint32_t n_params,
|
||||
struct spa_param **params,
|
||||
struct spa_pod_object **params,
|
||||
uint32_t n_datas,
|
||||
size_t *data_sizes,
|
||||
ssize_t *data_strides,
|
||||
|
|
@ -281,10 +295,10 @@ static struct spa_buffer **alloc_buffers(struct pw_link *this,
|
|||
/* collect metadata */
|
||||
for (i = 0; i < n_params; i++) {
|
||||
if (spa_pod_is_object_type
|
||||
(¶ms[i]->object.pod, this->core->type.param_alloc_meta_enable.MetaEnable)) {
|
||||
(¶ms[i]->pod, this->core->type.param_alloc_meta_enable.MetaEnable)) {
|
||||
uint32_t type, size;
|
||||
|
||||
if (spa_param_parse(params[i],
|
||||
if (spa_pod_object_parse(params[i],
|
||||
":", this->core->type.param_alloc_meta_enable.type, "I", &type,
|
||||
":", this->core->type.param_alloc_meta_enable.size, "i", &size, NULL) < 0)
|
||||
continue;
|
||||
|
|
@ -382,38 +396,46 @@ static int
|
|||
param_filter(struct pw_link *this,
|
||||
struct pw_port *in_port,
|
||||
struct pw_port *out_port,
|
||||
uint32_t id,
|
||||
struct spa_pod_builder *result)
|
||||
{
|
||||
int res;
|
||||
struct spa_param *oparam, *iparam;
|
||||
int iidx, oidx, num = 0;
|
||||
uint8_t ibuf[2048], obuf[2048];
|
||||
struct spa_pod_builder ib = { 0 }, ob = { 0 };
|
||||
struct spa_pod_object *oparam, *iparam;
|
||||
uint32_t iidx, oidx, num = 0;
|
||||
|
||||
for (iidx = 0;; iidx++) {
|
||||
for (iidx = 0;;) {
|
||||
spa_pod_builder_init(&ib, ibuf, sizeof(ibuf));
|
||||
if (spa_node_port_enum_params(in_port->node->node, in_port->direction, in_port->port_id,
|
||||
iidx, &iparam) < 0)
|
||||
id, &iidx, NULL, &ib) < 0)
|
||||
break;
|
||||
iparam = SPA_POD_BUILDER_DEREF(&ib, 0, struct spa_pod_object);
|
||||
|
||||
for (oidx = 0;; oidx++) {
|
||||
for (oidx = 0;;) {
|
||||
struct spa_pod_frame f;
|
||||
uint32_t offset;
|
||||
|
||||
spa_pod_builder_init(&ob, obuf, sizeof(obuf));
|
||||
if (spa_node_port_enum_params(out_port->node->node, out_port->direction,
|
||||
out_port->port_id, oidx, &oparam) < 0)
|
||||
out_port->port_id, id, &oidx,
|
||||
NULL, &ob) < 0)
|
||||
break;
|
||||
oparam = SPA_POD_BUILDER_DEREF(&ob, 0, struct spa_pod_object);
|
||||
|
||||
if (iidx == 0 && pw_log_level_enabled(SPA_LOG_LEVEL_DEBUG))
|
||||
spa_debug_param(oparam);
|
||||
if (iidx == 1 && pw_log_level_enabled(SPA_LOG_LEVEL_DEBUG))
|
||||
spa_debug_pod(&oparam->pod, 0);
|
||||
|
||||
if (iparam->object.body.type != oparam->object.body.type)
|
||||
if (iparam->body.type != oparam->body.type)
|
||||
continue;
|
||||
|
||||
offset = result->offset;
|
||||
spa_pod_builder_push_object(result, &f, 0, iparam->object.body.type);
|
||||
spa_pod_builder_push_object(result, &f, id, iparam->body.type);
|
||||
if ((res = spa_props_filter(result,
|
||||
SPA_POD_CONTENTS(struct spa_param, iparam),
|
||||
SPA_POD_CONTENTS_SIZE(struct spa_param, iparam),
|
||||
SPA_POD_CONTENTS(struct spa_param, oparam),
|
||||
SPA_POD_CONTENTS_SIZE(struct spa_param, oparam))) < 0) {
|
||||
SPA_POD_CONTENTS(struct spa_pod_object, iparam),
|
||||
SPA_POD_CONTENTS_SIZE(struct spa_pod_object, iparam),
|
||||
SPA_POD_CONTENTS(struct spa_pod_object, oparam),
|
||||
SPA_POD_CONTENTS_SIZE(struct spa_pod_object, oparam))) < 0) {
|
||||
result->offset = offset;
|
||||
result->stack = NULL;
|
||||
continue;
|
||||
|
|
@ -422,7 +444,7 @@ param_filter(struct pw_link *this,
|
|||
num++;
|
||||
}
|
||||
if (pw_log_level_enabled(SPA_LOG_LEVEL_DEBUG))
|
||||
spa_debug_param(iparam);
|
||||
spa_debug_pod(&iparam->pod, 0);
|
||||
|
||||
}
|
||||
return num;
|
||||
|
|
@ -436,6 +458,7 @@ static int do_allocation(struct pw_link *this, uint32_t in_state, uint32_t out_s
|
|||
uint32_t in_flags, out_flags;
|
||||
char *error = NULL;
|
||||
struct pw_port *input, *output;
|
||||
struct pw_type *t = &this->core->type;
|
||||
|
||||
if (in_state != PW_PORT_STATE_READY && out_state != PW_PORT_STATE_READY)
|
||||
return SPA_RESULT_OK;
|
||||
|
|
@ -506,34 +529,35 @@ static int do_allocation(struct pw_link *this, uint32_t in_state, uint32_t out_s
|
|||
}
|
||||
|
||||
if (this->buffers == NULL) {
|
||||
struct spa_param **params, *param;
|
||||
struct spa_pod_object **params, *param;
|
||||
uint8_t buffer[4096];
|
||||
struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buffer, sizeof(buffer));
|
||||
int i, offset, n_params;
|
||||
uint32_t max_buffers;
|
||||
size_t minsize = 1024, stride = 0;
|
||||
|
||||
n_params = param_filter(this, input, output, &b);
|
||||
n_params = param_filter(this, input, output, t->param.idBuffers, &b);
|
||||
n_params += param_filter(this, input, output, t->param.idMeta, &b);
|
||||
|
||||
params = alloca(n_params * sizeof(struct spa_param *));
|
||||
params = alloca(n_params * sizeof(struct spa_pod_object *));
|
||||
for (i = 0, offset = 0; i < n_params; i++) {
|
||||
params[i] = SPA_MEMBER(buffer, offset, struct spa_param);
|
||||
spa_param_fixate(params[i]);
|
||||
params[i] = SPA_MEMBER(buffer, offset, struct spa_pod_object);
|
||||
spa_pod_object_fixate(params[i]);
|
||||
pw_log_debug("fixated param %d:", i);
|
||||
if (pw_log_level_enabled(SPA_LOG_LEVEL_DEBUG))
|
||||
spa_debug_param(params[i]);
|
||||
spa_debug_pod(¶ms[i]->pod, 0);
|
||||
offset += SPA_ROUND_UP_N(SPA_POD_SIZE(params[i]), 8);
|
||||
}
|
||||
|
||||
param = find_meta_enable(this->core, params, n_params,
|
||||
this->core->type.meta.Ringbuffer);
|
||||
t->meta.Ringbuffer);
|
||||
if (param) {
|
||||
uint32_t ms, s;
|
||||
max_buffers = 1;
|
||||
|
||||
if (spa_param_parse(param,
|
||||
":", this->core->type.param_alloc_meta_enable.ringbufferSize, "i", &ms,
|
||||
":", this->core->type.param_alloc_meta_enable.ringbufferStride, "i", &s, NULL) >= 0) {
|
||||
if (spa_pod_object_parse(param,
|
||||
":", t->param_alloc_meta_enable.ringbufferSize, "i", &ms,
|
||||
":", t->param_alloc_meta_enable.ringbufferStride, "i", &s, NULL) >= 0) {
|
||||
minsize = ms;
|
||||
stride = s;
|
||||
}
|
||||
|
|
@ -541,15 +565,15 @@ static int do_allocation(struct pw_link *this, uint32_t in_state, uint32_t out_s
|
|||
max_buffers = MAX_BUFFERS;
|
||||
minsize = stride = 0;
|
||||
param = find_param(params, n_params,
|
||||
this->core->type.param_alloc_buffers.Buffers);
|
||||
t->param_alloc_buffers.Buffers);
|
||||
if (param) {
|
||||
uint32_t qmax_buffers = max_buffers,
|
||||
qminsize = minsize, qstride = stride;
|
||||
|
||||
spa_param_parse(param,
|
||||
":", this->core->type.param_alloc_buffers.size, "i", &qminsize,
|
||||
":", this->core->type.param_alloc_buffers.stride, "i", &qstride,
|
||||
":", this->core->type.param_alloc_buffers.buffers, "i", &qmax_buffers, NULL);
|
||||
spa_pod_object_parse(param,
|
||||
":", t->param_alloc_buffers.size, "i", &qminsize,
|
||||
":", t->param_alloc_buffers.stride, "i", &qstride,
|
||||
":", t->param_alloc_buffers.buffers, "i", &qmax_buffers, NULL);
|
||||
|
||||
max_buffers =
|
||||
qmax_buffers == 0 ? max_buffers : SPA_MIN(qmax_buffers,
|
||||
|
|
@ -1050,7 +1074,7 @@ static const struct pw_node_events output_node_events = {
|
|||
struct pw_link *pw_link_new(struct pw_core *core,
|
||||
struct pw_port *output,
|
||||
struct pw_port *input,
|
||||
struct spa_format *format_filter,
|
||||
struct spa_pod_object *format_filter,
|
||||
struct pw_properties *properties,
|
||||
char **error,
|
||||
size_t user_data_size)
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ struct pw_link *
|
|||
pw_link_new(struct pw_core *core, /**< the core object */
|
||||
struct pw_port *output, /**< an output port */
|
||||
struct pw_port *input, /**< an input port */
|
||||
struct spa_format *format_filter, /**< an optional format filter */
|
||||
struct spa_pod_object *format_filter, /**< an optional format filter */
|
||||
struct pw_properties *properties /**< extra properties */,
|
||||
char **error, /**< error string when result is NULL */
|
||||
size_t user_data_size /**< extra user data size */);
|
||||
|
|
|
|||
|
|
@ -83,14 +83,14 @@ static int suspend_node(struct pw_node *this)
|
|||
pw_log_debug("node %p: suspend node", this);
|
||||
|
||||
spa_list_for_each(p, &this->input_ports, link) {
|
||||
if ((res = pw_port_set_format(p, 0, NULL)) < 0)
|
||||
if ((res = pw_port_set_param(p, this->core->type.param.idFormat, 0, NULL)) < 0)
|
||||
pw_log_warn("error unset format input: %d", res);
|
||||
/* force CONFIGURE in case of async */
|
||||
p->state = PW_PORT_STATE_CONFIGURE;
|
||||
}
|
||||
|
||||
spa_list_for_each(p, &this->output_ports, link) {
|
||||
if ((res = pw_port_set_format(p, 0, NULL)) < 0)
|
||||
if ((res = pw_port_set_param(p, this->core->type.param.idFormat, 0, NULL)) < 0)
|
||||
pw_log_warn("error unset format output: %d", res);
|
||||
/* force CONFIGURE in case of async */
|
||||
p->state = PW_PORT_STATE_CONFIGURE;
|
||||
|
|
@ -222,39 +222,52 @@ static int update_port_ids(struct pw_node *node)
|
|||
static void
|
||||
update_info(struct pw_node *this)
|
||||
{
|
||||
this->info.input_formats = NULL;
|
||||
uint8_t buffer[4096];
|
||||
struct spa_pod_builder b = { 0 };
|
||||
|
||||
this->info.input_params = NULL;
|
||||
if (!spa_list_is_empty(&this->input_ports)) {
|
||||
struct pw_port *port = spa_list_first(&this->input_ports, struct pw_port, link);
|
||||
uint32_t state = 0;
|
||||
|
||||
for (this->info.n_input_formats = 0;; this->info.n_input_formats++) {
|
||||
struct spa_format *fmt;
|
||||
for (this->info.n_input_params = 0;; this->info.n_input_params++) {
|
||||
struct spa_pod_object *fmt;
|
||||
|
||||
if (spa_node_port_enum_formats(port->node->node, port->direction, port->port_id,
|
||||
&fmt, NULL, this->info.n_input_formats) < 0)
|
||||
spa_pod_builder_init(&b, buffer, sizeof(buffer));
|
||||
if (spa_node_port_enum_params(port->node->node,
|
||||
port->direction, port->port_id,
|
||||
this->core->type.param.idEnumFormat, &state,
|
||||
NULL, &b) < 0)
|
||||
break;
|
||||
fmt = SPA_POD_BUILDER_DEREF(&b, 0, struct spa_pod_object);
|
||||
|
||||
this->info.input_formats =
|
||||
realloc(this->info.input_formats,
|
||||
sizeof(struct spa_format *) * (this->info.n_input_formats + 1));
|
||||
this->info.input_formats[this->info.n_input_formats] = spa_format_copy(fmt);
|
||||
this->info.input_params =
|
||||
realloc(this->info.input_params,
|
||||
sizeof(struct spa_pod_object *) * (this->info.n_input_params + 1));
|
||||
this->info.input_params[this->info.n_input_params] = spa_pod_object_copy(fmt);
|
||||
}
|
||||
}
|
||||
|
||||
this->info.output_formats = NULL;
|
||||
this->info.output_params = NULL;
|
||||
if (!spa_list_is_empty(&this->output_ports)) {
|
||||
struct pw_port *port = spa_list_first(&this->output_ports, struct pw_port, link);
|
||||
uint32_t state = 0;
|
||||
|
||||
for (this->info.n_output_formats = 0;; this->info.n_output_formats++) {
|
||||
struct spa_format *fmt;
|
||||
for (this->info.n_output_params = 0;; this->info.n_output_params++) {
|
||||
struct spa_pod_object *fmt;
|
||||
|
||||
if (spa_node_port_enum_formats(port->node->node, port->direction, port->port_id,
|
||||
&fmt, NULL, this->info.n_output_formats) < 0)
|
||||
spa_pod_builder_init(&b, buffer, sizeof(buffer));
|
||||
if (spa_node_port_enum_params(port->node->node,
|
||||
port->direction, port->port_id,
|
||||
this->core->type.param.idEnumFormat, &state,
|
||||
NULL, &b) < 0)
|
||||
break;
|
||||
fmt = SPA_POD_BUILDER_DEREF(&b, 0, struct spa_pod_object);
|
||||
|
||||
this->info.output_formats =
|
||||
realloc(this->info.output_formats,
|
||||
sizeof(struct spa_format *) * (this->info.n_output_formats + 1));
|
||||
this->info.output_formats[this->info.n_output_formats] = spa_format_copy(fmt);
|
||||
this->info.output_params =
|
||||
realloc(this->info.output_params,
|
||||
sizeof(struct spa_pod_object *) * (this->info.n_output_params + 1));
|
||||
this->info.output_params[this->info.n_output_params] = spa_pod_object_copy(fmt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -265,16 +278,16 @@ clear_info(struct pw_node *this)
|
|||
int i;
|
||||
|
||||
free((char*)this->info.name);
|
||||
if (this->info.input_formats) {
|
||||
for (i = 0; i < this->info.n_input_formats; i++)
|
||||
free(this->info.input_formats[i]);
|
||||
free(this->info.input_formats);
|
||||
if (this->info.input_params) {
|
||||
for (i = 0; i < this->info.n_input_params; i++)
|
||||
free(this->info.input_params[i]);
|
||||
free(this->info.input_params);
|
||||
}
|
||||
|
||||
if (this->info.output_formats) {
|
||||
for (i = 0; i < this->info.n_output_formats; i++)
|
||||
free(this->info.output_formats[i]);
|
||||
free(this->info.output_formats);
|
||||
if (this->info.output_params) {
|
||||
for (i = 0; i < this->info.n_output_params; i++)
|
||||
free(this->info.output_params[i]);
|
||||
free(this->info.output_params);
|
||||
}
|
||||
free((char*)this->info.error);
|
||||
|
||||
|
|
|
|||
|
|
@ -364,15 +364,16 @@ do_port_pause(struct spa_loop *loop,
|
|||
&SPA_COMMAND_INIT(node->core->type.command_node.Pause));
|
||||
}
|
||||
|
||||
int pw_port_set_format(struct pw_port *port, uint32_t flags, const struct spa_format *format)
|
||||
int pw_port_set_param(struct pw_port *port, uint32_t id, uint32_t flags,
|
||||
const struct spa_pod_object *param)
|
||||
{
|
||||
int res;
|
||||
|
||||
res = spa_node_port_set_format(port->node->node, port->direction, port->port_id, flags, format);
|
||||
pw_log_debug("port %p: set format %d", port, res);
|
||||
res = spa_node_port_set_param(port->node->node, port->direction, port->port_id, id, flags, param);
|
||||
pw_log_debug("port %p: set param %d %d", port, id, res);
|
||||
|
||||
if (!SPA_RESULT_IS_ASYNC(res)) {
|
||||
if (format == NULL || res < 0) {
|
||||
if (!SPA_RESULT_IS_ASYNC(res) && id == port->node->core->type.param.idFormat) {
|
||||
if (param == NULL || res < 0) {
|
||||
if (port->allocated) {
|
||||
free(port->buffers);
|
||||
pw_memblock_free(&port->buffer_mem);
|
||||
|
|
@ -425,7 +426,7 @@ int pw_port_use_buffers(struct pw_port *port, struct spa_buffer **buffers, uint3
|
|||
}
|
||||
|
||||
int pw_port_alloc_buffers(struct pw_port *port,
|
||||
struct spa_param **params, uint32_t n_params,
|
||||
struct spa_pod_object **params, uint32_t n_params,
|
||||
struct spa_buffer **buffers, uint32_t *n_buffers)
|
||||
{
|
||||
int res;
|
||||
|
|
|
|||
|
|
@ -389,6 +389,26 @@ struct pw_factory {
|
|||
void *user_data;
|
||||
};
|
||||
|
||||
/** Find a good format between 2 ports */
|
||||
int pw_core_find_format(struct pw_core *core,
|
||||
struct pw_port *output,
|
||||
struct pw_port *input,
|
||||
struct pw_properties *props,
|
||||
uint32_t n_format_filters,
|
||||
struct spa_pod_object **format_filters,
|
||||
struct spa_pod_builder *builder,
|
||||
char **error);
|
||||
|
||||
/** Find a ports compatible with \a other_port and the format filters */
|
||||
struct pw_port *
|
||||
pw_core_find_port(struct pw_core *core,
|
||||
struct pw_port *other_port,
|
||||
uint32_t id,
|
||||
struct pw_properties *props,
|
||||
uint32_t n_format_filters,
|
||||
struct spa_pod_object **format_filters,
|
||||
char **error);
|
||||
|
||||
/** Create a new port \memberof pw_port
|
||||
* \return a newly allocated port */
|
||||
struct pw_port *
|
||||
|
|
@ -406,15 +426,16 @@ bool pw_port_add(struct pw_port *port, struct pw_node *node);
|
|||
/** Destroy a port \memberof pw_port */
|
||||
void pw_port_destroy(struct pw_port *port);
|
||||
|
||||
/** Set a format on a port \memberof pw_port */
|
||||
int pw_port_set_format(struct pw_port *port, uint32_t flags, const struct spa_format *format);
|
||||
/** Set a param on a port \memberof pw_port */
|
||||
int pw_port_set_param(struct pw_port *port, uint32_t id, uint32_t flags,
|
||||
const struct spa_pod_object *param);
|
||||
|
||||
/** Use buffers on a port \memberof pw_port */
|
||||
int pw_port_use_buffers(struct pw_port *port, struct spa_buffer **buffers, uint32_t n_buffers);
|
||||
|
||||
/** Allocate memory for buffers on a port \memberof pw_port */
|
||||
int pw_port_alloc_buffers(struct pw_port *port,
|
||||
struct spa_param **params, uint32_t n_params,
|
||||
struct spa_pod_object **params, uint32_t n_params,
|
||||
struct spa_buffer **buffers, uint32_t *n_buffers);
|
||||
|
||||
/** Change the state of the node */
|
||||
|
|
|
|||
|
|
@ -639,36 +639,42 @@ static void client_node_transport(void *object, uint32_t node_id,
|
|||
static void add_port_update(struct pw_proxy *proxy, struct pw_port *port, uint32_t change_mask)
|
||||
{
|
||||
struct node_data *data = proxy->user_data;
|
||||
const struct spa_format *format = NULL;
|
||||
const struct spa_port_info *port_info = NULL;
|
||||
struct spa_port_info pi;
|
||||
uint32_t n_possible_formats = 0, n_params = 0;
|
||||
struct spa_param **params = NULL;
|
||||
struct spa_format **possible_formats = NULL;
|
||||
uint32_t n_params = 0;
|
||||
struct spa_pod_object **params = NULL;
|
||||
|
||||
if (change_mask & PW_CLIENT_NODE_PORT_UPDATE_POSSIBLE_FORMATS) {
|
||||
if (port->direction == PW_DIRECTION_INPUT) {
|
||||
n_possible_formats = data->node->info.n_input_formats;
|
||||
possible_formats = data->node->info.input_formats;
|
||||
}
|
||||
else if (port->direction == PW_DIRECTION_OUTPUT) {
|
||||
n_possible_formats = data->node->info.n_output_formats;
|
||||
possible_formats = data->node->info.output_formats;
|
||||
}
|
||||
}
|
||||
if (change_mask & PW_CLIENT_NODE_PORT_UPDATE_FORMAT) {
|
||||
spa_node_port_get_format(port->node->node, port->direction, port->port_id, &format);
|
||||
}
|
||||
if (change_mask & PW_CLIENT_NODE_PORT_UPDATE_PARAMS) {
|
||||
for (;; n_params++) {
|
||||
struct spa_param *param;
|
||||
uint32_t idx1, idx2, id;
|
||||
uint8_t buf[2048];
|
||||
struct spa_pod_builder b = { 0 };
|
||||
|
||||
if (spa_node_port_enum_params(port->node->node, port->direction, port->port_id,
|
||||
n_params, ¶m) < 0)
|
||||
for (idx1 = 0;;) {
|
||||
struct spa_pod_object *param;
|
||||
|
||||
spa_pod_builder_init(&b, buf, sizeof(buf));
|
||||
if (spa_node_port_enum_params(port->node->node,
|
||||
port->direction, port->port_id,
|
||||
data->t->param.idList, &idx1,
|
||||
NULL, &b) < 0)
|
||||
break;
|
||||
param = SPA_POD_BUILDER_DEREF(&b, 0, struct spa_pod_object);
|
||||
|
||||
params = realloc(params, sizeof(struct spa_param *) * (n_params + 1));
|
||||
params[n_params] = spa_param_copy(param);
|
||||
spa_pod_object_parse(param,
|
||||
":", data->t->param.listId, "I", &id, NULL);
|
||||
|
||||
for (idx2 = 0;; n_params++) {
|
||||
spa_pod_builder_init(&b, buf, sizeof(buf));
|
||||
if (spa_node_port_enum_params(port->node->node,
|
||||
port->direction, port->port_id,
|
||||
id, &idx2,
|
||||
NULL, &b) < 0)
|
||||
break;
|
||||
param = SPA_POD_BUILDER_DEREF(&b, 0, struct spa_pod_object);
|
||||
|
||||
params = realloc(params, sizeof(struct spa_pod_object *) * (n_params + 1));
|
||||
params[n_params] = spa_pod_object_copy(param);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (change_mask & PW_CLIENT_NODE_PORT_UPDATE_INFO) {
|
||||
|
|
@ -681,11 +687,8 @@ static void add_port_update(struct pw_proxy *proxy, struct pw_port *port, uint32
|
|||
port->direction,
|
||||
port->port_id,
|
||||
change_mask,
|
||||
n_possible_formats,
|
||||
(const struct spa_format **) possible_formats,
|
||||
format,
|
||||
n_params,
|
||||
(const struct spa_param **) params,
|
||||
(const struct spa_pod_object **)params,
|
||||
&pi);
|
||||
if (params) {
|
||||
while (n_params > 0)
|
||||
|
|
@ -695,9 +698,10 @@ static void add_port_update(struct pw_proxy *proxy, struct pw_port *port, uint32
|
|||
}
|
||||
|
||||
static void
|
||||
client_node_set_props(void *object, uint32_t seq, const struct spa_props *props)
|
||||
client_node_set_param(void *object, uint32_t seq, uint32_t id, uint32_t flags,
|
||||
const struct spa_pod_object *param)
|
||||
{
|
||||
pw_log_warn("set property not implemented");
|
||||
pw_log_warn("set param not implemented");
|
||||
}
|
||||
|
||||
static void client_node_event(void *object, const struct spa_event *event)
|
||||
|
|
@ -705,6 +709,85 @@ static void client_node_event(void *object, const struct spa_event *event)
|
|||
pw_log_warn("unhandled node event %d", SPA_EVENT_TYPE(event));
|
||||
}
|
||||
|
||||
|
||||
static void node_need_input(void *data)
|
||||
{
|
||||
struct node_data *d = data;
|
||||
uint64_t cmd = 1;
|
||||
pw_client_node_transport_add_message(d->trans,
|
||||
&PW_CLIENT_NODE_MESSAGE_INIT(PW_CLIENT_NODE_MESSAGE_NEED_INPUT));
|
||||
write(d->rtwritefd, &cmd, 8);
|
||||
}
|
||||
|
||||
static void node_have_output(void *data)
|
||||
{
|
||||
struct node_data *d = data;
|
||||
uint64_t cmd = 1;
|
||||
pw_client_node_transport_add_message(d->trans,
|
||||
&PW_CLIENT_NODE_MESSAGE_INIT(PW_CLIENT_NODE_MESSAGE_HAVE_OUTPUT));
|
||||
write(d->rtwritefd, &cmd, 8);
|
||||
}
|
||||
|
||||
static void client_node_command(void *object, uint32_t seq, const struct spa_command *command)
|
||||
{
|
||||
struct pw_proxy *proxy = object;
|
||||
struct node_data *data = proxy->user_data;
|
||||
struct pw_remote *remote = proxy->remote;
|
||||
int res;
|
||||
|
||||
if (SPA_COMMAND_TYPE(command) == remote->core->type.command_node.Pause) {
|
||||
pw_log_debug("node %p: pause %d", proxy, seq);
|
||||
|
||||
pw_loop_update_io(remote->core->data_loop,
|
||||
data->rtsocket_source,
|
||||
SPA_IO_ERR | SPA_IO_HUP);
|
||||
|
||||
if ((res = spa_node_send_command(data->node->node, command)) < 0)
|
||||
pw_log_warn("node %p: pause failed", proxy);
|
||||
|
||||
pw_client_node_proxy_done(data->node_proxy, seq, res);
|
||||
}
|
||||
else if (SPA_COMMAND_TYPE(command) == remote->core->type.command_node.Start) {
|
||||
int i;
|
||||
|
||||
pw_log_debug("node %p: start %d", proxy, seq);
|
||||
|
||||
pw_loop_update_io(remote->core->data_loop,
|
||||
data->rtsocket_source,
|
||||
SPA_IO_IN | SPA_IO_ERR | SPA_IO_HUP);
|
||||
|
||||
if ((res = spa_node_send_command(data->node->node, command)) < 0)
|
||||
pw_log_warn("node %p: start failed", proxy);
|
||||
|
||||
/* FIXME we should call process_output on the node and see what its
|
||||
* status is */
|
||||
for (i = 0; i < data->trans->area->max_input_ports; i++)
|
||||
data->trans->inputs[i].status = SPA_RESULT_NEED_BUFFER;
|
||||
node_need_input(data);
|
||||
|
||||
pw_client_node_proxy_done(data->node_proxy, seq, res);
|
||||
}
|
||||
else if (SPA_COMMAND_TYPE(command) == remote->core->type.command_node.ClockUpdate) {
|
||||
struct spa_command_node_clock_update *cu = (__typeof__(cu)) command;
|
||||
|
||||
#if 0
|
||||
if (cu->body.flags.value & SPA_COMMAND_NODE_CLOCK_UPDATE_FLAG_LIVE) {
|
||||
pw_properties_set(stream->properties, PW_STREAM_PROP_IS_LIVE, "1");
|
||||
pw_properties_setf(stream->properties,
|
||||
PW_STREAM_PROP_LATENCY_MIN, "%" PRId64,
|
||||
cu->body.latency.value);
|
||||
}
|
||||
impl->last_ticks = cu->body.ticks.value;
|
||||
impl->last_rate = cu->body.rate.value;
|
||||
impl->last_monotonic = cu->body.monotonic_time.value;
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
pw_log_warn("unhandled node command %d", SPA_COMMAND_TYPE(command));
|
||||
pw_client_node_proxy_done(data->node_proxy, seq, SPA_RESULT_NOT_IMPLEMENTED);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
client_node_add_port(void *object, uint32_t seq, enum spa_direction direction, uint32_t port_id)
|
||||
{
|
||||
|
|
@ -718,10 +801,11 @@ client_node_remove_port(void *object, uint32_t seq, enum spa_direction direction
|
|||
}
|
||||
|
||||
static void
|
||||
client_node_set_format(void *object,
|
||||
uint32_t seq,
|
||||
enum spa_direction direction,
|
||||
uint32_t port_id, uint32_t flags, const struct spa_format *format)
|
||||
client_node_port_set_param(void *object,
|
||||
uint32_t seq,
|
||||
enum spa_direction direction, uint32_t port_id,
|
||||
uint32_t id, uint32_t flags,
|
||||
const struct spa_pod_object *param)
|
||||
{
|
||||
struct pw_proxy *proxy = object;
|
||||
struct node_data *data = proxy->user_data;
|
||||
|
|
@ -734,12 +818,11 @@ client_node_set_format(void *object,
|
|||
goto done;
|
||||
}
|
||||
|
||||
res = pw_port_set_format(port->port, flags, format);
|
||||
res = pw_port_set_param(port->port, id, flags, param);
|
||||
if (res != SPA_RESULT_OK)
|
||||
goto done;
|
||||
|
||||
add_port_update(proxy, port->port,
|
||||
PW_CLIENT_NODE_PORT_UPDATE_FORMAT |
|
||||
PW_CLIENT_NODE_PORT_UPDATE_PARAMS |
|
||||
PW_CLIENT_NODE_PORT_UPDATE_INFO);
|
||||
|
||||
|
|
@ -747,16 +830,6 @@ client_node_set_format(void *object,
|
|||
pw_client_node_proxy_done(data->node_proxy, seq, res);
|
||||
}
|
||||
|
||||
static void
|
||||
client_node_set_param(void *object,
|
||||
uint32_t seq,
|
||||
enum spa_direction direction,
|
||||
uint32_t port_id,
|
||||
const struct spa_param *param)
|
||||
{
|
||||
pw_log_warn("set param not implemented");
|
||||
}
|
||||
|
||||
static struct mem_id *find_mem(struct port *port, uint32_t id)
|
||||
{
|
||||
struct mem_id *mid;
|
||||
|
|
@ -807,11 +880,10 @@ static void clear_port(struct port *port)
|
|||
}
|
||||
|
||||
static void
|
||||
client_node_add_mem(void *object,
|
||||
enum spa_direction direction,
|
||||
uint32_t port_id,
|
||||
uint32_t mem_id,
|
||||
uint32_t type, int memfd, uint32_t flags, uint32_t offset, uint32_t size)
|
||||
client_node_port_add_mem(void *object,
|
||||
enum spa_direction direction, uint32_t port_id,
|
||||
uint32_t mem_id,
|
||||
uint32_t type, int memfd, uint32_t flags, uint32_t offset, uint32_t size)
|
||||
{
|
||||
struct pw_proxy *proxy = object;
|
||||
struct node_data *data = proxy->user_data;
|
||||
|
|
@ -837,10 +909,10 @@ client_node_add_mem(void *object,
|
|||
}
|
||||
|
||||
static void
|
||||
client_node_use_buffers(void *object,
|
||||
uint32_t seq,
|
||||
enum spa_direction direction,
|
||||
uint32_t port_id, uint32_t n_buffers, struct pw_client_node_buffer *buffers)
|
||||
client_node_port_use_buffers(void *object,
|
||||
uint32_t seq,
|
||||
enum spa_direction direction, uint32_t port_id,
|
||||
uint32_t n_buffers, struct pw_client_node_buffer *buffers)
|
||||
{
|
||||
struct pw_proxy *proxy = object;
|
||||
struct node_data *data = proxy->user_data;
|
||||
|
|
@ -964,93 +1036,6 @@ client_node_use_buffers(void *object,
|
|||
|
||||
}
|
||||
|
||||
static void node_need_input(void *data)
|
||||
{
|
||||
struct node_data *d = data;
|
||||
uint64_t cmd = 1;
|
||||
pw_client_node_transport_add_message(d->trans,
|
||||
&PW_CLIENT_NODE_MESSAGE_INIT(PW_CLIENT_NODE_MESSAGE_NEED_INPUT));
|
||||
write(d->rtwritefd, &cmd, 8);
|
||||
}
|
||||
|
||||
static void node_have_output(void *data)
|
||||
{
|
||||
struct node_data *d = data;
|
||||
uint64_t cmd = 1;
|
||||
pw_client_node_transport_add_message(d->trans,
|
||||
&PW_CLIENT_NODE_MESSAGE_INIT(PW_CLIENT_NODE_MESSAGE_HAVE_OUTPUT));
|
||||
write(d->rtwritefd, &cmd, 8);
|
||||
}
|
||||
|
||||
static bool
|
||||
handle_node_command(struct pw_proxy *proxy, uint32_t seq, const struct spa_command *command)
|
||||
{
|
||||
struct node_data *data = proxy->user_data;
|
||||
struct pw_remote *remote = proxy->remote;
|
||||
int res;
|
||||
|
||||
if (SPA_COMMAND_TYPE(command) == remote->core->type.command_node.Pause) {
|
||||
pw_log_debug("node %p: pause %d", proxy, seq);
|
||||
|
||||
pw_loop_update_io(remote->core->data_loop,
|
||||
data->rtsocket_source,
|
||||
SPA_IO_ERR | SPA_IO_HUP);
|
||||
|
||||
if ((res = spa_node_send_command(data->node->node, command)) < 0)
|
||||
pw_log_warn("node %p: pause failed", proxy);
|
||||
|
||||
pw_client_node_proxy_done(data->node_proxy, seq, res);
|
||||
}
|
||||
else if (SPA_COMMAND_TYPE(command) == remote->core->type.command_node.Start) {
|
||||
int i;
|
||||
|
||||
pw_log_debug("node %p: start %d", proxy, seq);
|
||||
|
||||
pw_loop_update_io(remote->core->data_loop,
|
||||
data->rtsocket_source,
|
||||
SPA_IO_IN | SPA_IO_ERR | SPA_IO_HUP);
|
||||
|
||||
if ((res = spa_node_send_command(data->node->node, command)) < 0)
|
||||
pw_log_warn("node %p: start failed", proxy);
|
||||
|
||||
/* FIXME we should call process_output on the node and see what its
|
||||
* status is */
|
||||
for (i = 0; i < data->trans->area->max_input_ports; i++)
|
||||
data->trans->inputs[i].status = SPA_RESULT_NEED_BUFFER;
|
||||
node_need_input(data);
|
||||
|
||||
pw_client_node_proxy_done(data->node_proxy, seq, res);
|
||||
}
|
||||
else if (SPA_COMMAND_TYPE(command) == remote->core->type.command_node.ClockUpdate) {
|
||||
struct spa_command_node_clock_update *cu = (__typeof__(cu)) command;
|
||||
|
||||
#if 0
|
||||
if (cu->body.flags.value & SPA_COMMAND_NODE_CLOCK_UPDATE_FLAG_LIVE) {
|
||||
pw_properties_set(stream->properties, PW_STREAM_PROP_IS_LIVE, "1");
|
||||
pw_properties_setf(stream->properties,
|
||||
PW_STREAM_PROP_LATENCY_MIN, "%" PRId64,
|
||||
cu->body.latency.value);
|
||||
}
|
||||
impl->last_ticks = cu->body.ticks.value;
|
||||
impl->last_rate = cu->body.rate.value;
|
||||
impl->last_monotonic = cu->body.monotonic_time.value;
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
pw_log_warn("unhandled node command %d", SPA_COMMAND_TYPE(command));
|
||||
pw_client_node_proxy_done(data->node_proxy, seq, SPA_RESULT_NOT_IMPLEMENTED);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void client_node_node_command(void *object, uint32_t seq, const struct spa_command *command)
|
||||
{
|
||||
struct pw_proxy *proxy = object;
|
||||
handle_node_command(proxy, seq, command);
|
||||
}
|
||||
|
||||
static void
|
||||
client_node_port_command(void *object,
|
||||
uint32_t direction,
|
||||
|
|
@ -1063,15 +1048,14 @@ client_node_port_command(void *object,
|
|||
static const struct pw_client_node_proxy_events client_node_events = {
|
||||
PW_VERSION_CLIENT_NODE_PROXY_EVENTS,
|
||||
.transport = client_node_transport,
|
||||
.set_props = client_node_set_props,
|
||||
.set_param = client_node_set_param,
|
||||
.event = client_node_event,
|
||||
.command = client_node_command,
|
||||
.add_port = client_node_add_port,
|
||||
.remove_port = client_node_remove_port,
|
||||
.set_format = client_node_set_format,
|
||||
.set_param = client_node_set_param,
|
||||
.add_mem = client_node_add_mem,
|
||||
.use_buffers = client_node_use_buffers,
|
||||
.node_command = client_node_node_command,
|
||||
.port_set_param = client_node_port_set_param,
|
||||
.port_add_mem = client_node_port_add_mem,
|
||||
.port_use_buffers = client_node_port_use_buffers,
|
||||
.port_command = client_node_port_command,
|
||||
};
|
||||
|
||||
|
|
@ -1083,19 +1067,19 @@ static void do_node_init(struct pw_proxy *proxy)
|
|||
pw_client_node_proxy_update(data->node_proxy,
|
||||
PW_CLIENT_NODE_UPDATE_MAX_INPUTS |
|
||||
PW_CLIENT_NODE_UPDATE_MAX_OUTPUTS |
|
||||
PW_CLIENT_NODE_UPDATE_PROPS,
|
||||
PW_CLIENT_NODE_UPDATE_PARAMS,
|
||||
data->node->info.max_input_ports,
|
||||
data->node->info.max_output_ports,
|
||||
NULL);
|
||||
0, NULL);
|
||||
|
||||
spa_list_for_each(port, &data->node->input_ports, link) {
|
||||
add_port_update(proxy, port,
|
||||
PW_CLIENT_NODE_PORT_UPDATE_POSSIBLE_FORMATS |
|
||||
PW_CLIENT_NODE_PORT_UPDATE_PARAMS |
|
||||
PW_CLIENT_NODE_PORT_UPDATE_INFO);
|
||||
}
|
||||
spa_list_for_each(port, &data->node->output_ports, link) {
|
||||
add_port_update(proxy, port,
|
||||
PW_CLIENT_NODE_PORT_UPDATE_POSSIBLE_FORMATS |
|
||||
PW_CLIENT_NODE_PORT_UPDATE_PARAMS |
|
||||
PW_CLIENT_NODE_PORT_UPDATE_INFO);
|
||||
}
|
||||
pw_client_node_proxy_done(data->node_proxy, 0, SPA_RESULT_OK);
|
||||
|
|
|
|||
|
|
@ -64,19 +64,19 @@ struct stream {
|
|||
|
||||
uint32_t type_client_node;
|
||||
|
||||
uint32_t n_possible_formats;
|
||||
struct spa_format **possible_formats;
|
||||
uint32_t n_init_params;
|
||||
struct spa_pod_object **init_params;
|
||||
|
||||
uint32_t n_params;
|
||||
struct spa_param **params;
|
||||
struct spa_pod_object **params;
|
||||
|
||||
struct spa_pod_object *format;
|
||||
|
||||
struct spa_format *format;
|
||||
struct spa_port_info port_info;
|
||||
enum spa_direction direction;
|
||||
uint32_t port_id;
|
||||
uint32_t pending_seq;
|
||||
|
||||
enum pw_stream_mode mode;
|
||||
enum pw_stream_flags flags;
|
||||
|
||||
int rtwritefd;
|
||||
|
|
@ -307,27 +307,28 @@ static void unhandle_socket(struct pw_stream *stream)
|
|||
}
|
||||
|
||||
static void
|
||||
set_possible_formats(struct pw_stream *stream,
|
||||
int n_possible_formats, const struct spa_format **possible_formats)
|
||||
set_init_params(struct pw_stream *stream,
|
||||
int n_init_params,
|
||||
const struct spa_pod_object **init_params)
|
||||
{
|
||||
struct stream *impl = SPA_CONTAINER_OF(stream, struct stream, this);
|
||||
int i;
|
||||
|
||||
if (impl->possible_formats) {
|
||||
for (i = 0; i < impl->n_possible_formats; i++)
|
||||
free(impl->possible_formats[i]);
|
||||
free(impl->possible_formats);
|
||||
impl->possible_formats = NULL;
|
||||
if (impl->init_params) {
|
||||
for (i = 0; i < impl->n_init_params; i++)
|
||||
free(impl->init_params[i]);
|
||||
free(impl->init_params);
|
||||
impl->init_params = NULL;
|
||||
}
|
||||
impl->n_possible_formats = n_possible_formats;
|
||||
if (n_possible_formats > 0) {
|
||||
impl->possible_formats = malloc(n_possible_formats * sizeof(struct spa_format *));
|
||||
for (i = 0; i < n_possible_formats; i++)
|
||||
impl->possible_formats[i] = spa_format_copy(possible_formats[i]);
|
||||
impl->n_init_params = n_init_params;
|
||||
if (n_init_params > 0) {
|
||||
impl->init_params = malloc(n_init_params * sizeof(struct spa_pod_object *));
|
||||
for (i = 0; i < n_init_params; i++)
|
||||
impl->init_params[i] = spa_pod_object_copy(init_params[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void set_params(struct pw_stream *stream, int n_params, struct spa_param **params)
|
||||
static void set_params(struct pw_stream *stream, int n_params, struct spa_pod_object **params)
|
||||
{
|
||||
struct stream *impl = SPA_CONTAINER_OF(stream, struct stream, this);
|
||||
int i;
|
||||
|
|
@ -340,9 +341,9 @@ static void set_params(struct pw_stream *stream, int n_params, struct spa_param
|
|||
}
|
||||
impl->n_params = n_params;
|
||||
if (n_params > 0) {
|
||||
impl->params = malloc(n_params * sizeof(struct spa_param *));
|
||||
impl->params = malloc(n_params * sizeof(struct spa_pod_object *));
|
||||
for (i = 0; i < n_params; i++)
|
||||
impl->params[i] = spa_param_copy(params[i]);
|
||||
impl->params[i] = spa_pod_object_copy(params[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -361,7 +362,7 @@ void pw_stream_destroy(struct pw_stream *stream)
|
|||
|
||||
spa_list_remove(&stream->link);
|
||||
|
||||
set_possible_formats(stream, 0, NULL);
|
||||
set_init_params(stream, 0, NULL);
|
||||
set_params(stream, 0, NULL);
|
||||
|
||||
if (impl->format)
|
||||
|
|
@ -396,23 +397,38 @@ static void add_node_update(struct pw_stream *stream, uint32_t change_mask)
|
|||
max_output_ports = impl->direction == SPA_DIRECTION_OUTPUT ? 1 : 0;
|
||||
|
||||
pw_client_node_proxy_update(impl->node_proxy,
|
||||
change_mask, max_input_ports, max_output_ports, NULL);
|
||||
change_mask, max_input_ports, max_output_ports,
|
||||
0, NULL);
|
||||
}
|
||||
|
||||
static void add_port_update(struct pw_stream *stream, uint32_t change_mask)
|
||||
{
|
||||
struct stream *impl = SPA_CONTAINER_OF(stream, struct stream, this);
|
||||
uint32_t n_params;
|
||||
struct spa_pod_object **params;
|
||||
int i, j;
|
||||
|
||||
n_params = impl->n_params + impl->n_init_params;
|
||||
if (impl->format)
|
||||
n_params += 1;
|
||||
|
||||
params = alloca(n_params * sizeof(struct spa_pod_object *));
|
||||
|
||||
j = 0;
|
||||
for (i = 0; i < impl->n_init_params; i++)
|
||||
params[j++] = (struct spa_pod_object *)impl->init_params[i];
|
||||
if (impl->format)
|
||||
params[j++] = impl->format;
|
||||
for (i = 0; i < impl->n_params; i++)
|
||||
params[j++] = impl->params[i];
|
||||
|
||||
pw_client_node_proxy_port_update(impl->node_proxy,
|
||||
impl->direction,
|
||||
impl->port_id,
|
||||
change_mask,
|
||||
impl->n_possible_formats,
|
||||
(const struct spa_format **) impl->possible_formats,
|
||||
impl->format,
|
||||
impl->n_params,
|
||||
(const struct spa_param **) impl->params, &impl->port_info);
|
||||
n_params,
|
||||
(const struct spa_pod_object **) params,
|
||||
&impl->port_info);
|
||||
}
|
||||
|
||||
static inline void send_need_input(struct pw_stream *stream)
|
||||
|
|
@ -472,8 +488,10 @@ static void do_node_init(struct pw_stream *stream)
|
|||
PW_CLIENT_NODE_UPDATE_MAX_OUTPUTS);
|
||||
|
||||
impl->port_info.flags = SPA_PORT_INFO_FLAG_CAN_USE_BUFFERS;
|
||||
add_port_update(stream, PW_CLIENT_NODE_PORT_UPDATE_POSSIBLE_FORMATS |
|
||||
PW_CLIENT_NODE_PORT_UPDATE_INFO);
|
||||
|
||||
add_port_update(stream, PW_CLIENT_NODE_PORT_UPDATE_PARAMS |
|
||||
PW_CLIENT_NODE_PORT_UPDATE_INFO);
|
||||
|
||||
add_async_complete(stream, 0, SPA_RESULT_OK);
|
||||
if (!(impl->flags & PW_STREAM_FLAG_INACTIVE))
|
||||
pw_client_node_proxy_set_active(impl->node_proxy, true);
|
||||
|
|
@ -639,10 +657,22 @@ static void handle_socket(struct pw_stream *stream, int rtreadfd, int rtwritefd)
|
|||
return;
|
||||
}
|
||||
|
||||
static bool
|
||||
handle_node_command(struct pw_stream *stream, uint32_t seq, const struct spa_command *command)
|
||||
static void
|
||||
client_node_set_param(void *data, uint32_t seq, uint32_t id, uint32_t flags,
|
||||
const struct spa_pod_object *param)
|
||||
{
|
||||
struct stream *impl = SPA_CONTAINER_OF(stream, struct stream, this);
|
||||
pw_log_warn("set param not implemented");
|
||||
}
|
||||
|
||||
static void client_node_event(void *data, const struct spa_event *event)
|
||||
{
|
||||
pw_log_warn("unhandled node event %d", SPA_EVENT_TYPE(event));
|
||||
}
|
||||
|
||||
static void client_node_command(void *data, uint32_t seq, const struct spa_command *command)
|
||||
{
|
||||
struct stream *impl = data;
|
||||
struct pw_stream *stream = &impl->this;
|
||||
struct pw_remote *remote = stream->remote;
|
||||
|
||||
if (SPA_COMMAND_TYPE(command) == remote->core->type.command_node.Pause) {
|
||||
|
|
@ -697,18 +727,6 @@ handle_node_command(struct pw_stream *stream, uint32_t seq, const struct spa_com
|
|||
pw_log_warn("unhandled node command %d", SPA_COMMAND_TYPE(command));
|
||||
add_async_complete(stream, seq, SPA_RESULT_NOT_IMPLEMENTED);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
client_node_set_props(void *data, uint32_t seq, const struct spa_props *props)
|
||||
{
|
||||
pw_log_warn("set property not implemented");
|
||||
}
|
||||
|
||||
static void client_node_event(void *data, const struct spa_event *event)
|
||||
{
|
||||
pw_log_warn("unhandled node event %d", SPA_EVENT_TYPE(event));
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -724,45 +742,48 @@ client_node_remove_port(void *data, uint32_t seq, enum spa_direction direction,
|
|||
}
|
||||
|
||||
static void
|
||||
client_node_set_format(void *data,
|
||||
uint32_t seq,
|
||||
enum spa_direction direction,
|
||||
uint32_t port_id, uint32_t flags, const struct spa_format *format)
|
||||
client_node_port_set_param(void *data,
|
||||
uint32_t seq,
|
||||
enum spa_direction direction, uint32_t port_id,
|
||||
uint32_t id, uint32_t flags,
|
||||
const struct spa_pod_object *param)
|
||||
{
|
||||
struct stream *impl = data;
|
||||
struct pw_stream *stream = &impl->this;
|
||||
struct pw_type *t = &stream->remote->core->type;
|
||||
|
||||
pw_log_debug("stream %p: format changed %d", stream, seq);
|
||||
if (id == t->param.idFormat) {
|
||||
pw_log_debug("stream %p: format changed %d", stream, seq);
|
||||
|
||||
if (impl->format)
|
||||
free(impl->format);
|
||||
impl->format = format ? spa_format_copy(format) : NULL;
|
||||
impl->pending_seq = seq;
|
||||
if (impl->format)
|
||||
free(impl->format);
|
||||
if (param) {
|
||||
impl->format = spa_pod_object_copy(param);
|
||||
impl->format->body.id = id;
|
||||
}
|
||||
else
|
||||
impl->format = NULL;
|
||||
|
||||
spa_hook_list_call(&stream->listener_list, struct pw_stream_events, format_changed, impl->format);
|
||||
impl->pending_seq = seq;
|
||||
|
||||
if (format)
|
||||
stream_set_state(stream, PW_STREAM_STATE_READY, NULL);
|
||||
spa_hook_list_call(&stream->listener_list,
|
||||
struct pw_stream_events,
|
||||
format_changed, impl->format);
|
||||
|
||||
if (impl->format)
|
||||
stream_set_state(stream, PW_STREAM_STATE_READY, NULL);
|
||||
else
|
||||
stream_set_state(stream, PW_STREAM_STATE_CONFIGURE, NULL);
|
||||
}
|
||||
else
|
||||
stream_set_state(stream, PW_STREAM_STATE_CONFIGURE, NULL);
|
||||
pw_log_warn("set param not implemented");
|
||||
}
|
||||
|
||||
static void
|
||||
client_node_set_param(void *data,
|
||||
uint32_t seq,
|
||||
enum spa_direction direction,
|
||||
uint32_t port_id,
|
||||
const struct spa_param *param)
|
||||
{
|
||||
pw_log_warn("set param not implemented");
|
||||
}
|
||||
|
||||
static void
|
||||
client_node_add_mem(void *data,
|
||||
enum spa_direction direction,
|
||||
uint32_t port_id,
|
||||
uint32_t mem_id,
|
||||
uint32_t type, int memfd, uint32_t flags, uint32_t offset, uint32_t size)
|
||||
client_node_port_add_mem(void *data,
|
||||
enum spa_direction direction, uint32_t port_id,
|
||||
uint32_t mem_id,
|
||||
uint32_t type, int memfd, uint32_t flags, uint32_t offset, uint32_t size)
|
||||
{
|
||||
struct stream *impl = data;
|
||||
struct pw_stream *stream = &impl->this;
|
||||
|
|
@ -787,10 +808,10 @@ client_node_add_mem(void *data,
|
|||
}
|
||||
|
||||
static void
|
||||
client_node_use_buffers(void *data,
|
||||
uint32_t seq,
|
||||
enum spa_direction direction,
|
||||
uint32_t port_id, uint32_t n_buffers, struct pw_client_node_buffer *buffers)
|
||||
client_node_port_use_buffers(void *data,
|
||||
uint32_t seq,
|
||||
enum spa_direction direction, uint32_t port_id,
|
||||
uint32_t n_buffers, struct pw_client_node_buffer *buffers)
|
||||
{
|
||||
struct stream *impl = data;
|
||||
struct pw_stream *stream = &impl->this;
|
||||
|
|
@ -901,13 +922,6 @@ client_node_use_buffers(void *data,
|
|||
}
|
||||
}
|
||||
|
||||
static void client_node_node_command(void *data, uint32_t seq, const struct spa_command *command)
|
||||
{
|
||||
struct stream *impl = data;
|
||||
struct pw_stream *this = &impl->this;
|
||||
handle_node_command(this, seq, command);
|
||||
}
|
||||
|
||||
static void
|
||||
client_node_port_command(void *data,
|
||||
uint32_t direction,
|
||||
|
|
@ -940,15 +954,14 @@ static void client_node_transport(void *data, uint32_t node_id,
|
|||
static const struct pw_client_node_proxy_events client_node_events = {
|
||||
PW_VERSION_CLIENT_NODE_PROXY_EVENTS,
|
||||
.transport = client_node_transport,
|
||||
.set_props = client_node_set_props,
|
||||
.set_param = client_node_set_param,
|
||||
.event = client_node_event,
|
||||
.command = client_node_command,
|
||||
.add_port = client_node_add_port,
|
||||
.remove_port = client_node_remove_port,
|
||||
.set_format = client_node_set_format,
|
||||
.set_param = client_node_set_param,
|
||||
.add_mem = client_node_add_mem,
|
||||
.use_buffers = client_node_use_buffers,
|
||||
.node_command = client_node_node_command,
|
||||
.port_set_param = client_node_port_set_param,
|
||||
.port_add_mem = client_node_port_add_mem,
|
||||
.port_use_buffers = client_node_port_use_buffers,
|
||||
.port_command = client_node_port_command,
|
||||
};
|
||||
|
||||
|
|
@ -972,21 +985,19 @@ static const struct pw_proxy_events proxy_events = {
|
|||
bool
|
||||
pw_stream_connect(struct pw_stream *stream,
|
||||
enum pw_direction direction,
|
||||
enum pw_stream_mode mode,
|
||||
const char *port_path,
|
||||
enum pw_stream_flags flags,
|
||||
uint32_t n_possible_formats,
|
||||
const struct spa_format **possible_formats)
|
||||
uint32_t n_params,
|
||||
const struct spa_pod_object **params)
|
||||
{
|
||||
struct stream *impl = SPA_CONTAINER_OF(stream, struct stream, this);
|
||||
|
||||
impl->direction =
|
||||
direction == PW_DIRECTION_INPUT ? SPA_DIRECTION_INPUT : SPA_DIRECTION_OUTPUT;
|
||||
impl->port_id = 0;
|
||||
impl->mode = mode;
|
||||
impl->flags = flags;
|
||||
|
||||
set_possible_formats(stream, n_possible_formats, possible_formats);
|
||||
set_init_params(stream, n_params, params);
|
||||
|
||||
stream_set_state(stream, PW_STREAM_STATE_CONNECTING, NULL);
|
||||
|
||||
|
|
@ -1021,7 +1032,9 @@ pw_stream_get_node_id(struct pw_stream *stream)
|
|||
|
||||
void
|
||||
pw_stream_finish_format(struct pw_stream *stream,
|
||||
int res, struct spa_param **params, uint32_t n_params)
|
||||
int res,
|
||||
uint32_t n_params,
|
||||
struct spa_pod_object **params)
|
||||
{
|
||||
struct stream *impl = SPA_CONTAINER_OF(stream, struct stream, this);
|
||||
|
||||
|
|
@ -1030,8 +1043,7 @@ pw_stream_finish_format(struct pw_stream *stream,
|
|||
set_params(stream, n_params, params);
|
||||
|
||||
if (SPA_RESULT_IS_OK(res)) {
|
||||
add_port_update(stream, (n_params ? PW_CLIENT_NODE_PORT_UPDATE_PARAMS : 0) |
|
||||
PW_CLIENT_NODE_PORT_UPDATE_FORMAT);
|
||||
add_port_update(stream, PW_CLIENT_NODE_PORT_UPDATE_PARAMS);
|
||||
|
||||
if (!impl->format) {
|
||||
clear_buffers(stream);
|
||||
|
|
|
|||
|
|
@ -189,9 +189,9 @@ struct pw_stream_events {
|
|||
void (*state_changed) (void *data, enum pw_stream_state old,
|
||||
enum pw_stream_state state, const char *error);
|
||||
/** when the format changed. The listener should call
|
||||
* pw_stream_finish_format() from within this callbaclk or later to complete
|
||||
* the format negotiation */
|
||||
void (*format_changed) (void *data, struct spa_format *format);
|
||||
* pw_stream_finish_format() from within this callback or later to complete
|
||||
* the format negotiation and start the buffer negotiation. */
|
||||
void (*format_changed) (void *data, struct spa_pod_object *format);
|
||||
|
||||
/** when a new buffer was created for this stream */
|
||||
void (*add_buffer) (void *data, uint32_t id);
|
||||
|
|
@ -217,12 +217,6 @@ enum pw_stream_flags {
|
|||
PW_STREAM_FLAG_INACTIVE = (1 << 2), /**< start the stream inactive */
|
||||
};
|
||||
|
||||
/** \enum pw_stream_mode The method for transfering data for a stream \memberof pw_stream */
|
||||
enum pw_stream_mode {
|
||||
PW_STREAM_MODE_BUFFER = 0, /**< data is placed in buffers */
|
||||
PW_STREAM_MODE_RINGBUFFER = 1, /**< a ringbuffer is used to exchange data */
|
||||
};
|
||||
|
||||
/** A time structure \memberof pw_stream */
|
||||
struct pw_time {
|
||||
int64_t now; /**< the monotonic time */
|
||||
|
|
@ -267,12 +261,13 @@ const struct pw_properties *pw_stream_get_properties(struct pw_stream *stream);
|
|||
bool
|
||||
pw_stream_connect(struct pw_stream *stream, /**< a \ref pw_stream */
|
||||
enum pw_direction direction, /**< the stream direction */
|
||||
enum pw_stream_mode mode, /**< a \ref pw_stream_mode */
|
||||
const char *port_path, /**< the port path to connect to or NULL
|
||||
* to let the server choose a port */
|
||||
enum pw_stream_flags flags, /**< stream flags */
|
||||
uint32_t n_possible_formats, /**< number of items in \a possible_formats */
|
||||
const struct spa_format **possible_formats /**< an array with possible accepted formats */);
|
||||
uint32_t n_params, /**< number of items in \a params */
|
||||
const struct spa_pod_object **params /**< an array with params. The params
|
||||
* should ideally contain supported
|
||||
* formats. */);
|
||||
|
||||
/** Get the node ID of the stream. \memberof pw_stream
|
||||
* \return node ID. */
|
||||
|
|
@ -291,8 +286,10 @@ void pw_stream_disconnect(struct pw_stream *stream);
|
|||
void
|
||||
pw_stream_finish_format(struct pw_stream *stream, /**< a \ref pw_stream */
|
||||
int res, /**< a result code */
|
||||
struct spa_param **params, /**< an array of pointers to \ref spa_param */
|
||||
uint32_t n_params /**< number of elements in \a params */);
|
||||
uint32_t n_params, /**< number of elements in \a params */
|
||||
struct spa_pod_object **params /**< an array of params. The params should
|
||||
* ideally contain parameters for doing
|
||||
* buffer allocation. */);
|
||||
|
||||
/** Activate or deactivate the stream \memberof pw_stream */
|
||||
void pw_stream_set_active(struct pw_stream *stream, bool active);
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@ void pw_type_init(struct pw_type *type)
|
|||
type->spa_format = spa_type_map_get_id(type->map, SPA_TYPE__Format);
|
||||
type->spa_props = spa_type_map_get_id(type->map, SPA_TYPE__Props);
|
||||
|
||||
spa_type_param_map(type->map, &type->param);
|
||||
spa_type_meta_map(type->map, &type->meta);
|
||||
spa_type_data_map(type->map, &type->data);
|
||||
spa_type_event_node_map(type->map, &type->event_node);
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@ struct pw_type {
|
|||
uint32_t spa_format;
|
||||
uint32_t spa_props;
|
||||
|
||||
struct spa_type_param param;
|
||||
struct spa_type_meta meta;
|
||||
struct spa_type_data data;
|
||||
struct spa_type_event_node event_node;
|
||||
|
|
|
|||
|
|
@ -54,9 +54,7 @@ pw_spa_pod_copy(const struct spa_pod *pod)
|
|||
return pod ? memcpy(malloc(SPA_POD_SIZE(pod)), pod, SPA_POD_SIZE(pod)) : NULL;
|
||||
}
|
||||
|
||||
#define spa_format_copy(f) ((struct spa_format*)pw_spa_pod_copy(&(f)->pod))
|
||||
#define spa_props_copy(p) ((struct spa_prop*)pw_spa_pod_copy(&(p)->object.pod))
|
||||
#define spa_param_copy(p) ((struct spa_param*)pw_spa_pod_copy(&(p)->object.pod))
|
||||
#define spa_pod_object_copy(p) ((struct spa_pod_object*)pw_spa_pod_copy(&(p)->pod))
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
|
|
|||
|
|
@ -524,20 +524,28 @@ static void info_module(struct proxy_data *pd)
|
|||
static void info_node(struct proxy_data *pd)
|
||||
{
|
||||
struct pw_node_info *info = pd->info;
|
||||
struct pw_type *t = pd->rd->data->t;
|
||||
int i;
|
||||
|
||||
info_global(pd);
|
||||
fprintf(stdout, "%c\tname: \"%s\"\n", MARK_CHANGE(0), info->name);
|
||||
fprintf(stdout, "%c\tinput ports: %u/%u\n", MARK_CHANGE(1), info->n_input_ports, info->max_input_ports);
|
||||
fprintf(stdout, "%c\tinput formats:\n", MARK_CHANGE(2));
|
||||
for (i = 0; i < info->n_input_formats; i++)
|
||||
spa_debug_format(info->input_formats[i]);
|
||||
fprintf(stdout, "%c\tinput params:\n", MARK_CHANGE(2));
|
||||
for (i = 0; i < info->n_input_params; i++) {
|
||||
uint32_t flags = 0;
|
||||
if (info->input_params[i]->body.type == t->spa_format)
|
||||
flags |= SPA_DEBUG_FLAG_FORMAT;
|
||||
spa_debug_pod(&info->input_params[i]->pod, flags);
|
||||
}
|
||||
|
||||
fprintf(stdout, "%c\toutput ports: %u/%u\n", MARK_CHANGE(3), info->n_output_ports, info->max_output_ports);
|
||||
fprintf(stdout, "%c\toutput formats:\n", MARK_CHANGE(4));
|
||||
for (i = 0; i < info->n_output_formats; i++)
|
||||
spa_debug_format(info->output_formats[i]);
|
||||
|
||||
fprintf(stdout, "%c\toutput params:\n", MARK_CHANGE(4));
|
||||
for (i = 0; i < info->n_output_params; i++) {
|
||||
uint32_t flags = 0;
|
||||
if (info->output_params[i]->body.type == t->spa_format)
|
||||
flags |= SPA_DEBUG_FLAG_FORMAT;
|
||||
spa_debug_pod(&info->output_params[i]->pod, flags);
|
||||
}
|
||||
fprintf(stdout, "%c\tstate: \"%s\"", MARK_CHANGE(5), pw_node_state_as_string(info->state));
|
||||
if (info->state == PW_NODE_STATE_ERROR && info->error)
|
||||
fprintf(stdout, " \"%s\"\n", info->error);
|
||||
|
|
@ -579,7 +587,7 @@ static void info_link(struct proxy_data *pd)
|
|||
fprintf(stdout, "%c\tinput-port-id: %u\n", MARK_CHANGE(1), info->input_port_id);
|
||||
fprintf(stdout, "%c\tformat:\n", MARK_CHANGE(2));
|
||||
if (info->format)
|
||||
spa_debug_format(info->format);
|
||||
spa_debug_pod(&info->format->pod, SPA_DEBUG_FLAG_FORMAT);
|
||||
else
|
||||
fprintf(stdout, "\t\tnone\n");
|
||||
print_properties(info->props, MARK_CHANGE(3));
|
||||
|
|
|
|||
|
|
@ -128,6 +128,7 @@ static void node_event_info(void *object, struct pw_node_info *info)
|
|||
{
|
||||
struct proxy_data *data = object;
|
||||
bool print_all, print_mark;
|
||||
struct pw_type *t = pw_core_get_type(data->data->core);
|
||||
|
||||
print_all = true;
|
||||
if (data->info == NULL) {
|
||||
|
|
@ -152,14 +153,22 @@ static void node_event_info(void *object, struct pw_node_info *info)
|
|||
|
||||
printf("%c\tname: \"%s\"\n", MARK_CHANGE(0), info->name);
|
||||
printf("%c\tinput ports: %u/%u\n", MARK_CHANGE(1), info->n_input_ports, info->max_input_ports);
|
||||
printf("%c\tinput formats:\n", MARK_CHANGE(2));
|
||||
for (i = 0; i < info->n_input_formats; i++)
|
||||
spa_debug_format(info->input_formats[i]);
|
||||
printf("%c\tinput params:\n", MARK_CHANGE(2));
|
||||
for (i = 0; i < info->n_input_params; i++) {
|
||||
uint32_t flags = 0;
|
||||
if (info->input_params[i]->body.type == t->spa_format)
|
||||
flags |= SPA_DEBUG_FLAG_FORMAT;
|
||||
spa_debug_pod(&info->input_params[i]->pod, flags);
|
||||
}
|
||||
|
||||
printf("%c\toutput ports: %u/%u\n", MARK_CHANGE(3), info->n_output_ports, info->max_output_ports);
|
||||
printf("%c\toutput formats:\n", MARK_CHANGE(4));
|
||||
for (i = 0; i < info->n_output_formats; i++)
|
||||
spa_debug_format(info->output_formats[i]);
|
||||
printf("%c\toutput params:\n", MARK_CHANGE(4));
|
||||
for (i = 0; i < info->n_output_params; i++) {
|
||||
uint32_t flags = 0;
|
||||
if (info->output_params[i]->body.type == t->spa_format)
|
||||
flags |= SPA_DEBUG_FLAG_FORMAT;
|
||||
spa_debug_pod(&info->output_params[i]->pod, flags);
|
||||
}
|
||||
|
||||
printf("%c\tstate: \"%s\"", MARK_CHANGE(5), pw_node_state_as_string(info->state));
|
||||
if (info->state == PW_NODE_STATE_ERROR && info->error)
|
||||
|
|
@ -274,7 +283,7 @@ static void link_event_info(void *object, struct pw_link_info *info)
|
|||
printf("%c\tinput-port-id: %u\n", MARK_CHANGE(1), info->input_port_id);
|
||||
printf("%c\tformat:\n", MARK_CHANGE(2));
|
||||
if (info->format)
|
||||
spa_debug_format(info->format);
|
||||
spa_debug_pod(&info->format->pod, SPA_DEBUG_FLAG_FORMAT);
|
||||
else
|
||||
printf("\t\tnone\n");
|
||||
print_properties(info->props, MARK_CHANGE(3));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue