mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-06 13:30:01 -05:00
Reorganise SPA tree
Reorganise the SPA includes to make it more extensible later Simplify the naming of the buffer and meta params
This commit is contained in:
parent
58451d626c
commit
caaeaff223
151 changed files with 1353 additions and 964 deletions
|
|
@ -27,10 +27,11 @@
|
|||
#include <libudev.h>
|
||||
#include <asoundlib.h>
|
||||
|
||||
#include <spa/log.h>
|
||||
#include <spa/type-map.h>
|
||||
#include <spa/loop.h>
|
||||
#include <spa/monitor.h>
|
||||
#include <spa/support/log.h>
|
||||
#include <spa/support/type-map.h>
|
||||
#include <spa/support/loop.h>
|
||||
#include <spa/monitor/monitor.h>
|
||||
|
||||
#include <lib/debug.h>
|
||||
|
||||
#define NAME "alsa-monitor"
|
||||
|
|
|
|||
|
|
@ -21,8 +21,9 @@
|
|||
|
||||
#include <asoundlib.h>
|
||||
|
||||
#include <spa/node.h>
|
||||
#include <spa/audio/format.h>
|
||||
#include <spa/node/node.h>
|
||||
#include <spa/param/audio/format.h>
|
||||
|
||||
#include <lib/pod.h>
|
||||
|
||||
#define NAME "alsa-sink"
|
||||
|
|
@ -331,14 +332,14 @@ impl_node_port_enum_params(struct spa_node *node,
|
|||
return SPA_RESULT_ENUM_END;
|
||||
|
||||
param = spa_pod_builder_object(builder,
|
||||
id, t->param_alloc_buffers.Buffers,
|
||||
":", t->param_alloc_buffers.size, "iru", this->props.min_latency * this->frame_size,
|
||||
2, this->props.min_latency * this->frame_size,
|
||||
INT32_MAX,
|
||||
":", t->param_alloc_buffers.stride, "i", 0,
|
||||
":", t->param_alloc_buffers.buffers, "ir", 2,
|
||||
id, t->param_buffers.Buffers,
|
||||
":", t->param_buffers.size, "iru", this->props.min_latency * this->frame_size,
|
||||
2, this->props.min_latency * this->frame_size,
|
||||
INT32_MAX,
|
||||
":", t->param_buffers.stride, "i", 0,
|
||||
":", t->param_buffers.buffers, "ir", 2,
|
||||
2, 2, MAX_BUFFERS,
|
||||
":", t->param_alloc_buffers.align, "i", 16);
|
||||
":", t->param_buffers.align, "i", 16);
|
||||
}
|
||||
else if (id == t->param.idMeta) {
|
||||
if (!this->have_format)
|
||||
|
|
@ -347,22 +348,22 @@ impl_node_port_enum_params(struct spa_node *node,
|
|||
switch (*index) {
|
||||
case 0:
|
||||
param = 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));
|
||||
id, t->param_meta.Meta,
|
||||
":", t->param_meta.type, "I", t->meta.Header,
|
||||
":", t->param_meta.size, "i", sizeof(struct spa_meta_header));
|
||||
break;
|
||||
case 1:
|
||||
param = 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, "iru",
|
||||
id, t->param_meta.Meta,
|
||||
":", t->param_meta.type, "I", t->meta.Ringbuffer,
|
||||
":", t->param_meta.size, "i", sizeof(struct spa_meta_ringbuffer),
|
||||
":", t->param_meta.ringbufferSize, "iru",
|
||||
this->props.max_latency * this->frame_size,
|
||||
2, this->props.min_latency * this->frame_size,
|
||||
this->period_frames * this->frame_size,
|
||||
":", t->param_alloc_meta_enable.ringbufferStride, "i", 0,
|
||||
":", t->param_alloc_meta_enable.ringbufferBlocks, "i", 1,
|
||||
":", t->param_alloc_meta_enable.ringbufferAlign, "i", 16);
|
||||
":", t->param_meta.ringbufferStride, "i", 0,
|
||||
":", t->param_meta.ringbufferBlocks, "i", 1,
|
||||
":", t->param_meta.ringbufferAlign, "i", 16);
|
||||
break;
|
||||
default:
|
||||
return SPA_RESULT_ENUM_END;
|
||||
|
|
|
|||
|
|
@ -21,9 +21,9 @@
|
|||
|
||||
#include <asoundlib.h>
|
||||
|
||||
#include <spa/node.h>
|
||||
#include <spa/list.h>
|
||||
#include <spa/audio/format.h>
|
||||
#include <spa/node/node.h>
|
||||
#include <spa/utils/list.h>
|
||||
#include <spa/param/audio/format.h>
|
||||
|
||||
#include <lib/pod.h>
|
||||
|
||||
|
|
@ -373,12 +373,12 @@ impl_node_port_enum_params(struct spa_node *node,
|
|||
return SPA_RESULT_ENUM_END;
|
||||
|
||||
param = spa_pod_builder_object(builder,
|
||||
id, t->param_alloc_buffers.Buffers,
|
||||
":", t->param_alloc_buffers.size, "i", this->props.min_latency * this->frame_size,
|
||||
":", t->param_alloc_buffers.stride, "i", 0,
|
||||
":", t->param_alloc_buffers.buffers, "ir", 2,
|
||||
2, 1, 32,
|
||||
":", t->param_alloc_buffers.align, "i", 16);
|
||||
id, t->param_buffers.Buffers,
|
||||
":", t->param_buffers.size, "i", this->props.min_latency * this->frame_size,
|
||||
":", t->param_buffers.stride, "i", 0,
|
||||
":", t->param_buffers.buffers, "ir", 2,
|
||||
2, 1, 32,
|
||||
":", t->param_buffers.align, "i", 16);
|
||||
}
|
||||
else if (id == t->param.idMeta) {
|
||||
if (!this->have_format)
|
||||
|
|
@ -387,9 +387,9 @@ impl_node_port_enum_params(struct spa_node *node,
|
|||
switch (*index) {
|
||||
case 0:
|
||||
param = 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));
|
||||
id, t->param_meta.Meta,
|
||||
":", t->param_meta.type, "I", t->meta.Header,
|
||||
":", t->param_meta.size, "i", sizeof(struct spa_meta_header));
|
||||
break;
|
||||
default:
|
||||
return SPA_RESULT_ENUM_END;
|
||||
|
|
|
|||
|
|
@ -28,15 +28,17 @@ extern "C" {
|
|||
|
||||
#include <asoundlib.h>
|
||||
|
||||
#include <spa/type-map.h>
|
||||
#include <spa/clock.h>
|
||||
#include <spa/log.h>
|
||||
#include <spa/list.h>
|
||||
#include <spa/node.h>
|
||||
#include <spa/param-alloc.h>
|
||||
#include <spa/loop.h>
|
||||
#include <spa/ringbuffer.h>
|
||||
#include <spa/audio/format-utils.h>
|
||||
#include <spa/support/type-map.h>
|
||||
#include <spa/support/loop.h>
|
||||
#include <spa/support/log.h>
|
||||
#include <spa/utils/list.h>
|
||||
#include <spa/utils/ringbuffer.h>
|
||||
|
||||
#include <spa/clock/clock.h>
|
||||
#include <spa/node/node.h>
|
||||
#include <spa/param/buffers.h>
|
||||
#include <spa/param/meta.h>
|
||||
#include <spa/param/audio/format-utils.h>
|
||||
|
||||
struct props {
|
||||
char device[64];
|
||||
|
|
@ -72,12 +74,12 @@ struct type {
|
|||
struct spa_type_media_type media_type;
|
||||
struct spa_type_media_subtype media_subtype;
|
||||
struct spa_type_media_subtype_audio media_subtype_audio;
|
||||
struct spa_type_format_audio format_audio;
|
||||
struct spa_type_audio_format audio_format;
|
||||
struct spa_type_event_node event_node;
|
||||
struct spa_type_command_node command_node;
|
||||
struct spa_type_param_alloc_buffers param_alloc_buffers;
|
||||
struct spa_type_param_alloc_meta_enable param_alloc_meta_enable;
|
||||
struct spa_type_format_audio format_audio;
|
||||
struct spa_type_param_buffers param_buffers;
|
||||
struct spa_type_param_meta param_meta;
|
||||
};
|
||||
|
||||
static inline void init_type(struct type *type, struct spa_type_map *map)
|
||||
|
|
@ -98,12 +100,12 @@ static inline void init_type(struct type *type, struct spa_type_map *map)
|
|||
spa_type_media_type_map(map, &type->media_type);
|
||||
spa_type_media_subtype_map(map, &type->media_subtype);
|
||||
spa_type_media_subtype_audio_map(map, &type->media_subtype_audio);
|
||||
spa_type_format_audio_map(map, &type->format_audio);
|
||||
spa_type_audio_format_map(map, &type->audio_format);
|
||||
spa_type_event_node_map(map, &type->event_node);
|
||||
spa_type_command_node_map(map, &type->command_node);
|
||||
spa_type_param_alloc_buffers_map(map, &type->param_alloc_buffers);
|
||||
spa_type_param_alloc_meta_enable_map(map, &type->param_alloc_meta_enable);
|
||||
spa_type_format_audio_map(map, &type->format_audio);
|
||||
spa_type_param_buffers_map(map, &type->param_buffers);
|
||||
spa_type_param_meta_map(map, &type->param_meta);
|
||||
}
|
||||
|
||||
struct state {
|
||||
|
|
|
|||
|
|
@ -17,8 +17,7 @@
|
|||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include <spa/plugin.h>
|
||||
#include <spa/node.h>
|
||||
#include <spa/support/plugin.h>
|
||||
|
||||
extern const struct spa_handle_factory spa_alsa_source_factory;
|
||||
extern const struct spa_handle_factory spa_alsa_sink_factory;
|
||||
|
|
|
|||
|
|
@ -20,12 +20,13 @@
|
|||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <spa/log.h>
|
||||
#include <spa/list.h>
|
||||
#include <spa/type-map.h>
|
||||
#include <spa/node.h>
|
||||
#include <spa/audio/format-utils.h>
|
||||
#include <spa/param-alloc.h>
|
||||
#include <spa/support/log.h>
|
||||
#include <spa/support/type-map.h>
|
||||
#include <spa/utils/list.h>
|
||||
#include <spa/node/node.h>
|
||||
#include <spa/param/audio/format-utils.h>
|
||||
#include <spa/param/buffers.h>
|
||||
#include <spa/param/meta.h>
|
||||
|
||||
#include <lib/pod.h>
|
||||
|
||||
|
|
@ -76,8 +77,8 @@ struct type {
|
|||
struct spa_type_command_node command_node;
|
||||
struct spa_type_meta meta;
|
||||
struct spa_type_data data;
|
||||
struct spa_type_param_alloc_buffers param_alloc_buffers;
|
||||
struct spa_type_param_alloc_meta_enable param_alloc_meta_enable;
|
||||
struct spa_type_param_buffers param_buffers;
|
||||
struct spa_type_param_meta param_meta;
|
||||
};
|
||||
|
||||
static inline void init_type(struct type *type, struct spa_type_map *map)
|
||||
|
|
@ -92,8 +93,8 @@ static inline void init_type(struct type *type, struct spa_type_map *map)
|
|||
spa_type_command_node_map(map, &type->command_node);
|
||||
spa_type_meta_map(map, &type->meta);
|
||||
spa_type_data_map(map, &type->data);
|
||||
spa_type_param_alloc_buffers_map(map, &type->param_alloc_buffers);
|
||||
spa_type_param_alloc_meta_enable_map(map, &type->param_alloc_meta_enable);
|
||||
spa_type_param_buffers_map(map, &type->param_buffers);
|
||||
spa_type_param_meta_map(map, &type->param_meta);
|
||||
}
|
||||
|
||||
struct impl {
|
||||
|
|
@ -430,14 +431,14 @@ impl_node_port_enum_params(struct spa_node *node,
|
|||
return SPA_RESULT_ENUM_END;
|
||||
|
||||
param = spa_pod_builder_object(builder,
|
||||
id, t->param_alloc_buffers.Buffers,
|
||||
":", t->param_alloc_buffers.size, "iru", 1024 * this->bpf,
|
||||
id, t->param_buffers.Buffers,
|
||||
":", t->param_buffers.size, "iru", 1024 * this->bpf,
|
||||
2, 16 * this->bpf,
|
||||
INT32_MAX / this->bpf,
|
||||
":", t->param_alloc_buffers.stride, "i", 0,
|
||||
":", t->param_alloc_buffers.buffers, "iru", 2,
|
||||
":", t->param_buffers.stride, "i", 0,
|
||||
":", t->param_buffers.buffers, "iru", 2,
|
||||
2, 2, MAX_BUFFERS,
|
||||
":", t->param_alloc_buffers.align, "i", 16);
|
||||
":", t->param_buffers.align, "i", 16);
|
||||
}
|
||||
else if (id == t->param.idMeta) {
|
||||
if (!port->have_format)
|
||||
|
|
@ -446,20 +447,20 @@ impl_node_port_enum_params(struct spa_node *node,
|
|||
switch (*index) {
|
||||
case 0:
|
||||
param = 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));
|
||||
id, t->param_meta.Meta,
|
||||
":", t->param_meta.type, "I", t->meta.Header,
|
||||
":", t->param_meta.size, "i", sizeof(struct spa_meta_header));
|
||||
break;
|
||||
case 1:
|
||||
param = 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, "iru", 1024 * this->bpf,
|
||||
id, t->param_meta.Meta,
|
||||
":", t->param_meta.type, "I", t->meta.Ringbuffer,
|
||||
":", t->param_meta.size, "i", sizeof(struct spa_meta_ringbuffer),
|
||||
":", t->param_meta.ringbufferSize, "iru", 1024 * this->bpf,
|
||||
2, 16 * this->bpf, INT32_MAX / this->bpf,
|
||||
":", t->param_alloc_meta_enable.ringbufferStride, "i", 0,
|
||||
":", t->param_alloc_meta_enable.ringbufferBlocks, "i", 1,
|
||||
":", t->param_alloc_meta_enable.ringbufferAlign, "i", 16);
|
||||
":", t->param_meta.ringbufferStride, "i", 0,
|
||||
":", t->param_meta.ringbufferBlocks, "i", 1,
|
||||
":", t->param_meta.ringbufferAlign, "i", 16);
|
||||
break;
|
||||
default:
|
||||
return SPA_RESULT_ENUM_END;
|
||||
|
|
|
|||
|
|
@ -19,7 +19,8 @@
|
|||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <spa/defs.h>
|
||||
|
||||
#include <spa/utils/defs.h>
|
||||
|
||||
typedef void (*mix_func_t) (void *dst, const void *src, int n_bytes);
|
||||
typedef void (*mix_scale_func_t) (void *dst, const void *src, const void *scale, int n_bytes);
|
||||
|
|
|
|||
|
|
@ -17,8 +17,7 @@
|
|||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include <spa/plugin.h>
|
||||
#include <spa/node.h>
|
||||
#include <spa/support/plugin.h>
|
||||
|
||||
extern const struct spa_handle_factory spa_audiomixer_factory;
|
||||
|
||||
|
|
|
|||
|
|
@ -23,14 +23,15 @@
|
|||
#include <stdio.h>
|
||||
#include <sys/timerfd.h>
|
||||
|
||||
#include <spa/type-map.h>
|
||||
#include <spa/clock.h>
|
||||
#include <spa/log.h>
|
||||
#include <spa/loop.h>
|
||||
#include <spa/node.h>
|
||||
#include <spa/param-alloc.h>
|
||||
#include <spa/list.h>
|
||||
#include <spa/audio/format-utils.h>
|
||||
#include <spa/support/type-map.h>
|
||||
#include <spa/support/log.h>
|
||||
#include <spa/support/loop.h>
|
||||
#include <spa/utils/list.h>
|
||||
#include <spa/clock/clock.h>
|
||||
#include <spa/node/node.h>
|
||||
#include <spa/param/audio/format-utils.h>
|
||||
#include <spa/param/buffers.h>
|
||||
#include <spa/param/meta.h>
|
||||
|
||||
#include <lib/pod.h>
|
||||
|
||||
|
|
@ -60,8 +61,8 @@ struct type {
|
|||
struct spa_type_audio_format audio_format;
|
||||
struct spa_type_event_node event_node;
|
||||
struct spa_type_command_node command_node;
|
||||
struct spa_type_param_alloc_buffers param_alloc_buffers;
|
||||
struct spa_type_param_alloc_meta_enable param_alloc_meta_enable;
|
||||
struct spa_type_param_buffers param_buffers;
|
||||
struct spa_type_param_meta param_meta;
|
||||
};
|
||||
|
||||
static inline void init_type(struct type *type, struct spa_type_map *map)
|
||||
|
|
@ -85,8 +86,8 @@ static inline void init_type(struct type *type, struct spa_type_map *map)
|
|||
spa_type_audio_format_map(map, &type->audio_format);
|
||||
spa_type_event_node_map(map, &type->event_node);
|
||||
spa_type_command_node_map(map, &type->command_node);
|
||||
spa_type_param_alloc_buffers_map(map, &type->param_alloc_buffers);
|
||||
spa_type_param_alloc_meta_enable_map(map, &type->param_alloc_meta_enable);
|
||||
spa_type_param_buffers_map(map, &type->param_buffers);
|
||||
spa_type_param_meta_map(map, &type->param_meta);
|
||||
}
|
||||
|
||||
struct props {
|
||||
|
|
@ -621,14 +622,14 @@ impl_node_port_enum_params(struct spa_node *node,
|
|||
return SPA_RESULT_ENUM_END;
|
||||
|
||||
param = spa_pod_builder_object(builder,
|
||||
id, t->param_alloc_buffers.Buffers,
|
||||
":", t->param_alloc_buffers.size, "iru", 1024 * this->bpf,
|
||||
id, t->param_buffers.Buffers,
|
||||
":", t->param_buffers.size, "iru", 1024 * this->bpf,
|
||||
2, 16 * this->bpf,
|
||||
INT32_MAX / this->bpf,
|
||||
":", t->param_alloc_buffers.stride, "i", 0,
|
||||
":", t->param_alloc_buffers.buffers, "iru", 2,
|
||||
":", t->param_buffers.stride, "i", 0,
|
||||
":", t->param_buffers.buffers, "iru", 2,
|
||||
2, 1, 32,
|
||||
":", t->param_alloc_buffers.align, "i", 16);
|
||||
":", t->param_buffers.align, "i", 16);
|
||||
}
|
||||
else if (id == t->param.idMeta) {
|
||||
if (!this->have_format)
|
||||
|
|
@ -637,20 +638,20 @@ impl_node_port_enum_params(struct spa_node *node,
|
|||
switch (*index) {
|
||||
case 0:
|
||||
param = 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));
|
||||
id, t->param_meta.Meta,
|
||||
":", t->param_meta.type, "I", t->meta.Header,
|
||||
":", t->param_meta.size, "i", sizeof(struct spa_meta_header));
|
||||
break;
|
||||
case 1:
|
||||
param = 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", 5512 * this->bpf,
|
||||
id, t->param_meta.Meta,
|
||||
":", t->param_meta.type, "I", t->meta.Ringbuffer,
|
||||
":", t->param_meta.size, "i", sizeof(struct spa_meta_ringbuffer),
|
||||
":", t->param_meta.ringbufferSize, "ir", 5512 * this->bpf,
|
||||
2, 16 * this->bpf, INT32_MAX / this->bpf,
|
||||
":", t->param_alloc_meta_enable.ringbufferStride, "i", 0,
|
||||
":", t->param_alloc_meta_enable.ringbufferBlocks, "i", 1,
|
||||
":", t->param_alloc_meta_enable.ringbufferAlign, "i", 16);
|
||||
":", t->param_meta.ringbufferStride, "i", 0,
|
||||
":", t->param_meta.ringbufferBlocks, "i", 1,
|
||||
":", t->param_meta.ringbufferAlign, "i", 16);
|
||||
break;
|
||||
default:
|
||||
return SPA_RESULT_ENUM_END;
|
||||
|
|
|
|||
|
|
@ -17,8 +17,7 @@
|
|||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include <spa/plugin.h>
|
||||
#include <spa/node.h>
|
||||
#include <spa/support/plugin.h>
|
||||
|
||||
extern const struct spa_handle_factory spa_audiotestsrc_factory;
|
||||
|
||||
|
|
|
|||
|
|
@ -22,10 +22,11 @@
|
|||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <spa/type-map.h>
|
||||
#include <spa/log.h>
|
||||
#include <spa/node.h>
|
||||
#include <spa/video/format-utils.h>
|
||||
#include <spa/support/type-map.h>
|
||||
#include <spa/support/log.h>
|
||||
#include <spa/node/node.h>
|
||||
#include <spa/param/video/format-utils.h>
|
||||
|
||||
#include <lib/pod.h>
|
||||
|
||||
#define IS_VALID_PORT(this,d,id) ((id) == 0)
|
||||
|
|
|
|||
|
|
@ -22,10 +22,10 @@
|
|||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <spa/log.h>
|
||||
#include <spa/type-map.h>
|
||||
#include <spa/node.h>
|
||||
#include <spa/video/format-utils.h>
|
||||
#include <spa/support/log.h>
|
||||
#include <spa/support/type-map.h>
|
||||
#include <spa/node/node.h>
|
||||
#include <spa/param/video/format-utils.h>
|
||||
|
||||
#include <lib/pod.h>
|
||||
|
||||
|
|
|
|||
|
|
@ -19,8 +19,8 @@
|
|||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <spa/plugin.h>
|
||||
#include <spa/node.h>
|
||||
#include <spa/support/plugin.h>
|
||||
#include <spa/node/node.h>
|
||||
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libavformat/avformat.h>
|
||||
|
|
|
|||
|
|
@ -24,14 +24,11 @@
|
|||
#include <stdio.h>
|
||||
#include <sys/eventfd.h>
|
||||
|
||||
#include <spa/type-map.h>
|
||||
#include <spa/clock.h>
|
||||
#include <spa/log.h>
|
||||
#include <spa/loop.h>
|
||||
#include <spa/node.h>
|
||||
#include <spa/param-alloc.h>
|
||||
#include <spa/list.h>
|
||||
#include <lib/pod.h>
|
||||
#include <spa/support/type-map.h>
|
||||
#include <spa/support/log.h>
|
||||
#include <spa/support/loop.h>
|
||||
#include <spa/support/plugin.h>
|
||||
#include <spa/utils/ringbuffer.h>
|
||||
|
||||
#define NAME "logger"
|
||||
|
||||
|
|
|
|||
|
|
@ -29,11 +29,12 @@
|
|||
#include <sys/signalfd.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include <spa/loop.h>
|
||||
#include <spa/list.h>
|
||||
#include <spa/log.h>
|
||||
#include <spa/type-map.h>
|
||||
#include <spa/ringbuffer.h>
|
||||
#include <spa/support/loop.h>
|
||||
#include <spa/support/log.h>
|
||||
#include <spa/support/type-map.h>
|
||||
#include <spa/support/plugin.h>
|
||||
#include <spa/utils/list.h>
|
||||
#include <spa/utils/ringbuffer.h>
|
||||
|
||||
#define NAME "loop"
|
||||
|
||||
|
|
|
|||
|
|
@ -24,13 +24,8 @@
|
|||
#include <stdio.h>
|
||||
#include <sys/eventfd.h>
|
||||
|
||||
#include <spa/type-map.h>
|
||||
#include <spa/clock.h>
|
||||
#include <spa/log.h>
|
||||
#include <spa/loop.h>
|
||||
#include <spa/node.h>
|
||||
#include <spa/param-alloc.h>
|
||||
#include <spa/list.h>
|
||||
#include <spa/support/type-map.h>
|
||||
#include <spa/support/plugin.h>
|
||||
|
||||
#define NAME "mapper"
|
||||
|
||||
|
|
|
|||
|
|
@ -19,8 +19,7 @@
|
|||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <spa/plugin.h>
|
||||
#include <spa/node.h>
|
||||
#include <spa/support/plugin.h>
|
||||
|
||||
#define MAX_FACTORIES 16
|
||||
|
||||
|
|
|
|||
|
|
@ -23,13 +23,17 @@
|
|||
#include <stdio.h>
|
||||
#include <sys/timerfd.h>
|
||||
|
||||
#include <spa/type-map.h>
|
||||
#include <spa/clock.h>
|
||||
#include <spa/log.h>
|
||||
#include <spa/loop.h>
|
||||
#include <spa/node.h>
|
||||
#include <spa/param-alloc.h>
|
||||
#include <spa/list.h>
|
||||
#include <spa/support/type-map.h>
|
||||
#include <spa/support/log.h>
|
||||
#include <spa/support/loop.h>
|
||||
#include <spa/utils/list.h>
|
||||
#include <spa/clock/clock.h>
|
||||
#include <spa/node/node.h>
|
||||
#include <spa/param/buffers.h>
|
||||
#include <spa/param/meta.h>
|
||||
#include <spa/param/format.h>
|
||||
#include <spa/pod/parser.h>
|
||||
|
||||
#include <lib/pod.h>
|
||||
|
||||
#define NAME "fakesink"
|
||||
|
|
@ -45,8 +49,8 @@ struct type {
|
|||
struct spa_type_data data;
|
||||
struct spa_type_event_node event_node;
|
||||
struct spa_type_command_node command_node;
|
||||
struct spa_type_param_alloc_buffers param_alloc_buffers;
|
||||
struct spa_type_param_alloc_meta_enable param_alloc_meta_enable;
|
||||
struct spa_type_param_buffers param_buffers;
|
||||
struct spa_type_param_meta param_meta;
|
||||
};
|
||||
|
||||
static inline void init_type(struct type *type, struct spa_type_map *map)
|
||||
|
|
@ -61,8 +65,8 @@ static inline void init_type(struct type *type, struct spa_type_map *map)
|
|||
spa_type_data_map(map, &type->data);
|
||||
spa_type_event_node_map(map, &type->event_node);
|
||||
spa_type_command_node_map(map, &type->command_node);
|
||||
spa_type_param_alloc_buffers_map(map, &type->param_alloc_buffers);
|
||||
spa_type_param_alloc_meta_enable_map(map, &type->param_alloc_meta_enable);
|
||||
spa_type_param_buffers_map(map, &type->param_buffers);
|
||||
spa_type_param_meta_map(map, &type->param_meta);
|
||||
}
|
||||
|
||||
struct props {
|
||||
|
|
@ -506,20 +510,20 @@ impl_node_port_enum_params(struct spa_node *node,
|
|||
return SPA_RESULT_ENUM_END;
|
||||
|
||||
param = spa_pod_builder_object(builder,
|
||||
id, t->param_alloc_buffers.Buffers,
|
||||
":", t->param_alloc_buffers.size, "i", 128,
|
||||
":", t->param_alloc_buffers.stride, "i", 1,
|
||||
":", t->param_alloc_buffers.buffers, "ir", 2,
|
||||
id, t->param_buffers.Buffers,
|
||||
":", t->param_buffers.size, "i", 128,
|
||||
":", t->param_buffers.stride, "i", 1,
|
||||
":", t->param_buffers.buffers, "ir", 2,
|
||||
2, 1, 32,
|
||||
":", t->param_alloc_buffers.align, "i", 16);
|
||||
":", t->param_buffers.align, "i", 16);
|
||||
}
|
||||
else if (id == t->param.idMeta) {
|
||||
switch (*index) {
|
||||
case 0:
|
||||
param = 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));
|
||||
id, t->param_meta.Meta,
|
||||
":", t->param_meta.type, "I", t->meta.Header,
|
||||
":", t->param_meta.size, "i", sizeof(struct spa_meta_header));
|
||||
break;
|
||||
default:
|
||||
return SPA_RESULT_ENUM_END;
|
||||
|
|
|
|||
|
|
@ -23,13 +23,16 @@
|
|||
#include <stdio.h>
|
||||
#include <sys/timerfd.h>
|
||||
|
||||
#include <spa/type-map.h>
|
||||
#include <spa/clock.h>
|
||||
#include <spa/log.h>
|
||||
#include <spa/loop.h>
|
||||
#include <spa/node.h>
|
||||
#include <spa/param-alloc.h>
|
||||
#include <spa/list.h>
|
||||
#include <spa/support/type-map.h>
|
||||
#include <spa/support/log.h>
|
||||
#include <spa/support/loop.h>
|
||||
#include <spa/utils/list.h>
|
||||
#include <spa/clock/clock.h>
|
||||
#include <spa/node/node.h>
|
||||
#include <spa/param/buffers.h>
|
||||
#include <spa/param/meta.h>
|
||||
#include <spa/param/format.h>
|
||||
#include <spa/pod/parser.h>
|
||||
|
||||
#include <lib/pod.h>
|
||||
|
||||
|
|
@ -47,8 +50,8 @@ struct type {
|
|||
struct spa_type_data data;
|
||||
struct spa_type_event_node event_node;
|
||||
struct spa_type_command_node command_node;
|
||||
struct spa_type_param_alloc_buffers param_alloc_buffers;
|
||||
struct spa_type_param_alloc_meta_enable param_alloc_meta_enable;
|
||||
struct spa_type_param_buffers param_buffers;
|
||||
struct spa_type_param_meta param_meta;
|
||||
};
|
||||
|
||||
static inline void init_type(struct type *type, struct spa_type_map *map)
|
||||
|
|
@ -64,8 +67,8 @@ static inline void init_type(struct type *type, struct spa_type_map *map)
|
|||
spa_type_data_map(map, &type->data);
|
||||
spa_type_event_node_map(map, &type->event_node);
|
||||
spa_type_command_node_map(map, &type->command_node);
|
||||
spa_type_param_alloc_buffers_map(map, &type->param_alloc_buffers);
|
||||
spa_type_param_alloc_meta_enable_map(map, &type->param_alloc_meta_enable);
|
||||
spa_type_param_buffers_map(map, &type->param_buffers);
|
||||
spa_type_param_meta_map(map, &type->param_meta);
|
||||
}
|
||||
|
||||
struct props {
|
||||
|
|
@ -521,20 +524,20 @@ impl_node_port_enum_params(struct spa_node *node,
|
|||
return SPA_RESULT_ENUM_END;
|
||||
|
||||
param = spa_pod_builder_object(builder,
|
||||
id, t->param_alloc_buffers.Buffers,
|
||||
":", t->param_alloc_buffers.size, "i", 128,
|
||||
":", t->param_alloc_buffers.stride, "i", 1,
|
||||
":", t->param_alloc_buffers.buffers, "ir", 32,
|
||||
id, t->param_buffers.Buffers,
|
||||
":", t->param_buffers.size, "i", 128,
|
||||
":", t->param_buffers.stride, "i", 1,
|
||||
":", t->param_buffers.buffers, "ir", 32,
|
||||
2, 2, 32,
|
||||
":", t->param_alloc_buffers.align, "i", 16);
|
||||
":", t->param_buffers.align, "i", 16);
|
||||
}
|
||||
else if (id == t->param.idMeta) {
|
||||
switch (*index) {
|
||||
case 0:
|
||||
param = 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));
|
||||
id, t->param_meta.Meta,
|
||||
":", t->param_meta.type, "I", t->meta.Header,
|
||||
":", t->param_meta.size, "i", sizeof(struct spa_meta_header));
|
||||
break;
|
||||
default:
|
||||
return SPA_RESULT_ENUM_END;
|
||||
|
|
|
|||
|
|
@ -17,8 +17,7 @@
|
|||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include <spa/plugin.h>
|
||||
#include <spa/node.h>
|
||||
#include <spa/support/plugin.h>
|
||||
|
||||
extern const struct spa_handle_factory spa_fakesrc_factory;
|
||||
extern const struct spa_handle_factory spa_fakesink_factory;
|
||||
|
|
|
|||
|
|
@ -25,10 +25,11 @@
|
|||
|
||||
#include <libudev.h>
|
||||
|
||||
#include <spa/log.h>
|
||||
#include <spa/type-map.h>
|
||||
#include <spa/loop.h>
|
||||
#include <spa/monitor.h>
|
||||
#include <spa/support/log.h>
|
||||
#include <spa/support/type-map.h>
|
||||
#include <spa/support/loop.h>
|
||||
#include <spa/monitor/monitor.h>
|
||||
|
||||
#include <lib/debug.h>
|
||||
|
||||
#define NAME "v4l2-monitor"
|
||||
|
|
|
|||
|
|
@ -24,14 +24,15 @@
|
|||
|
||||
#include <linux/videodev2.h>
|
||||
|
||||
#include <spa/node.h>
|
||||
#include <spa/video/format-utils.h>
|
||||
#include <spa/clock.h>
|
||||
#include <spa/list.h>
|
||||
#include <spa/log.h>
|
||||
#include <spa/loop.h>
|
||||
#include <spa/param-alloc.h>
|
||||
#include <spa/type-map.h>
|
||||
#include <spa/support/type-map.h>
|
||||
#include <spa/support/log.h>
|
||||
#include <spa/support/loop.h>
|
||||
#include <spa/utils/list.h>
|
||||
#include <spa/clock/clock.h>
|
||||
#include <spa/node/node.h>
|
||||
#include <spa/param/video/format-utils.h>
|
||||
#include <spa/param/buffers.h>
|
||||
#include <spa/param/meta.h>
|
||||
|
||||
#include <lib/debug.h>
|
||||
#include <lib/pod.h>
|
||||
|
|
@ -77,8 +78,8 @@ struct type {
|
|||
struct spa_type_video_format video_format;
|
||||
struct spa_type_event_node event_node;
|
||||
struct spa_type_command_node command_node;
|
||||
struct spa_type_param_alloc_buffers param_alloc_buffers;
|
||||
struct spa_type_param_alloc_meta_enable param_alloc_meta_enable;
|
||||
struct spa_type_param_buffers param_buffers;
|
||||
struct spa_type_param_meta param_meta;
|
||||
struct spa_type_meta meta;
|
||||
struct spa_type_data data;
|
||||
};
|
||||
|
|
@ -100,8 +101,8 @@ static inline void init_type(struct type *type, struct spa_type_map *map)
|
|||
spa_type_video_format_map(map, &type->video_format);
|
||||
spa_type_event_node_map(map, &type->event_node);
|
||||
spa_type_command_node_map(map, &type->command_node);
|
||||
spa_type_param_alloc_buffers_map(map, &type->param_alloc_buffers);
|
||||
spa_type_param_alloc_meta_enable_map(map, &type->param_alloc_meta_enable);
|
||||
spa_type_param_buffers_map(map, &type->param_buffers);
|
||||
spa_type_param_meta_map(map, &type->param_meta);
|
||||
spa_type_meta_map(map, &type->meta);
|
||||
spa_type_data_map(map, &type->data);
|
||||
}
|
||||
|
|
@ -564,20 +565,20 @@ static int impl_node_port_enum_params(struct spa_node *node,
|
|||
return SPA_RESULT_ENUM_END;
|
||||
|
||||
param = spa_pod_builder_object(builder,
|
||||
id, t->param_alloc_buffers.Buffers,
|
||||
":", t->param_alloc_buffers.size, "i", port->fmt.fmt.pix.sizeimage,
|
||||
":", t->param_alloc_buffers.stride, "i", port->fmt.fmt.pix.bytesperline,
|
||||
":", t->param_alloc_buffers.buffers, "iru", MAX_BUFFERS,
|
||||
id, t->param_buffers.Buffers,
|
||||
":", t->param_buffers.size, "i", port->fmt.fmt.pix.sizeimage,
|
||||
":", t->param_buffers.stride, "i", port->fmt.fmt.pix.bytesperline,
|
||||
":", t->param_buffers.buffers, "iru", MAX_BUFFERS,
|
||||
2, 2, MAX_BUFFERS,
|
||||
":", t->param_alloc_buffers.align, "i", 16);
|
||||
":", t->param_buffers.align, "i", 16);
|
||||
}
|
||||
else if (id == t->param.idMeta) {
|
||||
switch (*index) {
|
||||
case 0:
|
||||
param = 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));
|
||||
id, t->param_meta.Meta,
|
||||
":", t->param_meta.type, "I", t->meta.Header,
|
||||
":", t->param_meta.size, "i", sizeof(struct spa_meta_header));
|
||||
break;
|
||||
default:
|
||||
return SPA_RESULT_ENUM_END;
|
||||
|
|
|
|||
|
|
@ -17,8 +17,7 @@
|
|||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include <spa/plugin.h>
|
||||
#include <spa/node.h>
|
||||
#include <spa/support/plugin.h>
|
||||
|
||||
extern const struct spa_handle_factory spa_v4l2_source_factory;
|
||||
extern const struct spa_handle_factory spa_v4l2_monitor_factory;
|
||||
|
|
|
|||
|
|
@ -17,8 +17,7 @@
|
|||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include <spa/plugin.h>
|
||||
#include <spa/node.h>
|
||||
#include <spa/support/plugin.h>
|
||||
|
||||
extern const struct spa_handle_factory spa_videotestsrc_factory;
|
||||
|
||||
|
|
|
|||
|
|
@ -24,14 +24,15 @@
|
|||
#include <stdio.h>
|
||||
#include <sys/timerfd.h>
|
||||
|
||||
#include <spa/type-map.h>
|
||||
#include <spa/clock.h>
|
||||
#include <spa/log.h>
|
||||
#include <spa/loop.h>
|
||||
#include <spa/node.h>
|
||||
#include <spa/param-alloc.h>
|
||||
#include <spa/list.h>
|
||||
#include <spa/video/format-utils.h>
|
||||
#include <spa/support/type-map.h>
|
||||
#include <spa/support/log.h>
|
||||
#include <spa/support/loop.h>
|
||||
#include <spa/utils/list.h>
|
||||
#include <spa/clock/clock.h>
|
||||
#include <spa/node/node.h>
|
||||
#include <spa/param/video/format-utils.h>
|
||||
#include <spa/param/buffers.h>
|
||||
#include <spa/param/meta.h>
|
||||
|
||||
#include <lib/pod.h>
|
||||
|
||||
|
|
@ -58,8 +59,8 @@ struct type {
|
|||
struct spa_type_video_format video_format;
|
||||
struct spa_type_event_node event_node;
|
||||
struct spa_type_command_node command_node;
|
||||
struct spa_type_param_alloc_buffers param_alloc_buffers;
|
||||
struct spa_type_param_alloc_meta_enable param_alloc_meta_enable;
|
||||
struct spa_type_param_buffers param_buffers;
|
||||
struct spa_type_param_meta param_meta;
|
||||
};
|
||||
|
||||
static inline void init_type(struct type *type, struct spa_type_map *map)
|
||||
|
|
@ -81,8 +82,8 @@ static inline void init_type(struct type *type, struct spa_type_map *map)
|
|||
spa_type_video_format_map(map, &type->video_format);
|
||||
spa_type_event_node_map(map, &type->event_node);
|
||||
spa_type_command_node_map(map, &type->command_node);
|
||||
spa_type_param_alloc_buffers_map(map, &type->param_alloc_buffers);
|
||||
spa_type_param_alloc_meta_enable_map(map, &type->param_alloc_meta_enable);
|
||||
spa_type_param_buffers_map(map, &type->param_buffers);
|
||||
spa_type_param_meta_map(map, &type->param_meta);
|
||||
}
|
||||
|
||||
struct props {
|
||||
|
|
@ -567,12 +568,12 @@ impl_node_port_enum_params(struct spa_node *node,
|
|||
return SPA_RESULT_ENUM_END;
|
||||
|
||||
param = spa_pod_builder_object(builder,
|
||||
id, t->param_alloc_buffers.Buffers,
|
||||
":", t->param_alloc_buffers.size, "i", this->stride * raw_info->size.height,
|
||||
":", t->param_alloc_buffers.stride, "i", this->stride,
|
||||
":", t->param_alloc_buffers.buffers, "ir", 2,
|
||||
id, t->param_buffers.Buffers,
|
||||
":", t->param_buffers.size, "i", this->stride * raw_info->size.height,
|
||||
":", t->param_buffers.stride, "i", this->stride,
|
||||
":", t->param_buffers.buffers, "ir", 2,
|
||||
2, 1, 32,
|
||||
":", t->param_alloc_buffers.align, "i", 16);
|
||||
":", t->param_buffers.align, "i", 16);
|
||||
}
|
||||
else if (id == t->param.idMeta) {
|
||||
if (!this->have_format)
|
||||
|
|
@ -581,9 +582,9 @@ impl_node_port_enum_params(struct spa_node *node,
|
|||
switch (*index) {
|
||||
case 0:
|
||||
param = 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));
|
||||
id, t->param_meta.Meta,
|
||||
":", t->param_meta.type, "I", t->meta.Header,
|
||||
":", t->param_meta.size, "i", sizeof(struct spa_meta_header));
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -17,8 +17,7 @@
|
|||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include <spa/plugin.h>
|
||||
#include <spa/node.h>
|
||||
#include <spa/support/plugin.h>
|
||||
|
||||
extern const struct spa_handle_factory spa_volume_factory;
|
||||
|
||||
|
|
|
|||
|
|
@ -20,12 +20,13 @@
|
|||
#include <string.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include <spa/log.h>
|
||||
#include <spa/type-map.h>
|
||||
#include <spa/node.h>
|
||||
#include <spa/list.h>
|
||||
#include <spa/audio/format-utils.h>
|
||||
#include <spa/param-alloc.h>
|
||||
#include <spa/support/log.h>
|
||||
#include <spa/support/type-map.h>
|
||||
#include <spa/utils/list.h>
|
||||
#include <spa/node/node.h>
|
||||
#include <spa/param/audio/format-utils.h>
|
||||
#include <spa/param/buffers.h>
|
||||
#include <spa/param/meta.h>
|
||||
|
||||
#include <lib/pod.h>
|
||||
|
||||
|
|
@ -74,8 +75,8 @@ struct type {
|
|||
struct spa_type_audio_format audio_format;
|
||||
struct spa_type_event_node event_node;
|
||||
struct spa_type_command_node command_node;
|
||||
struct spa_type_param_alloc_buffers param_alloc_buffers;
|
||||
struct spa_type_param_alloc_meta_enable param_alloc_meta_enable;
|
||||
struct spa_type_param_buffers param_buffers;
|
||||
struct spa_type_param_meta param_meta;
|
||||
};
|
||||
|
||||
static inline void init_type(struct type *type, struct spa_type_map *map)
|
||||
|
|
@ -94,8 +95,8 @@ static inline void init_type(struct type *type, struct spa_type_map *map)
|
|||
spa_type_audio_format_map(map, &type->audio_format);
|
||||
spa_type_event_node_map(map, &type->event_node);
|
||||
spa_type_command_node_map(map, &type->command_node);
|
||||
spa_type_param_alloc_buffers_map(map, &type->param_alloc_buffers);
|
||||
spa_type_param_alloc_meta_enable_map(map, &type->param_alloc_meta_enable);
|
||||
spa_type_param_buffers_map(map, &type->param_buffers);
|
||||
spa_type_param_meta_map(map, &type->param_meta);
|
||||
}
|
||||
|
||||
struct impl {
|
||||
|
|
@ -435,22 +436,22 @@ impl_node_port_enum_params(struct spa_node *node,
|
|||
return SPA_RESULT_ENUM_END;
|
||||
|
||||
param = spa_pod_builder_object(builder,
|
||||
id, t->param_alloc_buffers.Buffers,
|
||||
":", t->param_alloc_buffers.size, "iru", 1024 * this->bpf,
|
||||
id, t->param_buffers.Buffers,
|
||||
":", t->param_buffers.size, "iru", 1024 * this->bpf,
|
||||
2, 16 * this->bpf,
|
||||
INT32_MAX / this->bpf,
|
||||
":", t->param_alloc_buffers.stride, "i", 0,
|
||||
":", t->param_alloc_buffers.buffers, "iru", 2,
|
||||
":", t->param_buffers.stride, "i", 0,
|
||||
":", t->param_buffers.buffers, "iru", 2,
|
||||
2, 1, MAX_BUFFERS,
|
||||
":", t->param_alloc_buffers.align, "i", 16);
|
||||
":", t->param_buffers.align, "i", 16);
|
||||
}
|
||||
else if (id == t->param.idMeta) {
|
||||
switch (*index) {
|
||||
case 0:
|
||||
param = 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));
|
||||
id, t->param_meta.Meta,
|
||||
":", t->param_meta.type, "I", t->meta.Header,
|
||||
":", t->param_meta.size, "i", sizeof(struct spa_meta_header));
|
||||
break;
|
||||
default:
|
||||
return SPA_RESULT_ENUM_END;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue