mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-10-31 22:25:38 -04:00
Remove dynamic types
Do not use dynamic types anymore. The reason is that it's difficult: - to maintain a shared type database over a network. - the extra overhead when translating between processes and for maintaining the translation tables. - race conditions in translating in RT-threads, this is a problem because we want to make event streams. We now have simple enums with types and extension points for all types. This is also nicer to use in general. We don't need the mapper anymore or pass strings around as types. There is a parallel type info system to get more info about ids and enums and their hierarchy. It can also be used for debugging.
This commit is contained in:
parent
e6977fa178
commit
fca3e1d85d
162 changed files with 5200 additions and 7461 deletions
|
|
@ -28,7 +28,7 @@
|
|||
#include <asoundlib.h>
|
||||
|
||||
#include <spa/support/log.h>
|
||||
#include <spa/support/type-map.h>
|
||||
#include <spa/utils/type.h>
|
||||
#include <spa/support/loop.h>
|
||||
#include <spa/support/plugin.h>
|
||||
#include <spa/monitor/monitor.h>
|
||||
|
|
@ -41,17 +41,6 @@
|
|||
extern const struct spa_handle_factory spa_alsa_sink_factory;
|
||||
extern const struct spa_handle_factory spa_alsa_source_factory;
|
||||
|
||||
struct type {
|
||||
uint32_t handle_factory;
|
||||
struct spa_type_monitor monitor;
|
||||
};
|
||||
|
||||
static inline void init_type(struct type *type, struct spa_type_map *map)
|
||||
{
|
||||
type->handle_factory = spa_type_map_get_id(map, SPA_TYPE__HandleFactory);
|
||||
spa_type_monitor_map(map, &type->monitor);
|
||||
}
|
||||
|
||||
struct device {
|
||||
int id;
|
||||
#define DEVICE_FLAG_VALID (1<<0)
|
||||
|
|
@ -76,8 +65,6 @@ struct impl {
|
|||
struct spa_handle handle;
|
||||
struct spa_monitor monitor;
|
||||
|
||||
struct type type;
|
||||
struct spa_type_map *map;
|
||||
struct spa_log *log;
|
||||
struct spa_loop *main_loop;
|
||||
|
||||
|
|
@ -133,7 +120,6 @@ fill_item(struct impl *this, snd_ctl_card_info_t *card_info,
|
|||
const char *str, *name, *klass = NULL;
|
||||
const struct spa_handle_factory *factory = NULL;
|
||||
char device_name[64], id[66];
|
||||
struct type *t = &this->type;
|
||||
struct udev_device *dev = card->dev;
|
||||
struct device *device;
|
||||
int device_idx = snd_pcm_info_get_device(dev_info);
|
||||
|
|
@ -175,16 +161,14 @@ fill_item(struct impl *this, snd_ctl_card_info_t *card_info,
|
|||
name = "Unknown";
|
||||
|
||||
spa_pod_builder_add(builder,
|
||||
"<", 0, t->monitor.MonitorItem,
|
||||
":", t->monitor.id, "s", id,
|
||||
":", t->monitor.flags, "i", 0,
|
||||
":", t->monitor.state, "i", SPA_MONITOR_ITEM_STATE_AVAILABLE,
|
||||
":", t->monitor.name, "s", name,
|
||||
":", t->monitor.klass, "s", klass,
|
||||
":", t->monitor.factory, "p", t->handle_factory, factory, NULL);
|
||||
|
||||
spa_pod_builder_add(builder,
|
||||
":", t->monitor.info, "[", NULL);
|
||||
"<", 0, SPA_ID_OBJECT_MonitorItem,
|
||||
":", SPA_MONITOR_ITEM_id, "s", id,
|
||||
":", SPA_MONITOR_ITEM_flags, "i", SPA_MONITOR_ITEM_FLAG_NONE,
|
||||
":", SPA_MONITOR_ITEM_state, "i", SPA_MONITOR_ITEM_STATE_AVAILABLE,
|
||||
":", SPA_MONITOR_ITEM_name, "s", name,
|
||||
":", SPA_MONITOR_ITEM_class, "s", klass,
|
||||
":", SPA_MONITOR_ITEM_factory, "p", SPA_ID_INTERFACE_HandleFactory, factory,
|
||||
":", SPA_MONITOR_ITEM_info, "[", NULL);
|
||||
|
||||
spa_pod_builder_add(builder,
|
||||
"s", "alsa.card", "s", card->name,
|
||||
|
|
@ -366,7 +350,6 @@ static void impl_on_fd_events(struct spa_source *source)
|
|||
uint32_t type;
|
||||
struct card *card;
|
||||
struct spa_event *event;
|
||||
struct type *t = &this->type;
|
||||
|
||||
dev = udev_monitor_receive_device(this->umonitor);
|
||||
|
||||
|
|
@ -374,18 +357,18 @@ static void impl_on_fd_events(struct spa_source *source)
|
|||
action = "change";
|
||||
|
||||
if (strcmp(action, "add") == 0) {
|
||||
type = this->type.monitor.Added;
|
||||
type = SPA_ID_EVENT_MONITOR_Added;
|
||||
} else if (strcmp(action, "change") == 0) {
|
||||
type = this->type.monitor.Changed;
|
||||
type = SPA_ID_EVENT_MONITOR_Changed;
|
||||
} else if (strcmp(action, "remove") == 0) {
|
||||
type = this->type.monitor.Removed;
|
||||
type = SPA_ID_EVENT_MONITOR_Removed;
|
||||
} else
|
||||
return;
|
||||
|
||||
if ((card = find_card(this, dev)) == NULL)
|
||||
return;
|
||||
|
||||
if (type == this->type.monitor.Removed) {
|
||||
if (type == SPA_ID_EVENT_MONITOR_Removed) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX_DEVICES; i++) {
|
||||
|
|
@ -399,18 +382,18 @@ static void impl_on_fd_events(struct spa_source *source)
|
|||
snprintf(id, 64, "%s,%d/P", card->name, device->id);
|
||||
event = spa_pod_builder_object(&b, 0, type);
|
||||
spa_pod_builder_object(&b,
|
||||
0, t->monitor.MonitorItem,
|
||||
":", t->monitor.id, "s", id,
|
||||
":", t->monitor.name, "s", id);
|
||||
0, SPA_ID_OBJECT_MonitorItem,
|
||||
":", SPA_MONITOR_ITEM_id, "s", id,
|
||||
":", SPA_MONITOR_ITEM_name, "s", id);
|
||||
this->callbacks->event(this->callbacks_data, event);
|
||||
}
|
||||
if (SPA_FLAG_CHECK(device->flags, DEVICE_FLAG_RECORD)) {
|
||||
snprintf(id, 64, "%s,%d/C", card->name, device->id);
|
||||
event = spa_pod_builder_object(&b, 0, type);
|
||||
spa_pod_builder_object(&b,
|
||||
0, t->monitor.MonitorItem,
|
||||
":", t->monitor.id, "s", id,
|
||||
":", t->monitor.name, "s", id);
|
||||
0, SPA_ID_OBJECT_MonitorItem,
|
||||
":", SPA_MONITOR_ITEM_id, "s", id,
|
||||
":", SPA_MONITOR_ITEM_name, "s", id);
|
||||
this->callbacks->event(this->callbacks_data, event);
|
||||
}
|
||||
device->flags = 0;
|
||||
|
|
@ -561,7 +544,7 @@ static int impl_get_interface(struct spa_handle *handle, uint32_t interface_id,
|
|||
|
||||
this = (struct impl *) handle;
|
||||
|
||||
if (interface_id == this->type.monitor.Monitor)
|
||||
if (interface_id == SPA_ID_INTERFACE_Monitor)
|
||||
*interface = &this->monitor;
|
||||
else
|
||||
return -ENOENT;
|
||||
|
|
@ -613,31 +596,23 @@ impl_init(const struct spa_handle_factory *factory,
|
|||
this = (struct impl *) handle;
|
||||
|
||||
for (i = 0; i < n_support; i++) {
|
||||
if (strcmp(support[i].type, SPA_TYPE__TypeMap) == 0)
|
||||
this->map = support[i].data;
|
||||
else if (strcmp(support[i].type, SPA_TYPE__Log) == 0)
|
||||
if (support[i].type == SPA_ID_INTERFACE_Log)
|
||||
this->log = support[i].data;
|
||||
else if (strcmp(support[i].type, SPA_TYPE_LOOP__MainLoop) == 0)
|
||||
else if (support[i].type == SPA_ID_INTERFACE_MainLoop)
|
||||
this->main_loop = support[i].data;
|
||||
}
|
||||
if (this->map == NULL) {
|
||||
spa_log_error(this->log, "an id-map is needed");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (this->main_loop == NULL) {
|
||||
spa_log_error(this->log, "a main-loop is needed");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
init_type(&this->type, this->map);
|
||||
|
||||
this->monitor = impl_monitor;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct spa_interface_info impl_interfaces[] = {
|
||||
{SPA_TYPE__Monitor,},
|
||||
{SPA_ID_INTERFACE_Monitor,},
|
||||
};
|
||||
|
||||
static int
|
||||
|
|
|
|||
|
|
@ -49,7 +49,6 @@ static int impl_node_enum_params(struct spa_node *node,
|
|||
struct spa_pod_builder *builder)
|
||||
{
|
||||
struct state *this;
|
||||
struct type *t;
|
||||
struct spa_pod *param;
|
||||
struct spa_pod_builder b = { 0 };
|
||||
uint8_t buffer[1024];
|
||||
|
|
@ -59,85 +58,92 @@ static int impl_node_enum_params(struct spa_node *node,
|
|||
spa_return_val_if_fail(builder != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct state, node);
|
||||
t = &this->type;
|
||||
|
||||
next:
|
||||
spa_pod_builder_init(&b, buffer, sizeof(buffer));
|
||||
|
||||
if (id == t->param.idList) {
|
||||
uint32_t list[] = { t->param.idPropInfo,
|
||||
t->param.idProps };
|
||||
switch (id) {
|
||||
case SPA_ID_PARAM_List:
|
||||
{
|
||||
uint32_t list[] = { SPA_ID_PARAM_PropInfo,
|
||||
SPA_ID_PARAM_Props };
|
||||
|
||||
if (*index < SPA_N_ELEMENTS(list))
|
||||
param = spa_pod_builder_object(&b, id, t->param.List,
|
||||
":", t->param.listId, "I", list[*index]);
|
||||
param = spa_pod_builder_object(&b, id, SPA_ID_OBJECT_ParamList,
|
||||
":", SPA_PARAM_LIST_id, "I", list[*index]);
|
||||
else
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
else if (id == t->param.idPropInfo) {
|
||||
case SPA_ID_PARAM_PropInfo:
|
||||
{
|
||||
struct props *p = &this->props;
|
||||
|
||||
switch (*index) {
|
||||
case 0:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param.PropInfo,
|
||||
":", t->param.propId, "I", t->prop_device,
|
||||
":", t->param.propName, "s", "The ALSA device",
|
||||
":", t->param.propType, "S", p->device, sizeof(p->device));
|
||||
id, SPA_ID_OBJECT_PropInfo,
|
||||
":", SPA_PROP_INFO_id, "I", SPA_PROP_device,
|
||||
":", SPA_PROP_INFO_name, "s", "The ALSA device",
|
||||
":", SPA_PROP_INFO_type, "S", p->device, sizeof(p->device));
|
||||
break;
|
||||
case 1:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param.PropInfo,
|
||||
":", t->param.propId, "I", t->prop_device_name,
|
||||
":", t->param.propName, "s", "The ALSA device name",
|
||||
":", t->param.propType, "S-r", p->device_name, sizeof(p->device_name));
|
||||
id, SPA_ID_OBJECT_PropInfo,
|
||||
":", SPA_PROP_INFO_id, "I", SPA_PROP_deviceName,
|
||||
":", SPA_PROP_INFO_name, "s", "The ALSA device name",
|
||||
":", SPA_PROP_INFO_type, "S-r", p->device_name, sizeof(p->device_name));
|
||||
break;
|
||||
case 2:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param.PropInfo,
|
||||
":", t->param.propId, "I", t->prop_card_name,
|
||||
":", t->param.propName, "s", "The ALSA card name",
|
||||
":", t->param.propType, "S-r", p->card_name, sizeof(p->card_name));
|
||||
id, SPA_ID_OBJECT_PropInfo,
|
||||
":", SPA_PROP_INFO_id, "I", SPA_PROP_cardName,
|
||||
":", SPA_PROP_INFO_name, "s", "The ALSA card name",
|
||||
":", SPA_PROP_INFO_type, "S-r", p->card_name, sizeof(p->card_name));
|
||||
break;
|
||||
case 3:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param.PropInfo,
|
||||
":", t->param.propId, "I", t->prop_min_latency,
|
||||
":", t->param.propName, "s", "The minimum latency",
|
||||
":", t->param.propType, "ir", p->min_latency,
|
||||
id, SPA_ID_OBJECT_PropInfo,
|
||||
":", SPA_PROP_INFO_id, "I", SPA_PROP_minLatency,
|
||||
":", SPA_PROP_INFO_name, "s", "The minimum latency",
|
||||
":", SPA_PROP_INFO_type, "ir", p->min_latency,
|
||||
SPA_POD_PROP_MIN_MAX(1, INT32_MAX));
|
||||
break;
|
||||
case 4:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param.PropInfo,
|
||||
":", t->param.propId, "I", t->prop_max_latency,
|
||||
":", t->param.propName, "s", "The maximum latency",
|
||||
":", t->param.propType, "ir", p->max_latency,
|
||||
id, SPA_ID_OBJECT_PropInfo,
|
||||
":", SPA_PROP_INFO_id, "I", SPA_PROP_maxLatency,
|
||||
":", SPA_PROP_INFO_name, "s", "The maximum latency",
|
||||
":", SPA_PROP_INFO_type, "ir", p->max_latency,
|
||||
SPA_POD_PROP_MIN_MAX(1, INT32_MAX));
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
else if (id == t->param.idProps) {
|
||||
case SPA_ID_PARAM_Props:
|
||||
{
|
||||
struct props *p = &this->props;
|
||||
|
||||
switch (*index) {
|
||||
case 0:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->props,
|
||||
":", t->prop_device, "S", p->device, sizeof(p->device),
|
||||
":", t->prop_device_name, "S-r", p->device_name, sizeof(p->device_name),
|
||||
":", t->prop_card_name, "S-r", p->card_name, sizeof(p->card_name),
|
||||
":", t->prop_min_latency, "i", p->min_latency,
|
||||
":", t->prop_max_latency, "i", p->max_latency);
|
||||
id, SPA_ID_OBJECT_Props,
|
||||
":", SPA_PROP_device, "S", p->device, sizeof(p->device),
|
||||
":", SPA_PROP_deviceName, "S-r", p->device_name, sizeof(p->device_name),
|
||||
":", SPA_PROP_cardName, "S-r", p->card_name, sizeof(p->card_name),
|
||||
":", SPA_PROP_minLatency, "i", p->min_latency,
|
||||
":", SPA_PROP_maxLatency, "i", p->max_latency);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
else
|
||||
default:
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
(*index)++;
|
||||
|
||||
|
|
@ -151,14 +157,12 @@ static int impl_node_set_param(struct spa_node *node, uint32_t id, uint32_t flag
|
|||
const struct spa_pod *param)
|
||||
{
|
||||
struct state *this;
|
||||
struct type *t;
|
||||
|
||||
spa_return_val_if_fail(node != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct state, node);
|
||||
t = &this->type;
|
||||
|
||||
if (id == t->param.idProps) {
|
||||
if (id == SPA_ID_PARAM_Props) {
|
||||
struct props *p = &this->props;
|
||||
|
||||
if (param == NULL) {
|
||||
|
|
@ -166,9 +170,9 @@ static int impl_node_set_param(struct spa_node *node, uint32_t id, uint32_t flag
|
|||
return 0;
|
||||
}
|
||||
spa_pod_object_parse(param,
|
||||
":", t->prop_device, "?S", p->device, sizeof(p->device),
|
||||
":", t->prop_min_latency, "?i", &p->min_latency,
|
||||
":", t->prop_max_latency, "?i", &p->max_latency, NULL);
|
||||
":", SPA_PROP_device, "?S", p->device, sizeof(p->device),
|
||||
":", SPA_PROP_minLatency, "?i", &p->min_latency,
|
||||
":", SPA_PROP_maxLatency, "?i", &p->max_latency, NULL);
|
||||
}
|
||||
else
|
||||
return -ENOENT;
|
||||
|
|
@ -186,7 +190,8 @@ static int impl_node_send_command(struct spa_node *node, const struct spa_comman
|
|||
|
||||
this = SPA_CONTAINER_OF(node, struct state, node);
|
||||
|
||||
if (SPA_COMMAND_TYPE(command) == this->type.command_node.Start) {
|
||||
switch (SPA_COMMAND_TYPE(command)) {
|
||||
case SPA_ID_COMMAND_NODE_Start:
|
||||
if (!this->have_format)
|
||||
return -EIO;
|
||||
if (this->n_buffers == 0)
|
||||
|
|
@ -194,12 +199,14 @@ static int impl_node_send_command(struct spa_node *node, const struct spa_comman
|
|||
|
||||
if ((res = spa_alsa_start(this, false)) < 0)
|
||||
return res;
|
||||
} else if (SPA_COMMAND_TYPE(command) == this->type.command_node.Pause) {
|
||||
break;
|
||||
case SPA_ID_COMMAND_NODE_Pause:
|
||||
if ((res = spa_alsa_pause(this, false)) < 0)
|
||||
return res;
|
||||
} else
|
||||
break;
|
||||
default:
|
||||
return -ENOTSUP;
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -295,7 +302,6 @@ impl_node_port_enum_params(struct spa_node *node,
|
|||
{
|
||||
|
||||
struct state *this;
|
||||
struct type *t;
|
||||
struct spa_pod *param;
|
||||
struct spa_pod_builder b = { 0 };
|
||||
uint8_t buffer[1024];
|
||||
|
|
@ -305,115 +311,110 @@ impl_node_port_enum_params(struct spa_node *node,
|
|||
spa_return_val_if_fail(builder != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct state, node);
|
||||
t = &this->type;
|
||||
|
||||
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
|
||||
|
||||
next:
|
||||
spa_pod_builder_init(&b, buffer, sizeof(buffer));
|
||||
|
||||
if (id == t->param.idList) {
|
||||
uint32_t list[] = { t->param.idEnumFormat,
|
||||
t->param.idFormat,
|
||||
t->param.idBuffers,
|
||||
t->param.idMeta,
|
||||
t->param_io.idBuffers,
|
||||
t->param_io.idClock, };
|
||||
switch (id) {
|
||||
case SPA_ID_PARAM_List:
|
||||
{
|
||||
uint32_t list[] = { SPA_ID_PARAM_EnumFormat,
|
||||
SPA_ID_PARAM_Format,
|
||||
SPA_ID_PARAM_Buffers,
|
||||
SPA_ID_PARAM_Meta,
|
||||
SPA_ID_PARAM_IO, };
|
||||
|
||||
if (*index < SPA_N_ELEMENTS(list))
|
||||
param = spa_pod_builder_object(&b, id, t->param.List,
|
||||
":", t->param.listId, "I", list[*index]);
|
||||
param = spa_pod_builder_object(&b, id, SPA_ID_OBJECT_ParamList,
|
||||
":", SPA_PARAM_LIST_id, "I", list[*index]);
|
||||
else
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
else if (id == t->param.idEnumFormat) {
|
||||
case SPA_ID_PARAM_EnumFormat:
|
||||
return spa_alsa_enum_format(this, index, filter, result, builder);
|
||||
}
|
||||
else if (id == t->param.idFormat) {
|
||||
|
||||
case SPA_ID_PARAM_Format:
|
||||
if (!this->have_format)
|
||||
return -EIO;
|
||||
if (*index > 0)
|
||||
return 0;
|
||||
|
||||
param = spa_pod_builder_object(&b,
|
||||
t->param.idFormat, t->format,
|
||||
"I", t->media_type.audio,
|
||||
"I", t->media_subtype.raw,
|
||||
":", t->format_audio.format, "I", this->current_format.info.raw.format,
|
||||
":", t->format_audio.layout, "i", this->current_format.info.raw.layout,
|
||||
":", t->format_audio.rate, "i", this->current_format.info.raw.rate,
|
||||
":", t->format_audio.channels, "i", this->current_format.info.raw.channels);
|
||||
}
|
||||
else if (id == t->param.idBuffers) {
|
||||
id, SPA_ID_OBJECT_Format,
|
||||
"I", SPA_MEDIA_TYPE_audio,
|
||||
"I", SPA_MEDIA_SUBTYPE_raw,
|
||||
":", SPA_FORMAT_AUDIO_format, "I", this->current_format.info.raw.format,
|
||||
":", SPA_FORMAT_AUDIO_layout, "i", this->current_format.info.raw.layout,
|
||||
":", SPA_FORMAT_AUDIO_rate, "i", this->current_format.info.raw.rate,
|
||||
":", SPA_FORMAT_AUDIO_channels, "i", this->current_format.info.raw.channels);
|
||||
break;
|
||||
|
||||
case SPA_ID_PARAM_Buffers:
|
||||
if (!this->have_format)
|
||||
return -EIO;
|
||||
if (*index > 0)
|
||||
return 0;
|
||||
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param_buffers.Buffers,
|
||||
":", t->param_buffers.size, "iru", this->props.max_latency *
|
||||
this->frame_size,
|
||||
id, SPA_ID_OBJECT_ParamBuffers,
|
||||
":", SPA_PARAM_BUFFERS_buffers, "ir", 1,
|
||||
SPA_POD_PROP_MIN_MAX(1, MAX_BUFFERS),
|
||||
":", SPA_PARAM_BUFFERS_blocks, "i", 1,
|
||||
":", SPA_PARAM_BUFFERS_size, "iru",
|
||||
this->props.max_latency * this->frame_size,
|
||||
SPA_POD_PROP_MIN_MAX(this->props.min_latency * this->frame_size,
|
||||
INT32_MAX),
|
||||
":", t->param_buffers.stride, "i", 0,
|
||||
":", t->param_buffers.buffers, "ir", 1,
|
||||
SPA_POD_PROP_MIN_MAX(1, MAX_BUFFERS),
|
||||
":", t->param_buffers.align, "i", 16);
|
||||
}
|
||||
else if (id == t->param.idMeta) {
|
||||
":", SPA_PARAM_BUFFERS_stride, "i", 0,
|
||||
":", SPA_PARAM_BUFFERS_align, "i", 16);
|
||||
break;
|
||||
|
||||
case SPA_ID_PARAM_Meta:
|
||||
if (!this->have_format)
|
||||
return -EIO;
|
||||
|
||||
switch (*index) {
|
||||
case 0:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param_meta.Meta,
|
||||
":", t->param_meta.type, "I", t->meta.Header,
|
||||
":", t->param_meta.size, "i", sizeof(struct spa_meta_header));
|
||||
id, SPA_ID_OBJECT_ParamMeta,
|
||||
":", SPA_PARAM_META_type, "I", SPA_META_Header,
|
||||
":", SPA_PARAM_META_size, "i", sizeof(struct spa_meta_header));
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if (id == t->param_io.idBuffers) {
|
||||
break;
|
||||
|
||||
case SPA_ID_PARAM_IO:
|
||||
switch (*index) {
|
||||
case 0:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param_io.Buffers,
|
||||
":", t->param_io.id, "I", t->io.Buffers,
|
||||
":", t->param_io.size, "i", sizeof(struct spa_io_buffers));
|
||||
id, SPA_ID_OBJECT_ParamIO,
|
||||
":", SPA_PARAM_IO_id, "I", SPA_ID_IO_Buffers,
|
||||
":", SPA_PARAM_IO_size, "i", sizeof(struct spa_io_buffers));
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if (id == t->param_io.idControl) {
|
||||
switch (*index) {
|
||||
case 0:
|
||||
case 1:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param_io.Control,
|
||||
":", t->param_io.id, "I", t->io.ControlRange,
|
||||
":", t->param_io.size, "i", sizeof(struct spa_io_control_range));
|
||||
id, SPA_ID_OBJECT_ParamIO,
|
||||
":", SPA_PARAM_IO_id, "I", SPA_ID_IO_ControlRange,
|
||||
":", SPA_PARAM_IO_size, "i", sizeof(struct spa_io_control_range));
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if (id == t->param_io.idClock) {
|
||||
switch (*index) {
|
||||
case 0:
|
||||
case 2:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param_io.Clock,
|
||||
":", t->param_io.id, "I", t->io.Clock,
|
||||
":", t->param_io.size, "i", sizeof(struct spa_io_clock));
|
||||
id, SPA_ID_OBJECT_ParamIO,
|
||||
":", SPA_PARAM_IO_id, "I", SPA_ID_IO_Clock,
|
||||
":", SPA_PARAM_IO_size, "i", sizeof(struct spa_io_clock));
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
break;
|
||||
|
||||
default:
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
(*index)++;
|
||||
|
||||
|
|
@ -454,11 +455,11 @@ static int port_set_format(struct spa_node *node,
|
|||
"I", &info.media_subtype)) < 0)
|
||||
return err;
|
||||
|
||||
if (info.media_type != this->type.media_type.audio ||
|
||||
info.media_subtype != this->type.media_subtype.raw)
|
||||
if (info.media_type != SPA_MEDIA_TYPE_audio ||
|
||||
info.media_subtype != SPA_MEDIA_SUBTYPE_raw)
|
||||
return -EINVAL;
|
||||
|
||||
if (spa_format_audio_raw_parse(format, &info.info.raw, &this->type.format_audio) < 0)
|
||||
if (spa_format_audio_raw_parse(format, &info.info.raw) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
if ((err = spa_alsa_set_format(this, &info, flags)) < 0)
|
||||
|
|
@ -481,17 +482,11 @@ impl_node_port_set_param(struct spa_node *node,
|
|||
uint32_t id, uint32_t flags,
|
||||
const struct spa_pod *param)
|
||||
{
|
||||
struct state *this;
|
||||
struct type *t;
|
||||
|
||||
spa_return_val_if_fail(node != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct state, node);
|
||||
t = &this->type;
|
||||
spa_return_val_if_fail(CHECK_PORT(node, direction, port_id), -EINVAL);
|
||||
|
||||
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
|
||||
|
||||
if (id == t->param.idFormat) {
|
||||
if (id == SPA_ID_PARAM_Format) {
|
||||
return port_set_format(node, direction, port_id, flags, param);
|
||||
}
|
||||
else
|
||||
|
|
@ -531,12 +526,12 @@ impl_node_port_use_buffers(struct spa_node *node,
|
|||
b->buf = buffers[i];
|
||||
b->flags = BUFFER_FLAG_OUT;
|
||||
|
||||
b->h = spa_buffer_find_meta_data(b->buf, this->type.meta.Header, sizeof(*b->h));
|
||||
b->h = spa_buffer_find_meta_data(b->buf, SPA_META_Header, sizeof(*b->h));
|
||||
|
||||
type = d[0].type;
|
||||
if ((type == this->type.data.MemFd ||
|
||||
type == this->type.data.DmaBuf ||
|
||||
type == this->type.data.MemPtr) && d[0].data == NULL) {
|
||||
if ((type == SPA_DATA_MemFd ||
|
||||
type == SPA_DATA_DmaBuf ||
|
||||
type == SPA_DATA_MemPtr) && d[0].data == NULL) {
|
||||
spa_log_error(this->log, NAME " %p: need mapped memory", this);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
@ -580,24 +575,26 @@ impl_node_port_set_io(struct spa_node *node,
|
|||
void *data, size_t size)
|
||||
{
|
||||
struct state *this;
|
||||
struct type *t;
|
||||
|
||||
spa_return_val_if_fail(node != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct state, node);
|
||||
t = &this->type;
|
||||
|
||||
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
|
||||
|
||||
if (id == t->io.Buffers)
|
||||
switch (id) {
|
||||
case SPA_ID_IO_Buffers:
|
||||
this->io = data;
|
||||
else if (id == t->io.ControlRange)
|
||||
break;
|
||||
case SPA_ID_IO_ControlRange:
|
||||
this->range = data;
|
||||
else if (id == t->io.Clock)
|
||||
break;
|
||||
case SPA_ID_IO_Clock:
|
||||
this->clock = data;
|
||||
else
|
||||
break;
|
||||
default:
|
||||
return -ENOENT;
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -692,7 +689,7 @@ static int impl_get_interface(struct spa_handle *handle, uint32_t interface_id,
|
|||
|
||||
this = (struct state *) handle;
|
||||
|
||||
if (interface_id == this->type.node)
|
||||
if (interface_id == SPA_ID_INTERFACE_Node)
|
||||
*interface = &this->node;
|
||||
else
|
||||
return -ENOENT;
|
||||
|
|
@ -726,21 +723,14 @@ impl_init(const struct spa_handle_factory *factory,
|
|||
handle->clear = impl_clear;
|
||||
|
||||
this = (struct state *) handle;
|
||||
|
||||
for (i = 0; i < n_support; i++) {
|
||||
if (strcmp(support[i].type, SPA_TYPE__TypeMap) == 0)
|
||||
this->map = support[i].data;
|
||||
else if (strcmp(support[i].type, SPA_TYPE__Log) == 0)
|
||||
if (support[i].type == SPA_ID_INTERFACE_Log)
|
||||
this->log = support[i].data;
|
||||
else if (strcmp(support[i].type, SPA_TYPE_LOOP__DataLoop) == 0)
|
||||
else if (support[i].type == SPA_ID_INTERFACE_DataLoop)
|
||||
this->data_loop = support[i].data;
|
||||
else if (strcmp(support[i].type, SPA_TYPE_LOOP__MainLoop) == 0)
|
||||
else if (support[i].type == SPA_ID_INTERFACE_MainLoop)
|
||||
this->main_loop = support[i].data;
|
||||
}
|
||||
if (this->map == NULL) {
|
||||
spa_log_error(this->log, "a type-map is needed");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (this->data_loop == NULL) {
|
||||
spa_log_error(this->log, "a data loop is needed");
|
||||
return -EINVAL;
|
||||
|
|
@ -749,7 +739,6 @@ impl_init(const struct spa_handle_factory *factory,
|
|||
spa_log_error(this->log, "a main loop is needed");
|
||||
return -EINVAL;
|
||||
}
|
||||
init_type(&this->type, this->map);
|
||||
|
||||
this->node = impl_node;
|
||||
this->stream = SND_PCM_STREAM_PLAYBACK;
|
||||
|
|
@ -772,7 +761,7 @@ impl_init(const struct spa_handle_factory *factory,
|
|||
}
|
||||
|
||||
static const struct spa_interface_info impl_interfaces[] = {
|
||||
{SPA_TYPE__Node,},
|
||||
{SPA_ID_INTERFACE_Node,},
|
||||
};
|
||||
|
||||
static int
|
||||
|
|
|
|||
|
|
@ -50,7 +50,6 @@ static int impl_node_enum_params(struct spa_node *node,
|
|||
struct spa_pod_builder *builder)
|
||||
{
|
||||
struct state *this;
|
||||
struct type *t;
|
||||
struct spa_pod *param;
|
||||
uint8_t buffer[1024];
|
||||
struct spa_pod_builder b = { 0 };
|
||||
|
|
@ -62,82 +61,87 @@ static int impl_node_enum_params(struct spa_node *node,
|
|||
spa_return_val_if_fail(builder != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct state, node);
|
||||
t = &this->type;
|
||||
p = &this->props;
|
||||
|
||||
next:
|
||||
spa_pod_builder_init(&b, buffer, sizeof(buffer));
|
||||
|
||||
if (id == t->param.idList) {
|
||||
uint32_t list[] = { t->param.idPropInfo,
|
||||
t->param.idProps };
|
||||
switch (id) {
|
||||
case SPA_ID_PARAM_List:
|
||||
{
|
||||
uint32_t list[] = { SPA_ID_PARAM_PropInfo,
|
||||
SPA_ID_PARAM_Props, };
|
||||
|
||||
if (*index < SPA_N_ELEMENTS(list))
|
||||
param = spa_pod_builder_object(&b, id, t->param.List,
|
||||
":", t->param.listId, "I", list[*index]);
|
||||
param = spa_pod_builder_object(&b, id, SPA_ID_OBJECT_ParamList,
|
||||
":", SPA_PARAM_LIST_id, "I", list[*index]);
|
||||
else
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
else if (id == t->param.idPropInfo) {
|
||||
case SPA_ID_PARAM_PropInfo:
|
||||
switch (*index) {
|
||||
case 0:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param.PropInfo,
|
||||
":", t->param.propId, "I", t->prop_device,
|
||||
":", t->param.propName, "s", "The ALSA device",
|
||||
":", t->param.propType, "S", p->device, sizeof(p->device));
|
||||
id, SPA_ID_OBJECT_PropInfo,
|
||||
":", SPA_PROP_INFO_id, "I", SPA_PROP_device,
|
||||
":", SPA_PROP_INFO_name, "s", "The ALSA device",
|
||||
":", SPA_PROP_INFO_type, "S", p->device, sizeof(p->device));
|
||||
break;
|
||||
case 1:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param.PropInfo,
|
||||
":", t->param.propId, "I", t->prop_device_name,
|
||||
":", t->param.propName, "s", "The ALSA device name",
|
||||
":", t->param.propType, "S-r", p->device_name, sizeof(p->device_name));
|
||||
id, SPA_ID_OBJECT_PropInfo,
|
||||
":", SPA_PROP_INFO_id, "I", SPA_PROP_deviceName,
|
||||
":", SPA_PROP_INFO_name, "s", "The ALSA device name",
|
||||
":", SPA_PROP_INFO_type, "S-r", p->device_name, sizeof(p->device_name));
|
||||
break;
|
||||
case 2:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param.PropInfo,
|
||||
":", t->param.propId, "I", t->prop_card_name,
|
||||
":", t->param.propName, "s", "The ALSA card name",
|
||||
":", t->param.propType, "S-r", p->card_name, sizeof(p->card_name));
|
||||
id, SPA_ID_OBJECT_PropInfo,
|
||||
":", SPA_PROP_INFO_id, "I", SPA_PROP_cardName,
|
||||
":", SPA_PROP_INFO_name, "s", "The ALSA card name",
|
||||
":", SPA_PROP_INFO_type, "S-r", p->card_name, sizeof(p->card_name));
|
||||
break;
|
||||
case 3:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param.PropInfo,
|
||||
":", t->param.propId, "I", t->prop_min_latency,
|
||||
":", t->param.propName, "s", "The minimum latency",
|
||||
":", t->param.propType, "ir", p->min_latency,
|
||||
id, SPA_ID_OBJECT_PropInfo,
|
||||
":", SPA_PROP_INFO_id, "I", SPA_PROP_minLatency,
|
||||
":", SPA_PROP_INFO_name, "s", "The minimum latency",
|
||||
":", SPA_PROP_INFO_type, "ir", p->min_latency,
|
||||
SPA_POD_PROP_MIN_MAX(1, INT32_MAX));
|
||||
break;
|
||||
case 4:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param.PropInfo,
|
||||
":", t->param.propId, "I", t->prop_max_latency,
|
||||
":", t->param.propName, "s", "The maximum latency",
|
||||
":", t->param.propType, "ir", p->max_latency,
|
||||
id, SPA_ID_OBJECT_PropInfo,
|
||||
":", SPA_PROP_INFO_id, "I", SPA_PROP_maxLatency,
|
||||
":", SPA_PROP_INFO_name, "s", "The maximum latency",
|
||||
":", SPA_PROP_INFO_type, "ir", p->max_latency,
|
||||
SPA_POD_PROP_MIN_MAX(1, INT32_MAX));
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if (id == t->param.idProps) {
|
||||
break;
|
||||
|
||||
case SPA_ID_PARAM_Props:
|
||||
switch (*index) {
|
||||
case 0:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->props,
|
||||
":", t->prop_device, "S", p->device, sizeof(p->device),
|
||||
":", t->prop_device_name, "S-r", p->device_name, sizeof(p->device_name),
|
||||
":", t->prop_card_name, "S-r", p->card_name, sizeof(p->card_name),
|
||||
":", t->prop_min_latency, "i", p->min_latency,
|
||||
":", t->prop_max_latency, "i", p->max_latency);
|
||||
id, SPA_ID_OBJECT_Props,
|
||||
":", SPA_PROP_device, "S", p->device, sizeof(p->device),
|
||||
":", SPA_PROP_deviceName, "S-r", p->device_name, sizeof(p->device_name),
|
||||
":", SPA_PROP_cardName, "S-r", p->card_name, sizeof(p->card_name),
|
||||
":", SPA_PROP_minLatency, "i", p->min_latency,
|
||||
":", SPA_PROP_maxLatency, "i", p->max_latency);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
break;
|
||||
|
||||
default:
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
(*index)++;
|
||||
|
||||
|
|
@ -151,14 +155,14 @@ static int impl_node_set_param(struct spa_node *node, uint32_t id, uint32_t flag
|
|||
const struct spa_pod *param)
|
||||
{
|
||||
struct state *this;
|
||||
struct type *t;
|
||||
|
||||
spa_return_val_if_fail(node != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct state, node);
|
||||
t = &this->type;
|
||||
|
||||
if (id == t->param.idProps) {
|
||||
switch (id) {
|
||||
case SPA_ID_PARAM_Props:
|
||||
{
|
||||
struct props *p = &this->props;
|
||||
|
||||
if (param == NULL) {
|
||||
|
|
@ -166,12 +170,14 @@ static int impl_node_set_param(struct spa_node *node, uint32_t id, uint32_t flag
|
|||
return 0;
|
||||
}
|
||||
spa_pod_object_parse(param,
|
||||
":", t->prop_device, "?S", p->device, sizeof(p->device),
|
||||
":", t->prop_min_latency, "?i", &p->min_latency,
|
||||
":", t->prop_max_latency, "?i", &p->max_latency, NULL);
|
||||
":", SPA_PROP_device, "?S", p->device, sizeof(p->device),
|
||||
":", SPA_PROP_minLatency, "?i", &p->min_latency,
|
||||
":", SPA_PROP_maxLatency, "?i", &p->max_latency, NULL);
|
||||
break;
|
||||
}
|
||||
else
|
||||
default:
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -186,7 +192,8 @@ static int impl_node_send_command(struct spa_node *node, const struct spa_comman
|
|||
|
||||
this = SPA_CONTAINER_OF(node, struct state, node);
|
||||
|
||||
if (SPA_COMMAND_TYPE(command) == this->type.command_node.Start) {
|
||||
switch (SPA_COMMAND_TYPE(command)) {
|
||||
case SPA_ID_COMMAND_NODE_Start:
|
||||
if (!this->have_format)
|
||||
return -EIO;
|
||||
if (this->n_buffers == 0)
|
||||
|
|
@ -194,12 +201,14 @@ static int impl_node_send_command(struct spa_node *node, const struct spa_comman
|
|||
|
||||
if ((res = spa_alsa_start(this, false)) < 0)
|
||||
return res;
|
||||
} else if (SPA_COMMAND_TYPE(command) == this->type.command_node.Pause) {
|
||||
break;
|
||||
case SPA_ID_COMMAND_NODE_Pause:
|
||||
if ((res = spa_alsa_pause(this, false)) < 0)
|
||||
return res;
|
||||
} else
|
||||
break;
|
||||
default:
|
||||
return -ENOTSUP;
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -303,7 +312,6 @@ static int port_get_format(struct spa_node *node,
|
|||
struct spa_pod_builder *builder)
|
||||
{
|
||||
struct state *this = SPA_CONTAINER_OF(node, struct state, node);
|
||||
struct type *t = &this->type;
|
||||
|
||||
if (!this->have_format)
|
||||
return -EIO;
|
||||
|
|
@ -311,13 +319,13 @@ static int port_get_format(struct spa_node *node,
|
|||
return 0;
|
||||
|
||||
*param = spa_pod_builder_object(builder,
|
||||
t->param.idFormat, t->format,
|
||||
"I", t->media_type.audio,
|
||||
"I", t->media_subtype.raw,
|
||||
":", t->format_audio.format, "I", this->current_format.info.raw.format,
|
||||
":", t->format_audio.layout, "i", this->current_format.info.raw.layout,
|
||||
":", t->format_audio.rate, "i", this->current_format.info.raw.rate,
|
||||
":", t->format_audio.channels, "i", this->current_format.info.raw.channels);
|
||||
SPA_ID_PARAM_Format, SPA_ID_OBJECT_Format,
|
||||
"I", SPA_MEDIA_TYPE_audio,
|
||||
"I", SPA_MEDIA_SUBTYPE_raw,
|
||||
":", SPA_FORMAT_AUDIO_format, "I", this->current_format.info.raw.format,
|
||||
":", SPA_FORMAT_AUDIO_layout, "i", this->current_format.info.raw.layout,
|
||||
":", SPA_FORMAT_AUDIO_rate, "i", this->current_format.info.raw.rate,
|
||||
":", SPA_FORMAT_AUDIO_channels, "i", this->current_format.info.raw.channels);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -331,7 +339,6 @@ impl_node_port_enum_params(struct spa_node *node,
|
|||
struct spa_pod_builder *builder)
|
||||
{
|
||||
struct state *this;
|
||||
struct type *t;
|
||||
struct spa_pod *param;
|
||||
struct spa_pod_builder b = { 0 };
|
||||
uint8_t buffer[1024];
|
||||
|
|
@ -342,90 +349,92 @@ impl_node_port_enum_params(struct spa_node *node,
|
|||
spa_return_val_if_fail(builder != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct state, node);
|
||||
t = &this->type;
|
||||
|
||||
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
|
||||
|
||||
next:
|
||||
spa_pod_builder_init(&b, buffer, sizeof(buffer));
|
||||
|
||||
if (id == t->param.idList) {
|
||||
uint32_t list[] = { t->param.idEnumFormat,
|
||||
t->param.idFormat,
|
||||
t->param.idBuffers,
|
||||
t->param.idMeta };
|
||||
switch (id) {
|
||||
case SPA_ID_PARAM_List:
|
||||
{
|
||||
uint32_t list[] = { SPA_ID_PARAM_EnumFormat,
|
||||
SPA_ID_PARAM_Format,
|
||||
SPA_ID_PARAM_Buffers,
|
||||
SPA_ID_PARAM_Meta };
|
||||
|
||||
if (*index < SPA_N_ELEMENTS(list))
|
||||
param = spa_pod_builder_object(&b, id, t->param.List,
|
||||
":", t->param.listId, "I", list[*index]);
|
||||
param = spa_pod_builder_object(&b, id, SPA_ID_OBJECT_ParamList,
|
||||
":", SPA_PARAM_LIST_id, "I", list[*index]);
|
||||
else
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
else if (id == t->param.idEnumFormat) {
|
||||
case SPA_ID_PARAM_EnumFormat:
|
||||
return spa_alsa_enum_format(this, index, filter, result, builder);
|
||||
}
|
||||
else if (id == t->param.idFormat) {
|
||||
|
||||
case SPA_ID_PARAM_Format:
|
||||
if ((res = port_get_format(node, direction, port_id, index, ¶m, &b)) <= 0)
|
||||
return res;
|
||||
}
|
||||
else if (id == t->param.idBuffers) {
|
||||
break;
|
||||
|
||||
case SPA_ID_PARAM_Buffers:
|
||||
if (!this->have_format)
|
||||
return -EIO;
|
||||
if (*index > 0)
|
||||
return 0;
|
||||
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param_buffers.Buffers,
|
||||
":", t->param_buffers.size, "iru", this->props.max_latency *
|
||||
id, SPA_ID_OBJECT_ParamBuffers,
|
||||
":", SPA_PARAM_BUFFERS_buffers, "ir", 2,
|
||||
SPA_POD_PROP_MIN_MAX(1, MAX_BUFFERS),
|
||||
":", SPA_PARAM_BUFFERS_blocks, "i", 1,
|
||||
":", SPA_PARAM_BUFFERS_size, "iru", this->props.max_latency *
|
||||
this->frame_size,
|
||||
SPA_POD_PROP_MIN_MAX(this->props.min_latency * this->frame_size,
|
||||
INT32_MAX),
|
||||
":", t->param_buffers.stride, "i", this->frame_size,
|
||||
":", t->param_buffers.buffers, "ir", 2,
|
||||
SPA_POD_PROP_MIN_MAX(1, MAX_BUFFERS),
|
||||
":", t->param_buffers.align, "i", 16);
|
||||
}
|
||||
else if (id == t->param.idMeta) {
|
||||
":", SPA_PARAM_BUFFERS_stride, "i", this->frame_size,
|
||||
":", SPA_PARAM_BUFFERS_align, "i", 16);
|
||||
break;
|
||||
|
||||
case SPA_ID_PARAM_Meta:
|
||||
if (!this->have_format)
|
||||
return -EIO;
|
||||
|
||||
switch (*index) {
|
||||
case 0:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param_meta.Meta,
|
||||
":", t->param_meta.type, "I", t->meta.Header,
|
||||
":", t->param_meta.size, "i", sizeof(struct spa_meta_header));
|
||||
id, SPA_ID_OBJECT_ParamMeta,
|
||||
":", SPA_PARAM_META_type, "I", SPA_META_Header,
|
||||
":", SPA_PARAM_META_size, "i", sizeof(struct spa_meta_header));
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if (id == t->param_io.idBuffers) {
|
||||
break;
|
||||
|
||||
case SPA_ID_PARAM_IO:
|
||||
switch (*index) {
|
||||
case 0:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param_io.Buffers,
|
||||
":", t->param_io.id, "I", t->io.Buffers,
|
||||
":", t->param_io.size, "i", sizeof(struct spa_io_buffers));
|
||||
id, SPA_ID_OBJECT_ParamIO,
|
||||
":", SPA_PARAM_IO_id, "I", SPA_ID_IO_Buffers,
|
||||
":", SPA_PARAM_IO_size, "i", sizeof(struct spa_io_buffers));
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if (id == t->param_io.idClock) {
|
||||
switch (*index) {
|
||||
case 0:
|
||||
case 1:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param_io.Clock,
|
||||
":", t->param_io.id, "I", t->io.Clock,
|
||||
":", t->param_io.size, "i", sizeof(struct spa_io_clock));
|
||||
id, SPA_ID_OBJECT_ParamIO,
|
||||
":", SPA_PARAM_IO_id, "I", SPA_ID_IO_Clock,
|
||||
":", SPA_PARAM_IO_size, "i", sizeof(struct spa_io_clock));
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
break;
|
||||
|
||||
default:
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
(*index)++;
|
||||
|
||||
|
|
@ -464,11 +473,11 @@ static int port_set_format(struct spa_node *node,
|
|||
"I", &info.media_type,
|
||||
"I", &info.media_subtype);
|
||||
|
||||
if (info.media_type != this->type.media_type.audio ||
|
||||
info.media_subtype != this->type.media_subtype.raw)
|
||||
if (info.media_type != SPA_MEDIA_TYPE_audio ||
|
||||
info.media_subtype != SPA_MEDIA_SUBTYPE_raw)
|
||||
return -EINVAL;
|
||||
|
||||
if (spa_format_audio_raw_parse(format, &info.info.raw, &this->type.format_audio) < 0)
|
||||
if (spa_format_audio_raw_parse(format, &info.info.raw) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
if ((err = spa_alsa_set_format(this, &info, flags)) < 0)
|
||||
|
|
@ -491,17 +500,11 @@ impl_node_port_set_param(struct spa_node *node,
|
|||
uint32_t id, uint32_t flags,
|
||||
const struct spa_pod *param)
|
||||
{
|
||||
struct state *this;
|
||||
struct type *t;
|
||||
|
||||
spa_return_val_if_fail(node != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct state, node);
|
||||
t = &this->type;
|
||||
spa_return_val_if_fail(CHECK_PORT(node, direction, port_id), -EINVAL);
|
||||
|
||||
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
|
||||
|
||||
if (id == t->param.idFormat) {
|
||||
if (id == SPA_ID_PARAM_Format) {
|
||||
return port_set_format(node, direction, port_id, flags, param);
|
||||
}
|
||||
else
|
||||
|
|
@ -538,11 +541,11 @@ impl_node_port_use_buffers(struct spa_node *node,
|
|||
b->buf = buffers[i];
|
||||
b->flags = 0;
|
||||
|
||||
b->h = spa_buffer_find_meta_data(b->buf, this->type.meta.Header, sizeof(*b->h));
|
||||
b->h = spa_buffer_find_meta_data(b->buf, SPA_META_Header, sizeof(*b->h));
|
||||
|
||||
if (!((d[0].type == this->type.data.MemFd ||
|
||||
d[0].type == this->type.data.DmaBuf ||
|
||||
d[0].type == this->type.data.MemPtr) && d[0].data != NULL)) {
|
||||
if (!((d[0].type == SPA_DATA_MemFd ||
|
||||
d[0].type == SPA_DATA_DmaBuf ||
|
||||
d[0].type == SPA_DATA_MemPtr) && d[0].data != NULL)) {
|
||||
spa_log_error(this->log, NAME " %p: need mapped memory", this);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
@ -589,18 +592,16 @@ impl_node_port_set_io(struct spa_node *node,
|
|||
void *data, size_t size)
|
||||
{
|
||||
struct state *this;
|
||||
struct type *t;
|
||||
|
||||
spa_return_val_if_fail(node != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct state, node);
|
||||
t = &this->type;
|
||||
|
||||
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
|
||||
|
||||
if (id == t->io.Buffers)
|
||||
if (id == SPA_ID_IO_Buffers)
|
||||
this->io = data;
|
||||
else if (id == t->io.Clock)
|
||||
else if (id == SPA_ID_IO_Clock)
|
||||
this->clock = data;
|
||||
else
|
||||
return -ENOENT;
|
||||
|
|
@ -712,7 +713,7 @@ static int impl_get_interface(struct spa_handle *handle, uint32_t interface_id,
|
|||
|
||||
this = (struct state *) handle;
|
||||
|
||||
if (interface_id == this->type.node)
|
||||
if (interface_id == SPA_ID_INTERFACE_Node)
|
||||
*interface = &this->node;
|
||||
else
|
||||
return -ENOENT;
|
||||
|
|
@ -751,19 +752,13 @@ impl_init(const struct spa_handle_factory *factory,
|
|||
this = (struct state *) handle;
|
||||
|
||||
for (i = 0; i < n_support; i++) {
|
||||
if (strcmp(support[i].type, SPA_TYPE__TypeMap) == 0)
|
||||
this->map = support[i].data;
|
||||
else if (strcmp(support[i].type, SPA_TYPE__Log) == 0)
|
||||
if (support[i].type == SPA_ID_INTERFACE_Log)
|
||||
this->log = support[i].data;
|
||||
else if (strcmp(support[i].type, SPA_TYPE_LOOP__DataLoop) == 0)
|
||||
else if (support[i].type == SPA_ID_INTERFACE_DataLoop)
|
||||
this->data_loop = support[i].data;
|
||||
else if (strcmp(support[i].type, SPA_TYPE_LOOP__MainLoop) == 0)
|
||||
else if (support[i].type == SPA_ID_INTERFACE_MainLoop)
|
||||
this->main_loop = support[i].data;
|
||||
}
|
||||
if (this->map == NULL) {
|
||||
spa_log_error(this->log, "an id-map is needed");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (this->data_loop == NULL) {
|
||||
spa_log_error(this->log, "a data loop is needed");
|
||||
return -EINVAL;
|
||||
|
|
@ -772,7 +767,6 @@ impl_init(const struct spa_handle_factory *factory,
|
|||
spa_log_error(this->log, "a main loop is needed");
|
||||
return -EINVAL;
|
||||
}
|
||||
init_type(&this->type, this->map);
|
||||
|
||||
this->node = impl_node;
|
||||
this->stream = SND_PCM_STREAM_CAPTURE;
|
||||
|
|
@ -795,7 +789,7 @@ impl_init(const struct spa_handle_factory *factory,
|
|||
}
|
||||
|
||||
static const struct spa_interface_info impl_interfaces[] = {
|
||||
{SPA_TYPE__Node,},
|
||||
{SPA_ID_INTERFACE_Node,},
|
||||
};
|
||||
|
||||
static int
|
||||
|
|
|
|||
|
|
@ -57,51 +57,42 @@ int spa_alsa_close(struct state *state)
|
|||
}
|
||||
|
||||
struct format_info {
|
||||
off_t format_offset;
|
||||
uint32_t spa_format;
|
||||
snd_pcm_format_t format;
|
||||
};
|
||||
|
||||
#if __BYTE_ORDER == __BIG_ENDIAN
|
||||
#define _FORMAT_LE(fmt) offsetof(struct type, audio_format. fmt ## _OE)
|
||||
#define _FORMAT_BE(fmt) offsetof(struct type, audio_format. fmt)
|
||||
#elif __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
#define _FORMAT_LE(fmt) offsetof(struct type, audio_format. fmt)
|
||||
#define _FORMAT_BE(fmt) offsetof(struct type, audio_format. fmt ## _OE)
|
||||
#endif
|
||||
|
||||
static const struct format_info format_info[] = {
|
||||
{offsetof(struct type, audio_format.UNKNOWN), SND_PCM_FORMAT_UNKNOWN},
|
||||
{offsetof(struct type, audio_format.S8), SND_PCM_FORMAT_S8},
|
||||
{offsetof(struct type, audio_format.U8), SND_PCM_FORMAT_U8},
|
||||
{_FORMAT_LE(S16), SND_PCM_FORMAT_S16_LE},
|
||||
{_FORMAT_BE(S16), SND_PCM_FORMAT_S16_BE},
|
||||
{_FORMAT_LE(U16), SND_PCM_FORMAT_U16_LE},
|
||||
{_FORMAT_BE(U16), SND_PCM_FORMAT_U16_BE},
|
||||
{_FORMAT_LE(S24_32), SND_PCM_FORMAT_S24_LE},
|
||||
{_FORMAT_BE(S24_32), SND_PCM_FORMAT_S24_BE},
|
||||
{_FORMAT_LE(U24_32), SND_PCM_FORMAT_U24_LE},
|
||||
{_FORMAT_BE(U24_32), SND_PCM_FORMAT_U24_BE},
|
||||
{_FORMAT_LE(S24), SND_PCM_FORMAT_S24_3LE},
|
||||
{_FORMAT_BE(S24), SND_PCM_FORMAT_S24_3BE},
|
||||
{_FORMAT_LE(U24), SND_PCM_FORMAT_U24_3LE},
|
||||
{_FORMAT_BE(U24), SND_PCM_FORMAT_U24_3BE},
|
||||
{_FORMAT_LE(S32), SND_PCM_FORMAT_S32_LE},
|
||||
{_FORMAT_BE(S32), SND_PCM_FORMAT_S32_BE},
|
||||
{_FORMAT_LE(U32), SND_PCM_FORMAT_U32_LE},
|
||||
{_FORMAT_BE(U32), SND_PCM_FORMAT_U32_BE},
|
||||
{_FORMAT_LE(F32), SND_PCM_FORMAT_FLOAT_LE},
|
||||
{_FORMAT_BE(F32), SND_PCM_FORMAT_FLOAT_BE},
|
||||
{_FORMAT_LE(F64), SND_PCM_FORMAT_FLOAT64_LE},
|
||||
{_FORMAT_BE(F64), SND_PCM_FORMAT_FLOAT64_BE},
|
||||
{ SPA_AUDIO_FORMAT_UNKNOWN, SND_PCM_FORMAT_UNKNOWN},
|
||||
{ SPA_AUDIO_FORMAT_S8, SND_PCM_FORMAT_S8},
|
||||
{ SPA_AUDIO_FORMAT_U8, SND_PCM_FORMAT_U8},
|
||||
{ SPA_AUDIO_FORMAT_S16_LE, SND_PCM_FORMAT_S16_LE},
|
||||
{ SPA_AUDIO_FORMAT_S16_BE, SND_PCM_FORMAT_S16_BE},
|
||||
{ SPA_AUDIO_FORMAT_U16_LE, SND_PCM_FORMAT_U16_LE},
|
||||
{ SPA_AUDIO_FORMAT_U16_BE, SND_PCM_FORMAT_U16_BE},
|
||||
{ SPA_AUDIO_FORMAT_S24_32_LE, SND_PCM_FORMAT_S24_LE},
|
||||
{ SPA_AUDIO_FORMAT_S24_32_BE, SND_PCM_FORMAT_S24_BE},
|
||||
{ SPA_AUDIO_FORMAT_U24_32_LE, SND_PCM_FORMAT_U24_LE},
|
||||
{ SPA_AUDIO_FORMAT_U24_32_BE, SND_PCM_FORMAT_U24_BE},
|
||||
{ SPA_AUDIO_FORMAT_S24_LE, SND_PCM_FORMAT_S24_3LE},
|
||||
{ SPA_AUDIO_FORMAT_S24_BE, SND_PCM_FORMAT_S24_3BE},
|
||||
{ SPA_AUDIO_FORMAT_U24_LE, SND_PCM_FORMAT_U24_3LE},
|
||||
{ SPA_AUDIO_FORMAT_U24_BE, SND_PCM_FORMAT_U24_3BE},
|
||||
{ SPA_AUDIO_FORMAT_S32_LE, SND_PCM_FORMAT_S32_LE},
|
||||
{ SPA_AUDIO_FORMAT_S32_BE, SND_PCM_FORMAT_S32_BE},
|
||||
{ SPA_AUDIO_FORMAT_U32_LE, SND_PCM_FORMAT_U32_LE},
|
||||
{ SPA_AUDIO_FORMAT_U32_BE, SND_PCM_FORMAT_U32_BE},
|
||||
{ SPA_AUDIO_FORMAT_F32_LE, SND_PCM_FORMAT_FLOAT_LE},
|
||||
{ SPA_AUDIO_FORMAT_F32_BE, SND_PCM_FORMAT_FLOAT_BE},
|
||||
{ SPA_AUDIO_FORMAT_F64_LE, SND_PCM_FORMAT_FLOAT64_LE},
|
||||
{ SPA_AUDIO_FORMAT_F64_BE, SND_PCM_FORMAT_FLOAT64_BE},
|
||||
};
|
||||
|
||||
static snd_pcm_format_t spa_alsa_format_to_alsa(struct type *map, uint32_t format)
|
||||
static snd_pcm_format_t spa_format_to_alsa(uint32_t format)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < SPA_N_ELEMENTS(format_info); i++) {
|
||||
uint32_t f = *SPA_MEMBER(map, format_info[i].format_offset, uint32_t);
|
||||
if (f == format)
|
||||
if (format_info[i].spa_format == format)
|
||||
return format_info[i].format;
|
||||
}
|
||||
return SND_PCM_FORMAT_UNKNOWN;
|
||||
|
|
@ -142,26 +133,25 @@ spa_alsa_enum_format(struct state *state, uint32_t *index,
|
|||
snd_pcm_hw_params_alloca(¶ms);
|
||||
CHECK(snd_pcm_hw_params_any(hndl, params), "Broken configuration: no configurations available");
|
||||
|
||||
spa_pod_builder_push_object(&b, state->type.param.idEnumFormat, state->type.format);
|
||||
spa_pod_builder_push_object(&b, SPA_ID_PARAM_EnumFormat, SPA_ID_OBJECT_Format);
|
||||
spa_pod_builder_add(&b,
|
||||
"I", state->type.media_type.audio,
|
||||
"I", state->type.media_subtype.raw, 0);
|
||||
"I", SPA_MEDIA_TYPE_audio,
|
||||
"I", SPA_MEDIA_SUBTYPE_raw, 0);
|
||||
|
||||
snd_pcm_format_mask_alloca(&fmask);
|
||||
snd_pcm_hw_params_get_format_mask(params, fmask);
|
||||
|
||||
prop = spa_pod_builder_deref(&b,
|
||||
spa_pod_builder_push_prop(&b, state->type.format_audio.format,
|
||||
spa_pod_builder_push_prop(&b, SPA_FORMAT_AUDIO_format,
|
||||
SPA_POD_PROP_RANGE_NONE));
|
||||
|
||||
for (i = 1, j = 0; i < SPA_N_ELEMENTS(format_info); i++) {
|
||||
const struct format_info *fi = &format_info[i];
|
||||
|
||||
if (snd_pcm_format_mask_test(fmask, fi->format)) {
|
||||
uint32_t f = *SPA_MEMBER(&state->type, fi->format_offset, uint32_t);
|
||||
if (j++ == 0)
|
||||
spa_pod_builder_id(&b, f);
|
||||
spa_pod_builder_id(&b, f);
|
||||
spa_pod_builder_id(&b, fi->spa_format);
|
||||
spa_pod_builder_id(&b, fi->spa_format);
|
||||
}
|
||||
}
|
||||
if (j > 1)
|
||||
|
|
@ -172,7 +162,7 @@ spa_alsa_enum_format(struct state *state, uint32_t *index,
|
|||
snd_pcm_hw_params_get_access_mask(params, amask);
|
||||
|
||||
prop = spa_pod_builder_deref(&b,
|
||||
spa_pod_builder_push_prop(&b, state->type.format_audio.layout,
|
||||
spa_pod_builder_push_prop(&b, SPA_FORMAT_AUDIO_layout,
|
||||
SPA_POD_PROP_RANGE_NONE));
|
||||
j = 0;
|
||||
if (snd_pcm_access_mask_test(amask, SND_PCM_ACCESS_MMAP_INTERLEAVED)) {
|
||||
|
|
@ -193,7 +183,7 @@ spa_alsa_enum_format(struct state *state, uint32_t *index,
|
|||
CHECK(snd_pcm_hw_params_get_rate_max(params, &max, &dir), "get_rate_max");
|
||||
|
||||
prop = spa_pod_builder_deref(&b,
|
||||
spa_pod_builder_push_prop(&b, state->type.format_audio.rate, SPA_POD_PROP_RANGE_NONE));
|
||||
spa_pod_builder_push_prop(&b, SPA_FORMAT_AUDIO_rate, SPA_POD_PROP_RANGE_NONE));
|
||||
|
||||
spa_pod_builder_int(&b, SPA_CLAMP(DEFAULT_RATE, min, max));
|
||||
if (min != max) {
|
||||
|
|
@ -207,7 +197,7 @@ spa_alsa_enum_format(struct state *state, uint32_t *index,
|
|||
CHECK(snd_pcm_hw_params_get_channels_max(params, &max), "get_channels_max");
|
||||
|
||||
prop = spa_pod_builder_deref(&b,
|
||||
spa_pod_builder_push_prop(&b, state->type.format_audio.channels, SPA_POD_PROP_RANGE_NONE));
|
||||
spa_pod_builder_push_prop(&b, SPA_FORMAT_AUDIO_channels, SPA_POD_PROP_RANGE_NONE));
|
||||
|
||||
spa_pod_builder_int(&b, SPA_CLAMP(DEFAULT_CHANNELS, min, max));
|
||||
if (min != max) {
|
||||
|
|
@ -261,7 +251,7 @@ int spa_alsa_set_format(struct state *state, struct spa_audio_info *fmt, uint32_
|
|||
CHECK(snd_pcm_hw_params_set_period_wakeup(hndl, params, 0), "set_period_wakeup");
|
||||
|
||||
/* set the sample format */
|
||||
format = spa_alsa_format_to_alsa(&state->type, info->format);
|
||||
format = spa_format_to_alsa(info->format);
|
||||
if (format == SND_PCM_FORMAT_UNKNOWN)
|
||||
return -EINVAL;
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,6 @@ extern "C" {
|
|||
|
||||
#include <asoundlib.h>
|
||||
|
||||
#include <spa/support/type-map.h>
|
||||
#include <spa/support/loop.h>
|
||||
#include <spa/support/log.h>
|
||||
#include <spa/utils/list.h>
|
||||
|
|
@ -61,66 +60,12 @@ struct buffer {
|
|||
struct spa_list link;
|
||||
};
|
||||
|
||||
struct type {
|
||||
uint32_t node;
|
||||
uint32_t format;
|
||||
uint32_t props;
|
||||
uint32_t prop_device;
|
||||
uint32_t prop_device_name;
|
||||
uint32_t prop_card_name;
|
||||
uint32_t prop_min_latency;
|
||||
uint32_t prop_max_latency;
|
||||
struct spa_type_io io;
|
||||
struct spa_type_param param;
|
||||
struct spa_type_meta meta;
|
||||
struct spa_type_data data;
|
||||
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_audio_format audio_format;
|
||||
struct spa_type_event_node event_node;
|
||||
struct spa_type_command_node command_node;
|
||||
struct spa_type_format_audio format_audio;
|
||||
struct spa_type_param_buffers param_buffers;
|
||||
struct spa_type_param_meta param_meta;
|
||||
struct spa_type_param_io param_io;
|
||||
};
|
||||
|
||||
static inline void init_type(struct type *type, struct spa_type_map *map)
|
||||
{
|
||||
type->node = spa_type_map_get_id(map, SPA_TYPE__Node);
|
||||
type->format = spa_type_map_get_id(map, SPA_TYPE__Format);
|
||||
type->props = spa_type_map_get_id(map, SPA_TYPE__Props);
|
||||
type->prop_device = spa_type_map_get_id(map, SPA_TYPE_PROPS__device);
|
||||
type->prop_device_name = spa_type_map_get_id(map, SPA_TYPE_PROPS__deviceName);
|
||||
type->prop_card_name = spa_type_map_get_id(map, SPA_TYPE_PROPS__cardName);
|
||||
type->prop_min_latency = spa_type_map_get_id(map, SPA_TYPE_PROPS__minLatency);
|
||||
type->prop_max_latency = spa_type_map_get_id(map, SPA_TYPE_PROPS__maxLatency);
|
||||
|
||||
spa_type_io_map(map, &type->io);
|
||||
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);
|
||||
spa_type_media_subtype_map(map, &type->media_subtype);
|
||||
spa_type_media_subtype_audio_map(map, &type->media_subtype_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_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);
|
||||
spa_type_param_io_map(map, &type->param_io);
|
||||
}
|
||||
|
||||
struct state {
|
||||
struct spa_handle handle;
|
||||
struct spa_node node;
|
||||
|
||||
uint32_t seq;
|
||||
|
||||
struct type type;
|
||||
struct spa_type_map *map;
|
||||
struct spa_log *log;
|
||||
struct spa_loop *main_loop;
|
||||
struct spa_loop *data_loop;
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#include <spa/support/log.h>
|
||||
#include <spa/support/type-map.h>
|
||||
#include <spa/utils/list.h>
|
||||
#include <spa/node/node.h>
|
||||
#include <spa/buffer/alloc.h>
|
||||
|
|
@ -33,58 +32,13 @@
|
|||
#include <spa/param/io.h>
|
||||
#include <spa/pod/filter.h>
|
||||
#include <spa/debug/pod.h>
|
||||
#include <spa/debug/types.h>
|
||||
|
||||
#define NAME "audioconvert"
|
||||
|
||||
#define PROP_DEFAULT_TRUNCATE false
|
||||
#define PROP_DEFAULT_DITHER 0
|
||||
|
||||
struct type {
|
||||
uint32_t node;
|
||||
uint32_t format;
|
||||
uint32_t prop_truncate;
|
||||
uint32_t prop_dither;
|
||||
|
||||
uint32_t prop_volume;
|
||||
uint32_t io_prop_volume;
|
||||
|
||||
struct spa_type_io io;
|
||||
struct spa_type_param param;
|
||||
struct spa_type_media_type media_type;
|
||||
struct spa_type_media_subtype media_subtype;
|
||||
struct spa_type_format_audio format_audio;
|
||||
struct spa_type_audio_format audio_format;
|
||||
struct spa_type_command_node command_node;
|
||||
struct spa_type_meta meta;
|
||||
struct spa_type_data data;
|
||||
struct spa_type_param_buffers param_buffers;
|
||||
struct spa_type_param_meta param_meta;
|
||||
struct spa_type_param_io param_io;
|
||||
};
|
||||
|
||||
static inline void init_type(struct type *type, struct spa_type_map *map)
|
||||
{
|
||||
type->node = spa_type_map_get_id(map, SPA_TYPE__Node);
|
||||
type->format = spa_type_map_get_id(map, SPA_TYPE__Format);
|
||||
type->prop_truncate = spa_type_map_get_id(map, SPA_TYPE_PROPS__truncate);
|
||||
type->prop_dither = spa_type_map_get_id(map, SPA_TYPE_PROPS__ditherType);
|
||||
|
||||
type->prop_volume = spa_type_map_get_id(map, SPA_TYPE_PROPS__volume);
|
||||
type->io_prop_volume = spa_type_map_get_id(map, SPA_TYPE_IO_PROP_BASE "volume");
|
||||
|
||||
spa_type_io_map(map, &type->io);
|
||||
spa_type_param_map(map, &type->param);
|
||||
spa_type_media_type_map(map, &type->media_type);
|
||||
spa_type_media_subtype_map(map, &type->media_subtype);
|
||||
spa_type_format_audio_map(map, &type->format_audio);
|
||||
spa_type_audio_format_map(map, &type->audio_format);
|
||||
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_buffers_map(map, &type->param_buffers);
|
||||
spa_type_param_meta_map(map, &type->param_meta);
|
||||
spa_type_param_io_map(map, &type->param_io);
|
||||
}
|
||||
struct props {
|
||||
bool truncate;
|
||||
uint32_t dither;
|
||||
|
|
@ -125,8 +79,6 @@ struct impl {
|
|||
struct spa_handle handle;
|
||||
struct spa_node node;
|
||||
|
||||
struct type type;
|
||||
struct spa_type_map *map;
|
||||
struct spa_log *log;
|
||||
|
||||
struct props props;
|
||||
|
|
@ -157,7 +109,6 @@ static int make_link(struct impl *this,
|
|||
struct spa_audio_info *info)
|
||||
{
|
||||
struct link *l = &this->links[this->n_links++];
|
||||
struct type *t = &this->type;
|
||||
|
||||
l->out_node = out_node;
|
||||
l->out_port = out_port;
|
||||
|
|
@ -173,28 +124,26 @@ static int make_link(struct impl *this,
|
|||
&l->out_info);
|
||||
spa_node_port_set_io(out_node,
|
||||
SPA_DIRECTION_OUTPUT, out_port,
|
||||
t->io.Buffers,
|
||||
SPA_ID_IO_Buffers,
|
||||
&l->io, sizeof(l->io));
|
||||
spa_node_port_get_info(in_node,
|
||||
SPA_DIRECTION_INPUT, in_port,
|
||||
&l->in_info);
|
||||
spa_node_port_set_io(in_node,
|
||||
SPA_DIRECTION_INPUT, in_port,
|
||||
t->io.Buffers,
|
||||
SPA_ID_IO_Buffers,
|
||||
&l->io, sizeof(l->io));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void clean_link(struct impl *this, struct link *link)
|
||||
{
|
||||
struct type *t = &this->type;
|
||||
|
||||
spa_node_port_set_param(link->in_node,
|
||||
SPA_DIRECTION_INPUT, link->in_port,
|
||||
t->param.idFormat, 0, NULL);
|
||||
SPA_ID_PARAM_Format, 0, NULL);
|
||||
spa_node_port_set_param(link->out_node,
|
||||
SPA_DIRECTION_OUTPUT, link->out_port,
|
||||
t->param.idFormat, 0, NULL);
|
||||
SPA_ID_PARAM_Format, 0, NULL);
|
||||
if (link->buffers)
|
||||
free(link->buffers);
|
||||
link->buffers = NULL;
|
||||
|
|
@ -221,19 +170,18 @@ static int debug_params(struct impl *this, struct spa_node *node,
|
|||
if (res <= 0)
|
||||
break;
|
||||
|
||||
spa_debug_pod(2, this->map, param);
|
||||
spa_debug_pod(2, spa_debug_types, param);
|
||||
}
|
||||
|
||||
spa_log_error(this->log, "failed filter:");
|
||||
if (filter)
|
||||
spa_debug_pod(2, this->map, filter);
|
||||
spa_debug_pod(2, spa_debug_types, filter);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int negotiate_link_format(struct impl *this, struct link *link)
|
||||
{
|
||||
struct type *t = &this->type;
|
||||
struct spa_pod_builder b = { 0 };
|
||||
uint8_t buffer[4096];
|
||||
uint32_t state;
|
||||
|
|
@ -249,20 +197,20 @@ static int negotiate_link_format(struct impl *this, struct link *link)
|
|||
filter = NULL;
|
||||
if ((res = spa_node_port_enum_params(link->out_node,
|
||||
SPA_DIRECTION_OUTPUT, link->out_port,
|
||||
t->param.idEnumFormat, &state,
|
||||
SPA_ID_PARAM_EnumFormat, &state,
|
||||
filter, &format, &b)) <= 0) {
|
||||
debug_params(this, link->out_node, SPA_DIRECTION_OUTPUT, link->out_port,
|
||||
t->param.idEnumFormat, filter);
|
||||
SPA_ID_PARAM_EnumFormat, filter);
|
||||
return -ENOTSUP;
|
||||
}
|
||||
filter = format;
|
||||
state = 0;
|
||||
if ((res = spa_node_port_enum_params(link->in_node,
|
||||
SPA_DIRECTION_INPUT, link->in_port,
|
||||
t->param.idEnumFormat, &state,
|
||||
SPA_ID_PARAM_EnumFormat, &state,
|
||||
filter, &format, &b)) <= 0) {
|
||||
debug_params(this, link->in_node, SPA_DIRECTION_INPUT, link->in_port,
|
||||
t->param.idEnumFormat, filter);
|
||||
SPA_ID_PARAM_EnumFormat, filter);
|
||||
return -ENOTSUP;
|
||||
}
|
||||
filter = format;
|
||||
|
|
@ -271,13 +219,13 @@ static int negotiate_link_format(struct impl *this, struct link *link)
|
|||
|
||||
if ((res = spa_node_port_set_param(link->out_node,
|
||||
SPA_DIRECTION_OUTPUT, link->out_port,
|
||||
t->param.idFormat, 0,
|
||||
SPA_ID_PARAM_Format, 0,
|
||||
filter)) < 0)
|
||||
return res;
|
||||
|
||||
if ((res = spa_node_port_set_param(link->in_node,
|
||||
SPA_DIRECTION_INPUT, link->in_port,
|
||||
t->param.idFormat, 0,
|
||||
SPA_ID_PARAM_Format, 0,
|
||||
filter)) < 0)
|
||||
return res;
|
||||
|
||||
|
|
@ -317,7 +265,6 @@ static int setup_convert(struct impl *this)
|
|||
|
||||
static int negotiate_link_buffers(struct impl *this, struct link *link)
|
||||
{
|
||||
struct type *t = &this->type;
|
||||
uint8_t buffer[4096];
|
||||
struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buffer, sizeof(buffer));
|
||||
uint32_t state;
|
||||
|
|
@ -334,19 +281,19 @@ static int negotiate_link_buffers(struct impl *this, struct link *link)
|
|||
state = 0;
|
||||
if ((res = spa_node_port_enum_params(link->in_node,
|
||||
SPA_DIRECTION_INPUT, link->in_port,
|
||||
t->param.idBuffers, &state,
|
||||
SPA_ID_PARAM_Buffers, &state,
|
||||
param, ¶m, &b)) <= 0) {
|
||||
debug_params(this, link->out_node, SPA_DIRECTION_OUTPUT, link->out_port,
|
||||
t->param.idBuffers, param);
|
||||
SPA_ID_PARAM_Buffers, param);
|
||||
return -ENOTSUP;
|
||||
}
|
||||
state = 0;
|
||||
if ((res = spa_node_port_enum_params(link->out_node,
|
||||
SPA_DIRECTION_OUTPUT, link->out_port,
|
||||
t->param.idBuffers, &state,
|
||||
SPA_ID_PARAM_Buffers, &state,
|
||||
param, ¶m, &b)) <= 0) {
|
||||
debug_params(this, link->in_node, SPA_DIRECTION_INPUT, link->in_port,
|
||||
t->param.idBuffers, param);
|
||||
SPA_ID_PARAM_Buffers, param);
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
|
|
@ -372,10 +319,10 @@ static int negotiate_link_buffers(struct impl *this, struct link *link)
|
|||
}
|
||||
|
||||
if (spa_pod_object_parse(param,
|
||||
":", t->param_buffers.buffers, "i", &buffers,
|
||||
":", t->param_buffers.blocks, "i", &blocks,
|
||||
":", t->param_buffers.size, "i", &size,
|
||||
":", t->param_buffers.align, "i", &align,
|
||||
":", SPA_PARAM_BUFFERS_buffers, "i", &buffers,
|
||||
":", SPA_PARAM_BUFFERS_blocks, "i", &blocks,
|
||||
":", SPA_PARAM_BUFFERS_size, "i", &size,
|
||||
":", SPA_PARAM_BUFFERS_align, "i", &align,
|
||||
NULL) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
|
|
@ -386,7 +333,7 @@ static int negotiate_link_buffers(struct impl *this, struct link *link)
|
|||
memset(datas, 0, sizeof(struct spa_data) * blocks);
|
||||
aligns = alloca(sizeof(uint32_t) * blocks);
|
||||
for (i = 0; i < blocks; i++) {
|
||||
datas[i].type = t->data.MemPtr;
|
||||
datas[i].type = SPA_DATA_MemPtr;
|
||||
datas[i].maxsize = size;
|
||||
aligns[i] = align;
|
||||
}
|
||||
|
|
@ -484,16 +431,19 @@ static int impl_node_send_command(struct spa_node *node, const struct spa_comman
|
|||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
|
||||
if (SPA_COMMAND_TYPE(command) == this->type.command_node.Start) {
|
||||
switch (SPA_COMMAND_TYPE(command)) {
|
||||
case SPA_ID_COMMAND_NODE_Start:
|
||||
if ((res = setup_convert(this)) < 0)
|
||||
goto error;
|
||||
setup_buffers(this, SPA_DIRECTION_INPUT);
|
||||
this->started = true;
|
||||
} else if (SPA_COMMAND_TYPE(command) == this->type.command_node.Pause) {
|
||||
break;
|
||||
case SPA_ID_COMMAND_NODE_Pause:
|
||||
this->started = false;
|
||||
} else
|
||||
break;
|
||||
default:
|
||||
return -ENOTSUP;
|
||||
|
||||
}
|
||||
return 0;
|
||||
|
||||
error:
|
||||
|
|
@ -607,25 +557,22 @@ impl_node_port_enum_params(struct spa_node *node,
|
|||
struct spa_pod *param;
|
||||
struct spa_pod_builder b = { 0 };
|
||||
uint8_t buffer[1024];
|
||||
struct type *t;
|
||||
|
||||
spa_return_val_if_fail(node != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
t = &this->type;
|
||||
|
||||
if (id == t->param_io.idPropsIn) {
|
||||
switch (id) {
|
||||
next:
|
||||
case SPA_ID_PARAM_PropInfo:
|
||||
spa_pod_builder_init(&b, buffer, sizeof(buffer));
|
||||
|
||||
switch (*index) {
|
||||
case 0:
|
||||
param = spa_pod_builder_object(builder,
|
||||
id, t->param_io.Prop,
|
||||
":", t->param_io.id, "I", this->type.io_prop_volume,
|
||||
":", t->param_io.size, "i", sizeof(struct spa_pod_float),
|
||||
":", t->param.propId, "I", this->type.prop_volume,
|
||||
":", t->param.propType, "fru", 1.0,
|
||||
id, SPA_ID_PARAM_PropInfo,
|
||||
":", SPA_PROP_INFO_id, "I", SPA_PROP_volume,
|
||||
":", SPA_PROP_INFO_type, "fru", 1.0,
|
||||
SPA_POD_PROP_MIN_MAX(0.0, 10.0));
|
||||
break;
|
||||
default:
|
||||
|
|
@ -638,10 +585,10 @@ impl_node_port_enum_params(struct spa_node *node,
|
|||
goto next;
|
||||
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
default:
|
||||
return spa_node_port_enum_params(this->fmt[direction], direction, port_id,
|
||||
id, index, filter, result, builder);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
@ -700,20 +647,18 @@ impl_node_port_set_io(struct spa_node *node,
|
|||
uint32_t id, void *data, size_t size)
|
||||
{
|
||||
struct impl *this;
|
||||
struct type *t;
|
||||
int res;
|
||||
|
||||
spa_return_val_if_fail(node != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
t = &this->type;
|
||||
|
||||
spa_log_debug(this->log, "set io %d %d %d", id, direction, port_id);
|
||||
|
||||
if (id == t->io.ControlRange)
|
||||
if (id == SPA_ID_IO_ControlRange)
|
||||
res = spa_node_port_set_io(this->resample, direction, 0, id, data, size);
|
||||
else if (id == t->io_prop_volume)
|
||||
res = spa_node_port_set_io(this->channelmix, direction, 0, id, data, size);
|
||||
// else if (id == t->io_prop_volume)
|
||||
// res = spa_node_port_set_io(this->channelmix, direction, 0, id, data, size);
|
||||
else
|
||||
res = spa_node_port_set_io(this->fmt[direction], direction, port_id, id, data, size);
|
||||
|
||||
|
|
@ -818,7 +763,7 @@ static int impl_get_interface(struct spa_handle *handle, uint32_t interface_id,
|
|||
|
||||
this = (struct impl *) handle;
|
||||
|
||||
if (interface_id == this->type.node)
|
||||
if (interface_id == SPA_ID_INTERFACE_Node)
|
||||
*interface = &this->node;
|
||||
else
|
||||
return -ENOENT;
|
||||
|
|
@ -877,17 +822,9 @@ impl_init(const struct spa_handle_factory *factory,
|
|||
this = (struct impl *) handle;
|
||||
|
||||
for (i = 0; i < n_support; i++) {
|
||||
if (strcmp(support[i].type, SPA_TYPE__TypeMap) == 0)
|
||||
this->map = support[i].data;
|
||||
else if (strcmp(support[i].type, SPA_TYPE__Log) == 0)
|
||||
if (support[i].type == SPA_ID_INTERFACE_Log)
|
||||
this->log = support[i].data;
|
||||
}
|
||||
if (this->map == NULL) {
|
||||
spa_log_error(this->log, "an id-map is needed");
|
||||
return -EINVAL;
|
||||
}
|
||||
init_type(&this->type, this->map);
|
||||
|
||||
this->node = impl_node;
|
||||
|
||||
this->hnd_fmt[SPA_DIRECTION_INPUT] = SPA_MEMBER(this, sizeof(struct impl), struct spa_handle);
|
||||
|
|
@ -914,13 +851,13 @@ impl_init(const struct spa_handle_factory *factory,
|
|||
info, support, n_support);
|
||||
size = spa_handle_factory_get_size(&spa_resample_factory, info);
|
||||
|
||||
spa_handle_get_interface(this->hnd_fmt[SPA_DIRECTION_INPUT], this->type.node, &iface);
|
||||
spa_handle_get_interface(this->hnd_fmt[SPA_DIRECTION_INPUT], SPA_ID_INTERFACE_Node, &iface);
|
||||
this->fmt[SPA_DIRECTION_INPUT] = iface;
|
||||
spa_handle_get_interface(this->hnd_fmt[SPA_DIRECTION_OUTPUT], this->type.node, &iface);
|
||||
spa_handle_get_interface(this->hnd_fmt[SPA_DIRECTION_OUTPUT], SPA_ID_INTERFACE_Node, &iface);
|
||||
this->fmt[SPA_DIRECTION_OUTPUT] = iface;
|
||||
spa_handle_get_interface(this->hnd_channelmix, this->type.node, &iface);
|
||||
spa_handle_get_interface(this->hnd_channelmix, SPA_ID_INTERFACE_Node, &iface);
|
||||
this->channelmix = iface;
|
||||
spa_handle_get_interface(this->hnd_resample, this->type.node, &iface);
|
||||
spa_handle_get_interface(this->hnd_resample, SPA_ID_INTERFACE_Node, &iface);
|
||||
this->resample = iface;
|
||||
|
||||
props_reset(&this->props);
|
||||
|
|
@ -929,7 +866,7 @@ impl_init(const struct spa_handle_factory *factory,
|
|||
}
|
||||
|
||||
static const struct spa_interface_info impl_interfaces[] = {
|
||||
{SPA_TYPE__Node,},
|
||||
{ SPA_ID_INTERFACE_Node, },
|
||||
};
|
||||
|
||||
static int
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#include <spa/support/log.h>
|
||||
#include <spa/support/type-map.h>
|
||||
#include <spa/utils/list.h>
|
||||
#include <spa/node/node.h>
|
||||
#include <spa/node/io.h>
|
||||
|
|
@ -84,58 +83,12 @@ struct port {
|
|||
struct spa_list queue;
|
||||
};
|
||||
|
||||
struct type {
|
||||
uint32_t node;
|
||||
uint32_t format;
|
||||
|
||||
uint32_t prop_volume;
|
||||
uint32_t io_prop_volume;
|
||||
|
||||
struct spa_type_io io;
|
||||
struct spa_type_param param;
|
||||
struct spa_type_media_type media_type;
|
||||
struct spa_type_media_subtype media_subtype;
|
||||
struct spa_type_format_audio format_audio;
|
||||
struct spa_type_audio_format audio_format;
|
||||
struct spa_type_command_node command_node;
|
||||
struct spa_type_meta meta;
|
||||
struct spa_type_data data;
|
||||
struct spa_type_param_buffers param_buffers;
|
||||
struct spa_type_param_meta param_meta;
|
||||
struct spa_type_param_io param_io;
|
||||
};
|
||||
|
||||
static inline void init_type(struct type *type, struct spa_type_map *map)
|
||||
{
|
||||
type->node = spa_type_map_get_id(map, SPA_TYPE__Node);
|
||||
type->format = spa_type_map_get_id(map, SPA_TYPE__Format);
|
||||
|
||||
type->prop_volume = spa_type_map_get_id(map, SPA_TYPE_PROPS__volume);
|
||||
type->io_prop_volume = spa_type_map_get_id(map, SPA_TYPE_IO_PROP_BASE "volume");
|
||||
|
||||
spa_type_io_map(map, &type->io);
|
||||
spa_type_param_map(map, &type->param);
|
||||
spa_type_media_type_map(map, &type->media_type);
|
||||
spa_type_media_subtype_map(map, &type->media_subtype);
|
||||
spa_type_format_audio_map(map, &type->format_audio);
|
||||
spa_type_audio_format_map(map, &type->audio_format);
|
||||
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_buffers_map(map, &type->param_buffers);
|
||||
spa_type_param_meta_map(map, &type->param_meta);
|
||||
spa_type_param_io_map(map, &type->param_io);
|
||||
}
|
||||
|
||||
|
||||
#include "channelmix-ops.c"
|
||||
|
||||
struct impl {
|
||||
struct spa_handle handle;
|
||||
struct spa_node node;
|
||||
|
||||
struct type type;
|
||||
struct spa_type_map *map;
|
||||
struct spa_log *log;
|
||||
|
||||
struct props props;
|
||||
|
|
@ -245,13 +198,16 @@ static int impl_node_send_command(struct spa_node *node, const struct spa_comman
|
|||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
|
||||
if (SPA_COMMAND_TYPE(command) == this->type.command_node.Start) {
|
||||
switch (SPA_COMMAND_TYPE(command)) {
|
||||
case SPA_ID_COMMAND_NODE_Start:
|
||||
this->started = true;
|
||||
} else if (SPA_COMMAND_TYPE(command) == this->type.command_node.Pause) {
|
||||
break;
|
||||
case SPA_ID_COMMAND_NODE_Pause:
|
||||
this->started = false;
|
||||
} else
|
||||
break;
|
||||
default:
|
||||
return -ENOTSUP;
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -350,7 +306,6 @@ static int port_enum_formats(struct spa_node *node,
|
|||
struct spa_pod_builder *builder)
|
||||
{
|
||||
struct impl *this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
struct type *t = &this->type;
|
||||
struct port *other;
|
||||
|
||||
other = GET_PORT(this, SPA_DIRECTION_REVERSE(direction), 0);
|
||||
|
|
@ -359,24 +314,24 @@ static int port_enum_formats(struct spa_node *node,
|
|||
case 0:
|
||||
if (other->have_format) {
|
||||
*param = spa_pod_builder_object(builder,
|
||||
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.layout, "i", SPA_AUDIO_LAYOUT_NON_INTERLEAVED,
|
||||
":", t->format_audio.rate, "i", other->format.info.raw.rate,
|
||||
":", t->format_audio.channels, "iru", 2,
|
||||
SPA_ID_PARAM_EnumFormat, SPA_ID_OBJECT_Format,
|
||||
"I", SPA_MEDIA_TYPE_audio,
|
||||
"I", SPA_MEDIA_SUBTYPE_raw,
|
||||
":", SPA_FORMAT_AUDIO_format, "I", SPA_AUDIO_FORMAT_F32,
|
||||
":", SPA_FORMAT_AUDIO_layout, "i", SPA_AUDIO_LAYOUT_NON_INTERLEAVED,
|
||||
":", SPA_FORMAT_AUDIO_rate, "i", other->format.info.raw.rate,
|
||||
":", SPA_FORMAT_AUDIO_channels, "iru", 2,
|
||||
SPA_POD_PROP_MIN_MAX(1, INT32_MAX));
|
||||
} else {
|
||||
*param = spa_pod_builder_object(builder,
|
||||
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.layout, "i", SPA_AUDIO_LAYOUT_NON_INTERLEAVED,
|
||||
":", t->format_audio.rate, "iru", DEFAULT_RATE,
|
||||
SPA_ID_PARAM_EnumFormat, SPA_ID_OBJECT_Format,
|
||||
"I", SPA_MEDIA_TYPE_audio,
|
||||
"I", SPA_MEDIA_SUBTYPE_raw,
|
||||
":", SPA_FORMAT_AUDIO_format, "I", SPA_AUDIO_FORMAT_F32,
|
||||
":", SPA_FORMAT_AUDIO_layout, "i", SPA_AUDIO_LAYOUT_NON_INTERLEAVED,
|
||||
":", SPA_FORMAT_AUDIO_rate, "iru", DEFAULT_RATE,
|
||||
SPA_POD_PROP_MIN_MAX(1, INT32_MAX),
|
||||
":", t->format_audio.channels, "iru", DEFAULT_CHANNELS,
|
||||
":", SPA_FORMAT_AUDIO_channels, "iru", DEFAULT_CHANNELS,
|
||||
SPA_POD_PROP_MIN_MAX(1, INT32_MAX));
|
||||
}
|
||||
break;
|
||||
|
|
@ -393,7 +348,6 @@ static int port_get_format(struct spa_node *node,
|
|||
struct spa_pod_builder *builder)
|
||||
{
|
||||
struct impl *this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
struct type *t = &this->type;
|
||||
struct port *port = GET_PORT(this, direction, port_id);
|
||||
|
||||
if (!port->have_format)
|
||||
|
|
@ -402,13 +356,13 @@ static int port_get_format(struct spa_node *node,
|
|||
return 0;
|
||||
|
||||
*param = spa_pod_builder_object(builder,
|
||||
t->param.idFormat, t->format,
|
||||
"I", t->media_type.audio,
|
||||
"I", t->media_subtype.raw,
|
||||
":", t->format_audio.format, "I", port->format.info.raw.format,
|
||||
":", t->format_audio.layout, "i", port->format.info.raw.layout,
|
||||
":", t->format_audio.rate, "i", port->format.info.raw.rate,
|
||||
":", t->format_audio.channels, "i", port->format.info.raw.channels);
|
||||
SPA_ID_PARAM_Format, SPA_ID_OBJECT_Format,
|
||||
"I", SPA_MEDIA_TYPE_audio,
|
||||
"I", SPA_MEDIA_SUBTYPE_raw,
|
||||
":", SPA_FORMAT_AUDIO_format, "I", port->format.info.raw.format,
|
||||
":", SPA_FORMAT_AUDIO_layout, "i", port->format.info.raw.layout,
|
||||
":", SPA_FORMAT_AUDIO_rate, "i", port->format.info.raw.rate,
|
||||
":", SPA_FORMAT_AUDIO_channels, "i", port->format.info.raw.channels);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -422,7 +376,6 @@ impl_node_port_enum_params(struct spa_node *node,
|
|||
struct spa_pod_builder *builder)
|
||||
{
|
||||
struct impl *this;
|
||||
struct type *t;
|
||||
struct port *port, *other;
|
||||
struct spa_pod *param;
|
||||
struct spa_pod_builder b = { 0 };
|
||||
|
|
@ -434,7 +387,6 @@ impl_node_port_enum_params(struct spa_node *node,
|
|||
spa_return_val_if_fail(builder != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
t = &this->type;
|
||||
|
||||
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
|
||||
|
||||
|
|
@ -444,28 +396,34 @@ impl_node_port_enum_params(struct spa_node *node,
|
|||
next:
|
||||
spa_pod_builder_init(&b, buffer, sizeof(buffer));
|
||||
|
||||
if (id == t->param.idList) {
|
||||
uint32_t list[] = { t->param.idEnumFormat,
|
||||
t->param.idFormat,
|
||||
t->param.idBuffers,
|
||||
t->param.idMeta,
|
||||
t->param_io.idBuffers };
|
||||
switch (id) {
|
||||
case SPA_ID_PARAM_List:
|
||||
{
|
||||
uint32_t list[] = { SPA_ID_PARAM_EnumFormat,
|
||||
SPA_ID_PARAM_Format,
|
||||
SPA_ID_PARAM_Buffers,
|
||||
SPA_ID_PARAM_Meta,
|
||||
SPA_ID_PARAM_IO };
|
||||
|
||||
if (*index < SPA_N_ELEMENTS(list))
|
||||
param = spa_pod_builder_object(&b, id, t->param.List,
|
||||
":", t->param.listId, "I", list[*index]);
|
||||
param = spa_pod_builder_object(&b, id, SPA_ID_OBJECT_ParamList,
|
||||
":", SPA_PARAM_LIST_id, "I", list[*index]);
|
||||
else
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
else if (id == t->param.idEnumFormat) {
|
||||
case SPA_ID_PARAM_EnumFormat:
|
||||
if ((res = port_enum_formats(node, direction, port_id, index, ¶m, &b)) <= 0)
|
||||
return res;
|
||||
}
|
||||
else if (id == t->param.idFormat) {
|
||||
break;
|
||||
|
||||
case SPA_ID_PARAM_Format:
|
||||
if ((res = port_get_format(node, direction, port_id, index, ¶m, &b)) <= 0)
|
||||
return res;
|
||||
}
|
||||
else if (id == t->param.idBuffers) {
|
||||
break;
|
||||
|
||||
case SPA_ID_PARAM_Buffers:
|
||||
{
|
||||
uint32_t buffers, size;
|
||||
|
||||
if (!port->have_format)
|
||||
|
|
@ -482,44 +440,47 @@ impl_node_port_enum_params(struct spa_node *node,
|
|||
}
|
||||
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param_buffers.Buffers,
|
||||
":", t->param_buffers.buffers, "iru", buffers,
|
||||
id, SPA_ID_OBJECT_ParamBuffers,
|
||||
":", SPA_PARAM_BUFFERS_buffers, "iru", buffers,
|
||||
SPA_POD_PROP_MIN_MAX(1, MAX_BUFFERS),
|
||||
":", t->param_buffers.blocks, "i", port->blocks,
|
||||
":", t->param_buffers.size, "iru", size * port->stride,
|
||||
":", SPA_PARAM_BUFFERS_blocks, "i", port->blocks,
|
||||
":", SPA_PARAM_BUFFERS_size, "iru", size * port->stride,
|
||||
SPA_POD_PROP_MIN_MAX(16 * port->stride, INT32_MAX / port->stride),
|
||||
":", t->param_buffers.stride, "i", port->stride,
|
||||
":", t->param_buffers.align, "i", 16);
|
||||
":", SPA_PARAM_BUFFERS_stride, "i", port->stride,
|
||||
":", SPA_PARAM_BUFFERS_align, "i", 16);
|
||||
break;
|
||||
}
|
||||
else if (id == t->param.idMeta) {
|
||||
case SPA_ID_PARAM_Meta:
|
||||
if (!port->have_format)
|
||||
return -EIO;
|
||||
|
||||
switch (*index) {
|
||||
case 0:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param_meta.Meta,
|
||||
":", t->param_meta.type, "I", t->meta.Header,
|
||||
":", t->param_meta.size, "i", sizeof(struct spa_meta_header));
|
||||
id, SPA_ID_OBJECT_ParamMeta,
|
||||
":", SPA_PARAM_META_type, "I", SPA_META_Header,
|
||||
":", SPA_PARAM_META_size, "i", sizeof(struct spa_meta_header));
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if (id == t->param_io.idBuffers) {
|
||||
break;
|
||||
|
||||
case SPA_ID_PARAM_IO:
|
||||
switch (*index) {
|
||||
case 0:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param_io.Buffers,
|
||||
":", t->param_io.id, "I", t->io.Buffers,
|
||||
":", t->param_io.size, "i", sizeof(struct spa_io_buffers));
|
||||
id, SPA_ID_OBJECT_ParamIO,
|
||||
":", SPA_PARAM_IO_id, "I", SPA_ID_IO_Buffers,
|
||||
":", SPA_PARAM_IO_size, "i", sizeof(struct spa_io_buffers));
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
break;
|
||||
default:
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
(*index)++;
|
||||
|
||||
|
|
@ -547,7 +508,6 @@ static int port_set_format(struct spa_node *node,
|
|||
{
|
||||
struct impl *this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
struct port *port, *other;
|
||||
struct type *t = &this->type;
|
||||
int res = 0;
|
||||
|
||||
port = GET_PORT(this, direction, port_id);
|
||||
|
|
@ -566,14 +526,14 @@ static int port_set_format(struct spa_node *node,
|
|||
"I", &info.media_type,
|
||||
"I", &info.media_subtype);
|
||||
|
||||
if (info.media_type != t->media_type.audio ||
|
||||
info.media_subtype != t->media_subtype.raw)
|
||||
if (info.media_type != SPA_MEDIA_TYPE_audio ||
|
||||
info.media_subtype != SPA_MEDIA_SUBTYPE_raw)
|
||||
return -EINVAL;
|
||||
|
||||
if (spa_format_audio_raw_parse(format, &info.info.raw, &t->format_audio) < 0)
|
||||
if (spa_format_audio_raw_parse(format, &info.info.raw) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (info.info.raw.format != t->audio_format.F32)
|
||||
if (info.info.raw.format != SPA_AUDIO_FORMAT_F32)
|
||||
return -EINVAL;
|
||||
if (info.info.raw.layout != SPA_AUDIO_LAYOUT_NON_INTERLEAVED)
|
||||
return -EINVAL;
|
||||
|
|
@ -599,17 +559,11 @@ impl_node_port_set_param(struct spa_node *node,
|
|||
uint32_t id, uint32_t flags,
|
||||
const struct spa_pod *param)
|
||||
{
|
||||
struct impl *this;
|
||||
struct type *t;
|
||||
|
||||
spa_return_val_if_fail(node != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
t = &this->type;
|
||||
spa_return_val_if_fail(CHECK_PORT(node, direction, port_id), -EINVAL);
|
||||
|
||||
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
|
||||
|
||||
if (id == t->param.idFormat) {
|
||||
if (id == SPA_ID_PARAM_Format) {
|
||||
return port_set_format(node, direction, port_id, flags, param);
|
||||
}
|
||||
else
|
||||
|
|
@ -626,12 +580,10 @@ impl_node_port_use_buffers(struct spa_node *node,
|
|||
struct impl *this;
|
||||
struct port *port;
|
||||
uint32_t i, size = SPA_ID_INVALID;
|
||||
struct type *t;
|
||||
|
||||
spa_return_val_if_fail(node != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
t = &this->type;
|
||||
|
||||
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
|
||||
|
||||
|
|
@ -650,7 +602,7 @@ impl_node_port_use_buffers(struct spa_node *node,
|
|||
b = &port->buffers[i];
|
||||
b->flags = 0;
|
||||
b->outbuf = buffers[i];
|
||||
b->h = spa_buffer_find_meta_data(buffers[i], t->meta.Header, sizeof(*b->h));
|
||||
b->h = spa_buffer_find_meta_data(buffers[i], SPA_META_Header, sizeof(*b->h));
|
||||
|
||||
if (size == SPA_ID_INVALID)
|
||||
size = d[0].maxsize;
|
||||
|
|
@ -658,9 +610,9 @@ impl_node_port_use_buffers(struct spa_node *node,
|
|||
if (size != d[0].maxsize)
|
||||
return -EINVAL;
|
||||
|
||||
if (!((d[0].type == t->data.MemPtr ||
|
||||
d[0].type == t->data.MemFd ||
|
||||
d[0].type == t->data.DmaBuf) && d[0].data != NULL)) {
|
||||
if (!((d[0].type == SPA_DATA_MemPtr ||
|
||||
d[0].type == SPA_DATA_MemFd ||
|
||||
d[0].type == SPA_DATA_DmaBuf) && d[0].data != NULL)) {
|
||||
spa_log_error(this->log, NAME " %p: invalid memory on buffer %p", this,
|
||||
buffers[i]);
|
||||
return -EINVAL;
|
||||
|
|
@ -695,21 +647,19 @@ impl_node_port_set_io(struct spa_node *node,
|
|||
{
|
||||
struct impl *this;
|
||||
struct port *port;
|
||||
struct type *t;
|
||||
|
||||
spa_return_val_if_fail(node != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
t = &this->type;
|
||||
|
||||
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
|
||||
|
||||
port = GET_PORT(this, direction, port_id);
|
||||
|
||||
if (id == t->io.Buffers)
|
||||
if (id == SPA_ID_IO_Buffers)
|
||||
port->io = data;
|
||||
else if (id == t->io_prop_volume)
|
||||
port->control.volume = data;
|
||||
// else if (id == t->io_prop_volume)
|
||||
// port->control.volume = data;
|
||||
else
|
||||
return -ENOENT;
|
||||
|
||||
|
|
@ -879,7 +829,7 @@ static int impl_get_interface(struct spa_handle *handle, uint32_t interface_id,
|
|||
|
||||
this = (struct impl *) handle;
|
||||
|
||||
if (interface_id == this->type.node)
|
||||
if (interface_id == SPA_ID_INTERFACE_Node)
|
||||
*interface = &this->node;
|
||||
else
|
||||
return -ENOENT;
|
||||
|
|
@ -919,16 +869,9 @@ impl_init(const struct spa_handle_factory *factory,
|
|||
this = (struct impl *) handle;
|
||||
|
||||
for (i = 0; i < n_support; i++) {
|
||||
if (strcmp(support[i].type, SPA_TYPE__TypeMap) == 0)
|
||||
this->map = support[i].data;
|
||||
else if (strcmp(support[i].type, SPA_TYPE__Log) == 0)
|
||||
if (support[i].type == SPA_ID_INTERFACE_Log)
|
||||
this->log = support[i].data;
|
||||
}
|
||||
if (this->map == NULL) {
|
||||
spa_log_error(this->log, "an id-map is needed");
|
||||
return -EINVAL;
|
||||
}
|
||||
init_type(&this->type, this->map);
|
||||
|
||||
this->node = impl_node;
|
||||
|
||||
|
|
@ -948,7 +891,7 @@ impl_init(const struct spa_handle_factory *factory,
|
|||
}
|
||||
|
||||
static const struct spa_interface_info impl_interfaces[] = {
|
||||
{SPA_TYPE__Node,},
|
||||
{SPA_ID_INTERFACE_Node,},
|
||||
};
|
||||
|
||||
static int
|
||||
|
|
|
|||
|
|
@ -670,8 +670,8 @@ typedef void (*convert_func_t) (void *data, int n_dst, void *dst[n_dst],
|
|||
int n_src, const void *src[n_src], int n_bytes);
|
||||
|
||||
static const struct conv_info {
|
||||
off_t src_fmt;
|
||||
off_t dst_fmt;
|
||||
uint32_t src_fmt;
|
||||
uint32_t dst_fmt;
|
||||
#define FEATURE_SSE (1<<0)
|
||||
uint32_t features;
|
||||
|
||||
|
|
@ -681,86 +681,67 @@ static const struct conv_info {
|
|||
} conv_table[] =
|
||||
{
|
||||
/* to f32 */
|
||||
{ offsetof(struct spa_type_audio_format, U8),
|
||||
offsetof(struct spa_type_audio_format, F32), 0,
|
||||
{ SPA_AUDIO_FORMAT_U8, SPA_AUDIO_FORMAT_F32, 0,
|
||||
conv_u8_to_f32, conv_u8_to_f32d, conv_u8d_to_f32 },
|
||||
#if defined (__SSE2__)
|
||||
{ offsetof(struct spa_type_audio_format, S16),
|
||||
offsetof(struct spa_type_audio_format, F32), FEATURE_SSE,
|
||||
{ SPA_AUDIO_FORMAT_S16, SPA_AUDIO_FORMAT_F32, FEATURE_SSE,
|
||||
conv_s16_to_f32, conv_s16_to_f32d_sse, conv_s16d_to_f32 },
|
||||
#endif
|
||||
{ offsetof(struct spa_type_audio_format, S16),
|
||||
offsetof(struct spa_type_audio_format, F32), 0,
|
||||
{ SPA_AUDIO_FORMAT_S16, SPA_AUDIO_FORMAT_F32, 0,
|
||||
conv_s16_to_f32, conv_s16_to_f32d, conv_s16d_to_f32 },
|
||||
{ offsetof(struct spa_type_audio_format, F32),
|
||||
offsetof(struct spa_type_audio_format, F32), 0,
|
||||
{ SPA_AUDIO_FORMAT_F32, SPA_AUDIO_FORMAT_F32, 0,
|
||||
conv_copy, deinterleave_32, interleave_32 },
|
||||
{ offsetof(struct spa_type_audio_format, S32),
|
||||
offsetof(struct spa_type_audio_format, F32), 0,
|
||||
{ SPA_AUDIO_FORMAT_S32, SPA_AUDIO_FORMAT_F32, 0,
|
||||
conv_s32_to_f32, conv_s32_to_f32d, conv_s32d_to_f32 },
|
||||
{ offsetof(struct spa_type_audio_format, S24),
|
||||
offsetof(struct spa_type_audio_format, F32), 0,
|
||||
{ SPA_AUDIO_FORMAT_S24, SPA_AUDIO_FORMAT_F32, 0,
|
||||
conv_s24_to_f32, conv_s24_to_f32d, conv_s24d_to_f32 },
|
||||
{ offsetof(struct spa_type_audio_format, S24_32),
|
||||
offsetof(struct spa_type_audio_format, F32), 0,
|
||||
{ SPA_AUDIO_FORMAT_S24_32, SPA_AUDIO_FORMAT_F32, 0,
|
||||
conv_s24_32_to_f32, conv_s24_32_to_f32d, conv_s24_32d_to_f32 },
|
||||
|
||||
/* from f32 */
|
||||
{ offsetof(struct spa_type_audio_format, F32),
|
||||
offsetof(struct spa_type_audio_format, U8), 0,
|
||||
{ SPA_AUDIO_FORMAT_F32, SPA_AUDIO_FORMAT_U8, 0,
|
||||
conv_f32_to_u8, conv_f32_to_u8d, conv_f32d_to_u8 },
|
||||
{ offsetof(struct spa_type_audio_format, F32),
|
||||
offsetof(struct spa_type_audio_format, S16), 0,
|
||||
{ SPA_AUDIO_FORMAT_F32, SPA_AUDIO_FORMAT_S16, 0,
|
||||
conv_f32_to_s16, conv_f32_to_s16d, conv_f32d_to_s16 },
|
||||
#if defined (__SSE2__)
|
||||
{ offsetof(struct spa_type_audio_format, F32),
|
||||
offsetof(struct spa_type_audio_format, S32), FEATURE_SSE,
|
||||
{ SPA_AUDIO_FORMAT_F32, SPA_AUDIO_FORMAT_S32, FEATURE_SSE,
|
||||
conv_f32_to_s32, conv_f32_to_s32d, conv_f32d_to_s32_sse },
|
||||
#endif
|
||||
{ offsetof(struct spa_type_audio_format, F32),
|
||||
offsetof(struct spa_type_audio_format, S32), 0,
|
||||
{ SPA_AUDIO_FORMAT_F32, SPA_AUDIO_FORMAT_S32, 0,
|
||||
conv_f32_to_s32, conv_f32_to_s32d, conv_f32d_to_s32 },
|
||||
{ offsetof(struct spa_type_audio_format, F32),
|
||||
offsetof(struct spa_type_audio_format, S24), 0,
|
||||
{ SPA_AUDIO_FORMAT_F32, SPA_AUDIO_FORMAT_S24, 0,
|
||||
conv_f32_to_s24, conv_f32_to_s24d, conv_f32d_to_s24 },
|
||||
{ offsetof(struct spa_type_audio_format, F32),
|
||||
offsetof(struct spa_type_audio_format, S24_32), 0,
|
||||
{ SPA_AUDIO_FORMAT_F32, SPA_AUDIO_FORMAT_S24_32, 0,
|
||||
conv_f32_to_s24_32, conv_f32_to_s24_32d, conv_f32d_to_s24_32 },
|
||||
|
||||
/* u8 */
|
||||
{ offsetof(struct spa_type_audio_format, U8),
|
||||
offsetof(struct spa_type_audio_format, U8), 0,
|
||||
{ SPA_AUDIO_FORMAT_U8, SPA_AUDIO_FORMAT_U8, 0,
|
||||
conv_copy, deinterleave_8, interleave_8 },
|
||||
|
||||
/* s16 */
|
||||
{ offsetof(struct spa_type_audio_format, S16),
|
||||
offsetof(struct spa_type_audio_format, S16), 0,
|
||||
{ SPA_AUDIO_FORMAT_S16, SPA_AUDIO_FORMAT_S16, 0,
|
||||
conv_copy, deinterleave_16, interleave_16 },
|
||||
|
||||
/* s32 */
|
||||
{ offsetof(struct spa_type_audio_format, S32),
|
||||
offsetof(struct spa_type_audio_format, S32), 0,
|
||||
{ SPA_AUDIO_FORMAT_S32, SPA_AUDIO_FORMAT_S32, 0,
|
||||
conv_copy, deinterleave_32, interleave_32 },
|
||||
|
||||
/* s24 */
|
||||
{ offsetof(struct spa_type_audio_format, S24),
|
||||
offsetof(struct spa_type_audio_format, S24), 0,
|
||||
{ SPA_AUDIO_FORMAT_S24, SPA_AUDIO_FORMAT_S24, 0,
|
||||
conv_copy, deinterleave_24, interleave_24 },
|
||||
|
||||
/* s24_32 */
|
||||
{ offsetof(struct spa_type_audio_format, S24_32),
|
||||
offsetof(struct spa_type_audio_format, S24_32), 0,
|
||||
{ SPA_AUDIO_FORMAT_S24_32, SPA_AUDIO_FORMAT_S24_32, 0,
|
||||
conv_copy, deinterleave_32, interleave_32 },
|
||||
};
|
||||
|
||||
static const struct conv_info *find_conv_info(struct spa_type_audio_format *audio_format,
|
||||
uint32_t src_fmt, uint32_t dst_fmt, uint32_t features)
|
||||
static const struct conv_info *find_conv_info(uint32_t src_fmt, uint32_t dst_fmt, uint32_t features)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < SPA_N_ELEMENTS(conv_table); i++) {
|
||||
if (*SPA_MEMBER(audio_format, conv_table[i].src_fmt, uint32_t) == src_fmt &&
|
||||
*SPA_MEMBER(audio_format, conv_table[i].dst_fmt, uint32_t) == dst_fmt &&
|
||||
if (conv_table[i].src_fmt == src_fmt &&
|
||||
conv_table[i].dst_fmt == dst_fmt &&
|
||||
(conv_table[i].features == 0 || (conv_table[i].features & features) != 0))
|
||||
return &conv_table[i];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#include <spa/support/log.h>
|
||||
#include <spa/support/type-map.h>
|
||||
#include <spa/utils/list.h>
|
||||
#include <spa/node/node.h>
|
||||
#include <spa/node/io.h>
|
||||
|
|
@ -31,6 +30,7 @@
|
|||
#include <spa/param/meta.h>
|
||||
#include <spa/param/io.h>
|
||||
#include <spa/pod/filter.h>
|
||||
#include <spa/debug/types.h>
|
||||
|
||||
#define NAME "fmtconvert"
|
||||
|
||||
|
|
@ -96,54 +96,12 @@ struct port {
|
|||
struct spa_list queue;
|
||||
};
|
||||
|
||||
struct type {
|
||||
uint32_t node;
|
||||
uint32_t format;
|
||||
uint32_t prop_truncate;
|
||||
uint32_t prop_dither;
|
||||
struct spa_type_io io;
|
||||
struct spa_type_param param;
|
||||
struct spa_type_media_type media_type;
|
||||
struct spa_type_media_subtype media_subtype;
|
||||
struct spa_type_format_audio format_audio;
|
||||
struct spa_type_audio_format audio_format;
|
||||
struct spa_type_command_node command_node;
|
||||
struct spa_type_meta meta;
|
||||
struct spa_type_data data;
|
||||
struct spa_type_param_buffers param_buffers;
|
||||
struct spa_type_param_meta param_meta;
|
||||
struct spa_type_param_io param_io;
|
||||
};
|
||||
|
||||
static inline void init_type(struct type *type, struct spa_type_map *map)
|
||||
{
|
||||
type->node = spa_type_map_get_id(map, SPA_TYPE__Node);
|
||||
type->format = spa_type_map_get_id(map, SPA_TYPE__Format);
|
||||
type->prop_truncate = spa_type_map_get_id(map, SPA_TYPE_PROPS__truncate);
|
||||
type->prop_dither = spa_type_map_get_id(map, SPA_TYPE_PROPS__ditherType);
|
||||
spa_type_io_map(map, &type->io);
|
||||
spa_type_param_map(map, &type->param);
|
||||
spa_type_media_type_map(map, &type->media_type);
|
||||
spa_type_media_subtype_map(map, &type->media_subtype);
|
||||
spa_type_format_audio_map(map, &type->format_audio);
|
||||
spa_type_audio_format_map(map, &type->audio_format);
|
||||
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_buffers_map(map, &type->param_buffers);
|
||||
spa_type_param_meta_map(map, &type->param_meta);
|
||||
spa_type_param_io_map(map, &type->param_io);
|
||||
}
|
||||
|
||||
|
||||
#include "fmt-ops.c"
|
||||
|
||||
struct impl {
|
||||
struct spa_handle handle;
|
||||
struct spa_node node;
|
||||
|
||||
struct type type;
|
||||
struct spa_type_map *map;
|
||||
struct spa_log *log;
|
||||
|
||||
struct props props;
|
||||
|
|
@ -193,7 +151,6 @@ static int collect_format(struct impl *this, enum spa_direction direction, struc
|
|||
static int setup_convert(struct impl *this)
|
||||
{
|
||||
uint32_t src_fmt, dst_fmt;
|
||||
struct type *t = &this->type;
|
||||
struct format informat, outformat;
|
||||
const struct conv_info *conv;
|
||||
|
||||
|
|
@ -206,11 +163,11 @@ static int setup_convert(struct impl *this)
|
|||
dst_fmt = outformat.format.info.raw.format;
|
||||
|
||||
spa_log_info(this->log, NAME " %p: %s/%d@%d.%d->%s/%d@%d.%d", this,
|
||||
spa_type_map_get_type(this->map, src_fmt),
|
||||
spa_debug_type_find_name(spa_debug_types, src_fmt),
|
||||
informat.format.info.raw.channels,
|
||||
informat.format.info.raw.rate,
|
||||
informat.format.info.raw.layout,
|
||||
spa_type_map_get_type(this->map, dst_fmt),
|
||||
spa_debug_type_find_name(spa_debug_types, dst_fmt),
|
||||
outformat.format.info.raw.channels,
|
||||
outformat.format.info.raw.rate,
|
||||
outformat.format.info.raw.layout);
|
||||
|
|
@ -222,7 +179,7 @@ static int setup_convert(struct impl *this)
|
|||
return -EINVAL;
|
||||
|
||||
/* find fast path */
|
||||
conv = find_conv_info(&t->audio_format, src_fmt, dst_fmt, FEATURE_SSE);
|
||||
conv = find_conv_info(src_fmt, dst_fmt, FEATURE_SSE);
|
||||
if (conv != NULL) {
|
||||
spa_log_info(this->log, NAME " %p: got converter features %08x", this,
|
||||
conv->features);
|
||||
|
|
@ -267,13 +224,16 @@ static int impl_node_send_command(struct spa_node *node, const struct spa_comman
|
|||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
|
||||
if (SPA_COMMAND_TYPE(command) == this->type.command_node.Start) {
|
||||
switch (SPA_COMMAND_TYPE(command)) {
|
||||
case SPA_ID_COMMAND_NODE_Start:
|
||||
this->started = true;
|
||||
} else if (SPA_COMMAND_TYPE(command) == this->type.command_node.Pause) {
|
||||
break;
|
||||
case SPA_ID_COMMAND_NODE_Pause:
|
||||
this->started = false;
|
||||
} else
|
||||
break;
|
||||
default:
|
||||
return -ENOTSUP;
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -455,7 +415,6 @@ static int port_enum_formats(struct spa_node *node,
|
|||
struct spa_pod_builder *builder)
|
||||
{
|
||||
struct impl *this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
struct type *t = &this->type;
|
||||
struct spa_audio_info *other;
|
||||
|
||||
other = &this->formats[SPA_DIRECTION_REVERSE(direction)].format;
|
||||
|
|
@ -464,41 +423,41 @@ static int port_enum_formats(struct spa_node *node,
|
|||
case 0:
|
||||
if (other->info.raw.channels > 0) {
|
||||
*param = spa_pod_builder_object(builder,
|
||||
t->param.idEnumFormat, t->format,
|
||||
"I", t->media_type.audio,
|
||||
"I", t->media_subtype.raw,
|
||||
":", t->format_audio.format, "Ieu", other->info.raw.format,
|
||||
SPA_ID_PARAM_EnumFormat, SPA_ID_OBJECT_Format,
|
||||
"I", SPA_MEDIA_TYPE_audio,
|
||||
"I", SPA_MEDIA_SUBTYPE_raw,
|
||||
":", SPA_FORMAT_AUDIO_format, "Ieu", other->info.raw.format,
|
||||
SPA_POD_PROP_ENUM(3, other->info.raw.format,
|
||||
t->audio_format.F32,
|
||||
t->audio_format.F32_OE),
|
||||
":", t->format_audio.layout, "ieu", other->info.raw.layout,
|
||||
SPA_AUDIO_FORMAT_F32,
|
||||
SPA_AUDIO_FORMAT_F32_OE),
|
||||
":", SPA_FORMAT_AUDIO_layout, "ieu", other->info.raw.layout,
|
||||
SPA_POD_PROP_ENUM(2, SPA_AUDIO_LAYOUT_INTERLEAVED,
|
||||
SPA_AUDIO_LAYOUT_NON_INTERLEAVED),
|
||||
":", t->format_audio.rate, "i", other->info.raw.rate,
|
||||
":", t->format_audio.channels, "i", other->info.raw.channels);
|
||||
":", SPA_FORMAT_AUDIO_rate, "i", other->info.raw.rate,
|
||||
":", SPA_FORMAT_AUDIO_channels, "i", other->info.raw.channels);
|
||||
} else {
|
||||
*param = spa_pod_builder_object(builder,
|
||||
t->param.idEnumFormat, t->format,
|
||||
"I", t->media_type.audio,
|
||||
"I", t->media_subtype.raw,
|
||||
":", t->format_audio.format, "Ieu", t->audio_format.S16,
|
||||
SPA_POD_PROP_ENUM(11, t->audio_format.U8,
|
||||
t->audio_format.S16,
|
||||
t->audio_format.S16_OE,
|
||||
t->audio_format.F32,
|
||||
t->audio_format.F32_OE,
|
||||
t->audio_format.S32,
|
||||
t->audio_format.S32_OE,
|
||||
t->audio_format.S24,
|
||||
t->audio_format.S24_OE,
|
||||
t->audio_format.S24_32,
|
||||
t->audio_format.S24_32_OE),
|
||||
":", t->format_audio.layout, "ieu", SPA_AUDIO_LAYOUT_INTERLEAVED,
|
||||
SPA_ID_PARAM_EnumFormat, SPA_ID_OBJECT_Format,
|
||||
"I", SPA_MEDIA_TYPE_audio,
|
||||
"I", SPA_MEDIA_SUBTYPE_raw,
|
||||
":", SPA_FORMAT_AUDIO_format, "Ieu", SPA_AUDIO_FORMAT_S16,
|
||||
SPA_POD_PROP_ENUM(11, SPA_AUDIO_FORMAT_U8,
|
||||
SPA_AUDIO_FORMAT_S16,
|
||||
SPA_AUDIO_FORMAT_S16_OE,
|
||||
SPA_AUDIO_FORMAT_F32,
|
||||
SPA_AUDIO_FORMAT_F32_OE,
|
||||
SPA_AUDIO_FORMAT_S32,
|
||||
SPA_AUDIO_FORMAT_S32_OE,
|
||||
SPA_AUDIO_FORMAT_S24,
|
||||
SPA_AUDIO_FORMAT_S24_OE,
|
||||
SPA_AUDIO_FORMAT_S24_32,
|
||||
SPA_AUDIO_FORMAT_S24_32_OE),
|
||||
":", SPA_FORMAT_AUDIO_layout, "ieu", SPA_AUDIO_LAYOUT_INTERLEAVED,
|
||||
SPA_POD_PROP_ENUM(2, SPA_AUDIO_LAYOUT_INTERLEAVED,
|
||||
SPA_AUDIO_LAYOUT_NON_INTERLEAVED),
|
||||
":", t->format_audio.rate, "iru", DEFAULT_RATE,
|
||||
":", SPA_FORMAT_AUDIO_rate, "iru", DEFAULT_RATE,
|
||||
SPA_POD_PROP_MIN_MAX(1, INT32_MAX),
|
||||
":", t->format_audio.channels, "iru", DEFAULT_CHANNELS,
|
||||
":", SPA_FORMAT_AUDIO_channels, "iru", DEFAULT_CHANNELS,
|
||||
SPA_POD_PROP_MIN_MAX(1, INT32_MAX));
|
||||
}
|
||||
break;
|
||||
|
|
@ -515,7 +474,6 @@ static int port_get_format(struct spa_node *node,
|
|||
struct spa_pod_builder *builder)
|
||||
{
|
||||
struct impl *this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
struct type *t = &this->type;
|
||||
struct port *port = GET_PORT(this, direction, port_id);
|
||||
|
||||
if (!port->have_format)
|
||||
|
|
@ -524,13 +482,13 @@ static int port_get_format(struct spa_node *node,
|
|||
return 0;
|
||||
|
||||
*param = spa_pod_builder_object(builder,
|
||||
t->param.idFormat, t->format,
|
||||
"I", t->media_type.audio,
|
||||
"I", t->media_subtype.raw,
|
||||
":", t->format_audio.format, "I", port->format.info.raw.format,
|
||||
":", t->format_audio.layout, "i", port->format.info.raw.layout,
|
||||
":", t->format_audio.rate, "i", port->format.info.raw.rate,
|
||||
":", t->format_audio.channels, "i", port->format.info.raw.channels);
|
||||
SPA_ID_PARAM_Format, SPA_ID_OBJECT_Format,
|
||||
"I", SPA_MEDIA_TYPE_audio,
|
||||
"I", SPA_MEDIA_SUBTYPE_raw,
|
||||
":", SPA_FORMAT_AUDIO_format, "I", port->format.info.raw.format,
|
||||
":", SPA_FORMAT_AUDIO_layout, "i", port->format.info.raw.layout,
|
||||
":", SPA_FORMAT_AUDIO_rate, "i", port->format.info.raw.rate,
|
||||
":", SPA_FORMAT_AUDIO_channels, "i", port->format.info.raw.channels);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -544,7 +502,6 @@ impl_node_port_enum_params(struct spa_node *node,
|
|||
struct spa_pod_builder *builder)
|
||||
{
|
||||
struct impl *this;
|
||||
struct type *t;
|
||||
struct port *port, *other;
|
||||
|
||||
struct spa_pod *param;
|
||||
|
|
@ -557,7 +514,6 @@ impl_node_port_enum_params(struct spa_node *node,
|
|||
spa_return_val_if_fail(builder != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
t = &this->type;
|
||||
|
||||
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
|
||||
|
||||
|
|
@ -567,28 +523,34 @@ impl_node_port_enum_params(struct spa_node *node,
|
|||
next:
|
||||
spa_pod_builder_init(&b, buffer, sizeof(buffer));
|
||||
|
||||
if (id == t->param.idList) {
|
||||
uint32_t list[] = { t->param.idEnumFormat,
|
||||
t->param.idFormat,
|
||||
t->param.idBuffers,
|
||||
t->param.idMeta,
|
||||
t->param_io.idBuffers };
|
||||
switch (id) {
|
||||
case SPA_ID_PARAM_List:
|
||||
{
|
||||
uint32_t list[] = { SPA_ID_PARAM_EnumFormat,
|
||||
SPA_ID_PARAM_Format,
|
||||
SPA_ID_PARAM_Buffers,
|
||||
SPA_ID_PARAM_Meta,
|
||||
SPA_ID_PARAM_IO };
|
||||
|
||||
if (*index < SPA_N_ELEMENTS(list))
|
||||
param = spa_pod_builder_object(&b, id, t->param.List,
|
||||
":", t->param.listId, "I", list[*index]);
|
||||
param = spa_pod_builder_object(&b, id, SPA_ID_OBJECT_ParamList,
|
||||
":", SPA_PARAM_LIST_id, "I", list[*index]);
|
||||
else
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
else if (id == t->param.idEnumFormat) {
|
||||
case SPA_ID_PARAM_EnumFormat:
|
||||
if ((res = port_enum_formats(node, direction, port_id, index, ¶m, &b)) <= 0)
|
||||
return res;
|
||||
}
|
||||
else if (id == t->param.idFormat) {
|
||||
break;
|
||||
|
||||
case SPA_ID_PARAM_Format:
|
||||
if ((res = port_get_format(node, direction, port_id, index, ¶m, &b)) <= 0)
|
||||
return res;
|
||||
}
|
||||
else if (id == t->param.idBuffers) {
|
||||
break;
|
||||
|
||||
case SPA_ID_PARAM_Buffers:
|
||||
{
|
||||
uint32_t buffers, size;
|
||||
const char *size_fmt;
|
||||
|
||||
|
|
@ -608,44 +570,48 @@ impl_node_port_enum_params(struct spa_node *node,
|
|||
}
|
||||
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param_buffers.Buffers,
|
||||
":", t->param_buffers.buffers, "iru", buffers,
|
||||
id, SPA_ID_OBJECT_ParamBuffers,
|
||||
":", SPA_PARAM_BUFFERS_buffers, "iru", buffers,
|
||||
SPA_POD_PROP_MIN_MAX(2, MAX_BUFFERS),
|
||||
":", t->param_buffers.blocks, "i", port->blocks,
|
||||
":", t->param_buffers.size, size_fmt, size * port->stride,
|
||||
":", SPA_PARAM_BUFFERS_blocks, "i", port->blocks,
|
||||
":", SPA_PARAM_BUFFERS_size, size_fmt, size * port->stride,
|
||||
SPA_POD_PROP_MIN_MAX(16 * port->stride, INT32_MAX / port->stride),
|
||||
":", t->param_buffers.stride, "i", port->stride,
|
||||
":", t->param_buffers.align, "i", 16);
|
||||
":", SPA_PARAM_BUFFERS_stride, "i", port->stride,
|
||||
":", SPA_PARAM_BUFFERS_align, "i", 16);
|
||||
break;
|
||||
}
|
||||
else if (id == t->param.idMeta) {
|
||||
case SPA_ID_PARAM_Meta:
|
||||
if (!port->have_format)
|
||||
return -EIO;
|
||||
|
||||
switch (*index) {
|
||||
case 0:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param_meta.Meta,
|
||||
":", t->param_meta.type, "I", t->meta.Header,
|
||||
":", t->param_meta.size, "i", sizeof(struct spa_meta_header));
|
||||
id, SPA_ID_OBJECT_ParamMeta,
|
||||
":", SPA_PARAM_META_type, "I", SPA_META_Header,
|
||||
":", SPA_PARAM_META_size, "i", sizeof(struct spa_meta_header));
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if (id == t->param_io.idBuffers) {
|
||||
break;
|
||||
|
||||
case SPA_ID_PARAM_IO:
|
||||
switch (*index) {
|
||||
case 0:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param_io.Buffers,
|
||||
":", t->param_io.id, "I", t->io.Buffers,
|
||||
":", t->param_io.size, "i", sizeof(struct spa_io_buffers));
|
||||
id, SPA_ID_OBJECT_ParamIO,
|
||||
":", SPA_PARAM_IO_id, "I", SPA_ID_IO_Buffers,
|
||||
":", SPA_PARAM_IO_size, "i", sizeof(struct spa_io_buffers));
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
break;
|
||||
|
||||
default:
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
(*index)++;
|
||||
|
||||
|
|
@ -655,18 +621,20 @@ impl_node_port_enum_params(struct spa_node *node,
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int calc_width(struct spa_audio_info *info, struct type *t)
|
||||
static int calc_width(struct spa_audio_info *info)
|
||||
{
|
||||
if (info->info.raw.format == t->audio_format.U8)
|
||||
switch (info->info.raw.format) {
|
||||
case SPA_AUDIO_FORMAT_U8:
|
||||
return 1;
|
||||
else if (info->info.raw.format == t->audio_format.S16 ||
|
||||
info->info.raw.format == t->audio_format.S16_OE)
|
||||
case SPA_AUDIO_FORMAT_S16:
|
||||
case SPA_AUDIO_FORMAT_S16_OE:
|
||||
return 2;
|
||||
else if (info->info.raw.format == t->audio_format.S24 ||
|
||||
info->info.raw.format == t->audio_format.S24_OE)
|
||||
case SPA_AUDIO_FORMAT_S24:
|
||||
case SPA_AUDIO_FORMAT_S24_OE:
|
||||
return 3;
|
||||
else
|
||||
default:
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
|
||||
static int clear_buffers(struct impl *this, struct port *port)
|
||||
|
|
@ -695,7 +663,6 @@ static int port_set_format(struct spa_node *node,
|
|||
{
|
||||
struct impl *this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
struct port *port;
|
||||
struct type *t = &this->type;
|
||||
int res = 0;
|
||||
|
||||
port = GET_PORT(this, direction, port_id);
|
||||
|
|
@ -715,11 +682,11 @@ static int port_set_format(struct spa_node *node,
|
|||
"I", &info.media_type,
|
||||
"I", &info.media_subtype);
|
||||
|
||||
if (info.media_type != t->media_type.audio ||
|
||||
info.media_subtype != t->media_subtype.raw)
|
||||
if (info.media_type != SPA_MEDIA_TYPE_audio ||
|
||||
info.media_subtype != SPA_MEDIA_SUBTYPE_raw)
|
||||
return -EINVAL;
|
||||
|
||||
if (spa_format_audio_raw_parse(format, &info.info.raw, &t->format_audio) < 0)
|
||||
if (spa_format_audio_raw_parse(format, &info.info.raw) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (this->n_formats[direction] > 0) {
|
||||
|
|
@ -735,7 +702,7 @@ static int port_set_format(struct spa_node *node,
|
|||
port->have_format = true;
|
||||
port->format = info;
|
||||
|
||||
port->stride = calc_width(&info, t);
|
||||
port->stride = calc_width(&info);
|
||||
|
||||
if (info.info.raw.layout == SPA_AUDIO_LAYOUT_INTERLEAVED) {
|
||||
port->stride *= info.info.raw.channels;
|
||||
|
|
@ -762,20 +729,19 @@ impl_node_port_set_param(struct spa_node *node,
|
|||
const struct spa_pod *param)
|
||||
{
|
||||
struct impl *this;
|
||||
struct type *t;
|
||||
|
||||
spa_return_val_if_fail(node != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
t = &this->type;
|
||||
|
||||
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
|
||||
|
||||
if (id == t->param.idFormat) {
|
||||
switch (id) {
|
||||
case SPA_ID_PARAM_Format:
|
||||
return port_set_format(node, direction, port_id, flags, param);
|
||||
}
|
||||
else
|
||||
default:
|
||||
return -ENOENT;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
@ -788,12 +754,10 @@ impl_node_port_use_buffers(struct spa_node *node,
|
|||
struct impl *this;
|
||||
struct port *port;
|
||||
uint32_t i, size = SPA_ID_INVALID;
|
||||
struct type *t;
|
||||
|
||||
spa_return_val_if_fail(node != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
t = &this->type;
|
||||
|
||||
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
|
||||
|
||||
|
|
@ -812,7 +776,7 @@ impl_node_port_use_buffers(struct spa_node *node,
|
|||
b = &port->buffers[i];
|
||||
b->flags = 0;
|
||||
b->outbuf = buffers[i];
|
||||
b->h = spa_buffer_find_meta_data(buffers[i], t->meta.Header, sizeof(*b->h));
|
||||
b->h = spa_buffer_find_meta_data(buffers[i], SPA_META_Header, sizeof(*b->h));
|
||||
|
||||
if (size == SPA_ID_INVALID)
|
||||
size = d[0].maxsize;
|
||||
|
|
@ -820,9 +784,9 @@ impl_node_port_use_buffers(struct spa_node *node,
|
|||
if (size != d[0].maxsize)
|
||||
return -EINVAL;
|
||||
|
||||
if (!((d[0].type == t->data.MemPtr ||
|
||||
d[0].type == t->data.MemFd ||
|
||||
d[0].type == t->data.DmaBuf) && d[0].data != NULL)) {
|
||||
if (!((d[0].type == SPA_DATA_MemPtr ||
|
||||
d[0].type == SPA_DATA_MemFd ||
|
||||
d[0].type == SPA_DATA_DmaBuf) && d[0].data != NULL)) {
|
||||
spa_log_error(this->log, NAME " %p: invalid memory on buffer %p", this,
|
||||
buffers[i]);
|
||||
return -EINVAL;
|
||||
|
|
@ -859,12 +823,10 @@ impl_node_port_set_io(struct spa_node *node,
|
|||
{
|
||||
struct impl *this;
|
||||
struct port *port;
|
||||
struct type *t;
|
||||
|
||||
spa_return_val_if_fail(node != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
t = &this->type;
|
||||
|
||||
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
|
||||
|
||||
|
|
@ -873,13 +835,16 @@ impl_node_port_set_io(struct spa_node *node,
|
|||
spa_log_debug(this->log, NAME " %p: port %d:%d update io %d %p",
|
||||
this, direction, port_id, id, data);
|
||||
|
||||
if (id == t->io.Buffers)
|
||||
switch (id) {
|
||||
case SPA_ID_IO_Buffers:
|
||||
port->io = data;
|
||||
else if (id == t->io.ControlRange)
|
||||
break;
|
||||
case SPA_ID_IO_ControlRange:
|
||||
port->ctrl = data;
|
||||
else
|
||||
break;
|
||||
default:
|
||||
return -ENOENT;
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1172,7 +1137,7 @@ static int impl_get_interface(struct spa_handle *handle, uint32_t interface_id,
|
|||
|
||||
this = (struct impl *) handle;
|
||||
|
||||
if (interface_id == this->type.node)
|
||||
if (interface_id == SPA_ID_INTERFACE_Node)
|
||||
*interface = &this->node;
|
||||
else
|
||||
return -ENOENT;
|
||||
|
|
@ -1211,17 +1176,9 @@ impl_init(const struct spa_handle_factory *factory,
|
|||
this = (struct impl *) handle;
|
||||
|
||||
for (i = 0; i < n_support; i++) {
|
||||
if (strcmp(support[i].type, SPA_TYPE__TypeMap) == 0)
|
||||
this->map = support[i].data;
|
||||
else if (strcmp(support[i].type, SPA_TYPE__Log) == 0)
|
||||
if (support[i].type == SPA_ID_INTERFACE_Log)
|
||||
this->log = support[i].data;
|
||||
}
|
||||
if (this->map == NULL) {
|
||||
spa_log_error(this->log, "an id-map is needed");
|
||||
return -EINVAL;
|
||||
}
|
||||
init_type(&this->type, this->map);
|
||||
|
||||
this->node = impl_node;
|
||||
|
||||
init_port(this, SPA_DIRECTION_OUTPUT, 0, SPA_PORT_INFO_FLAG_CAN_USE_BUFFERS);
|
||||
|
|
@ -1233,7 +1190,7 @@ impl_init(const struct spa_handle_factory *factory,
|
|||
}
|
||||
|
||||
static const struct spa_interface_info impl_interfaces[] = {
|
||||
{SPA_TYPE__Node,},
|
||||
{SPA_ID_INTERFACE_Node,},
|
||||
};
|
||||
|
||||
static int
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@
|
|||
#include <limits.h>
|
||||
|
||||
#include <spa/support/log.h>
|
||||
#include <spa/support/type-map.h>
|
||||
#include <spa/utils/list.h>
|
||||
#include <spa/node/node.h>
|
||||
#include <spa/node/io.h>
|
||||
|
|
@ -32,6 +31,7 @@
|
|||
#include <spa/param/meta.h>
|
||||
#include <spa/param/io.h>
|
||||
#include <spa/pod/filter.h>
|
||||
#include <spa/debug/types.h>
|
||||
|
||||
#define NAME "merger"
|
||||
|
||||
|
|
@ -41,41 +41,6 @@
|
|||
#define MAX_BUFFERS 64
|
||||
#define MAX_PORTS 128
|
||||
|
||||
struct type {
|
||||
uint32_t node;
|
||||
uint32_t format;
|
||||
struct spa_type_io io;
|
||||
struct spa_type_param param;
|
||||
struct spa_type_media_type media_type;
|
||||
struct spa_type_media_subtype media_subtype;
|
||||
struct spa_type_format_audio format_audio;
|
||||
struct spa_type_audio_format audio_format;
|
||||
struct spa_type_command_node command_node;
|
||||
struct spa_type_meta meta;
|
||||
struct spa_type_data data;
|
||||
struct spa_type_param_buffers param_buffers;
|
||||
struct spa_type_param_meta param_meta;
|
||||
struct spa_type_param_io param_io;
|
||||
};
|
||||
|
||||
static inline void init_type(struct type *type, struct spa_type_map *map)
|
||||
{
|
||||
type->node = spa_type_map_get_id(map, SPA_TYPE__Node);
|
||||
type->format = spa_type_map_get_id(map, SPA_TYPE__Format);
|
||||
spa_type_io_map(map, &type->io);
|
||||
spa_type_param_map(map, &type->param);
|
||||
spa_type_media_type_map(map, &type->media_type);
|
||||
spa_type_media_subtype_map(map, &type->media_subtype);
|
||||
spa_type_format_audio_map(map, &type->format_audio);
|
||||
spa_type_audio_format_map(map, &type->audio_format);
|
||||
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_buffers_map(map, &type->param_buffers);
|
||||
spa_type_param_meta_map(map, &type->param_meta);
|
||||
spa_type_param_io_map(map, &type->param_io);
|
||||
}
|
||||
|
||||
struct buffer {
|
||||
#define BUFFER_FLAG_QUEUED (1<<0)
|
||||
uint32_t flags;
|
||||
|
|
@ -109,8 +74,6 @@ struct impl {
|
|||
struct spa_handle handle;
|
||||
struct spa_node node;
|
||||
|
||||
struct type type;
|
||||
struct spa_type_map *map;
|
||||
struct spa_log *log;
|
||||
|
||||
const struct spa_node_callbacks *callbacks;
|
||||
|
|
@ -164,13 +127,16 @@ static int impl_node_send_command(struct spa_node *node, const struct spa_comman
|
|||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
|
||||
if (SPA_COMMAND_TYPE(command) == this->type.command_node.Start) {
|
||||
switch (SPA_COMMAND_TYPE(command)) {
|
||||
case SPA_ID_COMMAND_NODE_Start:
|
||||
this->started = true;
|
||||
} else if (SPA_COMMAND_TYPE(command) == this->type.command_node.Pause) {
|
||||
break;
|
||||
case SPA_ID_COMMAND_NODE_Pause:
|
||||
this->started = false;
|
||||
} else
|
||||
break;
|
||||
default:
|
||||
return -ENOTSUP;
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -339,7 +305,6 @@ static int port_enum_formats(struct spa_node *node,
|
|||
struct spa_pod_builder *builder)
|
||||
{
|
||||
struct impl *this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
struct type *t = &this->type;
|
||||
uint32_t rate;
|
||||
const char *rspec;
|
||||
|
||||
|
|
@ -356,39 +321,39 @@ static int port_enum_formats(struct spa_node *node,
|
|||
|
||||
if (direction == SPA_DIRECTION_OUTPUT) {
|
||||
*param = spa_pod_builder_object(builder,
|
||||
t->param.idEnumFormat, t->format,
|
||||
"I", t->media_type.audio,
|
||||
"I", t->media_subtype.raw,
|
||||
":", t->format_audio.format, "Ieu", t->audio_format.F32,
|
||||
SPA_ID_PARAM_EnumFormat, SPA_ID_OBJECT_Format,
|
||||
"I", SPA_MEDIA_TYPE_audio,
|
||||
"I", SPA_MEDIA_SUBTYPE_raw,
|
||||
":", SPA_FORMAT_AUDIO_format, "Ieu", SPA_AUDIO_FORMAT_F32,
|
||||
SPA_POD_PROP_ENUM(11,
|
||||
t->audio_format.F32,
|
||||
t->audio_format.F32_OE,
|
||||
t->audio_format.S32,
|
||||
t->audio_format.S32_OE,
|
||||
t->audio_format.S24_32,
|
||||
t->audio_format.S24_32_OE,
|
||||
t->audio_format.S24,
|
||||
t->audio_format.S24_OE,
|
||||
t->audio_format.S16,
|
||||
t->audio_format.S16_OE,
|
||||
t->audio_format.U8),
|
||||
":", t->format_audio.layout, "ieu", SPA_AUDIO_LAYOUT_INTERLEAVED,
|
||||
SPA_AUDIO_FORMAT_F32,
|
||||
SPA_AUDIO_FORMAT_F32_OE,
|
||||
SPA_AUDIO_FORMAT_S32,
|
||||
SPA_AUDIO_FORMAT_S32_OE,
|
||||
SPA_AUDIO_FORMAT_S24_32,
|
||||
SPA_AUDIO_FORMAT_S24_32_OE,
|
||||
SPA_AUDIO_FORMAT_S24,
|
||||
SPA_AUDIO_FORMAT_S24_OE,
|
||||
SPA_AUDIO_FORMAT_S16,
|
||||
SPA_AUDIO_FORMAT_S16_OE,
|
||||
SPA_AUDIO_FORMAT_U8),
|
||||
":", SPA_FORMAT_AUDIO_layout, "ieu", SPA_AUDIO_LAYOUT_INTERLEAVED,
|
||||
SPA_POD_PROP_ENUM(2, SPA_AUDIO_LAYOUT_INTERLEAVED,
|
||||
SPA_AUDIO_LAYOUT_NON_INTERLEAVED),
|
||||
":", t->format_audio.rate, rspec, rate,
|
||||
":", SPA_FORMAT_AUDIO_rate, rspec, rate,
|
||||
SPA_POD_PROP_MIN_MAX(1, INT32_MAX),
|
||||
":", t->format_audio.channels, "i", this->port_count);
|
||||
":", SPA_FORMAT_AUDIO_channels, "i", this->port_count);
|
||||
}
|
||||
else {
|
||||
*param = spa_pod_builder_object(builder,
|
||||
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.layout, "i", SPA_AUDIO_LAYOUT_NON_INTERLEAVED,
|
||||
":", t->format_audio.rate, rspec, rate,
|
||||
SPA_ID_PARAM_EnumFormat, SPA_ID_OBJECT_Format,
|
||||
"I", SPA_MEDIA_TYPE_audio,
|
||||
"I", SPA_MEDIA_SUBTYPE_raw,
|
||||
":", SPA_FORMAT_AUDIO_format, "I", SPA_AUDIO_FORMAT_F32,
|
||||
":", SPA_FORMAT_AUDIO_layout, "i", SPA_AUDIO_LAYOUT_NON_INTERLEAVED,
|
||||
":", SPA_FORMAT_AUDIO_rate, rspec, rate,
|
||||
SPA_POD_PROP_MIN_MAX(1, INT32_MAX),
|
||||
":", t->format_audio.channels, "i", 1);
|
||||
":", SPA_FORMAT_AUDIO_channels, "i", 1);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
|
@ -404,7 +369,6 @@ static int port_get_format(struct spa_node *node,
|
|||
struct spa_pod_builder *builder)
|
||||
{
|
||||
struct impl *this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
struct type *t = &this->type;
|
||||
struct port *port = GET_PORT(this, direction, port_id);
|
||||
|
||||
if (!port->have_format)
|
||||
|
|
@ -413,13 +377,13 @@ static int port_get_format(struct spa_node *node,
|
|||
return 0;
|
||||
|
||||
*param = spa_pod_builder_object(builder,
|
||||
t->param.idFormat, t->format,
|
||||
"I", t->media_type.audio,
|
||||
"I", t->media_subtype.raw,
|
||||
":", t->format_audio.format, "I", port->format.info.raw.format,
|
||||
":", t->format_audio.layout, "i", port->format.info.raw.layout,
|
||||
":", t->format_audio.rate, "i", port->format.info.raw.rate,
|
||||
":", t->format_audio.channels, "i", port->format.info.raw.channels);
|
||||
SPA_ID_PARAM_Format, SPA_ID_OBJECT_Format,
|
||||
"I", SPA_MEDIA_TYPE_audio,
|
||||
"I", SPA_MEDIA_SUBTYPE_raw,
|
||||
":", SPA_FORMAT_AUDIO_format, "I", port->format.info.raw.format,
|
||||
":", SPA_FORMAT_AUDIO_layout, "i", port->format.info.raw.layout,
|
||||
":", SPA_FORMAT_AUDIO_rate, "i", port->format.info.raw.rate,
|
||||
":", SPA_FORMAT_AUDIO_channels, "i", port->format.info.raw.channels);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -433,7 +397,6 @@ impl_node_port_enum_params(struct spa_node *node,
|
|||
struct spa_pod_builder *builder)
|
||||
{
|
||||
struct impl *this;
|
||||
struct type *t;
|
||||
struct port *port;
|
||||
struct spa_pod *param;
|
||||
struct spa_pod_builder b = { 0 };
|
||||
|
|
@ -445,7 +408,6 @@ impl_node_port_enum_params(struct spa_node *node,
|
|||
spa_return_val_if_fail(builder != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
t = &this->type;
|
||||
|
||||
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
|
||||
|
||||
|
|
@ -456,72 +418,75 @@ impl_node_port_enum_params(struct spa_node *node,
|
|||
|
||||
spa_log_debug(this->log, NAME " %p: enum param %d %d", this, id, this->have_format);
|
||||
|
||||
if (id == t->param.idList) {
|
||||
uint32_t list[] = { t->param.idEnumFormat,
|
||||
t->param.idFormat,
|
||||
t->param.idBuffers,
|
||||
t->param.idMeta,
|
||||
t->param_io.idBuffers };
|
||||
switch (id) {
|
||||
case SPA_ID_PARAM_List:
|
||||
{
|
||||
uint32_t list[] = { SPA_ID_PARAM_EnumFormat,
|
||||
SPA_ID_PARAM_Format,
|
||||
SPA_ID_PARAM_Buffers,
|
||||
SPA_ID_PARAM_Meta,
|
||||
SPA_ID_PARAM_IO, };
|
||||
|
||||
if (*index < SPA_N_ELEMENTS(list))
|
||||
param = spa_pod_builder_object(&b, id, t->param.List,
|
||||
":", t->param.listId, "I", list[*index]);
|
||||
param = spa_pod_builder_object(&b, id, SPA_ID_OBJECT_ParamList,
|
||||
":", SPA_PARAM_LIST_id, "I", list[*index]);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
else if (id == t->param.idEnumFormat) {
|
||||
case SPA_ID_PARAM_EnumFormat:
|
||||
if ((res = port_enum_formats(node, direction, port_id, index, ¶m, &b)) <= 0)
|
||||
return res;
|
||||
}
|
||||
else if (id == t->param.idFormat) {
|
||||
break;
|
||||
case SPA_ID_PARAM_Format:
|
||||
if ((res = port_get_format(node, direction, port_id, index, ¶m, &b)) <= 0)
|
||||
return res;
|
||||
}
|
||||
else if (id == t->param.idBuffers) {
|
||||
break;
|
||||
case SPA_ID_PARAM_Buffers:
|
||||
if (!port->have_format)
|
||||
return -EIO;
|
||||
if (*index > 0)
|
||||
return 0;
|
||||
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param_buffers.Buffers,
|
||||
":", t->param_buffers.size, "iru", 1024 * port->stride,
|
||||
SPA_POD_PROP_MIN_MAX(16 * port->stride, MAX_SAMPLES * port->stride),
|
||||
":", t->param_buffers.blocks, "i", port->blocks,
|
||||
":", t->param_buffers.stride, "i", port->stride,
|
||||
":", t->param_buffers.buffers, "iru", 1,
|
||||
id, SPA_ID_OBJECT_ParamBuffers,
|
||||
":", SPA_PARAM_BUFFERS_buffers, "iru", 1,
|
||||
SPA_POD_PROP_MIN_MAX(1, MAX_BUFFERS),
|
||||
":", t->param_buffers.align, "i", 16);
|
||||
}
|
||||
else if (id == t->param.idMeta) {
|
||||
":", SPA_PARAM_BUFFERS_blocks, "i", port->blocks,
|
||||
":", SPA_PARAM_BUFFERS_size, "iru", 1024 * port->stride,
|
||||
SPA_POD_PROP_MIN_MAX(16 * port->stride, MAX_SAMPLES * port->stride),
|
||||
":", SPA_PARAM_BUFFERS_stride, "i", port->stride,
|
||||
":", SPA_PARAM_BUFFERS_align, "i", 16);
|
||||
break;
|
||||
case SPA_ID_PARAM_Meta:
|
||||
if (!port->have_format)
|
||||
return -EIO;
|
||||
|
||||
switch (*index) {
|
||||
case 0:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param_meta.Meta,
|
||||
":", t->param_meta.type, "I", t->meta.Header,
|
||||
":", t->param_meta.size, "i", sizeof(struct spa_meta_header));
|
||||
id, SPA_ID_OBJECT_ParamMeta,
|
||||
":", SPA_PARAM_META_type, "i", SPA_META_Header,
|
||||
":", SPA_PARAM_META_size, "i", sizeof(struct spa_meta_header));
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if (id == t->param_io.idBuffers) {
|
||||
break;
|
||||
case SPA_ID_PARAM_IO:
|
||||
switch (*index) {
|
||||
case 0:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param_io.Buffers,
|
||||
":", t->param_io.id, "I", t->io.Buffers,
|
||||
":", t->param_io.size, "i", sizeof(struct spa_io_buffers));
|
||||
id, SPA_ID_OBJECT_ParamIO,
|
||||
":", SPA_PARAM_IO_id, "I", SPA_ID_IO_Buffers,
|
||||
":", SPA_PARAM_IO_size, "i", sizeof(struct spa_io_buffers));
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
break;
|
||||
default:
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
(*index)++;
|
||||
|
||||
|
|
@ -557,7 +522,6 @@ static struct port *find_in_port(struct impl *this)
|
|||
static int setup_convert(struct impl *this)
|
||||
{
|
||||
const struct conv_info *conv;
|
||||
struct type *t = &this->type;
|
||||
struct port *inport, *outport;
|
||||
uint32_t src_fmt, dst_fmt;
|
||||
|
||||
|
|
@ -570,17 +534,17 @@ static int setup_convert(struct impl *this)
|
|||
dst_fmt = outport->format.info.raw.format;
|
||||
|
||||
spa_log_info(this->log, NAME " %p: %s/%d@%d.%dx%d->%s/%d@%d.%d", this,
|
||||
spa_type_map_get_type(this->map, src_fmt),
|
||||
spa_debug_type_find_name(spa_debug_types, src_fmt),
|
||||
inport->format.info.raw.channels,
|
||||
inport->format.info.raw.rate,
|
||||
inport->format.info.raw.layout,
|
||||
this->port_count,
|
||||
spa_type_map_get_type(this->map, dst_fmt),
|
||||
spa_debug_type_find_name(spa_debug_types, dst_fmt),
|
||||
outport->format.info.raw.channels,
|
||||
outport->format.info.raw.rate,
|
||||
outport->format.info.raw.layout);
|
||||
|
||||
conv = find_conv_info(&t->audio_format, src_fmt, dst_fmt, FEATURE_SSE);
|
||||
conv = find_conv_info(src_fmt, dst_fmt, FEATURE_SSE);
|
||||
if (conv != NULL) {
|
||||
spa_log_info(this->log, NAME " %p: got converter features %08x", this,
|
||||
conv->features);
|
||||
|
|
@ -601,18 +565,20 @@ static int setup_convert(struct impl *this)
|
|||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
static int calc_width(struct spa_audio_info *info, struct type *t)
|
||||
static int calc_width(struct spa_audio_info *info)
|
||||
{
|
||||
if (info->info.raw.format == t->audio_format.U8)
|
||||
switch (info->info.raw.format) {
|
||||
case SPA_AUDIO_FORMAT_U8:
|
||||
return 1;
|
||||
else if (info->info.raw.format == t->audio_format.S16 ||
|
||||
info->info.raw.format == t->audio_format.S16_OE)
|
||||
case SPA_AUDIO_FORMAT_S16:
|
||||
case SPA_AUDIO_FORMAT_S16_OE:
|
||||
return 2;
|
||||
else if (info->info.raw.format == t->audio_format.S24 ||
|
||||
info->info.raw.format == t->audio_format.S24_OE)
|
||||
case SPA_AUDIO_FORMAT_S24:
|
||||
case SPA_AUDIO_FORMAT_S24_OE:
|
||||
return 3;
|
||||
else
|
||||
default:
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
|
||||
static int port_set_format(struct spa_node *node,
|
||||
|
|
@ -623,7 +589,6 @@ static int port_set_format(struct spa_node *node,
|
|||
{
|
||||
struct impl *this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
struct port *port;
|
||||
struct type *t = &this->type;
|
||||
|
||||
port = GET_PORT(this, direction, port_id);
|
||||
|
||||
|
|
@ -643,11 +608,11 @@ static int port_set_format(struct spa_node *node,
|
|||
"I", &info.media_type,
|
||||
"I", &info.media_subtype);
|
||||
|
||||
if (info.media_type != t->media_type.audio ||
|
||||
info.media_subtype != t->media_subtype.raw)
|
||||
if (info.media_type != SPA_MEDIA_TYPE_audio ||
|
||||
info.media_subtype != SPA_MEDIA_SUBTYPE_raw)
|
||||
return -EINVAL;
|
||||
|
||||
if (spa_format_audio_raw_parse(format, &info.info.raw, &t->format_audio) < 0)
|
||||
if (spa_format_audio_raw_parse(format, &info.info.raw) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
if ((this->have_format || this->force_rate) &&
|
||||
|
|
@ -658,7 +623,7 @@ static int port_set_format(struct spa_node *node,
|
|||
if (info.info.raw.channels != this->port_count)
|
||||
return -EINVAL;
|
||||
} else {
|
||||
if (info.info.raw.format != t->audio_format.F32)
|
||||
if (info.info.raw.format != SPA_AUDIO_FORMAT_F32)
|
||||
return -EINVAL;
|
||||
if (info.info.raw.layout != SPA_AUDIO_LAYOUT_NON_INTERLEAVED)
|
||||
return -EINVAL;
|
||||
|
|
@ -667,7 +632,7 @@ static int port_set_format(struct spa_node *node,
|
|||
}
|
||||
|
||||
port->format = info;
|
||||
port->stride = calc_width(&info, t);
|
||||
port->stride = calc_width(&info);
|
||||
if (info.info.raw.layout == SPA_AUDIO_LAYOUT_INTERLEAVED) {
|
||||
port->stride *= info.info.raw.channels;
|
||||
port->blocks = 1;
|
||||
|
|
@ -700,20 +665,19 @@ impl_node_port_set_param(struct spa_node *node,
|
|||
const struct spa_pod *param)
|
||||
{
|
||||
struct impl *this;
|
||||
struct type *t;
|
||||
|
||||
spa_return_val_if_fail(node != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
t = &this->type;
|
||||
|
||||
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
|
||||
|
||||
if (id == t->param.idFormat) {
|
||||
switch (id) {
|
||||
case SPA_ID_PARAM_Format:
|
||||
return port_set_format(node, direction, port_id, flags, param);
|
||||
}
|
||||
else
|
||||
default:
|
||||
return -ENOENT;
|
||||
}
|
||||
}
|
||||
|
||||
static void queue_buffer(struct impl *this, struct port *port, uint32_t id)
|
||||
|
|
@ -755,12 +719,10 @@ impl_node_port_use_buffers(struct spa_node *node,
|
|||
struct impl *this;
|
||||
struct port *port;
|
||||
uint32_t i;
|
||||
struct type *t;
|
||||
|
||||
spa_return_val_if_fail(node != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
t = &this->type;
|
||||
|
||||
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
|
||||
|
||||
|
|
@ -780,9 +742,9 @@ impl_node_port_use_buffers(struct spa_node *node,
|
|||
b->buf = buffers[i];
|
||||
b->flags = 0;
|
||||
|
||||
if (!((d[0].type == t->data.MemPtr ||
|
||||
d[0].type == t->data.MemFd ||
|
||||
d[0].type == t->data.DmaBuf) && d[0].data != NULL)) {
|
||||
if (!((d[0].type == SPA_DATA_MemPtr ||
|
||||
d[0].type == SPA_DATA_MemFd ||
|
||||
d[0].type == SPA_DATA_DmaBuf) && d[0].data != NULL)) {
|
||||
spa_log_error(this->log, NAME " %p: invalid memory on buffer %p %d %p", this,
|
||||
buffers[i], d[0].type, d[0].data);
|
||||
return -EINVAL;
|
||||
|
|
@ -814,24 +776,25 @@ impl_node_port_set_io(struct spa_node *node,
|
|||
{
|
||||
struct impl *this;
|
||||
struct port *port;
|
||||
struct type *t;
|
||||
|
||||
spa_return_val_if_fail(node != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
t = &this->type;
|
||||
|
||||
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
|
||||
|
||||
port = GET_PORT(this, direction, port_id);
|
||||
|
||||
if (id == t->io.Buffers)
|
||||
switch (id) {
|
||||
case SPA_ID_IO_Buffers:
|
||||
port->io = data;
|
||||
else if (id == t->io.ControlRange)
|
||||
break;
|
||||
case SPA_ID_IO_ControlRange:
|
||||
port->ctrl = data;
|
||||
else
|
||||
break;
|
||||
default:
|
||||
return -ENOENT;
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -983,7 +946,7 @@ static int impl_get_interface(struct spa_handle *handle, uint32_t interface_id,
|
|||
|
||||
this = (struct impl *) handle;
|
||||
|
||||
if (interface_id == this->type.node)
|
||||
if (interface_id == SPA_ID_INTERFACE_Node)
|
||||
*interface = &this->node;
|
||||
else
|
||||
return -ENOENT;
|
||||
|
|
@ -1026,16 +989,9 @@ impl_init(const struct spa_handle_factory *factory,
|
|||
this = (struct impl *) handle;
|
||||
|
||||
for (i = 0; i < n_support; i++) {
|
||||
if (strcmp(support[i].type, SPA_TYPE__TypeMap) == 0)
|
||||
this->map = support[i].data;
|
||||
else if (strcmp(support[i].type, SPA_TYPE__Log) == 0)
|
||||
if (support[i].type == SPA_ID_INTERFACE_Log)
|
||||
this->log = support[i].data;
|
||||
}
|
||||
if (this->map == NULL) {
|
||||
spa_log_error(this->log, "an id-map is needed");
|
||||
return -EINVAL;
|
||||
}
|
||||
init_type(&this->type, this->map);
|
||||
|
||||
if ((str = spa_dict_lookup(info, "node.format.rate")))
|
||||
if ((rate = atoi(str)) != 0) {
|
||||
|
|
@ -1056,7 +1012,7 @@ impl_init(const struct spa_handle_factory *factory,
|
|||
}
|
||||
|
||||
static const struct spa_interface_info impl_interfaces[] = {
|
||||
{SPA_TYPE__Node,},
|
||||
{SPA_ID_INTERFACE_Node,},
|
||||
};
|
||||
|
||||
static int
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@
|
|||
#include <speex/speex_resampler.h>
|
||||
|
||||
#include <spa/support/log.h>
|
||||
#include <spa/support/type-map.h>
|
||||
#include <spa/utils/list.h>
|
||||
#include <spa/node/node.h>
|
||||
#include <spa/node/io.h>
|
||||
|
|
@ -79,52 +78,10 @@ struct port {
|
|||
uint32_t offset;
|
||||
};
|
||||
|
||||
struct type {
|
||||
uint32_t node;
|
||||
uint32_t format;
|
||||
uint32_t prop_truncate;
|
||||
uint32_t prop_dither;
|
||||
struct spa_type_io io;
|
||||
struct spa_type_param param;
|
||||
struct spa_type_media_type media_type;
|
||||
struct spa_type_media_subtype media_subtype;
|
||||
struct spa_type_format_audio format_audio;
|
||||
struct spa_type_audio_format audio_format;
|
||||
struct spa_type_command_node command_node;
|
||||
struct spa_type_meta meta;
|
||||
struct spa_type_data data;
|
||||
struct spa_type_param_buffers param_buffers;
|
||||
struct spa_type_param_meta param_meta;
|
||||
struct spa_type_param_io param_io;
|
||||
};
|
||||
|
||||
static inline void init_type(struct type *type, struct spa_type_map *map)
|
||||
{
|
||||
type->node = spa_type_map_get_id(map, SPA_TYPE__Node);
|
||||
type->format = spa_type_map_get_id(map, SPA_TYPE__Format);
|
||||
type->prop_truncate = spa_type_map_get_id(map, SPA_TYPE_PROPS__truncate);
|
||||
type->prop_dither = spa_type_map_get_id(map, SPA_TYPE_PROPS__ditherType);
|
||||
spa_type_io_map(map, &type->io);
|
||||
spa_type_param_map(map, &type->param);
|
||||
spa_type_media_type_map(map, &type->media_type);
|
||||
spa_type_media_subtype_map(map, &type->media_subtype);
|
||||
spa_type_format_audio_map(map, &type->format_audio);
|
||||
spa_type_audio_format_map(map, &type->audio_format);
|
||||
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_buffers_map(map, &type->param_buffers);
|
||||
spa_type_param_meta_map(map, &type->param_meta);
|
||||
spa_type_param_io_map(map, &type->param_io);
|
||||
}
|
||||
|
||||
|
||||
struct impl {
|
||||
struct spa_handle handle;
|
||||
struct spa_node node;
|
||||
|
||||
struct type type;
|
||||
struct spa_type_map *map;
|
||||
struct spa_log *log;
|
||||
|
||||
struct props props;
|
||||
|
|
@ -211,13 +168,16 @@ static int impl_node_send_command(struct spa_node *node, const struct spa_comman
|
|||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
|
||||
if (SPA_COMMAND_TYPE(command) == this->type.command_node.Start) {
|
||||
switch (SPA_COMMAND_TYPE(command)) {
|
||||
case SPA_ID_COMMAND_NODE_Start:
|
||||
this->started = true;
|
||||
} else if (SPA_COMMAND_TYPE(command) == this->type.command_node.Pause) {
|
||||
break;
|
||||
case SPA_ID_COMMAND_NODE_Pause:
|
||||
this->started = false;
|
||||
} else
|
||||
break;
|
||||
default:
|
||||
return -ENOTSUP;
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -316,7 +276,6 @@ static int port_enum_formats(struct spa_node *node,
|
|||
struct spa_pod_builder *builder)
|
||||
{
|
||||
struct impl *this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
struct type *t = &this->type;
|
||||
struct port *other;
|
||||
|
||||
other = GET_PORT(this, SPA_DIRECTION_REVERSE(direction), 0);
|
||||
|
|
@ -325,24 +284,24 @@ static int port_enum_formats(struct spa_node *node,
|
|||
case 0:
|
||||
if (other->have_format) {
|
||||
*param = spa_pod_builder_object(builder,
|
||||
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.layout, "i", SPA_AUDIO_LAYOUT_NON_INTERLEAVED,
|
||||
":", t->format_audio.rate, "iru", other->format.info.raw.rate,
|
||||
SPA_ID_PARAM_EnumFormat, SPA_ID_OBJECT_Format,
|
||||
"I", SPA_MEDIA_TYPE_audio,
|
||||
"I", SPA_MEDIA_SUBTYPE_raw,
|
||||
":", SPA_FORMAT_AUDIO_format, "I", SPA_AUDIO_FORMAT_F32,
|
||||
":", SPA_FORMAT_AUDIO_layout, "i", SPA_AUDIO_LAYOUT_NON_INTERLEAVED,
|
||||
":", SPA_FORMAT_AUDIO_rate, "iru", other->format.info.raw.rate,
|
||||
SPA_POD_PROP_MIN_MAX(1, INT32_MAX),
|
||||
":", t->format_audio.channels, "i", other->format.info.raw.channels);
|
||||
":", SPA_FORMAT_AUDIO_channels, "i", other->format.info.raw.channels);
|
||||
} else {
|
||||
*param = spa_pod_builder_object(builder,
|
||||
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.layout, "i", SPA_AUDIO_LAYOUT_NON_INTERLEAVED,
|
||||
":", t->format_audio.rate, "iru", DEFAULT_RATE,
|
||||
SPA_ID_PARAM_EnumFormat, SPA_ID_OBJECT_Format,
|
||||
"I", SPA_MEDIA_TYPE_audio,
|
||||
"I", SPA_MEDIA_SUBTYPE_raw,
|
||||
":", SPA_FORMAT_AUDIO_format, "I", SPA_AUDIO_FORMAT_F32,
|
||||
":", SPA_FORMAT_AUDIO_layout, "i", SPA_AUDIO_LAYOUT_NON_INTERLEAVED,
|
||||
":", SPA_FORMAT_AUDIO_rate, "iru", DEFAULT_RATE,
|
||||
SPA_POD_PROP_MIN_MAX(1, INT32_MAX),
|
||||
":", t->format_audio.channels, "iru", DEFAULT_CHANNELS,
|
||||
":", SPA_FORMAT_AUDIO_channels, "iru", DEFAULT_CHANNELS,
|
||||
SPA_POD_PROP_MIN_MAX(1, INT32_MAX));
|
||||
}
|
||||
break;
|
||||
|
|
@ -359,7 +318,6 @@ static int port_get_format(struct spa_node *node,
|
|||
struct spa_pod_builder *builder)
|
||||
{
|
||||
struct impl *this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
struct type *t = &this->type;
|
||||
struct port *port = GET_PORT(this, direction, port_id);
|
||||
|
||||
if (!port->have_format)
|
||||
|
|
@ -368,13 +326,13 @@ static int port_get_format(struct spa_node *node,
|
|||
return 0;
|
||||
|
||||
*param = spa_pod_builder_object(builder,
|
||||
t->param.idFormat, t->format,
|
||||
"I", t->media_type.audio,
|
||||
"I", t->media_subtype.raw,
|
||||
":", t->format_audio.format, "I", port->format.info.raw.format,
|
||||
":", t->format_audio.layout, "i", port->format.info.raw.layout,
|
||||
":", t->format_audio.rate, "i", port->format.info.raw.rate,
|
||||
":", t->format_audio.channels, "i", port->format.info.raw.channels);
|
||||
SPA_ID_PARAM_Format, SPA_ID_OBJECT_Format,
|
||||
"I", SPA_MEDIA_TYPE_audio,
|
||||
"I", SPA_MEDIA_SUBTYPE_raw,
|
||||
":", SPA_FORMAT_AUDIO_format, "I", port->format.info.raw.format,
|
||||
":", SPA_FORMAT_AUDIO_layout, "i", port->format.info.raw.layout,
|
||||
":", SPA_FORMAT_AUDIO_rate, "i", port->format.info.raw.rate,
|
||||
":", SPA_FORMAT_AUDIO_channels, "i", port->format.info.raw.channels);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -388,7 +346,6 @@ impl_node_port_enum_params(struct spa_node *node,
|
|||
struct spa_pod_builder *builder)
|
||||
{
|
||||
struct impl *this;
|
||||
struct type *t;
|
||||
struct port *port, *other;
|
||||
struct spa_pod *param;
|
||||
struct spa_pod_builder b = { 0 };
|
||||
|
|
@ -400,7 +357,6 @@ impl_node_port_enum_params(struct spa_node *node,
|
|||
spa_return_val_if_fail(builder != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
t = &this->type;
|
||||
|
||||
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
|
||||
|
||||
|
|
@ -410,28 +366,32 @@ impl_node_port_enum_params(struct spa_node *node,
|
|||
next:
|
||||
spa_pod_builder_init(&b, buffer, sizeof(buffer));
|
||||
|
||||
if (id == t->param.idList) {
|
||||
uint32_t list[] = { t->param.idEnumFormat,
|
||||
t->param.idFormat,
|
||||
t->param.idBuffers,
|
||||
t->param.idMeta,
|
||||
t->param_io.idBuffers };
|
||||
switch (id) {
|
||||
case SPA_ID_PARAM_List:
|
||||
{
|
||||
uint32_t list[] = { SPA_ID_PARAM_EnumFormat,
|
||||
SPA_ID_PARAM_Format,
|
||||
SPA_ID_PARAM_Buffers,
|
||||
SPA_ID_PARAM_Meta,
|
||||
SPA_ID_PARAM_IO };
|
||||
|
||||
if (*index < SPA_N_ELEMENTS(list))
|
||||
param = spa_pod_builder_object(&b, id, t->param.List,
|
||||
":", t->param.listId, "I", list[*index]);
|
||||
param = spa_pod_builder_object(&b, id, SPA_ID_OBJECT_ParamList,
|
||||
":", SPA_PARAM_LIST_id, "I", list[*index]);
|
||||
else
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
else if (id == t->param.idEnumFormat) {
|
||||
case SPA_ID_PARAM_EnumFormat:
|
||||
if ((res = port_enum_formats(node, direction, port_id, index, ¶m, &b)) <= 0)
|
||||
return res;
|
||||
}
|
||||
else if (id == t->param.idFormat) {
|
||||
break;
|
||||
case SPA_ID_PARAM_Format:
|
||||
if ((res = port_get_format(node, direction, port_id, index, ¶m, &b)) <= 0)
|
||||
return res;
|
||||
}
|
||||
else if (id == t->param.idBuffers) {
|
||||
break;
|
||||
case SPA_ID_PARAM_Buffers:
|
||||
{
|
||||
uint32_t buffers, size;
|
||||
|
||||
if (!port->have_format)
|
||||
|
|
@ -449,44 +409,46 @@ impl_node_port_enum_params(struct spa_node *node,
|
|||
}
|
||||
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param_buffers.Buffers,
|
||||
":", t->param_buffers.buffers, "iru", buffers,
|
||||
id, SPA_ID_OBJECT_ParamBuffers,
|
||||
":", SPA_PARAM_BUFFERS_buffers, "iru", buffers,
|
||||
SPA_POD_PROP_MIN_MAX(1, MAX_BUFFERS),
|
||||
":", t->param_buffers.blocks, "i", port->blocks,
|
||||
":", t->param_buffers.size, "iru", size * port->stride,
|
||||
":", SPA_PARAM_BUFFERS_blocks, "i", port->blocks,
|
||||
":", SPA_PARAM_BUFFERS_size, "iru", size * port->stride,
|
||||
SPA_POD_PROP_MIN_MAX(16 * port->stride, INT32_MAX / port->stride),
|
||||
":", t->param_buffers.stride, "i", port->stride,
|
||||
":", t->param_buffers.align, "i", 16);
|
||||
":", SPA_PARAM_BUFFERS_stride, "i", port->stride,
|
||||
":", SPA_PARAM_BUFFERS_align, "i", 16);
|
||||
break;
|
||||
}
|
||||
else if (id == t->param.idMeta) {
|
||||
case SPA_ID_PARAM_Meta:
|
||||
if (!port->have_format)
|
||||
return -EIO;
|
||||
|
||||
switch (*index) {
|
||||
case 0:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param_meta.Meta,
|
||||
":", t->param_meta.type, "I", t->meta.Header,
|
||||
":", t->param_meta.size, "i", sizeof(struct spa_meta_header));
|
||||
id, SPA_ID_OBJECT_ParamMeta,
|
||||
":", SPA_PARAM_META_type, "I", SPA_META_Header,
|
||||
":", SPA_PARAM_META_size, "i", sizeof(struct spa_meta_header));
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if (id == t->param_io.idBuffers) {
|
||||
break;
|
||||
case SPA_ID_PARAM_IO:
|
||||
switch (*index) {
|
||||
case 0:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param_io.Buffers,
|
||||
":", t->param_io.id, "I", t->io.Buffers,
|
||||
":", t->param_io.size, "i", sizeof(struct spa_io_buffers));
|
||||
id, SPA_ID_OBJECT_ParamIO,
|
||||
":", SPA_PARAM_IO_id, "I", SPA_ID_IO_Buffers,
|
||||
":", SPA_PARAM_IO_size, "i", sizeof(struct spa_io_buffers));
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
break;
|
||||
default:
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
(*index)++;
|
||||
|
||||
|
|
@ -514,7 +476,6 @@ static int port_set_format(struct spa_node *node,
|
|||
{
|
||||
struct impl *this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
struct port *port, *other;
|
||||
struct type *t = &this->type;
|
||||
int res = 0;
|
||||
|
||||
port = GET_PORT(this, direction, port_id);
|
||||
|
|
@ -532,14 +493,14 @@ static int port_set_format(struct spa_node *node,
|
|||
"I", &info.media_type,
|
||||
"I", &info.media_subtype);
|
||||
|
||||
if (info.media_type != t->media_type.audio ||
|
||||
info.media_subtype != t->media_subtype.raw)
|
||||
if (info.media_type != SPA_MEDIA_TYPE_audio ||
|
||||
info.media_subtype != SPA_MEDIA_SUBTYPE_raw)
|
||||
return -EINVAL;
|
||||
|
||||
if (spa_format_audio_raw_parse(format, &info.info.raw, &t->format_audio) < 0)
|
||||
if (spa_format_audio_raw_parse(format, &info.info.raw) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (info.info.raw.format != t->audio_format.F32)
|
||||
if (info.info.raw.format != SPA_AUDIO_FORMAT_F32)
|
||||
return -EINVAL;
|
||||
if (info.info.raw.layout != SPA_AUDIO_LAYOUT_NON_INTERLEAVED)
|
||||
return -EINVAL;
|
||||
|
|
@ -565,17 +526,11 @@ impl_node_port_set_param(struct spa_node *node,
|
|||
uint32_t id, uint32_t flags,
|
||||
const struct spa_pod *param)
|
||||
{
|
||||
struct impl *this;
|
||||
struct type *t;
|
||||
|
||||
spa_return_val_if_fail(node != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
t = &this->type;
|
||||
spa_return_val_if_fail(CHECK_PORT(node, direction, port_id), -EINVAL);
|
||||
|
||||
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
|
||||
|
||||
if (id == t->param.idFormat) {
|
||||
if (id == SPA_ID_PARAM_Format) {
|
||||
return port_set_format(node, direction, port_id, flags, param);
|
||||
}
|
||||
else
|
||||
|
|
@ -592,12 +547,10 @@ impl_node_port_use_buffers(struct spa_node *node,
|
|||
struct impl *this;
|
||||
struct port *port;
|
||||
uint32_t i, size = SPA_ID_INVALID;
|
||||
struct type *t;
|
||||
|
||||
spa_return_val_if_fail(node != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
t = &this->type;
|
||||
|
||||
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
|
||||
|
||||
|
|
@ -616,7 +569,7 @@ impl_node_port_use_buffers(struct spa_node *node,
|
|||
b = &port->buffers[i];
|
||||
b->flags = 0;
|
||||
b->outbuf = buffers[i];
|
||||
b->h = spa_buffer_find_meta_data(buffers[i], t->meta.Header, sizeof(*b->h));
|
||||
b->h = spa_buffer_find_meta_data(buffers[i], SPA_META_Header, sizeof(*b->h));
|
||||
|
||||
if (size == SPA_ID_INVALID)
|
||||
size = d[0].maxsize;
|
||||
|
|
@ -624,9 +577,9 @@ impl_node_port_use_buffers(struct spa_node *node,
|
|||
if (size != d[0].maxsize)
|
||||
return -EINVAL;
|
||||
|
||||
if (!((d[0].type == t->data.MemPtr ||
|
||||
d[0].type == t->data.MemFd ||
|
||||
d[0].type == t->data.DmaBuf) && d[0].data != NULL)) {
|
||||
if (!((d[0].type == SPA_DATA_MemPtr ||
|
||||
d[0].type == SPA_DATA_MemFd ||
|
||||
d[0].type == SPA_DATA_DmaBuf) && d[0].data != NULL)) {
|
||||
spa_log_error(this->log, NAME " %p: invalid memory on buffer %p", this,
|
||||
buffers[i]);
|
||||
return -EINVAL;
|
||||
|
|
@ -663,20 +616,18 @@ impl_node_port_set_io(struct spa_node *node,
|
|||
{
|
||||
struct impl *this;
|
||||
struct port *port;
|
||||
struct type *t;
|
||||
|
||||
spa_return_val_if_fail(node != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
t = &this->type;
|
||||
|
||||
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
|
||||
|
||||
port = GET_PORT(this, direction, port_id);
|
||||
|
||||
if (id == t->io.Buffers)
|
||||
if (id == SPA_ID_IO_Buffers)
|
||||
port->io = data;
|
||||
else if (id == t->io.ControlRange)
|
||||
else if (id == SPA_ID_IO_ControlRange)
|
||||
port->ctrl = data;
|
||||
else
|
||||
return -ENOENT;
|
||||
|
|
@ -859,7 +810,7 @@ static int impl_get_interface(struct spa_handle *handle, uint32_t interface_id,
|
|||
|
||||
this = (struct impl *) handle;
|
||||
|
||||
if (interface_id == this->type.node)
|
||||
if (interface_id == SPA_ID_INTERFACE_Node)
|
||||
*interface = &this->node;
|
||||
else
|
||||
return -ENOENT;
|
||||
|
|
@ -907,16 +858,9 @@ impl_init(const struct spa_handle_factory *factory,
|
|||
this = (struct impl *) handle;
|
||||
|
||||
for (i = 0; i < n_support; i++) {
|
||||
if (strcmp(support[i].type, SPA_TYPE__TypeMap) == 0)
|
||||
this->map = support[i].data;
|
||||
else if (strcmp(support[i].type, SPA_TYPE__Log) == 0)
|
||||
if (support[i].type == SPA_ID_INTERFACE_Log)
|
||||
this->log = support[i].data;
|
||||
}
|
||||
if (this->map == NULL) {
|
||||
spa_log_error(this->log, "an id-map is needed");
|
||||
return -EINVAL;
|
||||
}
|
||||
init_type(&this->type, this->map);
|
||||
|
||||
this->node = impl_node;
|
||||
|
||||
|
|
@ -936,7 +880,7 @@ impl_init(const struct spa_handle_factory *factory,
|
|||
}
|
||||
|
||||
static const struct spa_interface_info impl_interfaces[] = {
|
||||
{SPA_TYPE__Node,},
|
||||
{SPA_ID_INTERFACE_Node,},
|
||||
};
|
||||
|
||||
static int
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@
|
|||
#include <limits.h>
|
||||
|
||||
#include <spa/support/log.h>
|
||||
#include <spa/support/type-map.h>
|
||||
#include <spa/utils/list.h>
|
||||
#include <spa/node/node.h>
|
||||
#include <spa/node/io.h>
|
||||
|
|
@ -32,6 +31,7 @@
|
|||
#include <spa/param/meta.h>
|
||||
#include <spa/param/io.h>
|
||||
#include <spa/pod/filter.h>
|
||||
#include <spa/debug/types.h>
|
||||
|
||||
#define NAME "splitter"
|
||||
|
||||
|
|
@ -41,41 +41,6 @@
|
|||
#define MAX_BUFFERS 64
|
||||
#define MAX_PORTS 128
|
||||
|
||||
struct type {
|
||||
uint32_t node;
|
||||
uint32_t format;
|
||||
struct spa_type_io io;
|
||||
struct spa_type_param param;
|
||||
struct spa_type_media_type media_type;
|
||||
struct spa_type_media_subtype media_subtype;
|
||||
struct spa_type_format_audio format_audio;
|
||||
struct spa_type_audio_format audio_format;
|
||||
struct spa_type_command_node command_node;
|
||||
struct spa_type_meta meta;
|
||||
struct spa_type_data data;
|
||||
struct spa_type_param_buffers param_buffers;
|
||||
struct spa_type_param_meta param_meta;
|
||||
struct spa_type_param_io param_io;
|
||||
};
|
||||
|
||||
static inline void init_type(struct type *type, struct spa_type_map *map)
|
||||
{
|
||||
type->node = spa_type_map_get_id(map, SPA_TYPE__Node);
|
||||
type->format = spa_type_map_get_id(map, SPA_TYPE__Format);
|
||||
spa_type_io_map(map, &type->io);
|
||||
spa_type_param_map(map, &type->param);
|
||||
spa_type_media_type_map(map, &type->media_type);
|
||||
spa_type_media_subtype_map(map, &type->media_subtype);
|
||||
spa_type_format_audio_map(map, &type->format_audio);
|
||||
spa_type_audio_format_map(map, &type->audio_format);
|
||||
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_buffers_map(map, &type->param_buffers);
|
||||
spa_type_param_meta_map(map, &type->param_meta);
|
||||
spa_type_param_io_map(map, &type->param_io);
|
||||
}
|
||||
|
||||
struct buffer {
|
||||
#define BUFFER_FLAG_QUEUED (1<<0)
|
||||
uint32_t flags;
|
||||
|
|
@ -109,8 +74,6 @@ struct impl {
|
|||
struct spa_handle handle;
|
||||
struct spa_node node;
|
||||
|
||||
struct type type;
|
||||
struct spa_type_map *map;
|
||||
struct spa_log *log;
|
||||
|
||||
const struct spa_node_callbacks *callbacks;
|
||||
|
|
@ -164,13 +127,16 @@ static int impl_node_send_command(struct spa_node *node, const struct spa_comman
|
|||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
|
||||
if (SPA_COMMAND_TYPE(command) == this->type.command_node.Start) {
|
||||
switch (SPA_COMMAND_TYPE(command)) {
|
||||
case SPA_ID_COMMAND_NODE_Start:
|
||||
this->started = true;
|
||||
} else if (SPA_COMMAND_TYPE(command) == this->type.command_node.Pause) {
|
||||
break;
|
||||
case SPA_ID_COMMAND_NODE_Pause:
|
||||
this->started = false;
|
||||
} else
|
||||
break;
|
||||
default:
|
||||
return -ENOTSUP;
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -339,7 +305,6 @@ static int port_enum_formats(struct spa_node *node,
|
|||
struct spa_pod_builder *builder)
|
||||
{
|
||||
struct impl *this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
struct type *t = &this->type;
|
||||
uint32_t rate;
|
||||
const char *rspec;
|
||||
|
||||
|
|
@ -356,39 +321,39 @@ static int port_enum_formats(struct spa_node *node,
|
|||
|
||||
if (direction == SPA_DIRECTION_INPUT) {
|
||||
*param = spa_pod_builder_object(builder,
|
||||
t->param.idEnumFormat, t->format,
|
||||
"I", t->media_type.audio,
|
||||
"I", t->media_subtype.raw,
|
||||
":", t->format_audio.format, "Ieu", t->audio_format.F32,
|
||||
SPA_ID_PARAM_EnumFormat, SPA_ID_OBJECT_Format,
|
||||
"I", SPA_MEDIA_TYPE_audio,
|
||||
"I", SPA_MEDIA_SUBTYPE_raw,
|
||||
":", SPA_FORMAT_AUDIO_format, "Ieu", SPA_AUDIO_FORMAT_F32,
|
||||
SPA_POD_PROP_ENUM(11,
|
||||
t->audio_format.F32,
|
||||
t->audio_format.F32_OE,
|
||||
t->audio_format.S32,
|
||||
t->audio_format.S32_OE,
|
||||
t->audio_format.S24_32,
|
||||
t->audio_format.S24_32_OE,
|
||||
t->audio_format.S24,
|
||||
t->audio_format.S24_OE,
|
||||
t->audio_format.S16,
|
||||
t->audio_format.S16_OE,
|
||||
t->audio_format.U8),
|
||||
":", t->format_audio.layout, "ieu", SPA_AUDIO_LAYOUT_INTERLEAVED,
|
||||
SPA_AUDIO_FORMAT_F32,
|
||||
SPA_AUDIO_FORMAT_F32_OE,
|
||||
SPA_AUDIO_FORMAT_S32,
|
||||
SPA_AUDIO_FORMAT_S32_OE,
|
||||
SPA_AUDIO_FORMAT_S24_32,
|
||||
SPA_AUDIO_FORMAT_S24_32_OE,
|
||||
SPA_AUDIO_FORMAT_S24,
|
||||
SPA_AUDIO_FORMAT_S24_OE,
|
||||
SPA_AUDIO_FORMAT_S16,
|
||||
SPA_AUDIO_FORMAT_S16_OE,
|
||||
SPA_AUDIO_FORMAT_U8),
|
||||
":", SPA_FORMAT_AUDIO_layout, "ieu", SPA_AUDIO_LAYOUT_INTERLEAVED,
|
||||
SPA_POD_PROP_ENUM(2, SPA_AUDIO_LAYOUT_INTERLEAVED,
|
||||
SPA_AUDIO_LAYOUT_NON_INTERLEAVED),
|
||||
":", t->format_audio.rate, rspec, rate,
|
||||
":", SPA_FORMAT_AUDIO_rate, rspec, rate,
|
||||
SPA_POD_PROP_MIN_MAX(1, INT32_MAX),
|
||||
":", t->format_audio.channels, "i", this->port_count);
|
||||
":", SPA_FORMAT_AUDIO_channels, "i", this->port_count);
|
||||
}
|
||||
else {
|
||||
*param = spa_pod_builder_object(builder,
|
||||
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.layout, "i", SPA_AUDIO_LAYOUT_NON_INTERLEAVED,
|
||||
":", t->format_audio.rate, rspec, rate,
|
||||
SPA_ID_PARAM_EnumFormat, SPA_ID_OBJECT_Format,
|
||||
"I", SPA_MEDIA_TYPE_audio,
|
||||
"I", SPA_MEDIA_SUBTYPE_raw,
|
||||
":", SPA_FORMAT_AUDIO_format, "I", SPA_AUDIO_FORMAT_F32,
|
||||
":", SPA_FORMAT_AUDIO_layout, "i", SPA_AUDIO_LAYOUT_NON_INTERLEAVED,
|
||||
":", SPA_FORMAT_AUDIO_rate, rspec, rate,
|
||||
SPA_POD_PROP_MIN_MAX(1, INT32_MAX),
|
||||
":", t->format_audio.channels, "i", 1);
|
||||
":", SPA_FORMAT_AUDIO_channels, "i", 1);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
|
@ -404,7 +369,6 @@ static int port_get_format(struct spa_node *node,
|
|||
struct spa_pod_builder *builder)
|
||||
{
|
||||
struct impl *this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
struct type *t = &this->type;
|
||||
struct port *port = GET_PORT(this, direction, port_id);
|
||||
|
||||
if (!port->have_format)
|
||||
|
|
@ -413,13 +377,13 @@ static int port_get_format(struct spa_node *node,
|
|||
return 0;
|
||||
|
||||
*param = spa_pod_builder_object(builder,
|
||||
t->param.idFormat, t->format,
|
||||
"I", t->media_type.audio,
|
||||
"I", t->media_subtype.raw,
|
||||
":", t->format_audio.format, "I", port->format.info.raw.format,
|
||||
":", t->format_audio.layout, "i", port->format.info.raw.layout,
|
||||
":", t->format_audio.rate, "i", port->format.info.raw.rate,
|
||||
":", t->format_audio.channels, "i", port->format.info.raw.channels);
|
||||
SPA_ID_PARAM_Format, SPA_ID_OBJECT_Format,
|
||||
"I", SPA_MEDIA_TYPE_audio,
|
||||
"I", SPA_MEDIA_SUBTYPE_raw,
|
||||
":", SPA_FORMAT_AUDIO_format, "I", port->format.info.raw.format,
|
||||
":", SPA_FORMAT_AUDIO_layout, "i", port->format.info.raw.layout,
|
||||
":", SPA_FORMAT_AUDIO_rate, "i", port->format.info.raw.rate,
|
||||
":", SPA_FORMAT_AUDIO_channels, "i", port->format.info.raw.channels);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -433,7 +397,6 @@ impl_node_port_enum_params(struct spa_node *node,
|
|||
struct spa_pod_builder *builder)
|
||||
{
|
||||
struct impl *this;
|
||||
struct type *t;
|
||||
struct port *port;
|
||||
struct spa_pod *param;
|
||||
struct spa_pod_builder b = { 0 };
|
||||
|
|
@ -445,7 +408,6 @@ impl_node_port_enum_params(struct spa_node *node,
|
|||
spa_return_val_if_fail(builder != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
t = &this->type;
|
||||
|
||||
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
|
||||
|
||||
|
|
@ -456,72 +418,77 @@ impl_node_port_enum_params(struct spa_node *node,
|
|||
|
||||
spa_log_debug(this->log, NAME " %p: enum param %d %d", this, id, this->have_format);
|
||||
|
||||
if (id == t->param.idList) {
|
||||
uint32_t list[] = { t->param.idEnumFormat,
|
||||
t->param.idFormat,
|
||||
t->param.idBuffers,
|
||||
t->param.idMeta,
|
||||
t->param_io.idBuffers };
|
||||
switch (id) {
|
||||
case SPA_ID_PARAM_List:
|
||||
{
|
||||
uint32_t list[] = { SPA_ID_PARAM_EnumFormat,
|
||||
SPA_ID_PARAM_Format,
|
||||
SPA_ID_PARAM_Buffers,
|
||||
SPA_ID_PARAM_Meta,
|
||||
SPA_ID_PARAM_IO };
|
||||
|
||||
if (*index < SPA_N_ELEMENTS(list))
|
||||
param = spa_pod_builder_object(&b, id, t->param.List,
|
||||
":", t->param.listId, "I", list[*index]);
|
||||
param = spa_pod_builder_object(&b, id, SPA_ID_OBJECT_ParamList,
|
||||
":", SPA_PARAM_LIST_id, "I", list[*index]);
|
||||
else
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
else if (id == t->param.idEnumFormat) {
|
||||
case SPA_ID_PARAM_EnumFormat:
|
||||
if ((res = port_enum_formats(node, direction, port_id, index, ¶m, &b)) <= 0)
|
||||
return res;
|
||||
}
|
||||
else if (id == t->param.idFormat) {
|
||||
break;
|
||||
case SPA_ID_PARAM_Format:
|
||||
if ((res = port_get_format(node, direction, port_id, index, ¶m, &b)) <= 0)
|
||||
return res;
|
||||
}
|
||||
else if (id == t->param.idBuffers) {
|
||||
break;
|
||||
case SPA_ID_PARAM_Buffers:
|
||||
if (!port->have_format)
|
||||
return -EIO;
|
||||
if (*index > 0)
|
||||
return 0;
|
||||
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param_buffers.Buffers,
|
||||
":", t->param_buffers.size, "iru", 1024 * port->stride,
|
||||
SPA_POD_PROP_MIN_MAX(16 * port->stride, MAX_SAMPLES * port->stride),
|
||||
":", t->param_buffers.blocks, "i", port->blocks,
|
||||
":", t->param_buffers.stride, "i", port->stride,
|
||||
":", t->param_buffers.buffers, "iru", 1,
|
||||
id, SPA_ID_OBJECT_ParamBuffers,
|
||||
":", SPA_PARAM_BUFFERS_buffers, "iru", 1,
|
||||
SPA_POD_PROP_MIN_MAX(1, MAX_BUFFERS),
|
||||
":", t->param_buffers.align, "i", 16);
|
||||
}
|
||||
else if (id == t->param.idMeta) {
|
||||
":", SPA_PARAM_BUFFERS_blocks, "i", port->blocks,
|
||||
":", SPA_PARAM_BUFFERS_size, "iru", 1024 * port->stride,
|
||||
SPA_POD_PROP_MIN_MAX(16 * port->stride, MAX_SAMPLES * port->stride),
|
||||
":", SPA_PARAM_BUFFERS_stride, "i", port->stride,
|
||||
":", SPA_PARAM_BUFFERS_align, "i", 16);
|
||||
break;
|
||||
|
||||
case SPA_ID_PARAM_Meta:
|
||||
if (!port->have_format)
|
||||
return -EIO;
|
||||
|
||||
switch (*index) {
|
||||
case 0:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param_meta.Meta,
|
||||
":", t->param_meta.type, "I", t->meta.Header,
|
||||
":", t->param_meta.size, "i", sizeof(struct spa_meta_header));
|
||||
id, SPA_ID_OBJECT_ParamMeta,
|
||||
":", SPA_PARAM_META_type, "I", SPA_META_Header,
|
||||
":", SPA_PARAM_META_size, "i", sizeof(struct spa_meta_header));
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if (id == t->param_io.idBuffers) {
|
||||
break;
|
||||
case SPA_ID_PARAM_IO:
|
||||
switch (*index) {
|
||||
case 0:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param_io.Buffers,
|
||||
":", t->param_io.id, "I", t->io.Buffers,
|
||||
":", t->param_io.size, "i", sizeof(struct spa_io_buffers));
|
||||
id, SPA_ID_OBJECT_ParamIO,
|
||||
":", SPA_PARAM_IO_id, "I", SPA_ID_IO_Buffers,
|
||||
":", SPA_PARAM_IO_size, "i", sizeof(struct spa_io_buffers));
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
break;
|
||||
default:
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
(*index)++;
|
||||
|
||||
|
|
@ -557,7 +524,6 @@ static struct port *find_out_port(struct impl *this)
|
|||
static int setup_convert(struct impl *this)
|
||||
{
|
||||
const struct conv_info *conv;
|
||||
struct type *t = &this->type;
|
||||
struct port *inport, *outport;
|
||||
uint32_t src_fmt, dst_fmt;
|
||||
|
||||
|
|
@ -570,17 +536,17 @@ static int setup_convert(struct impl *this)
|
|||
dst_fmt = outport->format.info.raw.format;
|
||||
|
||||
spa_log_info(this->log, NAME " %p: %s/%d@%d.%dx%d->%s/%d@%d.%d", this,
|
||||
spa_type_map_get_type(this->map, src_fmt),
|
||||
spa_debug_type_find_name(spa_debug_types, src_fmt),
|
||||
inport->format.info.raw.channels,
|
||||
inport->format.info.raw.rate,
|
||||
inport->format.info.raw.layout,
|
||||
this->port_count,
|
||||
spa_type_map_get_type(this->map, dst_fmt),
|
||||
spa_debug_type_find_name(spa_debug_types, dst_fmt),
|
||||
outport->format.info.raw.channels,
|
||||
outport->format.info.raw.rate,
|
||||
outport->format.info.raw.layout);
|
||||
|
||||
conv = find_conv_info(&t->audio_format, src_fmt, dst_fmt, FEATURE_SSE);
|
||||
conv = find_conv_info(src_fmt, dst_fmt, FEATURE_SSE);
|
||||
if (conv != NULL) {
|
||||
spa_log_info(this->log, NAME " %p: got converter features %08x", this,
|
||||
conv->features);
|
||||
|
|
@ -601,18 +567,20 @@ static int setup_convert(struct impl *this)
|
|||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
static int calc_width(struct spa_audio_info *info, struct type *t)
|
||||
static int calc_width(struct spa_audio_info *info)
|
||||
{
|
||||
if (info->info.raw.format == t->audio_format.U8)
|
||||
switch (info->info.raw.format) {
|
||||
case SPA_AUDIO_FORMAT_U8:
|
||||
return 1;
|
||||
else if (info->info.raw.format == t->audio_format.S16 ||
|
||||
info->info.raw.format == t->audio_format.S16_OE)
|
||||
case SPA_AUDIO_FORMAT_S16:
|
||||
case SPA_AUDIO_FORMAT_S16_OE:
|
||||
return 2;
|
||||
else if (info->info.raw.format == t->audio_format.S24 ||
|
||||
info->info.raw.format == t->audio_format.S24_OE)
|
||||
case SPA_AUDIO_FORMAT_S24:
|
||||
case SPA_AUDIO_FORMAT_S24_OE:
|
||||
return 3;
|
||||
else
|
||||
default:
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
|
||||
static int port_set_format(struct spa_node *node,
|
||||
|
|
@ -623,7 +591,6 @@ static int port_set_format(struct spa_node *node,
|
|||
{
|
||||
struct impl *this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
struct port *port;
|
||||
struct type *t = &this->type;
|
||||
|
||||
port = GET_PORT(this, direction, port_id);
|
||||
|
||||
|
|
@ -643,11 +610,11 @@ static int port_set_format(struct spa_node *node,
|
|||
"I", &info.media_type,
|
||||
"I", &info.media_subtype);
|
||||
|
||||
if (info.media_type != t->media_type.audio ||
|
||||
info.media_subtype != t->media_subtype.raw)
|
||||
if (info.media_type != SPA_MEDIA_TYPE_audio ||
|
||||
info.media_subtype != SPA_MEDIA_SUBTYPE_raw)
|
||||
return -EINVAL;
|
||||
|
||||
if (spa_format_audio_raw_parse(format, &info.info.raw, &t->format_audio) < 0)
|
||||
if (spa_format_audio_raw_parse(format, &info.info.raw) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
if ((this->have_format || this->force_rate) &&
|
||||
|
|
@ -658,7 +625,7 @@ static int port_set_format(struct spa_node *node,
|
|||
if (info.info.raw.channels != this->port_count)
|
||||
return -EINVAL;
|
||||
} else {
|
||||
if (info.info.raw.format != t->audio_format.F32)
|
||||
if (info.info.raw.format != SPA_AUDIO_FORMAT_F32)
|
||||
return -EINVAL;
|
||||
if (info.info.raw.layout != SPA_AUDIO_LAYOUT_NON_INTERLEAVED)
|
||||
return -EINVAL;
|
||||
|
|
@ -667,7 +634,7 @@ static int port_set_format(struct spa_node *node,
|
|||
}
|
||||
|
||||
port->format = info;
|
||||
port->stride = calc_width(&info, t);
|
||||
port->stride = calc_width(&info);
|
||||
if (info.info.raw.layout == SPA_AUDIO_LAYOUT_INTERLEAVED) {
|
||||
port->stride *= info.info.raw.channels;
|
||||
port->blocks = 1;
|
||||
|
|
@ -700,20 +667,19 @@ impl_node_port_set_param(struct spa_node *node,
|
|||
const struct spa_pod *param)
|
||||
{
|
||||
struct impl *this;
|
||||
struct type *t;
|
||||
|
||||
spa_return_val_if_fail(node != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
t = &this->type;
|
||||
|
||||
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
|
||||
|
||||
if (id == t->param.idFormat) {
|
||||
switch (id) {
|
||||
case SPA_ID_PARAM_Format:
|
||||
return port_set_format(node, direction, port_id, flags, param);
|
||||
}
|
||||
else
|
||||
default:
|
||||
return -ENOENT;
|
||||
}
|
||||
}
|
||||
|
||||
static void queue_buffer(struct impl *this, struct port *port, uint32_t id)
|
||||
|
|
@ -755,12 +721,10 @@ impl_node_port_use_buffers(struct spa_node *node,
|
|||
struct impl *this;
|
||||
struct port *port;
|
||||
uint32_t i;
|
||||
struct type *t;
|
||||
|
||||
spa_return_val_if_fail(node != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
t = &this->type;
|
||||
|
||||
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
|
||||
|
||||
|
|
@ -780,9 +744,9 @@ impl_node_port_use_buffers(struct spa_node *node,
|
|||
b->buf = buffers[i];
|
||||
b->flags = 0;
|
||||
|
||||
if (!((d[0].type == t->data.MemPtr ||
|
||||
d[0].type == t->data.MemFd ||
|
||||
d[0].type == t->data.DmaBuf) && d[0].data != NULL)) {
|
||||
if (!((d[0].type == SPA_DATA_MemPtr ||
|
||||
d[0].type == SPA_DATA_MemFd ||
|
||||
d[0].type == SPA_DATA_DmaBuf) && d[0].data != NULL)) {
|
||||
spa_log_error(this->log, NAME " %p: invalid memory on buffer %p %d %p", this,
|
||||
buffers[i], d[0].type, d[0].data);
|
||||
return -EINVAL;
|
||||
|
|
@ -814,20 +778,18 @@ impl_node_port_set_io(struct spa_node *node,
|
|||
{
|
||||
struct impl *this;
|
||||
struct port *port;
|
||||
struct type *t;
|
||||
|
||||
spa_return_val_if_fail(node != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
t = &this->type;
|
||||
|
||||
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
|
||||
|
||||
port = GET_PORT(this, direction, port_id);
|
||||
|
||||
if (id == t->io.Buffers)
|
||||
if (id == SPA_ID_IO_Buffers)
|
||||
port->io = data;
|
||||
else if (id == t->io.ControlRange)
|
||||
else if (id == SPA_ID_IO_ControlRange)
|
||||
port->ctrl = data;
|
||||
else
|
||||
return -ENOENT;
|
||||
|
|
@ -993,7 +955,7 @@ static int impl_get_interface(struct spa_handle *handle, uint32_t interface_id,
|
|||
|
||||
this = (struct impl *) handle;
|
||||
|
||||
if (interface_id == this->type.node)
|
||||
if (interface_id == SPA_ID_INTERFACE_Node)
|
||||
*interface = &this->node;
|
||||
else
|
||||
return -ENOENT;
|
||||
|
|
@ -1036,16 +998,9 @@ impl_init(const struct spa_handle_factory *factory,
|
|||
this = (struct impl *) handle;
|
||||
|
||||
for (i = 0; i < n_support; i++) {
|
||||
if (strcmp(support[i].type, SPA_TYPE__TypeMap) == 0)
|
||||
this->map = support[i].data;
|
||||
else if (strcmp(support[i].type, SPA_TYPE__Log) == 0)
|
||||
if (support[i].type == SPA_ID_INTERFACE_Log)
|
||||
this->log = support[i].data;
|
||||
}
|
||||
if (this->map == NULL) {
|
||||
spa_log_error(this->log, "an id-map is needed");
|
||||
return -EINVAL;
|
||||
}
|
||||
init_type(&this->type, this->map);
|
||||
|
||||
if ((str = spa_dict_lookup(info, "node.format.rate")))
|
||||
if ((rate = atoi(str)) != 0) {
|
||||
|
|
@ -1065,7 +1020,7 @@ impl_init(const struct spa_handle_factory *factory,
|
|||
}
|
||||
|
||||
static const struct spa_interface_info impl_interfaces[] = {
|
||||
{SPA_TYPE__Node,},
|
||||
{SPA_ID_INTERFACE_Node,},
|
||||
};
|
||||
|
||||
static int
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#include <spa/support/log.h>
|
||||
#include <spa/support/type-map.h>
|
||||
#include <spa/utils/list.h>
|
||||
#include <spa/node/node.h>
|
||||
#include <spa/node/io.h>
|
||||
|
|
@ -84,55 +83,10 @@ struct port {
|
|||
size_t queued_bytes;
|
||||
};
|
||||
|
||||
struct type {
|
||||
uint32_t node;
|
||||
uint32_t format;
|
||||
uint32_t prop_volume;
|
||||
uint32_t prop_mute;
|
||||
uint32_t io_prop_volume;
|
||||
uint32_t io_prop_mute;
|
||||
struct spa_type_io io;
|
||||
struct spa_type_param param;
|
||||
struct spa_type_media_type media_type;
|
||||
struct spa_type_media_subtype media_subtype;
|
||||
struct spa_type_format_audio format_audio;
|
||||
struct spa_type_audio_format audio_format;
|
||||
struct spa_type_command_node command_node;
|
||||
struct spa_type_meta meta;
|
||||
struct spa_type_data data;
|
||||
struct spa_type_param_buffers param_buffers;
|
||||
struct spa_type_param_meta param_meta;
|
||||
struct spa_type_param_io param_io;
|
||||
};
|
||||
|
||||
static inline void init_type(struct type *type, struct spa_type_map *map)
|
||||
{
|
||||
type->node = spa_type_map_get_id(map, SPA_TYPE__Node);
|
||||
type->format = spa_type_map_get_id(map, SPA_TYPE__Format);
|
||||
type->prop_volume = spa_type_map_get_id(map, SPA_TYPE_PROPS__volume);
|
||||
type->prop_mute = spa_type_map_get_id(map, SPA_TYPE_PROPS__mute);
|
||||
type->io_prop_volume = spa_type_map_get_id(map, SPA_TYPE_IO_PROP_BASE "volume");
|
||||
type->io_prop_mute = spa_type_map_get_id(map, SPA_TYPE_IO_PROP_BASE "mute");
|
||||
spa_type_io_map(map, &type->io);
|
||||
spa_type_param_map(map, &type->param);
|
||||
spa_type_media_type_map(map, &type->media_type);
|
||||
spa_type_media_subtype_map(map, &type->media_subtype);
|
||||
spa_type_format_audio_map(map, &type->format_audio);
|
||||
spa_type_audio_format_map(map, &type->audio_format);
|
||||
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_buffers_map(map, &type->param_buffers);
|
||||
spa_type_param_meta_map(map, &type->param_meta);
|
||||
spa_type_param_io_map(map, &type->param_io);
|
||||
}
|
||||
|
||||
struct impl {
|
||||
struct spa_handle handle;
|
||||
struct spa_node node;
|
||||
|
||||
struct type type;
|
||||
struct spa_type_map *map;
|
||||
struct spa_log *log;
|
||||
|
||||
struct spa_audiomixer_ops ops;
|
||||
|
|
@ -191,13 +145,16 @@ static int impl_node_send_command(struct spa_node *node, const struct spa_comman
|
|||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
|
||||
if (SPA_COMMAND_TYPE(command) == this->type.command_node.Start) {
|
||||
switch (SPA_COMMAND_TYPE(command)) {
|
||||
case SPA_ID_COMMAND_NODE_Start:
|
||||
this->started = true;
|
||||
} else if (SPA_COMMAND_TYPE(command) == this->type.command_node.Pause) {
|
||||
break;
|
||||
case SPA_ID_COMMAND_NODE_Pause:
|
||||
this->started = false;
|
||||
} else
|
||||
break;
|
||||
default:
|
||||
return -ENOTSUP;
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -367,29 +324,28 @@ static int port_enum_formats(struct spa_node *node,
|
|||
struct spa_pod_builder *builder)
|
||||
{
|
||||
struct impl *this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
struct type *t = &this->type;
|
||||
|
||||
switch (*index) {
|
||||
case 0:
|
||||
if (this->have_format) {
|
||||
*param = spa_pod_builder_object(builder,
|
||||
t->param.idEnumFormat, t->format,
|
||||
"I", t->media_type.audio,
|
||||
"I", t->media_subtype.raw,
|
||||
":", t->format_audio.format, "I", this->format.info.raw.format,
|
||||
":", t->format_audio.rate, "i", this->format.info.raw.rate,
|
||||
":", t->format_audio.channels, "i", this->format.info.raw.channels);
|
||||
SPA_ID_PARAM_EnumFormat, SPA_ID_OBJECT_Format,
|
||||
"I", SPA_MEDIA_TYPE_audio,
|
||||
"I", SPA_MEDIA_SUBTYPE_raw,
|
||||
":", SPA_FORMAT_AUDIO_format, "I", this->format.info.raw.format,
|
||||
":", SPA_FORMAT_AUDIO_rate, "i", this->format.info.raw.rate,
|
||||
":", SPA_FORMAT_AUDIO_channels, "i", this->format.info.raw.channels);
|
||||
} else {
|
||||
*param = spa_pod_builder_object(builder,
|
||||
t->param.idEnumFormat, t->format,
|
||||
"I", t->media_type.audio,
|
||||
"I", t->media_subtype.raw,
|
||||
":", t->format_audio.format, "Ieu", t->audio_format.S16,
|
||||
SPA_POD_PROP_ENUM(2, t->audio_format.S16,
|
||||
t->audio_format.F32),
|
||||
":", t->format_audio.rate, "iru", 44100,
|
||||
SPA_ID_PARAM_EnumFormat, SPA_ID_OBJECT_Format,
|
||||
"I", SPA_MEDIA_TYPE_audio,
|
||||
"I", SPA_MEDIA_SUBTYPE_raw,
|
||||
":", SPA_FORMAT_AUDIO_format, "Ieu", SPA_AUDIO_FORMAT_S16,
|
||||
SPA_POD_PROP_ENUM(2, SPA_AUDIO_FORMAT_S16,
|
||||
SPA_AUDIO_FORMAT_F32),
|
||||
":", SPA_FORMAT_AUDIO_rate, "iru", 44100,
|
||||
SPA_POD_PROP_MIN_MAX(1, INT32_MAX),
|
||||
":", t->format_audio.channels, "iru", 2,
|
||||
":", SPA_FORMAT_AUDIO_channels, "iru", 2,
|
||||
SPA_POD_PROP_MIN_MAX(1, INT32_MAX));
|
||||
}
|
||||
break;
|
||||
|
|
@ -406,7 +362,6 @@ static int port_get_format(struct spa_node *node,
|
|||
struct spa_pod_builder *builder)
|
||||
{
|
||||
struct impl *this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
struct type *t = &this->type;
|
||||
struct port *port = GET_PORT(this, direction, port_id);
|
||||
|
||||
if (!port->have_format)
|
||||
|
|
@ -415,12 +370,12 @@ static int port_get_format(struct spa_node *node,
|
|||
return 0;
|
||||
|
||||
*param = spa_pod_builder_object(builder,
|
||||
t->param.idFormat, t->format,
|
||||
"I", t->media_type.audio,
|
||||
"I", t->media_subtype.raw,
|
||||
":", t->format_audio.format, "I", this->format.info.raw.format,
|
||||
":", t->format_audio.rate, "i", this->format.info.raw.rate,
|
||||
":", t->format_audio.channels, "i", this->format.info.raw.channels);
|
||||
SPA_ID_PARAM_Format, SPA_ID_OBJECT_Format,
|
||||
"I", SPA_MEDIA_TYPE_audio,
|
||||
"I", SPA_MEDIA_SUBTYPE_raw,
|
||||
":", SPA_FORMAT_AUDIO_format, "I", this->format.info.raw.format,
|
||||
":", SPA_FORMAT_AUDIO_rate, "i", this->format.info.raw.rate,
|
||||
":", SPA_FORMAT_AUDIO_channels, "i", this->format.info.raw.channels);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -434,7 +389,6 @@ impl_node_port_enum_params(struct spa_node *node,
|
|||
struct spa_pod_builder *builder)
|
||||
{
|
||||
struct impl *this;
|
||||
struct type *t;
|
||||
struct port *port;
|
||||
struct spa_pod *param;
|
||||
struct spa_pod_builder b = { 0 };
|
||||
|
|
@ -446,7 +400,6 @@ impl_node_port_enum_params(struct spa_node *node,
|
|||
spa_return_val_if_fail(builder != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
t = &this->type;
|
||||
|
||||
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
|
||||
|
||||
|
|
@ -455,83 +408,79 @@ impl_node_port_enum_params(struct spa_node *node,
|
|||
next:
|
||||
spa_pod_builder_init(&b, buffer, sizeof(buffer));
|
||||
|
||||
if (id == t->param.idList) {
|
||||
uint32_t list[] = { t->param.idEnumFormat,
|
||||
t->param.idFormat,
|
||||
t->param.idBuffers,
|
||||
t->param.idMeta,
|
||||
t->param_io.idBuffers,
|
||||
t->param_io.idControl,
|
||||
t->param_io.idPropsIn };
|
||||
switch (id) {
|
||||
case SPA_ID_PARAM_List:
|
||||
{
|
||||
uint32_t list[] = { SPA_ID_PARAM_EnumFormat,
|
||||
SPA_ID_PARAM_Format,
|
||||
SPA_ID_PARAM_Buffers,
|
||||
SPA_ID_PARAM_Meta,
|
||||
SPA_ID_PARAM_IO, };
|
||||
|
||||
if (*index < SPA_N_ELEMENTS(list))
|
||||
param = spa_pod_builder_object(&b, id, t->param.List,
|
||||
":", t->param.listId, "I", list[*index]);
|
||||
param = spa_pod_builder_object(&b, id, SPA_ID_OBJECT_ParamList,
|
||||
":", SPA_PARAM_LIST_id, "I", list[*index]);
|
||||
else
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
else if (id == t->param.idEnumFormat) {
|
||||
case SPA_ID_PARAM_EnumFormat:
|
||||
if ((res = port_enum_formats(node, direction, port_id, index, ¶m, &b)) <= 0)
|
||||
return res;
|
||||
}
|
||||
else if (id == t->param.idFormat) {
|
||||
break;
|
||||
case SPA_ID_PARAM_Format:
|
||||
if ((res = port_get_format(node, direction, port_id, index, ¶m, &b)) <= 0)
|
||||
return res;
|
||||
}
|
||||
else if (id == t->param.idBuffers) {
|
||||
break;
|
||||
case SPA_ID_PARAM_Buffers:
|
||||
if (!port->have_format)
|
||||
return -EIO;
|
||||
if (*index > 0)
|
||||
return 0;
|
||||
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param_buffers.Buffers,
|
||||
":", t->param_buffers.size, "iru", 1024 * this->bpf,
|
||||
SPA_POD_PROP_MIN_MAX(16 * this->bpf, INT32_MAX / this->bpf),
|
||||
":", t->param_buffers.stride, "i", 0,
|
||||
":", t->param_buffers.buffers, "iru", 1,
|
||||
id, SPA_ID_OBJECT_ParamBuffers,
|
||||
":", SPA_PARAM_BUFFERS_buffers, "iru", 1,
|
||||
SPA_POD_PROP_MIN_MAX(1, MAX_BUFFERS),
|
||||
":", t->param_buffers.align, "i", 16);
|
||||
}
|
||||
else if (id == t->param.idMeta) {
|
||||
":", SPA_PARAM_BUFFERS_blocks, "i", 1,
|
||||
":", SPA_PARAM_BUFFERS_size, "iru", 1024 * this->bpf,
|
||||
SPA_POD_PROP_MIN_MAX(16 * this->bpf, INT32_MAX / this->bpf),
|
||||
":", SPA_PARAM_BUFFERS_stride, "i", 0,
|
||||
":", SPA_PARAM_BUFFERS_align, "i", 16);
|
||||
break;
|
||||
case SPA_ID_PARAM_Meta:
|
||||
if (!port->have_format)
|
||||
return -EIO;
|
||||
|
||||
switch (*index) {
|
||||
case 0:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param_meta.Meta,
|
||||
":", t->param_meta.type, "I", t->meta.Header,
|
||||
":", t->param_meta.size, "i", sizeof(struct spa_meta_header));
|
||||
id, SPA_ID_OBJECT_ParamMeta,
|
||||
":", SPA_PARAM_META_type, "I", SPA_META_Header,
|
||||
":", SPA_PARAM_META_size, "i", sizeof(struct spa_meta_header));
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if (id == t->param_io.idBuffers) {
|
||||
break;
|
||||
case SPA_ID_PARAM_IO:
|
||||
switch (*index) {
|
||||
case 0:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param_io.Buffers,
|
||||
":", t->param_io.id, "I", t->io.Buffers,
|
||||
":", t->param_io.size, "i", sizeof(struct spa_io_buffers));
|
||||
id, SPA_ID_OBJECT_ParamIO,
|
||||
":", SPA_PARAM_IO_id, "I", SPA_ID_IO_Buffers,
|
||||
":", SPA_PARAM_IO_size, "i", sizeof(struct spa_io_buffers));
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if (id == t->param_io.idControl) {
|
||||
switch (*index) {
|
||||
case 0:
|
||||
case 1:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param_io.Control,
|
||||
":", t->param_io.id, "I", t->io.ControlRange,
|
||||
":", t->param_io.size, "i", sizeof(struct spa_io_control_range));
|
||||
id, SPA_ID_OBJECT_ParamIO,
|
||||
":", SPA_PARAM_IO_id, "I", SPA_ID_IO_ControlRange,
|
||||
":", SPA_PARAM_IO_size, "i", sizeof(struct spa_io_control_range));
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
else if (id == t->param_io.idPropsIn) {
|
||||
struct port_props *p = &port->props;
|
||||
|
||||
|
|
@ -560,8 +509,10 @@ impl_node_port_enum_params(struct spa_node *node,
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
default:
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
(*index)++;
|
||||
|
||||
|
|
@ -589,7 +540,6 @@ static int port_set_format(struct spa_node *node,
|
|||
{
|
||||
struct impl *this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
struct port *port;
|
||||
struct type *t = &this->type;
|
||||
|
||||
port = GET_PORT(this, direction, port_id);
|
||||
|
||||
|
|
@ -607,18 +557,18 @@ static int port_set_format(struct spa_node *node,
|
|||
"I", &info.media_type,
|
||||
"I", &info.media_subtype);
|
||||
|
||||
if (info.media_type != t->media_type.audio ||
|
||||
info.media_subtype != t->media_subtype.raw)
|
||||
if (info.media_type != SPA_MEDIA_TYPE_audio ||
|
||||
info.media_subtype != SPA_MEDIA_SUBTYPE_raw)
|
||||
return -EINVAL;
|
||||
|
||||
if (spa_format_audio_raw_parse(format, &info.info.raw, &t->format_audio) < 0)
|
||||
if (spa_format_audio_raw_parse(format, &info.info.raw) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (this->have_format) {
|
||||
if (memcmp(&info, &this->format, sizeof(struct spa_audio_info)))
|
||||
return -EINVAL;
|
||||
} else {
|
||||
if (info.info.raw.format == t->audio_format.S16) {
|
||||
if (info.info.raw.format == SPA_AUDIO_FORMAT_S16) {
|
||||
this->clear = this->ops.clear[FMT_S16];
|
||||
this->copy = this->ops.copy[FMT_S16];
|
||||
this->add = this->ops.add[FMT_S16];
|
||||
|
|
@ -626,7 +576,7 @@ static int port_set_format(struct spa_node *node,
|
|||
this->add_scale = this->ops.add_scale[FMT_S16];
|
||||
this->bpf = sizeof(int16_t) * info.info.raw.channels;
|
||||
}
|
||||
else if (info.info.raw.format == t->audio_format.F32) {
|
||||
else if (info.info.raw.format == SPA_AUDIO_FORMAT_F32) {
|
||||
this->clear = this->ops.clear[FMT_F32];
|
||||
this->copy = this->ops.copy[FMT_F32];
|
||||
this->add = this->ops.add[FMT_F32];
|
||||
|
|
@ -658,16 +608,14 @@ impl_node_port_set_param(struct spa_node *node,
|
|||
const struct spa_pod *param)
|
||||
{
|
||||
struct impl *this;
|
||||
struct type *t;
|
||||
|
||||
spa_return_val_if_fail(node != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
t = &this->type;
|
||||
|
||||
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
|
||||
|
||||
if (id == t->param.idFormat) {
|
||||
if (id == SPA_ID_PARAM_Format) {
|
||||
return port_set_format(node, direction, port_id, flags, param);
|
||||
}
|
||||
else
|
||||
|
|
@ -684,12 +632,10 @@ impl_node_port_use_buffers(struct spa_node *node,
|
|||
struct impl *this;
|
||||
struct port *port;
|
||||
uint32_t i;
|
||||
struct type *t;
|
||||
|
||||
spa_return_val_if_fail(node != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
t = &this->type;
|
||||
|
||||
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
|
||||
|
||||
|
|
@ -708,11 +654,11 @@ impl_node_port_use_buffers(struct spa_node *node,
|
|||
b = &port->buffers[i];
|
||||
b->outbuf = buffers[i];
|
||||
b->outstanding = (direction == SPA_DIRECTION_INPUT);
|
||||
b->h = spa_buffer_find_meta_data(buffers[i], t->meta.Header, sizeof(*b->h));
|
||||
b->h = spa_buffer_find_meta_data(buffers[i], SPA_META_Header, sizeof(*b->h));
|
||||
|
||||
if (!((d[0].type == t->data.MemPtr ||
|
||||
d[0].type == t->data.MemFd ||
|
||||
d[0].type == t->data.DmaBuf) && d[0].data != NULL)) {
|
||||
if (!((d[0].type == SPA_DATA_MemPtr ||
|
||||
d[0].type == SPA_DATA_MemFd ||
|
||||
d[0].type == SPA_DATA_DmaBuf) && d[0].data != NULL)) {
|
||||
spa_log_error(this->log, NAME " %p: invalid memory on buffer %p", this,
|
||||
buffers[i]);
|
||||
return -EINVAL;
|
||||
|
|
@ -748,21 +694,20 @@ impl_node_port_set_io(struct spa_node *node,
|
|||
{
|
||||
struct impl *this;
|
||||
struct port *port;
|
||||
struct type *t;
|
||||
|
||||
spa_return_val_if_fail(node != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
t = &this->type;
|
||||
|
||||
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
|
||||
|
||||
port = GET_PORT(this, direction, port_id);
|
||||
|
||||
if (id == t->io.Buffers)
|
||||
if (id == SPA_ID_IO_Buffers)
|
||||
port->io = data;
|
||||
else if (id == t->io.ControlRange)
|
||||
else if (id == SPA_ID_IO_ControlRange)
|
||||
port->io_range = data;
|
||||
#if 0
|
||||
else if (id == t->io_prop_volume && direction == SPA_DIRECTION_INPUT)
|
||||
if (data && size >= sizeof(struct spa_pod_double))
|
||||
port->io_volume = &SPA_POD_VALUE(struct spa_pod_double, data);
|
||||
|
|
@ -773,6 +718,7 @@ impl_node_port_set_io(struct spa_node *node,
|
|||
port->io_mute = &SPA_POD_VALUE(struct spa_pod_bool, data);
|
||||
else
|
||||
port->io_mute = &port->props.mute;
|
||||
#endif
|
||||
else
|
||||
return -ENOENT;
|
||||
|
||||
|
|
@ -1036,7 +982,7 @@ static int impl_get_interface(struct spa_handle *handle, uint32_t interface_id,
|
|||
|
||||
this = (struct impl *) handle;
|
||||
|
||||
if (interface_id == this->type.node)
|
||||
if (interface_id == SPA_ID_INTERFACE_Node)
|
||||
*interface = &this->node;
|
||||
else
|
||||
return -ENOENT;
|
||||
|
|
@ -1076,16 +1022,9 @@ impl_init(const struct spa_handle_factory *factory,
|
|||
this = (struct impl *) handle;
|
||||
|
||||
for (i = 0; i < n_support; i++) {
|
||||
if (strcmp(support[i].type, SPA_TYPE__TypeMap) == 0)
|
||||
this->map = support[i].data;
|
||||
else if (strcmp(support[i].type, SPA_TYPE__Log) == 0)
|
||||
if (support[i].type == SPA_ID_INTERFACE_Log)
|
||||
this->log = support[i].data;
|
||||
}
|
||||
if (this->map == NULL) {
|
||||
spa_log_error(this->log, "an id-map is needed");
|
||||
return -EINVAL;
|
||||
}
|
||||
init_type(&this->type, this->map);
|
||||
|
||||
this->node = impl_node;
|
||||
|
||||
|
|
@ -1102,7 +1041,7 @@ impl_init(const struct spa_handle_factory *factory,
|
|||
}
|
||||
|
||||
static const struct spa_interface_info impl_interfaces[] = {
|
||||
{SPA_TYPE__Node,},
|
||||
{SPA_ID_INTERFACE_Node,},
|
||||
};
|
||||
|
||||
static int
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@
|
|||
#include <stdio.h>
|
||||
#include <sys/timerfd.h>
|
||||
|
||||
#include <spa/support/type-map.h>
|
||||
#include <spa/support/log.h>
|
||||
#include <spa/support/loop.h>
|
||||
#include <spa/utils/list.h>
|
||||
|
|
@ -42,59 +41,6 @@
|
|||
#define BYTES_TO_SAMPLES(this,b) ((b)/(this)->bpf)
|
||||
#define BYTES_TO_TIME(this,b) SAMPLES_TO_TIME(this, BYTES_TO_SAMPLES (this, b))
|
||||
|
||||
struct type {
|
||||
uint32_t node;
|
||||
uint32_t format;
|
||||
uint32_t props;
|
||||
uint32_t prop_live;
|
||||
uint32_t prop_wave;
|
||||
uint32_t prop_freq;
|
||||
uint32_t prop_volume;
|
||||
uint32_t io_prop_wave;
|
||||
uint32_t io_prop_freq;
|
||||
uint32_t io_prop_volume;
|
||||
struct spa_type_io io;
|
||||
struct spa_type_param param;
|
||||
struct spa_type_meta meta;
|
||||
struct spa_type_data data;
|
||||
struct spa_type_media_type media_type;
|
||||
struct spa_type_media_subtype media_subtype;
|
||||
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_buffers param_buffers;
|
||||
struct spa_type_param_meta param_meta;
|
||||
struct spa_type_param_io param_io;
|
||||
};
|
||||
|
||||
static inline void init_type(struct type *type, struct spa_type_map *map)
|
||||
{
|
||||
type->node = spa_type_map_get_id(map, SPA_TYPE__Node);
|
||||
type->format = spa_type_map_get_id(map, SPA_TYPE__Format);
|
||||
type->props = spa_type_map_get_id(map, SPA_TYPE__Props);
|
||||
type->prop_live = spa_type_map_get_id(map, SPA_TYPE_PROPS__live);
|
||||
type->prop_wave = spa_type_map_get_id(map, SPA_TYPE_PROPS__waveType);
|
||||
type->prop_freq = spa_type_map_get_id(map, SPA_TYPE_PROPS__frequency);
|
||||
type->prop_volume = spa_type_map_get_id(map, SPA_TYPE_PROPS__volume);
|
||||
type->io_prop_wave = spa_type_map_get_id(map, SPA_TYPE_IO_PROP_BASE "waveType");
|
||||
type->io_prop_freq = spa_type_map_get_id(map, SPA_TYPE_IO_PROP_BASE "frequency");
|
||||
type->io_prop_volume = spa_type_map_get_id(map, SPA_TYPE_IO_PROP_BASE "volume");
|
||||
spa_type_io_map(map, &type->io);
|
||||
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);
|
||||
spa_type_media_subtype_map(map, &type->media_subtype);
|
||||
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_buffers_map(map, &type->param_buffers);
|
||||
spa_type_param_meta_map(map, &type->param_meta);
|
||||
spa_type_param_io_map(map, &type->param_io);
|
||||
}
|
||||
|
||||
enum wave_type {
|
||||
WAVE_SINE,
|
||||
WAVE_SQUARE,
|
||||
|
|
@ -138,8 +84,6 @@ struct impl {
|
|||
struct spa_handle handle;
|
||||
struct spa_node node;
|
||||
|
||||
struct type type;
|
||||
struct spa_type_map *map;
|
||||
struct spa_log *log;
|
||||
struct spa_loop *data_loop;
|
||||
|
||||
|
|
@ -186,7 +130,6 @@ static int impl_node_enum_params(struct spa_node *node,
|
|||
struct spa_pod_builder *builder)
|
||||
{
|
||||
struct impl *this;
|
||||
struct type *t;
|
||||
struct spa_pod *param;
|
||||
struct spa_pod_builder b = { 0 };
|
||||
uint8_t buffer[1024];
|
||||
|
|
@ -196,80 +139,87 @@ static int impl_node_enum_params(struct spa_node *node,
|
|||
spa_return_val_if_fail(builder != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
t = &this->type;
|
||||
|
||||
next:
|
||||
spa_pod_builder_init(&b, buffer, sizeof(buffer));
|
||||
|
||||
if (id == t->param.idList) {
|
||||
uint32_t list[] = { t->param.idPropInfo,
|
||||
t->param.idProps };
|
||||
switch (id) {
|
||||
case SPA_ID_PARAM_List:
|
||||
{
|
||||
uint32_t list[] = { SPA_ID_PARAM_PropInfo,
|
||||
SPA_ID_PARAM_Props };
|
||||
|
||||
if (*index < SPA_N_ELEMENTS(list))
|
||||
param = spa_pod_builder_object(&b, id, t->param.List,
|
||||
":", t->param.listId, "I", list[*index]);
|
||||
param = spa_pod_builder_object(&b, id, SPA_ID_OBJECT_ParamList,
|
||||
":", SPA_PARAM_LIST_id, "I", list[*index]);
|
||||
else
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
else if (id == t->param.idPropInfo) {
|
||||
case SPA_ID_PARAM_PropInfo:
|
||||
{
|
||||
struct props *p = &this->props;
|
||||
|
||||
switch (*index) {
|
||||
case 0:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param.PropInfo,
|
||||
":", t->param.propId, "I", t->prop_live,
|
||||
":", t->param.propName, "s", "Configure live mode of the source",
|
||||
":", t->param.propType, "b", p->live);
|
||||
id, SPA_ID_OBJECT_PropInfo,
|
||||
":", SPA_PROP_INFO_id, "I", SPA_PROP_live,
|
||||
":", SPA_PROP_INFO_name, "s", "Configure live mode of the source",
|
||||
":", SPA_PROP_INFO_type, "b", p->live);
|
||||
break;
|
||||
case 1:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param.PropInfo,
|
||||
":", t->param.propId, "I", t->prop_wave,
|
||||
":", t->param.propName, "s", "Select the waveform",
|
||||
":", t->param.propType, "i", p->wave,
|
||||
":", t->param.propLabels, "[-i",
|
||||
id, SPA_ID_OBJECT_PropInfo,
|
||||
":", SPA_PROP_INFO_id, "I", SPA_PROP_waveType,
|
||||
":", SPA_PROP_INFO_name, "s", "Select the waveform",
|
||||
":", SPA_PROP_INFO_type, "i", p->wave,
|
||||
":", SPA_PROP_INFO_labels, "[-i",
|
||||
"i", WAVE_SINE, "s", "Sine wave",
|
||||
"i", WAVE_SQUARE, "s", "Square wave", "]");
|
||||
break;
|
||||
case 2:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param.PropInfo,
|
||||
":", t->param.propId, "I", t->prop_freq,
|
||||
":", t->param.propName, "s", "Select the frequency",
|
||||
":", t->param.propType, "dr", p->freq,
|
||||
id, SPA_ID_OBJECT_PropInfo,
|
||||
":", SPA_PROP_INFO_id, "I", SPA_PROP_frequency,
|
||||
":", SPA_PROP_INFO_name, "s", "Select the frequency",
|
||||
":", SPA_PROP_INFO_type, "dr", p->freq,
|
||||
SPA_POD_PROP_MIN_MAX(0.0, 50000000.0));
|
||||
break;
|
||||
case 3:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param.PropInfo,
|
||||
":", t->param.propId, "I", t->prop_volume,
|
||||
":", t->param.propName, "s", "Select the volume",
|
||||
":", t->param.propType, "dr", p->volume,
|
||||
id, SPA_ID_OBJECT_PropInfo,
|
||||
":", SPA_PROP_INFO_id, "I", SPA_PROP_volume,
|
||||
":", SPA_PROP_INFO_name, "s", "Select the volume",
|
||||
":", SPA_PROP_INFO_type, "dr", p->volume,
|
||||
SPA_POD_PROP_MIN_MAX(0.0, 10.0));
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
else if (id == t->param.idProps) {
|
||||
case SPA_ID_PARAM_Props:
|
||||
{
|
||||
struct props *p = &this->props;
|
||||
|
||||
switch (*index) {
|
||||
case 0:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->props,
|
||||
":", t->prop_live, "b", p->live,
|
||||
":", t->prop_wave, "i", p->wave,
|
||||
":", t->prop_freq, "d", p->freq,
|
||||
":", t->prop_volume, "d", p->volume);
|
||||
id, SPA_ID_OBJECT_Props,
|
||||
":", SPA_PROP_live, "b", p->live,
|
||||
":", SPA_PROP_waveType, "i", p->wave,
|
||||
":", SPA_PROP_frequency, "d", p->freq,
|
||||
":", SPA_PROP_volume, "d", p->volume);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
else
|
||||
default:
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
(*index)++;
|
||||
|
||||
|
|
@ -283,14 +233,12 @@ static int impl_node_set_param(struct spa_node *node, uint32_t id, uint32_t flag
|
|||
const struct spa_pod *param)
|
||||
{
|
||||
struct impl *this;
|
||||
struct type *t;
|
||||
|
||||
spa_return_val_if_fail(node != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
t = &this->type;
|
||||
|
||||
if (id == t->param.idProps) {
|
||||
if (id == SPA_ID_PARAM_Props) {
|
||||
struct props *p = &this->props;
|
||||
|
||||
if (param == NULL) {
|
||||
|
|
@ -298,10 +246,10 @@ static int impl_node_set_param(struct spa_node *node, uint32_t id, uint32_t flag
|
|||
return 0;
|
||||
}
|
||||
spa_pod_object_parse(param,
|
||||
":",t->prop_live, "?b", &p->live,
|
||||
":",t->prop_wave, "?i", &p->wave,
|
||||
":",t->prop_freq, "?d", &p->freq,
|
||||
":",t->prop_volume, "?d", &p->volume,
|
||||
":",SPA_PROP_live, "?b", &p->live,
|
||||
":",SPA_PROP_waveType, "?i", &p->wave,
|
||||
":",SPA_PROP_frequency, "?d", &p->freq,
|
||||
":",SPA_PROP_volume, "?d", &p->volume,
|
||||
NULL);
|
||||
|
||||
if (p->live)
|
||||
|
|
@ -440,7 +388,9 @@ static int impl_node_send_command(struct spa_node *node, const struct spa_comman
|
|||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
|
||||
if (SPA_COMMAND_TYPE(command) == this->type.command_node.Start) {
|
||||
switch (SPA_COMMAND_TYPE(command)) {
|
||||
case SPA_ID_COMMAND_NODE_Start:
|
||||
{
|
||||
struct timespec now;
|
||||
|
||||
if (!this->have_format)
|
||||
|
|
@ -461,7 +411,9 @@ static int impl_node_send_command(struct spa_node *node, const struct spa_comman
|
|||
|
||||
this->started = true;
|
||||
set_timer(this, true);
|
||||
} else if (SPA_COMMAND_TYPE(command) == this->type.command_node.Pause) {
|
||||
break;
|
||||
}
|
||||
case SPA_ID_COMMAND_NODE_Pause:
|
||||
if (!this->have_format)
|
||||
return -EIO;
|
||||
if (this->n_buffers == 0)
|
||||
|
|
@ -472,9 +424,11 @@ static int impl_node_send_command(struct spa_node *node, const struct spa_comman
|
|||
|
||||
this->started = false;
|
||||
set_timer(this, false);
|
||||
} else
|
||||
return -ENOTSUP;
|
||||
break;
|
||||
|
||||
default:
|
||||
return -ENOTSUP;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -569,22 +523,20 @@ port_enum_formats(struct impl *this,
|
|||
struct spa_pod **param,
|
||||
struct spa_pod_builder *builder)
|
||||
{
|
||||
struct type *t = &this->type;
|
||||
|
||||
switch (*index) {
|
||||
case 0:
|
||||
*param = spa_pod_builder_object(builder,
|
||||
t->param.idEnumFormat, t->format,
|
||||
"I", t->media_type.audio,
|
||||
"I", t->media_subtype.raw,
|
||||
":", t->format_audio.format, "Ieu", t->audio_format.S16,
|
||||
SPA_POD_PROP_ENUM(4, t->audio_format.S16,
|
||||
t->audio_format.S32,
|
||||
t->audio_format.F32,
|
||||
t->audio_format.F64),
|
||||
":", t->format_audio.rate, "iru", 44100,
|
||||
SPA_ID_PARAM_EnumFormat, SPA_ID_OBJECT_Format,
|
||||
"I", SPA_MEDIA_TYPE_audio,
|
||||
"I", SPA_MEDIA_SUBTYPE_raw,
|
||||
":", SPA_FORMAT_AUDIO_format, "Ieu", SPA_AUDIO_FORMAT_S16,
|
||||
SPA_POD_PROP_ENUM(4, SPA_AUDIO_FORMAT_S16,
|
||||
SPA_AUDIO_FORMAT_S32,
|
||||
SPA_AUDIO_FORMAT_F32,
|
||||
SPA_AUDIO_FORMAT_F64),
|
||||
":", SPA_FORMAT_AUDIO_rate, "iru", 44100,
|
||||
SPA_POD_PROP_MIN_MAX(1, INT32_MAX),
|
||||
":", t->format_audio.channels, "iru", 2,
|
||||
":", SPA_FORMAT_AUDIO_channels, "iru", 2,
|
||||
SPA_POD_PROP_MIN_MAX(1, INT32_MAX));
|
||||
break;
|
||||
default:
|
||||
|
|
@ -601,20 +553,18 @@ port_get_format(struct impl *this,
|
|||
struct spa_pod **param,
|
||||
struct spa_pod_builder *builder)
|
||||
{
|
||||
struct type *t = &this->type;
|
||||
|
||||
if (!this->have_format)
|
||||
return -EIO;
|
||||
if (*index > 0)
|
||||
return 0;
|
||||
|
||||
*param = spa_pod_builder_object(builder,
|
||||
t->param.idFormat, t->format,
|
||||
"I", t->media_type.audio,
|
||||
"I", t->media_subtype.raw,
|
||||
":", t->format_audio.format, "I", this->current_format.info.raw.format,
|
||||
":", t->format_audio.rate, "i", this->current_format.info.raw.rate,
|
||||
":", t->format_audio.channels, "i", this->current_format.info.raw.channels);
|
||||
SPA_ID_PARAM_Format, SPA_ID_OBJECT_Format,
|
||||
"I", SPA_MEDIA_TYPE_audio,
|
||||
"I", SPA_MEDIA_SUBTYPE_raw,
|
||||
":", SPA_FORMAT_AUDIO_format, "I", this->current_format.info.raw.format,
|
||||
":", SPA_FORMAT_AUDIO_rate, "i", this->current_format.info.raw.rate,
|
||||
":", SPA_FORMAT_AUDIO_channels, "i", this->current_format.info.raw.channels);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -628,7 +578,6 @@ impl_node_port_enum_params(struct spa_node *node,
|
|||
struct spa_pod_builder *builder)
|
||||
{
|
||||
struct impl *this;
|
||||
struct type *t;
|
||||
struct spa_pod_builder b = { 0 };
|
||||
uint8_t buffer[1024];
|
||||
struct spa_pod *param;
|
||||
|
|
@ -639,90 +588,87 @@ impl_node_port_enum_params(struct spa_node *node,
|
|||
spa_return_val_if_fail(builder != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
t = &this->type;
|
||||
|
||||
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
|
||||
|
||||
next:
|
||||
spa_pod_builder_init(&b, buffer, sizeof(buffer));
|
||||
|
||||
if (id == t->param.idList) {
|
||||
uint32_t list[] = { t->param.idEnumFormat,
|
||||
t->param.idFormat,
|
||||
t->param.idBuffers,
|
||||
t->param.idMeta,
|
||||
t->param_io.idBuffers,
|
||||
t->param_io.idControl,
|
||||
t->param_io.idPropsIn };
|
||||
switch (id) {
|
||||
case SPA_ID_PARAM_List:
|
||||
{
|
||||
uint32_t list[] = { SPA_ID_PARAM_EnumFormat,
|
||||
SPA_ID_PARAM_Format,
|
||||
SPA_ID_PARAM_Buffers,
|
||||
SPA_ID_PARAM_Meta,
|
||||
SPA_ID_PARAM_IO, };
|
||||
|
||||
if (*index < SPA_N_ELEMENTS(list))
|
||||
param = spa_pod_builder_object(&b, id, t->param.List,
|
||||
":", t->param.listId, "I", list[*index]);
|
||||
param = spa_pod_builder_object(&b, id, SPA_ID_OBJECT_ParamList,
|
||||
":", SPA_PARAM_LIST_id, "I", list[*index]);
|
||||
else
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
else if (id == t->param.idEnumFormat) {
|
||||
case SPA_ID_PARAM_EnumFormat:
|
||||
if ((res = port_enum_formats(this, direction, port_id, index, ¶m, &b)) <= 0)
|
||||
return res;
|
||||
}
|
||||
else if (id == t->param.idFormat) {
|
||||
break;
|
||||
case SPA_ID_PARAM_Format:
|
||||
if ((res = port_get_format(this, direction, port_id, index, ¶m, &b)) <= 0)
|
||||
return res;
|
||||
}
|
||||
else if (id == t->param.idBuffers) {
|
||||
break;
|
||||
|
||||
case SPA_ID_PARAM_Buffers:
|
||||
if (!this->have_format)
|
||||
return -EIO;
|
||||
if (*index > 0)
|
||||
return 0;
|
||||
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param_buffers.Buffers,
|
||||
":", t->param_buffers.size, "iru", 1024 * this->bpf,
|
||||
SPA_POD_PROP_MIN_MAX(16 * this->bpf, INT32_MAX / this->bpf),
|
||||
":", t->param_buffers.stride, "i", 0,
|
||||
":", t->param_buffers.buffers, "iru", 1,
|
||||
id, SPA_ID_OBJECT_ParamBuffers,
|
||||
":", SPA_PARAM_BUFFERS_buffers, "iru", 1,
|
||||
SPA_POD_PROP_MIN_MAX(1, MAX_BUFFERS),
|
||||
":", t->param_buffers.align, "i", 16);
|
||||
}
|
||||
else if (id == t->param.idMeta) {
|
||||
":", SPA_PARAM_BUFFERS_blocks, "i", 1,
|
||||
":", SPA_PARAM_BUFFERS_size, "iru", 1024 * this->bpf,
|
||||
SPA_POD_PROP_MIN_MAX(16 * this->bpf, INT32_MAX / this->bpf),
|
||||
":", SPA_PARAM_BUFFERS_stride, "i", 0,
|
||||
":", SPA_PARAM_BUFFERS_align, "i", 16);
|
||||
break;
|
||||
case SPA_ID_PARAM_Meta:
|
||||
if (!this->have_format)
|
||||
return -EIO;
|
||||
|
||||
switch (*index) {
|
||||
case 0:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param_meta.Meta,
|
||||
":", t->param_meta.type, "I", t->meta.Header,
|
||||
":", t->param_meta.size, "i", sizeof(struct spa_meta_header));
|
||||
id, SPA_ID_OBJECT_ParamMeta,
|
||||
":", SPA_PARAM_META_type, "I", SPA_META_Header,
|
||||
":", SPA_PARAM_META_size, "i", sizeof(struct spa_meta_header));
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if (id == t->param_io.idBuffers) {
|
||||
break;
|
||||
case SPA_ID_PARAM_IO:
|
||||
switch (*index) {
|
||||
case 0:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param_io.Buffers,
|
||||
":", t->param_io.id, "I", t->io.Buffers,
|
||||
":", t->param_io.size, "i", sizeof(struct spa_io_buffers));
|
||||
id, SPA_ID_OBJECT_ParamIO,
|
||||
":", SPA_PARAM_IO_id, "I", SPA_ID_IO_Buffers,
|
||||
":", SPA_PARAM_IO_size, "i", sizeof(struct spa_io_buffers));
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if (id == t->param_io.idControl) {
|
||||
switch (*index) {
|
||||
case 0:
|
||||
case 1:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param_io.Control,
|
||||
":", t->param_io.id, "I", t->io.ControlRange,
|
||||
":", t->param_io.size, "i", sizeof(struct spa_io_control_range));
|
||||
id, SPA_ID_OBJECT_ParamIO,
|
||||
":", SPA_PARAM_IO_id, "I", SPA_ID_IO_ControlRange,
|
||||
":", SPA_PARAM_IO_size, "i", sizeof(struct spa_io_control_range));
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
#if 0
|
||||
else if (id == t->param_io.idPropsIn) {
|
||||
struct props *p = &this->props;
|
||||
|
||||
|
|
@ -732,9 +678,9 @@ impl_node_port_enum_params(struct spa_node *node,
|
|||
id, t->param_io.Prop,
|
||||
":", t->param_io.id, "I", t->io_prop_wave,
|
||||
":", t->param_io.size, "i", sizeof(struct spa_pod_id),
|
||||
":", t->param.propId, "I", t->prop_wave,
|
||||
":", t->param.propType, "i", p->wave,
|
||||
":", t->param.propLabels, "[-i",
|
||||
":", SPA_PROP_INFO_id, "I", SPA_PROP_wave,
|
||||
":", SPA_PROP_INFO_type, "i", p->wave,
|
||||
":", SPA_PROP_INFO_labels, "[-i",
|
||||
"i", WAVE_SINE, "s", "Sine wave",
|
||||
"i", WAVE_SQUARE, "s", "Square wave", "]");
|
||||
break;
|
||||
|
|
@ -743,8 +689,8 @@ impl_node_port_enum_params(struct spa_node *node,
|
|||
id, t->param_io.Prop,
|
||||
":", t->param_io.id, "I", t->io_prop_freq,
|
||||
":", t->param_io.size, "i", sizeof(struct spa_pod_double),
|
||||
":", t->param.propId, "I", t->prop_freq,
|
||||
":", t->param.propType, "dr", p->freq,
|
||||
":", SPA_PROP_INFO_id, "I", SPA_PROP_freq,
|
||||
":", SPA_PROP_INFO_type, "dr", p->freq,
|
||||
SPA_POD_PROP_MIN_MAX(0.0, 50000000.0));
|
||||
break;
|
||||
case 2:
|
||||
|
|
@ -752,16 +698,18 @@ impl_node_port_enum_params(struct spa_node *node,
|
|||
id, t->param_io.Prop,
|
||||
":", t->param_io.id, "I", t->io_prop_volume,
|
||||
":", t->param_io.size, "i", sizeof(struct spa_pod_double),
|
||||
":", t->param.propId, "I", t->prop_volume,
|
||||
":", t->param.propType, "dr", p->volume,
|
||||
":", SPA_PROP_INFO_id, "I", SPA_PROP_volume,
|
||||
":", SPA_PROP_INFO_type, "dr", p->volume,
|
||||
SPA_POD_PROP_MIN_MAX(0.0, 10.0));
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
default:
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
(*index)++;
|
||||
|
||||
|
|
@ -790,8 +738,6 @@ port_set_format(struct impl *this,
|
|||
uint32_t flags,
|
||||
const struct spa_pod *format)
|
||||
{
|
||||
struct type *t = &this->type;
|
||||
|
||||
if (format == NULL) {
|
||||
this->have_format = false;
|
||||
clear_buffers(this);
|
||||
|
|
@ -804,20 +750,20 @@ port_set_format(struct impl *this,
|
|||
"I", &info.media_type,
|
||||
"I", &info.media_subtype);
|
||||
|
||||
if (info.media_type != t->media_type.audio ||
|
||||
info.media_subtype != t->media_subtype.raw)
|
||||
if (info.media_type != SPA_MEDIA_TYPE_audio ||
|
||||
info.media_subtype != SPA_MEDIA_SUBTYPE_raw)
|
||||
return -EINVAL;
|
||||
|
||||
if (spa_format_audio_raw_parse(format, &info.info.raw, &t->format_audio) < 0)
|
||||
if (spa_format_audio_raw_parse(format, &info.info.raw) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (info.info.raw.format == t->audio_format.S16)
|
||||
if (info.info.raw.format == SPA_AUDIO_FORMAT_S16)
|
||||
idx = 0;
|
||||
else if (info.info.raw.format == t->audio_format.S32)
|
||||
else if (info.info.raw.format == SPA_AUDIO_FORMAT_S32)
|
||||
idx = 1;
|
||||
else if (info.info.raw.format == t->audio_format.F32)
|
||||
else if (info.info.raw.format == SPA_AUDIO_FORMAT_F32)
|
||||
idx = 2;
|
||||
else if (info.info.raw.format == t->audio_format.F64)
|
||||
else if (info.info.raw.format == SPA_AUDIO_FORMAT_F64)
|
||||
idx = 3;
|
||||
else
|
||||
return -EINVAL;
|
||||
|
|
@ -841,16 +787,14 @@ impl_node_port_set_param(struct spa_node *node,
|
|||
const struct spa_pod *param)
|
||||
{
|
||||
struct impl *this;
|
||||
struct type *t;
|
||||
|
||||
spa_return_val_if_fail(node != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
t = &this->type;
|
||||
|
||||
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
|
||||
|
||||
if (id == t->param.idFormat)
|
||||
if (id == SPA_ID_PARAM_Format)
|
||||
return port_set_format(this, direction, port_id, flags, param);
|
||||
|
||||
return -ENOENT;
|
||||
|
|
@ -865,7 +809,6 @@ impl_node_port_use_buffers(struct spa_node *node,
|
|||
{
|
||||
struct impl *this;
|
||||
uint32_t i;
|
||||
struct type *t;
|
||||
|
||||
spa_return_val_if_fail(node != NULL, -EINVAL);
|
||||
|
||||
|
|
@ -876,8 +819,6 @@ impl_node_port_use_buffers(struct spa_node *node,
|
|||
if (!this->have_format)
|
||||
return -EIO;
|
||||
|
||||
t = &this->type;
|
||||
|
||||
clear_buffers(this);
|
||||
|
||||
for (i = 0; i < n_buffers; i++) {
|
||||
|
|
@ -887,11 +828,11 @@ impl_node_port_use_buffers(struct spa_node *node,
|
|||
b = &this->buffers[i];
|
||||
b->outbuf = buffers[i];
|
||||
b->outstanding = false;
|
||||
b->h = spa_buffer_find_meta_data(buffers[i], t->meta.Header, sizeof(*b->h));
|
||||
b->h = spa_buffer_find_meta_data(buffers[i], SPA_META_Header, sizeof(*b->h));
|
||||
|
||||
if ((d[0].type == t->data.MemPtr ||
|
||||
d[0].type == t->data.MemFd ||
|
||||
d[0].type == t->data.DmaBuf) && d[0].data == NULL) {
|
||||
if ((d[0].type == SPA_DATA_MemPtr ||
|
||||
d[0].type == SPA_DATA_MemFd ||
|
||||
d[0].type == SPA_DATA_DmaBuf) && d[0].data == NULL) {
|
||||
spa_log_error(this->log, NAME " %p: invalid memory on buffer %p", this,
|
||||
buffers[i]);
|
||||
return -EINVAL;
|
||||
|
|
@ -934,19 +875,18 @@ impl_node_port_set_io(struct spa_node *node,
|
|||
void *data, size_t size)
|
||||
{
|
||||
struct impl *this;
|
||||
struct type *t;
|
||||
|
||||
spa_return_val_if_fail(node != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
t = &this->type;
|
||||
|
||||
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
|
||||
|
||||
if (id == t->io.Buffers)
|
||||
if (id == SPA_ID_IO_Buffers)
|
||||
this->io = data;
|
||||
else if (id == t->io.ControlRange)
|
||||
else if (id == SPA_ID_IO_ControlRange)
|
||||
this->io_range = data;
|
||||
#if 0
|
||||
else if (id == t->io_prop_wave) {
|
||||
if (data && size >= sizeof(struct spa_pod_id))
|
||||
this->io_wave = &SPA_POD_VALUE(struct spa_pod_id, data);
|
||||
|
|
@ -963,6 +903,7 @@ impl_node_port_set_io(struct spa_node *node,
|
|||
this->io_volume = &SPA_POD_VALUE(struct spa_pod_double, data);
|
||||
else
|
||||
this->io_volume = &this->props.volume;
|
||||
#endif
|
||||
else
|
||||
return -ENOENT;
|
||||
|
||||
|
|
@ -1073,7 +1014,7 @@ static int impl_get_interface(struct spa_handle *handle, uint32_t interface_id,
|
|||
|
||||
this = (struct impl *) handle;
|
||||
|
||||
if (interface_id == this->type.node)
|
||||
if (interface_id == SPA_ID_INTERFACE_Node)
|
||||
*interface = &this->node;
|
||||
else
|
||||
return -ENOENT;
|
||||
|
|
@ -1122,18 +1063,11 @@ impl_init(const struct spa_handle_factory *factory,
|
|||
this = (struct impl *) handle;
|
||||
|
||||
for (i = 0; i < n_support; i++) {
|
||||
if (strcmp(support[i].type, SPA_TYPE__TypeMap) == 0)
|
||||
this->map = support[i].data;
|
||||
else if (strcmp(support[i].type, SPA_TYPE__Log) == 0)
|
||||
if (support[i].type == SPA_ID_INTERFACE_Log)
|
||||
this->log = support[i].data;
|
||||
else if (strcmp(support[i].type, SPA_TYPE_LOOP__DataLoop) == 0)
|
||||
else if (support[i].type == SPA_ID_INTERFACE_DataLoop)
|
||||
this->data_loop = support[i].data;
|
||||
}
|
||||
if (this->map == NULL) {
|
||||
spa_log_error(this->log, "a type-map is needed");
|
||||
return -EINVAL;
|
||||
}
|
||||
init_type(&this->type, this->map);
|
||||
|
||||
this->node = impl_node;
|
||||
reset_props(&this->props);
|
||||
|
|
@ -1167,7 +1101,7 @@ impl_init(const struct spa_handle_factory *factory,
|
|||
}
|
||||
|
||||
static const struct spa_interface_info impl_interfaces[] = {
|
||||
{SPA_TYPE__Node,},
|
||||
{SPA_ID_INTERFACE_Node,},
|
||||
};
|
||||
|
||||
static int
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@
|
|||
#include <arpa/inet.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include <spa/support/type-map.h>
|
||||
#include <spa/support/loop.h>
|
||||
#include <spa/support/log.h>
|
||||
#include <spa/utils/list.h>
|
||||
|
|
@ -59,58 +58,12 @@ struct buffer {
|
|||
struct spa_list link;
|
||||
};
|
||||
|
||||
struct type {
|
||||
uint32_t node;
|
||||
uint32_t format;
|
||||
uint32_t props;
|
||||
uint32_t prop_min_latency;
|
||||
uint32_t prop_max_latency;
|
||||
struct spa_type_io io;
|
||||
struct spa_type_param param;
|
||||
struct spa_type_meta meta;
|
||||
struct spa_type_data data;
|
||||
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_audio_format audio_format;
|
||||
struct spa_type_event_node event_node;
|
||||
struct spa_type_command_node command_node;
|
||||
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)
|
||||
{
|
||||
type->node = spa_type_map_get_id(map, SPA_TYPE__Node);
|
||||
type->format = spa_type_map_get_id(map, SPA_TYPE__Format);
|
||||
type->props = spa_type_map_get_id(map, SPA_TYPE__Props);
|
||||
type->prop_min_latency = spa_type_map_get_id(map, SPA_TYPE_PROPS__minLatency);
|
||||
type->prop_max_latency = spa_type_map_get_id(map, SPA_TYPE_PROPS__maxLatency);
|
||||
|
||||
spa_type_io_map(map, &type->io);
|
||||
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);
|
||||
spa_type_media_subtype_map(map, &type->media_subtype);
|
||||
spa_type_media_subtype_audio_map(map, &type->media_subtype_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_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 impl {
|
||||
struct spa_handle handle;
|
||||
struct spa_node node;
|
||||
|
||||
uint32_t seq;
|
||||
|
||||
struct type type;
|
||||
struct spa_type_map *map;
|
||||
struct spa_log *log;
|
||||
struct spa_loop *main_loop;
|
||||
struct spa_loop *data_loop;
|
||||
|
|
@ -194,7 +147,6 @@ static int impl_node_enum_params(struct spa_node *node,
|
|||
struct spa_pod_builder *builder)
|
||||
{
|
||||
struct impl *this;
|
||||
struct type *t;
|
||||
struct spa_pod *param;
|
||||
struct spa_pod_builder b = { 0 };
|
||||
uint8_t buffer[1024];
|
||||
|
|
@ -204,61 +156,68 @@ static int impl_node_enum_params(struct spa_node *node,
|
|||
spa_return_val_if_fail(builder != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
t = &this->type;
|
||||
|
||||
next:
|
||||
spa_pod_builder_init(&b, buffer, sizeof(buffer));
|
||||
|
||||
if (id == t->param.idList) {
|
||||
uint32_t list[] = { t->param.idPropInfo,
|
||||
t->param.idProps };
|
||||
switch (id) {
|
||||
case SPA_ID_PARAM_List:
|
||||
{
|
||||
uint32_t list[] = { SPA_ID_PARAM_PropInfo,
|
||||
SPA_ID_PARAM_Props };
|
||||
|
||||
if (*index < SPA_N_ELEMENTS(list))
|
||||
param = spa_pod_builder_object(&b, id, t->param.List,
|
||||
":", t->param.listId, "I", list[*index]);
|
||||
param = spa_pod_builder_object(&b, id, SPA_ID_OBJECT_ParamList,
|
||||
":", SPA_PARAM_LIST_id, "I", list[*index]);
|
||||
else
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
else if (id == t->param.idPropInfo) {
|
||||
case SPA_ID_PARAM_PropInfo:
|
||||
{
|
||||
struct props *p = &this->props;
|
||||
|
||||
switch (*index) {
|
||||
case 0:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param.PropInfo,
|
||||
":", t->param.propId, "I", t->prop_min_latency,
|
||||
":", t->param.propName, "s", "The minimum latency",
|
||||
":", t->param.propType, "ir", p->min_latency,
|
||||
id, SPA_ID_OBJECT_PropInfo,
|
||||
":", SPA_PROP_INFO_id, "I", SPA_PROP_minLatency,
|
||||
":", SPA_PROP_INFO_name, "s", "The minimum latency",
|
||||
":", SPA_PROP_INFO_type, "ir", p->min_latency,
|
||||
SPA_POD_PROP_MIN_MAX(1, INT32_MAX));
|
||||
break;
|
||||
case 1:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param.PropInfo,
|
||||
":", t->param.propId, "I", t->prop_max_latency,
|
||||
":", t->param.propName, "s", "The maximum latency",
|
||||
":", t->param.propType, "ir", p->max_latency,
|
||||
id, SPA_ID_OBJECT_PropInfo,
|
||||
":", SPA_PROP_INFO_id, "I", SPA_PROP_maxLatency,
|
||||
":", SPA_PROP_INFO_name, "s", "The maximum latency",
|
||||
":", SPA_PROP_INFO_type, "ir", p->max_latency,
|
||||
SPA_POD_PROP_MIN_MAX(1, INT32_MAX));
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
else if (id == t->param.idProps) {
|
||||
case SPA_ID_PARAM_Props:
|
||||
{
|
||||
struct props *p = &this->props;
|
||||
|
||||
switch (*index) {
|
||||
case 0:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->props,
|
||||
":", t->prop_min_latency, "i", p->min_latency,
|
||||
":", t->prop_max_latency, "i", p->max_latency);
|
||||
id, SPA_ID_OBJECT_Props,
|
||||
":", SPA_PROP_minLatency, "i", p->min_latency,
|
||||
":", SPA_PROP_maxLatency, "i", p->max_latency);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
else
|
||||
default:
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
(*index)++;
|
||||
|
||||
|
|
@ -272,14 +231,14 @@ static int impl_node_set_param(struct spa_node *node, uint32_t id, uint32_t flag
|
|||
const struct spa_pod *param)
|
||||
{
|
||||
struct impl *this;
|
||||
struct type *t;
|
||||
|
||||
spa_return_val_if_fail(node != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
t = &this->type;
|
||||
|
||||
if (id == t->param.idProps) {
|
||||
switch (id) {
|
||||
case SPA_ID_PARAM_Props:
|
||||
{
|
||||
struct props *p = &this->props;
|
||||
|
||||
if (param == NULL) {
|
||||
|
|
@ -287,11 +246,13 @@ static int impl_node_set_param(struct spa_node *node, uint32_t id, uint32_t flag
|
|||
return 0;
|
||||
}
|
||||
spa_pod_object_parse(param,
|
||||
":", t->prop_min_latency, "?i", &p->min_latency,
|
||||
":", t->prop_max_latency, "?i", &p->max_latency, NULL);
|
||||
":", SPA_PROP_minLatency, "?i", &p->min_latency,
|
||||
":", SPA_PROP_maxLatency, "?i", &p->max_latency, NULL);
|
||||
break;
|
||||
}
|
||||
else
|
||||
default:
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -850,7 +811,8 @@ static int impl_node_send_command(struct spa_node *node, const struct spa_comman
|
|||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
|
||||
if (SPA_COMMAND_TYPE(command) == this->type.command_node.Start) {
|
||||
switch (SPA_COMMAND_TYPE(command)) {
|
||||
case SPA_ID_COMMAND_NODE_Start:
|
||||
if (!this->have_format)
|
||||
return -EIO;
|
||||
if (this->n_buffers == 0)
|
||||
|
|
@ -858,13 +820,14 @@ static int impl_node_send_command(struct spa_node *node, const struct spa_comman
|
|||
|
||||
if ((res = do_start(this)) < 0)
|
||||
return res;
|
||||
|
||||
} else if (SPA_COMMAND_TYPE(command) == this->type.command_node.Pause) {
|
||||
break;
|
||||
case SPA_ID_COMMAND_NODE_Pause:
|
||||
if ((res = do_stop(this)) < 0)
|
||||
return res;
|
||||
} else
|
||||
break;
|
||||
default:
|
||||
return -ENOTSUP;
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -960,7 +923,6 @@ impl_node_port_enum_params(struct spa_node *node,
|
|||
{
|
||||
|
||||
struct impl *this;
|
||||
struct type *t;
|
||||
struct spa_pod *param;
|
||||
struct spa_pod_builder b = { 0 };
|
||||
uint8_t buffer[1024];
|
||||
|
|
@ -970,26 +932,28 @@ impl_node_port_enum_params(struct spa_node *node,
|
|||
spa_return_val_if_fail(builder != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
t = &this->type;
|
||||
|
||||
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
|
||||
|
||||
next:
|
||||
spa_pod_builder_init(&b, buffer, sizeof(buffer));
|
||||
|
||||
if (id == t->param.idList) {
|
||||
uint32_t list[] = { t->param.idEnumFormat,
|
||||
t->param.idFormat,
|
||||
t->param.idBuffers,
|
||||
t->param.idMeta };
|
||||
switch (id) {
|
||||
case SPA_ID_PARAM_List:
|
||||
{
|
||||
uint32_t list[] = { SPA_ID_PARAM_EnumFormat,
|
||||
SPA_ID_PARAM_Format,
|
||||
SPA_ID_PARAM_Buffers,
|
||||
SPA_ID_PARAM_Meta };
|
||||
|
||||
if (*index < SPA_N_ELEMENTS(list))
|
||||
param = spa_pod_builder_object(&b, id, t->param.List,
|
||||
":", t->param.listId, "I", list[*index]);
|
||||
param = spa_pod_builder_object(&b, id, SPA_ID_OBJECT_ParamList,
|
||||
":", SPA_PARAM_LIST_id, "I", list[*index]);
|
||||
else
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
else if (id == t->param.idEnumFormat) {
|
||||
case SPA_ID_PARAM_EnumFormat:
|
||||
if (*index > 0)
|
||||
return 0;
|
||||
|
||||
|
|
@ -1003,65 +967,72 @@ impl_node_port_enum_params(struct spa_node *node,
|
|||
return -EIO;
|
||||
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->format,
|
||||
"I", t->media_type.audio,
|
||||
"I", t->media_subtype.raw,
|
||||
":", t->format_audio.format, "I", t->audio_format.S16,
|
||||
":", t->format_audio.layout, "i", SPA_AUDIO_LAYOUT_INTERLEAVED,
|
||||
":", t->format_audio.rate, "i", rate,
|
||||
":", t->format_audio.channels, "i", channels);
|
||||
id, SPA_ID_OBJECT_Format,
|
||||
"I", SPA_MEDIA_TYPE_audio,
|
||||
"I", SPA_MEDIA_SUBTYPE_raw,
|
||||
":", SPA_FORMAT_AUDIO_format, "I", SPA_AUDIO_FORMAT_S16,
|
||||
":", SPA_FORMAT_AUDIO_layout, "i", SPA_AUDIO_LAYOUT_INTERLEAVED,
|
||||
":", SPA_FORMAT_AUDIO_rate, "i", rate,
|
||||
":", SPA_FORMAT_AUDIO_channels, "i", channels);
|
||||
}
|
||||
else
|
||||
return -EIO;
|
||||
}
|
||||
else if (id == t->param.idFormat) {
|
||||
break;
|
||||
|
||||
case SPA_ID_PARAM_Format:
|
||||
if (!this->have_format)
|
||||
return -EIO;
|
||||
if (*index > 0)
|
||||
return 0;
|
||||
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->format,
|
||||
"I", t->media_type.audio,
|
||||
"I", t->media_subtype.raw,
|
||||
":", t->format_audio.format, "I", this->current_format.info.raw.format,
|
||||
":", t->format_audio.rate, "i", this->current_format.info.raw.rate,
|
||||
":", t->format_audio.channels, "i", this->current_format.info.raw.channels);
|
||||
}
|
||||
else if (id == t->param.idBuffers) {
|
||||
id, SPA_ID_OBJECT_Format,
|
||||
"I", SPA_MEDIA_TYPE_audio,
|
||||
"I", SPA_MEDIA_SUBTYPE_raw,
|
||||
":", SPA_FORMAT_AUDIO_format, "I", this->current_format.info.raw.format,
|
||||
":", SPA_FORMAT_AUDIO_layout, "i", this->current_format.info.raw.layout,
|
||||
":", SPA_FORMAT_AUDIO_rate, "i", this->current_format.info.raw.rate,
|
||||
":", SPA_FORMAT_AUDIO_channels, "i", this->current_format.info.raw.channels);
|
||||
break;
|
||||
|
||||
case SPA_ID_PARAM_Buffers:
|
||||
if (!this->have_format)
|
||||
return -EIO;
|
||||
if (*index > 0)
|
||||
return 0;
|
||||
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param_buffers.Buffers,
|
||||
":", t->param_buffers.size, "iru", this->props.min_latency *
|
||||
id, SPA_ID_OBJECT_ParamBuffers,
|
||||
":", SPA_PARAM_BUFFERS_buffers, "ir", 2,
|
||||
SPA_POD_PROP_MIN_MAX(2, MAX_BUFFERS),
|
||||
":", SPA_PARAM_BUFFERS_blocks, "i", 1,
|
||||
":", SPA_PARAM_BUFFERS_size, "iru", this->props.min_latency *
|
||||
this->frame_size,
|
||||
SPA_POD_PROP_MIN_MAX(this->props.min_latency * this->frame_size,
|
||||
INT32_MAX),
|
||||
":", t->param_buffers.stride, "i", 0,
|
||||
":", t->param_buffers.buffers, "ir", 2,
|
||||
SPA_POD_PROP_MIN_MAX(2, MAX_BUFFERS),
|
||||
":", t->param_buffers.align, "i", 16);
|
||||
}
|
||||
else if (id == t->param.idMeta) {
|
||||
":", SPA_PARAM_BUFFERS_stride, "i", 0,
|
||||
":", SPA_PARAM_BUFFERS_align, "i", 16);
|
||||
break;
|
||||
|
||||
case SPA_ID_PARAM_Meta:
|
||||
if (!this->have_format)
|
||||
return -EIO;
|
||||
|
||||
switch (*index) {
|
||||
case 0:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param_meta.Meta,
|
||||
":", t->param_meta.type, "I", t->meta.Header,
|
||||
":", t->param_meta.size, "i", sizeof(struct spa_meta_header));
|
||||
id, SPA_ID_OBJECT_ParamMeta,
|
||||
":", SPA_PARAM_META_type, "I", SPA_META_Header,
|
||||
":", SPA_PARAM_META_size, "i", sizeof(struct spa_meta_header));
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
break;
|
||||
|
||||
default:
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
(*index)++;
|
||||
|
||||
|
|
@ -1101,11 +1072,11 @@ static int port_set_format(struct spa_node *node,
|
|||
"I", &info.media_subtype)) < 0)
|
||||
return err;
|
||||
|
||||
if (info.media_type != this->type.media_type.audio ||
|
||||
info.media_subtype != this->type.media_subtype.raw)
|
||||
if (info.media_type != SPA_MEDIA_TYPE_audio ||
|
||||
info.media_subtype != SPA_MEDIA_SUBTYPE_raw)
|
||||
return -EINVAL;
|
||||
|
||||
if (spa_format_audio_raw_parse(format, &info.info.raw, &this->type.format_audio) < 0)
|
||||
if (spa_format_audio_raw_parse(format, &info.info.raw) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
this->frame_size = info.info.raw.channels * 2;
|
||||
|
|
@ -1128,17 +1099,11 @@ impl_node_port_set_param(struct spa_node *node,
|
|||
uint32_t id, uint32_t flags,
|
||||
const struct spa_pod *param)
|
||||
{
|
||||
struct impl *this;
|
||||
struct type *t;
|
||||
|
||||
spa_return_val_if_fail(node != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
t = &this->type;
|
||||
spa_return_val_if_fail(CHECK_PORT(node, direction, port_id), -EINVAL);
|
||||
|
||||
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
|
||||
|
||||
if (id == t->param.idFormat) {
|
||||
if (id == SPA_ID_PARAM_Format) {
|
||||
return port_set_format(node, direction, port_id, flags, param);
|
||||
}
|
||||
else
|
||||
|
|
@ -1152,7 +1117,6 @@ impl_node_port_use_buffers(struct spa_node *node,
|
|||
{
|
||||
struct impl *this;
|
||||
int i;
|
||||
struct type *t;
|
||||
|
||||
spa_return_val_if_fail(node != NULL, -EINVAL);
|
||||
|
||||
|
|
@ -1165,8 +1129,6 @@ impl_node_port_use_buffers(struct spa_node *node,
|
|||
if (!this->have_format)
|
||||
return -EIO;
|
||||
|
||||
t = &this->type;
|
||||
|
||||
clear_buffers(this);
|
||||
|
||||
for (i = 0; i < n_buffers; i++) {
|
||||
|
|
@ -1176,12 +1138,12 @@ impl_node_port_use_buffers(struct spa_node *node,
|
|||
b->buf = buffers[i];
|
||||
b->outstanding = true;
|
||||
|
||||
b->h = spa_buffer_find_meta_data(buffers[i], t->meta.Header, sizeof(*b->h));
|
||||
b->h = spa_buffer_find_meta_data(buffers[i], SPA_META_Header, sizeof(*b->h));
|
||||
|
||||
type = buffers[i]->datas[0].type;
|
||||
if ((type == t->data.MemFd ||
|
||||
type == t->data.DmaBuf ||
|
||||
type == t->data.MemPtr) && buffers[i]->datas[0].data == NULL) {
|
||||
if ((type == SPA_DATA_MemFd ||
|
||||
type == SPA_DATA_DmaBuf ||
|
||||
type == SPA_DATA_MemPtr) && buffers[i]->datas[0].data == NULL) {
|
||||
spa_log_error(this->log, NAME " %p: need mapped memory", this);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
@ -1224,22 +1186,23 @@ impl_node_port_set_io(struct spa_node *node,
|
|||
void *data, size_t size)
|
||||
{
|
||||
struct impl *this;
|
||||
struct type *t;
|
||||
|
||||
spa_return_val_if_fail(node != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
t = &this->type;
|
||||
|
||||
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
|
||||
|
||||
if (id == t->io.Buffers)
|
||||
switch (id) {
|
||||
case SPA_ID_IO_Buffers:
|
||||
this->io = data;
|
||||
else if (id == t->io.ControlRange)
|
||||
break;
|
||||
case SPA_ID_IO_ControlRange:
|
||||
this->range = data;
|
||||
else
|
||||
break;
|
||||
default:
|
||||
return -ENOENT;
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1335,7 +1298,7 @@ static int impl_get_interface(struct spa_handle *handle, uint32_t interface_id,
|
|||
|
||||
this = (struct impl *) handle;
|
||||
|
||||
if (interface_id == this->type.node)
|
||||
if (interface_id == SPA_ID_INTERFACE_Node)
|
||||
*interface = &this->node;
|
||||
else
|
||||
return -ENOENT;
|
||||
|
|
@ -1374,19 +1337,13 @@ impl_init(const struct spa_handle_factory *factory,
|
|||
this = (struct impl *) handle;
|
||||
|
||||
for (i = 0; i < n_support; i++) {
|
||||
if (strcmp(support[i].type, SPA_TYPE__TypeMap) == 0)
|
||||
this->map = support[i].data;
|
||||
else if (strcmp(support[i].type, SPA_TYPE__Log) == 0)
|
||||
if (support[i].type == SPA_ID_INTERFACE_Log)
|
||||
this->log = support[i].data;
|
||||
else if (strcmp(support[i].type, SPA_TYPE_LOOP__DataLoop) == 0)
|
||||
else if (support[i].type == SPA_ID_INTERFACE_DataLoop)
|
||||
this->data_loop = support[i].data;
|
||||
else if (strcmp(support[i].type, SPA_TYPE_LOOP__MainLoop) == 0)
|
||||
else if (support[i].type == SPA_ID_INTERFACE_MainLoop)
|
||||
this->main_loop = support[i].data;
|
||||
}
|
||||
if (this->map == NULL) {
|
||||
spa_log_error(this->log, "a type-map is needed");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (this->data_loop == NULL) {
|
||||
spa_log_error(this->log, "a data loop is needed");
|
||||
return -EINVAL;
|
||||
|
|
@ -1395,7 +1352,6 @@ impl_init(const struct spa_handle_factory *factory,
|
|||
spa_log_error(this->log, "a main loop is needed");
|
||||
return -EINVAL;
|
||||
}
|
||||
init_type(&this->type, this->map);
|
||||
|
||||
this->node = impl_node;
|
||||
reset_props(&this->props);
|
||||
|
|
@ -1418,7 +1374,7 @@ impl_init(const struct spa_handle_factory *factory,
|
|||
}
|
||||
|
||||
static const struct spa_interface_info impl_interfaces[] = {
|
||||
{SPA_TYPE__Node,},
|
||||
{SPA_ID_INTERFACE_Node,},
|
||||
};
|
||||
|
||||
static int
|
||||
|
|
|
|||
|
|
@ -30,34 +30,21 @@
|
|||
#include <dbus/dbus.h>
|
||||
|
||||
#include <spa/support/log.h>
|
||||
#include <spa/support/type-map.h>
|
||||
#include <spa/support/loop.h>
|
||||
#include <spa/support/dbus.h>
|
||||
#include <spa/support/plugin.h>
|
||||
#include <spa/monitor/monitor.h>
|
||||
#include <spa/utils/type.h>
|
||||
|
||||
#include "a2dp-codecs.h"
|
||||
#include "defs.h"
|
||||
|
||||
#define NAME "bluez5-monitor"
|
||||
|
||||
struct type {
|
||||
uint32_t handle_factory;
|
||||
struct spa_type_monitor monitor;
|
||||
};
|
||||
|
||||
static inline void init_type(struct type *type, struct spa_type_map *map)
|
||||
{
|
||||
type->handle_factory = spa_type_map_get_id(map, SPA_TYPE__HandleFactory);
|
||||
spa_type_monitor_map(map, &type->monitor);
|
||||
}
|
||||
|
||||
struct spa_bt_monitor {
|
||||
struct spa_handle handle;
|
||||
struct spa_monitor monitor;
|
||||
|
||||
struct type type;
|
||||
struct spa_type_map *map;
|
||||
struct spa_log *log;
|
||||
struct spa_dbus *dbus;
|
||||
struct spa_dbus_connection *dbus_connection;
|
||||
|
|
@ -80,18 +67,17 @@ struct spa_handle_factory spa_a2dp_sink_factory;
|
|||
static void fill_item(struct spa_bt_monitor *this, struct spa_bt_transport *transport,
|
||||
struct spa_pod **result, struct spa_pod_builder *builder)
|
||||
{
|
||||
struct type *t = &this->type;
|
||||
char trans[16];
|
||||
|
||||
spa_pod_builder_add(builder,
|
||||
"<", 0, t->monitor.MonitorItem,
|
||||
":", t->monitor.id, "s", transport->path,
|
||||
":", t->monitor.flags, "i", 0,
|
||||
":", t->monitor.state, "i", SPA_MONITOR_ITEM_STATE_AVAILABLE,
|
||||
":", t->monitor.name, "s", transport->path,
|
||||
":", t->monitor.klass, "s", "Adapter/Bluetooth",
|
||||
":", t->monitor.factory, "p", t->handle_factory, &spa_a2dp_sink_factory,
|
||||
":", t->monitor.info, "[",
|
||||
"<", 0, SPA_ID_OBJECT_MonitorItem,
|
||||
":", SPA_MONITOR_ITEM_id, "s", transport->path,
|
||||
":", SPA_MONITOR_ITEM_flags, "i", SPA_MONITOR_ITEM_FLAG_NONE,
|
||||
":", SPA_MONITOR_ITEM_state, "i", SPA_MONITOR_ITEM_STATE_AVAILABLE,
|
||||
":", SPA_MONITOR_ITEM_name, "s", transport->path,
|
||||
":", SPA_MONITOR_ITEM_class, "s", "Adapter/Bluetooth",
|
||||
":", SPA_MONITOR_ITEM_factory, "p", SPA_ID_INTERFACE_HandleFactory, &spa_a2dp_sink_factory,
|
||||
":", SPA_MONITOR_ITEM_info, "[",
|
||||
NULL);
|
||||
|
||||
snprintf(trans, sizeof(trans), "%p", transport);
|
||||
|
|
@ -654,7 +640,7 @@ static struct spa_bt_node *node_create(struct spa_bt_monitor *monitor, struct sp
|
|||
struct spa_pod *item;
|
||||
|
||||
spa_pod_builder_init(&b, buffer, sizeof(buffer));
|
||||
event = spa_pod_builder_object(&b, 0, monitor->type.monitor.Added);
|
||||
event = spa_pod_builder_object(&b, 0, SPA_ID_EVENT_MONITOR_Added);
|
||||
fill_item(monitor, transport, &item, &b);
|
||||
|
||||
monitor->callbacks->event(monitor->callbacks_data, event);
|
||||
|
|
@ -670,7 +656,7 @@ static struct spa_bt_node *node_destroy(struct spa_bt_monitor *monitor, struct s
|
|||
struct spa_pod *item;
|
||||
|
||||
spa_pod_builder_init(&b, buffer, sizeof(buffer));
|
||||
event = spa_pod_builder_object(&b, 0, monitor->type.monitor.Removed);
|
||||
event = spa_pod_builder_object(&b, 0, SPA_ID_EVENT_MONITOR_Removed);
|
||||
fill_item(monitor, transport, &item, &b);
|
||||
|
||||
monitor->callbacks->event(monitor->callbacks_data, event);
|
||||
|
|
@ -1201,7 +1187,7 @@ static int impl_get_interface(struct spa_handle *handle, uint32_t interface_id,
|
|||
|
||||
this = (struct spa_bt_monitor *) handle;
|
||||
|
||||
if (interface_id == this->type.monitor.Monitor)
|
||||
if (interface_id == SPA_ID_INTERFACE_Monitor)
|
||||
*interface = &this->monitor;
|
||||
else
|
||||
return -ENOENT;
|
||||
|
|
@ -1240,22 +1226,15 @@ impl_init(const struct spa_handle_factory *factory,
|
|||
this = (struct spa_bt_monitor *) handle;
|
||||
|
||||
for (i = 0; i < n_support; i++) {
|
||||
if (strcmp(support[i].type, SPA_TYPE__TypeMap) == 0)
|
||||
this->map = support[i].data;
|
||||
else if (strcmp(support[i].type, SPA_TYPE__Log) == 0)
|
||||
if (support[i].type == SPA_ID_INTERFACE_Log)
|
||||
this->log = support[i].data;
|
||||
else if (strcmp(support[i].type, SPA_TYPE__DBus) == 0)
|
||||
else if (support[i].type == SPA_ID_INTERFACE_DBus)
|
||||
this->dbus = support[i].data;
|
||||
}
|
||||
if (this->map == NULL) {
|
||||
spa_log_error(this->log, "a type-map is needed");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (this->dbus == NULL) {
|
||||
spa_log_error(this->log, "a dbus is needed");
|
||||
return -EINVAL;
|
||||
}
|
||||
init_type(&this->type, this->map);
|
||||
|
||||
this->dbus_connection = spa_dbus_get_connection(this->dbus, DBUS_BUS_SYSTEM);
|
||||
if (this->dbus_connection == NULL) {
|
||||
|
|
@ -1274,7 +1253,7 @@ impl_init(const struct spa_handle_factory *factory,
|
|||
}
|
||||
|
||||
static const struct spa_interface_info impl_interfaces[] = {
|
||||
{SPA_TYPE__Monitor,},
|
||||
{SPA_ID_INTERFACE_Monitor,},
|
||||
};
|
||||
|
||||
static int
|
||||
|
|
|
|||
|
|
@ -23,11 +23,11 @@
|
|||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <spa/support/type-map.h>
|
||||
#include <spa/support/log.h>
|
||||
#include <spa/node/node.h>
|
||||
#include <spa/node/io.h>
|
||||
#include <spa/param/video/format-utils.h>
|
||||
#include <spa/param/video/format.h>
|
||||
#include <spa/pod/filter.h>
|
||||
|
||||
#define IS_VALID_PORT(this,d,id) ((id) == 0)
|
||||
|
|
@ -52,33 +52,10 @@ struct port {
|
|||
struct spa_io_buffers *io;
|
||||
};
|
||||
|
||||
struct type {
|
||||
uint32_t node;
|
||||
struct spa_type_io io;
|
||||
struct spa_type_param param;
|
||||
struct spa_type_media_type media_type;
|
||||
struct spa_type_media_subtype media_subtype;
|
||||
struct spa_type_format_video format_video;
|
||||
struct spa_type_command_node command_node;
|
||||
};
|
||||
|
||||
static inline void init_type(struct type *type, struct spa_type_map *map)
|
||||
{
|
||||
type->node = spa_type_map_get_id(map, SPA_TYPE__Node);
|
||||
spa_type_io_map(map, &type->io);
|
||||
spa_type_param_map(map, &type->param);
|
||||
spa_type_media_type_map(map, &type->media_type);
|
||||
spa_type_media_subtype_map(map, &type->media_subtype);
|
||||
spa_type_format_video_map(map, &type->format_video);
|
||||
spa_type_command_node_map(map, &type->command_node);
|
||||
}
|
||||
|
||||
struct impl {
|
||||
struct spa_handle handle;
|
||||
struct spa_node node;
|
||||
|
||||
struct type type;
|
||||
struct spa_type_map *map;
|
||||
struct spa_log *log;
|
||||
|
||||
const struct spa_node_callbacks *callbacks;
|
||||
|
|
@ -115,13 +92,16 @@ static int spa_ffmpeg_dec_node_send_command(struct spa_node *node, const struct
|
|||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
|
||||
if (SPA_COMMAND_TYPE(command) == this->type.command_node.Start) {
|
||||
switch (SPA_COMMAND_TYPE(command)) {
|
||||
case SPA_ID_COMMAND_NODE_Start:
|
||||
this->started = true;
|
||||
} else if (SPA_COMMAND_TYPE(command) == this->type.command_node.Pause) {
|
||||
break;
|
||||
case SPA_ID_COMMAND_NODE_Pause:
|
||||
this->started = false;
|
||||
} else
|
||||
break;
|
||||
default:
|
||||
return -ENOTSUP;
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -280,8 +260,6 @@ spa_ffmpeg_dec_node_port_enum_params(struct spa_node *node,
|
|||
struct spa_pod **result,
|
||||
struct spa_pod_builder *builder)
|
||||
{
|
||||
struct impl *this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
struct type *t = &this->type;
|
||||
struct spa_pod_builder b = { 0 };
|
||||
uint8_t buffer[1024];
|
||||
struct spa_pod *param;
|
||||
|
|
@ -290,26 +268,32 @@ spa_ffmpeg_dec_node_port_enum_params(struct spa_node *node,
|
|||
next:
|
||||
spa_pod_builder_init(&b, buffer, sizeof(buffer));
|
||||
|
||||
if (id == t->param.idList) {
|
||||
uint32_t list[] = { t->param.idEnumFormat,
|
||||
t->param.idFormat };
|
||||
switch (id) {
|
||||
case SPA_ID_PARAM_List:
|
||||
{
|
||||
uint32_t list[] = { SPA_ID_PARAM_EnumFormat,
|
||||
SPA_ID_PARAM_Format };
|
||||
|
||||
if (*index < SPA_N_ELEMENTS(list))
|
||||
param = spa_pod_builder_object(&b, id, t->param.List,
|
||||
":", t->param.listId, "I", list[*index]);
|
||||
param = spa_pod_builder_object(&b, id, SPA_ID_OBJECT_ParamList,
|
||||
":", SPA_PARAM_LIST_id, "I", list[*index]);
|
||||
else
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
else if (id == t->param.idEnumFormat) {
|
||||
case SPA_ID_PARAM_EnumFormat:
|
||||
if ((res = port_enum_formats(node, direction, port_id, index, filter, ¶m, &b)) <= 0)
|
||||
return res;
|
||||
}
|
||||
else if (id == t->param.idFormat) {
|
||||
break;
|
||||
|
||||
case SPA_ID_PARAM_Format:
|
||||
if ((res = port_get_format(node, direction, port_id, index, filter, ¶m, &b)) <= 0)
|
||||
return res;
|
||||
}
|
||||
else
|
||||
break;
|
||||
|
||||
default:
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
(*index)++;
|
||||
|
||||
|
|
@ -347,11 +331,11 @@ static int port_set_format(struct spa_node *node,
|
|||
"I", &info.media_type,
|
||||
"I", &info.media_subtype);
|
||||
|
||||
if (info.media_type != this->type.media_type.video &&
|
||||
info.media_subtype != this->type.media_subtype.raw)
|
||||
if (info.media_type != SPA_MEDIA_TYPE_video &&
|
||||
info.media_subtype != SPA_MEDIA_SUBTYPE_raw)
|
||||
return -EINVAL;
|
||||
|
||||
if (spa_format_video_raw_parse(format, &info.info.raw, &this->type.format_video) < 0)
|
||||
if (spa_format_video_raw_parse(format, &info.info.raw) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (!(flags & SPA_NODE_PARAM_FLAG_TEST_ONLY)) {
|
||||
|
|
@ -368,10 +352,7 @@ spa_ffmpeg_dec_node_port_set_param(struct spa_node *node,
|
|||
uint32_t id, uint32_t flags,
|
||||
const struct spa_pod *param)
|
||||
{
|
||||
struct impl *this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
struct type *t = &this->type;
|
||||
|
||||
if (id == t->param.idFormat) {
|
||||
if (id == SPA_ID_PARAM_Format) {
|
||||
return port_set_format(node, direction, port_id, flags, param);
|
||||
}
|
||||
else
|
||||
|
|
@ -415,20 +396,18 @@ spa_ffmpeg_dec_node_port_set_io(struct spa_node *node,
|
|||
{
|
||||
struct impl *this;
|
||||
struct port *port;
|
||||
struct type *t;
|
||||
|
||||
if (node == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
t = &this->type;
|
||||
|
||||
if (!IS_VALID_PORT(this, direction, port_id))
|
||||
return -EINVAL;
|
||||
|
||||
port = GET_PORT(this, direction, port_id);
|
||||
|
||||
if (id == t->io.Buffers)
|
||||
if (id == SPA_ID_IO_Buffers)
|
||||
port->io = data;
|
||||
else
|
||||
return -ENOENT;
|
||||
|
|
@ -515,7 +494,7 @@ spa_ffmpeg_dec_get_interface(struct spa_handle *handle, uint32_t interface_id, v
|
|||
|
||||
this = (struct impl *) handle;
|
||||
|
||||
if (interface_id == this->type.node)
|
||||
if (interface_id == SPA_ID_INTERFACE_Node)
|
||||
*interface = &this->node;
|
||||
else
|
||||
return -ENOENT;
|
||||
|
|
@ -537,16 +516,9 @@ spa_ffmpeg_dec_init(struct spa_handle *handle,
|
|||
this = (struct impl *) handle;
|
||||
|
||||
for (i = 0; i < n_support; i++) {
|
||||
if (strcmp(support[i].type, SPA_TYPE__TypeMap) == 0)
|
||||
this->map = support[i].data;
|
||||
else if (strcmp(support[i].type, SPA_TYPE__Log) == 0)
|
||||
if (support[i].type == SPA_ID_INTERFACE_Log)
|
||||
this->log = support[i].data;
|
||||
}
|
||||
if (this->map == NULL) {
|
||||
spa_log_error(this->log, "a type-map is needed");
|
||||
return -EINVAL;
|
||||
}
|
||||
init_type(&this->type, this->map);
|
||||
|
||||
this->node = ffmpeg_dec_node;
|
||||
|
||||
|
|
|
|||
|
|
@ -24,13 +24,11 @@
|
|||
#include <fcntl.h>
|
||||
|
||||
#include <spa/support/log.h>
|
||||
#include <spa/support/type-map.h>
|
||||
#include <spa/node/node.h>
|
||||
#include <spa/node/io.h>
|
||||
#include <spa/param/video/format-utils.h>
|
||||
#include <spa/pod/filter.h>
|
||||
|
||||
|
||||
#define IS_VALID_PORT(this,d,id) ((id) == 0)
|
||||
#define GET_IN_PORT(this,p) (&this->in_ports[p])
|
||||
#define GET_OUT_PORT(this,p) (&this->out_ports[p])
|
||||
|
|
@ -57,33 +55,10 @@ struct port {
|
|||
struct spa_io_buffers *io;
|
||||
};
|
||||
|
||||
struct type {
|
||||
uint32_t node;
|
||||
struct spa_type_io io;
|
||||
struct spa_type_param param;
|
||||
struct spa_type_media_type media_type;
|
||||
struct spa_type_media_subtype media_subtype;
|
||||
struct spa_type_format_video format_video;
|
||||
struct spa_type_command_node command_node;
|
||||
};
|
||||
|
||||
static inline void init_type(struct type *type, struct spa_type_map *map)
|
||||
{
|
||||
type->node = spa_type_map_get_id(map, SPA_TYPE__Node);
|
||||
spa_type_io_map(map, &type->io);
|
||||
spa_type_param_map(map, &type->param);
|
||||
spa_type_media_type_map(map, &type->media_type);
|
||||
spa_type_media_subtype_map(map, &type->media_subtype);
|
||||
spa_type_format_video_map(map, &type->format_video);
|
||||
spa_type_command_node_map(map, &type->command_node);
|
||||
}
|
||||
|
||||
struct impl {
|
||||
struct spa_handle handle;
|
||||
struct spa_node node;
|
||||
|
||||
struct type type;
|
||||
struct spa_type_map *map;
|
||||
struct spa_log *log;
|
||||
|
||||
const struct spa_node_callbacks *callbacks;
|
||||
|
|
@ -119,13 +94,16 @@ static int spa_ffmpeg_enc_node_send_command(struct spa_node *node, const struct
|
|||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
|
||||
if (SPA_COMMAND_TYPE(command) == this->type.command_node.Start) {
|
||||
switch (SPA_COMMAND_TYPE(command)) {
|
||||
case SPA_ID_COMMAND_NODE_Start:
|
||||
this->started = true;
|
||||
} else if (SPA_COMMAND_TYPE(command) == this->type.command_node.Pause) {
|
||||
break;
|
||||
case SPA_ID_COMMAND_NODE_Pause:
|
||||
this->started = false;
|
||||
} else
|
||||
break;
|
||||
default:
|
||||
return -ENOTSUP;
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -230,11 +208,6 @@ static int port_enum_formats(struct spa_node *node,
|
|||
struct spa_pod **param,
|
||||
struct spa_pod_builder *builder)
|
||||
{
|
||||
//struct impl *this = SPA_CONTAINER_OF (node, struct impl, node);
|
||||
//struct port *port;
|
||||
|
||||
//port = GET_PORT(this, direction, port_id);
|
||||
|
||||
switch (*index) {
|
||||
case 0:
|
||||
*param = NULL;
|
||||
|
|
@ -276,8 +249,6 @@ spa_ffmpeg_enc_node_port_enum_params(struct spa_node *node,
|
|||
struct spa_pod **result,
|
||||
struct spa_pod_builder *builder)
|
||||
{
|
||||
struct impl *this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
struct type *t = &this->type;
|
||||
struct spa_pod_builder b = { 0 };
|
||||
uint8_t buffer[1024];
|
||||
struct spa_pod *param;
|
||||
|
|
@ -286,26 +257,32 @@ spa_ffmpeg_enc_node_port_enum_params(struct spa_node *node,
|
|||
next:
|
||||
spa_pod_builder_init(&b, buffer, sizeof(buffer));
|
||||
|
||||
if (id == t->param.idList) {
|
||||
uint32_t list[] = { t->param.idEnumFormat,
|
||||
t->param.idFormat };
|
||||
switch (id) {
|
||||
case SPA_ID_PARAM_List:
|
||||
{
|
||||
uint32_t list[] = { SPA_ID_PARAM_EnumFormat,
|
||||
SPA_ID_PARAM_Format };
|
||||
|
||||
if (*index < SPA_N_ELEMENTS(list))
|
||||
param = spa_pod_builder_object(&b, id, t->param.List,
|
||||
":", t->param.listId, "I", list[*index]);
|
||||
param = spa_pod_builder_object(&b, id, SPA_ID_OBJECT_ParamList,
|
||||
":", SPA_PARAM_LIST_id, "I", list[*index]);
|
||||
else
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
else if (id == t->param.idEnumFormat) {
|
||||
case SPA_ID_PARAM_EnumFormat:
|
||||
if ((res = port_enum_formats(node, direction, port_id, index, filter, ¶m, &b)) <= 0)
|
||||
return res;
|
||||
}
|
||||
else if (id == t->param.idFormat) {
|
||||
break;
|
||||
|
||||
case SPA_ID_PARAM_Format:
|
||||
if ((res = port_get_format(node, direction, port_id, index, filter, ¶m, &b)) <= 0)
|
||||
return res;
|
||||
}
|
||||
else
|
||||
break;
|
||||
|
||||
default:
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
(*index)++;
|
||||
|
||||
|
|
@ -334,11 +311,11 @@ static int port_set_format(struct spa_node *node,
|
|||
"I", &info.media_type,
|
||||
"I", &info.media_subtype);
|
||||
|
||||
if (info.media_type != this->type.media_type.video &&
|
||||
info.media_subtype != this->type.media_subtype.raw)
|
||||
if (info.media_type != SPA_MEDIA_TYPE_video &&
|
||||
info.media_subtype != SPA_MEDIA_SUBTYPE_raw)
|
||||
return -EINVAL;
|
||||
|
||||
if (spa_format_video_raw_parse(format, &info.info.raw, &this->type.format_video) < 0)
|
||||
if (spa_format_video_raw_parse(format, &info.info.raw) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (!(flags & SPA_NODE_PARAM_FLAG_TEST_ONLY)) {
|
||||
|
|
@ -355,10 +332,7 @@ spa_ffmpeg_enc_node_port_set_param(struct spa_node *node,
|
|||
uint32_t id, uint32_t flags,
|
||||
const struct spa_pod *param)
|
||||
{
|
||||
struct impl *this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
struct type *t = &this->type;
|
||||
|
||||
if (id == t->param.idFormat) {
|
||||
if (id == SPA_ID_PARAM_Format) {
|
||||
return port_set_format(node, direction, port_id, flags, param);
|
||||
}
|
||||
else
|
||||
|
|
@ -401,20 +375,18 @@ spa_ffmpeg_enc_node_port_set_io(struct spa_node *node,
|
|||
{
|
||||
struct impl *this;
|
||||
struct port *port;
|
||||
struct type *t;
|
||||
|
||||
if (node == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
t = &this->type;
|
||||
|
||||
if (!IS_VALID_PORT(this, direction, port_id))
|
||||
return -EINVAL;
|
||||
|
||||
port = GET_PORT(this, direction, port_id);
|
||||
|
||||
if (id == t->io.Buffers)
|
||||
if (id == SPA_ID_IO_Buffers)
|
||||
port->io = data;
|
||||
else
|
||||
return -ENOENT;
|
||||
|
|
@ -499,7 +471,7 @@ spa_ffmpeg_enc_get_interface(struct spa_handle *handle, uint32_t interface_id, v
|
|||
|
||||
this = (struct impl *) handle;
|
||||
|
||||
if (interface_id == this->type.node)
|
||||
if (interface_id == SPA_ID_INTERFACE_Node)
|
||||
*interface = &this->node;
|
||||
else
|
||||
return -ENOENT;
|
||||
|
|
@ -520,15 +492,9 @@ spa_ffmpeg_enc_init(struct spa_handle *handle,
|
|||
this = (struct impl *) handle;
|
||||
|
||||
for (i = 0; i < n_support; i++) {
|
||||
if (strcmp(support[i].type, SPA_TYPE__TypeMap) == 0)
|
||||
this->map = support[i].data;
|
||||
else if (strcmp(support[i].type, SPA_TYPE__Log) == 0)
|
||||
if (support[i].type == SPA_ID_INTERFACE_Log)
|
||||
this->log = support[i].data;
|
||||
}
|
||||
if (this->map == NULL) {
|
||||
spa_log_error(this->log, "a type-map is needed");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
this->node = ffmpeg_enc_node;
|
||||
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ ffmpeg_enc_init(const struct spa_handle_factory *factory,
|
|||
}
|
||||
|
||||
static const struct spa_interface_info ffmpeg_interfaces[] = {
|
||||
{SPA_TYPE__Node, },
|
||||
{SPA_ID_INTERFACE_Node, },
|
||||
};
|
||||
|
||||
static int
|
||||
|
|
|
|||
|
|
@ -27,29 +27,17 @@
|
|||
|
||||
#include <dbus/dbus.h>
|
||||
|
||||
#include <spa/support/type-map.h>
|
||||
#include <spa/utils/type.h>
|
||||
#include <spa/support/log.h>
|
||||
#include <spa/support/plugin.h>
|
||||
#include <spa/support/dbus.h>
|
||||
|
||||
#define NAME "dbus"
|
||||
|
||||
struct type {
|
||||
uint32_t dbus;
|
||||
};
|
||||
|
||||
static inline void init_type(struct type *type, struct spa_type_map *map)
|
||||
{
|
||||
type->dbus = spa_type_map_get_id(map, SPA_TYPE__DBus);
|
||||
}
|
||||
|
||||
struct impl {
|
||||
struct spa_handle handle;
|
||||
struct spa_dbus dbus;
|
||||
|
||||
struct type type;
|
||||
|
||||
struct spa_type_map *map;
|
||||
struct spa_log *log;
|
||||
struct spa_loop_utils *utils;
|
||||
|
||||
|
|
@ -339,7 +327,7 @@ static int impl_get_interface(struct spa_handle *handle, uint32_t interface_id,
|
|||
|
||||
this = (struct impl *) handle;
|
||||
|
||||
if (interface_id == this->type.dbus)
|
||||
if (interface_id == SPA_ID_INTERFACE_DBus)
|
||||
*interface = &this->dbus;
|
||||
else
|
||||
return -ENOENT;
|
||||
|
|
@ -382,22 +370,15 @@ impl_init(const struct spa_handle_factory *factory,
|
|||
this->dbus = impl_dbus;
|
||||
|
||||
for (i = 0; i < n_support; i++) {
|
||||
if (strcmp(support[i].type, SPA_TYPE__TypeMap) == 0)
|
||||
this->map = support[i].data;
|
||||
else if (strcmp(support[i].type, SPA_TYPE__Log) == 0)
|
||||
if (support[i].type == SPA_ID_INTERFACE_Log)
|
||||
this->log = support[i].data;
|
||||
else if (strcmp(support[i].type, SPA_TYPE__LoopUtils) == 0)
|
||||
else if (support[i].type == SPA_ID_INTERFACE_LoopUtils)
|
||||
this->utils = support[i].data;
|
||||
}
|
||||
if (this->map == NULL) {
|
||||
spa_log_error(this->log, "a type-map is needed");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (this->utils == NULL) {
|
||||
spa_log_error(this->log, "a LoopUtils is needed");
|
||||
return -EINVAL;
|
||||
}
|
||||
init_type(&this->type, this->map);
|
||||
|
||||
spa_log_debug(this->log, NAME " %p: initialized", this);
|
||||
|
||||
|
|
@ -405,7 +386,7 @@ impl_init(const struct spa_handle_factory *factory,
|
|||
}
|
||||
|
||||
static const struct spa_interface_info impl_interfaces[] = {
|
||||
{SPA_TYPE__DBus,},
|
||||
{SPA_ID_INTERFACE_DBus,},
|
||||
};
|
||||
|
||||
static int
|
||||
|
|
|
|||
|
|
@ -24,11 +24,11 @@
|
|||
#include <stdio.h>
|
||||
#include <sys/eventfd.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>
|
||||
#include <spa/utils/type.h>
|
||||
|
||||
#define NAME "logger"
|
||||
|
||||
|
|
@ -36,22 +36,10 @@
|
|||
|
||||
#define TRACE_BUFFER (16*1024)
|
||||
|
||||
struct type {
|
||||
uint32_t log;
|
||||
};
|
||||
|
||||
static inline void init_type(struct type *type, struct spa_type_map *map)
|
||||
{
|
||||
type->log = spa_type_map_get_id(map, SPA_TYPE__Log);
|
||||
}
|
||||
|
||||
struct impl {
|
||||
struct spa_handle handle;
|
||||
struct spa_log log;
|
||||
|
||||
struct type type;
|
||||
struct spa_type_map *map;
|
||||
|
||||
bool colors;
|
||||
|
||||
struct spa_ringbuffer trace_rb;
|
||||
|
|
@ -170,7 +158,7 @@ static int impl_get_interface(struct spa_handle *handle, uint32_t interface_id,
|
|||
|
||||
this = (struct impl *) handle;
|
||||
|
||||
if (interface_id == this->type.log)
|
||||
if (interface_id == SPA_ID_INTERFACE_Log)
|
||||
*interface = &this->log;
|
||||
else
|
||||
return -ENOENT;
|
||||
|
|
@ -224,16 +212,9 @@ impl_init(const struct spa_handle_factory *factory,
|
|||
this->log = impl_log;
|
||||
|
||||
for (i = 0; i < n_support; i++) {
|
||||
if (strcmp(support[i].type, SPA_TYPE__TypeMap) == 0)
|
||||
this->map = support[i].data;
|
||||
if (strcmp(support[i].type, SPA_TYPE_LOOP__MainLoop) == 0)
|
||||
if (support[i].type == SPA_ID_INTERFACE_MainLoop)
|
||||
loop = support[i].data;
|
||||
}
|
||||
if (this->map == NULL) {
|
||||
spa_log_error(&this->log, "a type-map is needed");
|
||||
return -EINVAL;
|
||||
}
|
||||
init_type(&this->type, this->map);
|
||||
|
||||
if (info && (str = spa_dict_lookup(info, "log.colors")) != NULL)
|
||||
this->colors = (strcmp(str, "true") == 0 || atoi(str) == 1);
|
||||
|
|
@ -256,7 +237,7 @@ impl_init(const struct spa_handle_factory *factory,
|
|||
}
|
||||
|
||||
static const struct spa_interface_info impl_interfaces[] = {
|
||||
{SPA_TYPE__Log,},
|
||||
{SPA_ID_INTERFACE_Log,},
|
||||
};
|
||||
|
||||
static int
|
||||
|
|
|
|||
|
|
@ -31,9 +31,9 @@
|
|||
|
||||
#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/type.h>
|
||||
#include <spa/utils/ringbuffer.h>
|
||||
|
||||
#define NAME "loop"
|
||||
|
|
@ -53,21 +53,8 @@ struct invoke_item {
|
|||
int res;
|
||||
};
|
||||
|
||||
struct type {
|
||||
uint32_t loop;
|
||||
uint32_t loop_control;
|
||||
uint32_t loop_utils;
|
||||
};
|
||||
|
||||
static void loop_signal_event(struct spa_source *source);
|
||||
|
||||
static inline void init_type(struct type *type, struct spa_type_map *map)
|
||||
{
|
||||
type->loop = spa_type_map_get_id(map, SPA_TYPE__Loop);
|
||||
type->loop_control = spa_type_map_get_id(map, SPA_TYPE__LoopControl);
|
||||
type->loop_utils = spa_type_map_get_id(map, SPA_TYPE__LoopUtils);
|
||||
}
|
||||
|
||||
struct impl {
|
||||
struct spa_handle handle;
|
||||
struct spa_loop loop;
|
||||
|
|
@ -75,8 +62,6 @@ struct impl {
|
|||
struct spa_loop_utils utils;
|
||||
|
||||
struct spa_log *log;
|
||||
struct type type;
|
||||
struct spa_type_map *map;
|
||||
|
||||
struct spa_list source_list;
|
||||
struct spa_list destroy_list;
|
||||
|
|
@ -676,15 +661,19 @@ static int impl_get_interface(struct spa_handle *handle, uint32_t interface_id,
|
|||
|
||||
impl = (struct impl *) handle;
|
||||
|
||||
if (interface_id == impl->type.loop)
|
||||
switch (interface_id) {
|
||||
case SPA_ID_INTERFACE_Loop:
|
||||
*interface = &impl->loop;
|
||||
else if (interface_id == impl->type.loop_control)
|
||||
break;
|
||||
case SPA_ID_INTERFACE_LoopControl:
|
||||
*interface = &impl->control;
|
||||
else if (interface_id == impl->type.loop_utils)
|
||||
break;
|
||||
case SPA_ID_INTERFACE_LoopUtils:
|
||||
*interface = &impl->utils;
|
||||
else
|
||||
break;
|
||||
default:
|
||||
return -ENOENT;
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -737,16 +726,9 @@ impl_init(const struct spa_handle_factory *factory,
|
|||
impl->utils = impl_loop_utils;
|
||||
|
||||
for (i = 0; i < n_support; i++) {
|
||||
if (strcmp(support[i].type, SPA_TYPE__TypeMap) == 0)
|
||||
impl->map = support[i].data;
|
||||
else if (strcmp(support[i].type, SPA_TYPE__Log) == 0)
|
||||
if (support[i].type == SPA_ID_INTERFACE_Log)
|
||||
impl->log = support[i].data;
|
||||
}
|
||||
if (impl->map == NULL) {
|
||||
spa_log_error(impl->log, NAME " %p: a type-map is needed", impl);
|
||||
return -EINVAL;
|
||||
}
|
||||
init_type(&impl->type, impl->map);
|
||||
|
||||
impl->epoll_fd = epoll_create1(EPOLL_CLOEXEC);
|
||||
if (impl->epoll_fd == -1)
|
||||
|
|
@ -767,9 +749,9 @@ impl_init(const struct spa_handle_factory *factory,
|
|||
}
|
||||
|
||||
static const struct spa_interface_info impl_interfaces[] = {
|
||||
{SPA_TYPE__Loop,},
|
||||
{SPA_TYPE__LoopControl,},
|
||||
{SPA_TYPE__LoopUtils,},
|
||||
{SPA_ID_INTERFACE_Loop,},
|
||||
{SPA_ID_INTERFACE_LoopControl,},
|
||||
{SPA_ID_INTERFACE_LoopUtils,},
|
||||
};
|
||||
|
||||
static int
|
||||
|
|
|
|||
|
|
@ -1,227 +0,0 @@
|
|||
/* Spa
|
||||
* Copyright (C) 2017 Wim Taymans <wim.taymans@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/eventfd.h>
|
||||
|
||||
#include <spa/support/type-map.h>
|
||||
#include <spa/support/plugin.h>
|
||||
|
||||
#define NAME "mapper"
|
||||
|
||||
struct type {
|
||||
uint32_t type_map;
|
||||
};
|
||||
|
||||
static inline void init_type(struct type *type, struct spa_type_map *map)
|
||||
{
|
||||
type->type_map = spa_type_map_get_id(map, SPA_TYPE__TypeMap);
|
||||
}
|
||||
|
||||
struct array {
|
||||
size_t size;
|
||||
size_t maxsize;
|
||||
void *data;
|
||||
};
|
||||
|
||||
struct impl {
|
||||
struct spa_handle handle;
|
||||
struct spa_type_map map;
|
||||
|
||||
struct type type;
|
||||
|
||||
struct array types;
|
||||
struct array strings;
|
||||
};
|
||||
|
||||
static inline void * alloc_size(struct array *array, size_t size, size_t extend)
|
||||
{
|
||||
void *res;
|
||||
if (array->size + size > array->maxsize) {
|
||||
array->maxsize = SPA_ROUND_UP_N(array->size + size, extend);
|
||||
array->data = realloc(array->data, array->maxsize);
|
||||
}
|
||||
res = SPA_MEMBER(array->data, array->size, void);
|
||||
array->size += size;
|
||||
return res;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
impl_type_map_get_id(struct spa_type_map *map, const char *type)
|
||||
{
|
||||
struct impl *impl = SPA_CONTAINER_OF(map, struct impl, map);
|
||||
uint32_t i, len;
|
||||
void *p;
|
||||
off_t o, *off;
|
||||
|
||||
if (type == NULL)
|
||||
return SPA_ID_INVALID;
|
||||
|
||||
for (i = 0; i < impl->types.size / sizeof(off_t); i++) {
|
||||
o = ((off_t *)impl->types.data)[i];
|
||||
if (strcmp(SPA_MEMBER(impl->strings.data, o, char), type) == 0)
|
||||
return i;
|
||||
}
|
||||
len = strlen(type);
|
||||
p = alloc_size(&impl->strings, len+1, 1024);
|
||||
memcpy(p, type, len + 1);
|
||||
|
||||
off = alloc_size(&impl->types, sizeof(off_t), 128);
|
||||
*off = SPA_PTRDIFF(p, impl->strings.data);
|
||||
i = SPA_PTRDIFF(off, impl->types.data) / sizeof(off_t);
|
||||
|
||||
return i;
|
||||
|
||||
}
|
||||
|
||||
static const char *
|
||||
impl_type_map_get_type(const struct spa_type_map *map, uint32_t id)
|
||||
{
|
||||
struct impl *impl = SPA_CONTAINER_OF(map, struct impl, map);
|
||||
|
||||
if (id < impl->types.size / sizeof(off_t)) {
|
||||
off_t o = ((off_t *)impl->types.data)[id];
|
||||
return SPA_MEMBER(impl->strings.data, o, char);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static size_t
|
||||
impl_type_map_get_size(const struct spa_type_map *map)
|
||||
{
|
||||
struct impl *impl = SPA_CONTAINER_OF(map, struct impl, map);
|
||||
return impl->types.size / sizeof(off_t);
|
||||
}
|
||||
|
||||
static const struct spa_type_map impl_type_map = {
|
||||
SPA_VERSION_TYPE_MAP,
|
||||
NULL,
|
||||
impl_type_map_get_id,
|
||||
impl_type_map_get_type,
|
||||
impl_type_map_get_size,
|
||||
};
|
||||
|
||||
static int impl_get_interface(struct spa_handle *handle, uint32_t interface_id, void **interface)
|
||||
{
|
||||
struct impl *impl;
|
||||
|
||||
spa_return_val_if_fail(handle != NULL, -EINVAL);
|
||||
spa_return_val_if_fail(interface != NULL, -EINVAL);
|
||||
|
||||
impl = (struct impl *) handle;
|
||||
|
||||
if (interface_id == impl->type.type_map)
|
||||
*interface = &impl->map;
|
||||
else
|
||||
return -ENOENT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int impl_clear(struct spa_handle *handle)
|
||||
{
|
||||
struct impl *impl;
|
||||
|
||||
spa_return_val_if_fail(handle != NULL, -EINVAL);
|
||||
|
||||
impl = (struct impl *) handle;
|
||||
|
||||
if (impl->types.data)
|
||||
free(impl->types.data);
|
||||
if (impl->strings.data)
|
||||
free(impl->strings.data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static size_t
|
||||
impl_get_size(const struct spa_handle_factory *factory,
|
||||
const struct spa_dict *params)
|
||||
{
|
||||
return sizeof(struct impl);
|
||||
}
|
||||
|
||||
static int
|
||||
impl_init(const struct spa_handle_factory *factory,
|
||||
struct spa_handle *handle,
|
||||
const struct spa_dict *info,
|
||||
const struct spa_support *support,
|
||||
uint32_t n_support)
|
||||
{
|
||||
struct impl *impl;
|
||||
|
||||
spa_return_val_if_fail(factory != NULL, -EINVAL);
|
||||
spa_return_val_if_fail(handle != NULL, -EINVAL);
|
||||
|
||||
handle->get_interface = impl_get_interface;
|
||||
handle->clear = impl_clear;
|
||||
|
||||
impl = (struct impl *) handle;
|
||||
|
||||
impl->map = impl_type_map;
|
||||
|
||||
init_type(&impl->type, &impl->map);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct spa_interface_info impl_interfaces[] = {
|
||||
{SPA_TYPE__TypeMap,},
|
||||
};
|
||||
|
||||
static int
|
||||
impl_enum_interface_info(const struct spa_handle_factory *factory,
|
||||
const struct spa_interface_info **info,
|
||||
uint32_t *index)
|
||||
{
|
||||
spa_return_val_if_fail(factory != NULL, -EINVAL);
|
||||
spa_return_val_if_fail(info != NULL, -EINVAL);
|
||||
spa_return_val_if_fail(index != NULL, -EINVAL);
|
||||
|
||||
switch (*index) {
|
||||
case 0:
|
||||
*info = &impl_interfaces[*index];
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
(*index)++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const struct spa_handle_factory type_map_factory = {
|
||||
SPA_VERSION_HANDLE_FACTORY,
|
||||
NAME,
|
||||
NULL,
|
||||
impl_get_size,
|
||||
impl_init,
|
||||
impl_enum_interface_info,
|
||||
};
|
||||
|
||||
int spa_handle_factory_register(const struct spa_handle_factory *factory);
|
||||
|
||||
static void reg(void) __attribute__ ((constructor));
|
||||
static void reg(void)
|
||||
{
|
||||
spa_handle_factory_register(&type_map_factory);
|
||||
}
|
||||
|
|
@ -1,5 +1,4 @@
|
|||
spa_support_sources = ['mapper.c',
|
||||
'logger.c',
|
||||
spa_support_sources = ['logger.c',
|
||||
'loop.c',
|
||||
'plugin.c']
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@
|
|||
#include <stdio.h>
|
||||
#include <sys/timerfd.h>
|
||||
|
||||
#include <spa/support/type-map.h>
|
||||
#include <spa/support/log.h>
|
||||
#include <spa/support/loop.h>
|
||||
#include <spa/utils/list.h>
|
||||
|
|
@ -38,37 +37,6 @@
|
|||
|
||||
#define NAME "fakesink"
|
||||
|
||||
struct type {
|
||||
uint32_t node;
|
||||
uint32_t format;
|
||||
uint32_t props;
|
||||
uint32_t prop_live;
|
||||
struct spa_type_io io;
|
||||
struct spa_type_param param;
|
||||
struct spa_type_meta meta;
|
||||
struct spa_type_data data;
|
||||
struct spa_type_event_node event_node;
|
||||
struct spa_type_command_node command_node;
|
||||
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)
|
||||
{
|
||||
type->node = spa_type_map_get_id(map, SPA_TYPE__Node);
|
||||
type->format = spa_type_map_get_id(map, SPA_TYPE__Format);
|
||||
type->props = spa_type_map_get_id(map, SPA_TYPE__Props);
|
||||
type->prop_live = spa_type_map_get_id(map, SPA_TYPE_PROPS__live);
|
||||
spa_type_io_map(map, &type->io);
|
||||
spa_type_param_map(map, &type->param);
|
||||
spa_type_meta_map(map, &type->meta);
|
||||
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_buffers_map(map, &type->param_buffers);
|
||||
spa_type_param_meta_map(map, &type->param_meta);
|
||||
}
|
||||
|
||||
struct props {
|
||||
bool live;
|
||||
};
|
||||
|
|
@ -87,8 +55,6 @@ struct impl {
|
|||
struct spa_handle handle;
|
||||
struct spa_node node;
|
||||
|
||||
struct type type;
|
||||
struct spa_type_map *map;
|
||||
struct spa_log *log;
|
||||
struct spa_loop *data_loop;
|
||||
|
||||
|
|
@ -133,7 +99,6 @@ static int impl_node_enum_params(struct spa_node *node,
|
|||
struct spa_pod_builder *builder)
|
||||
{
|
||||
struct impl *this;
|
||||
struct type *t;
|
||||
struct spa_pod_builder b = { 0 };
|
||||
uint8_t buffer[1024];
|
||||
struct spa_pod *param;
|
||||
|
|
@ -142,29 +107,30 @@ static int impl_node_enum_params(struct spa_node *node,
|
|||
spa_return_val_if_fail(builder != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
t = &this->type;
|
||||
|
||||
next:
|
||||
spa_pod_builder_init(&b, buffer, sizeof(buffer));
|
||||
|
||||
if (id == t->param.idList) {
|
||||
switch (id) {
|
||||
case SPA_ID_PARAM_List:
|
||||
if (*index > 0)
|
||||
return 0;
|
||||
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param.List,
|
||||
":", t->param.listId, "I", t->param.idProps);
|
||||
}
|
||||
else if (id == t->param.idProps) {
|
||||
id, SPA_ID_OBJECT_ParamList,
|
||||
":", SPA_PARAM_LIST_id, "I", SPA_ID_PARAM_Props);
|
||||
break;
|
||||
case SPA_ID_PARAM_Props:
|
||||
if (*index > 0)
|
||||
return 0;
|
||||
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->props,
|
||||
":", t->prop_live, "b", this->props.live);
|
||||
}
|
||||
else
|
||||
id, SPA_ID_OBJECT_Props,
|
||||
":", SPA_PROP_live, "b", this->props.live);
|
||||
break;
|
||||
default:
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
(*index)++;
|
||||
|
||||
|
|
@ -178,29 +144,29 @@ static int impl_node_set_param(struct spa_node *node, uint32_t id, uint32_t flag
|
|||
const struct spa_pod *param)
|
||||
{
|
||||
struct impl *this;
|
||||
struct type *t;
|
||||
|
||||
spa_return_val_if_fail(node != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
t = &this->type;
|
||||
|
||||
if (id == t->param.idProps) {
|
||||
switch (id) {
|
||||
case SPA_ID_PARAM_Props:
|
||||
if (param == NULL) {
|
||||
reset_props(this, &this->props);
|
||||
return 0;
|
||||
}
|
||||
spa_pod_object_parse(param,
|
||||
":", t->prop_live, "?b", &this->props.live, NULL);
|
||||
":", SPA_PROP_live, "?b", &this->props.live, NULL);
|
||||
|
||||
if (this->props.live)
|
||||
this->info.flags |= SPA_PORT_INFO_FLAG_LIVE;
|
||||
else
|
||||
this->info.flags &= ~SPA_PORT_INFO_FLAG_LIVE;
|
||||
}
|
||||
else
|
||||
return -ENOENT;
|
||||
break;
|
||||
|
||||
default:
|
||||
return -ENOENT;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -302,7 +268,9 @@ static int impl_node_send_command(struct spa_node *node, const struct spa_comman
|
|||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
|
||||
if (SPA_COMMAND_TYPE(command) == this->type.command_node.Start) {
|
||||
switch (SPA_COMMAND_TYPE(command)) {
|
||||
case SPA_ID_COMMAND_NODE_Start:
|
||||
{
|
||||
struct timespec now;
|
||||
|
||||
if (!this->have_format)
|
||||
|
|
@ -323,7 +291,9 @@ static int impl_node_send_command(struct spa_node *node, const struct spa_comman
|
|||
|
||||
this->started = true;
|
||||
set_timer(this, true);
|
||||
} else if (SPA_COMMAND_TYPE(command) == this->type.command_node.Pause) {
|
||||
break;
|
||||
}
|
||||
case SPA_ID_COMMAND_NODE_Pause:
|
||||
if (!this->have_format)
|
||||
return -EIO;
|
||||
if (this->n_buffers == 0)
|
||||
|
|
@ -334,8 +304,10 @@ static int impl_node_send_command(struct spa_node *node, const struct spa_comman
|
|||
|
||||
this->started = false;
|
||||
set_timer(this, false);
|
||||
} else
|
||||
break;
|
||||
default:
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -466,8 +438,6 @@ impl_node_port_enum_params(struct spa_node *node,
|
|||
struct spa_pod **result,
|
||||
struct spa_pod_builder *builder)
|
||||
{
|
||||
struct impl *this;
|
||||
struct type *t;
|
||||
struct spa_pod_builder b = { 0 };
|
||||
uint8_t buffer[1024];
|
||||
struct spa_pod *param;
|
||||
|
|
@ -477,60 +447,62 @@ impl_node_port_enum_params(struct spa_node *node,
|
|||
spa_return_val_if_fail(index != NULL, -EINVAL);
|
||||
spa_return_val_if_fail(builder != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
t = &this->type;
|
||||
|
||||
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
|
||||
spa_return_val_if_fail(CHECK_PORT(node, direction, port_id), -EINVAL);
|
||||
|
||||
next:
|
||||
spa_pod_builder_init(&b, buffer, sizeof(buffer));
|
||||
|
||||
if (id == t->param.idList) {
|
||||
uint32_t list[] = { t->param.idEnumFormat,
|
||||
t->param.idFormat,
|
||||
t->param.idBuffers,
|
||||
t->param.idMeta };
|
||||
switch (id) {
|
||||
case SPA_ID_PARAM_List:
|
||||
{
|
||||
uint32_t list[] = { SPA_ID_PARAM_EnumFormat,
|
||||
SPA_ID_PARAM_Format,
|
||||
SPA_ID_PARAM_Buffers,
|
||||
SPA_ID_PARAM_Meta };
|
||||
|
||||
if (*index < SPA_N_ELEMENTS(list))
|
||||
param = spa_pod_builder_object(&b, id, t->param.List,
|
||||
":", t->param.listId, "I", list[*index]);
|
||||
param = spa_pod_builder_object(&b, id, SPA_ID_OBJECT_ParamList,
|
||||
":", SPA_PARAM_LIST_id, "I", list[*index]);
|
||||
else
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
else if (id == t->param.idEnumFormat) {
|
||||
case SPA_ID_PARAM_EnumFormat:
|
||||
if ((res = port_enum_formats(node, direction, port_id, index, filter, ¶m, &b)) <= 0)
|
||||
return res;
|
||||
}
|
||||
else if (id == t->param.idFormat) {
|
||||
break;
|
||||
case SPA_ID_PARAM_Format:
|
||||
if ((res = port_get_format(node, direction, port_id, index, filter, ¶m, &b)) <= 0)
|
||||
return res;
|
||||
}
|
||||
else if (id == t->param.idBuffers) {
|
||||
break;
|
||||
case SPA_ID_PARAM_Buffers:
|
||||
if (*index > 0)
|
||||
return 0;
|
||||
|
||||
param = spa_pod_builder_object(&b,
|
||||
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_buffers.align, "i", 16);
|
||||
}
|
||||
else if (id == t->param.idMeta) {
|
||||
id, SPA_ID_OBJECT_ParamBuffers,
|
||||
":", SPA_PARAM_BUFFERS_buffers, "ir", 2,
|
||||
SPA_POD_PROP_MIN_MAX(1, 32),
|
||||
":", SPA_PARAM_BUFFERS_blocks, "i", 1,
|
||||
":", SPA_PARAM_BUFFERS_size, "i", 128,
|
||||
":", SPA_PARAM_BUFFERS_stride, "i", 1,
|
||||
":", SPA_PARAM_BUFFERS_align, "i", 16);
|
||||
break;
|
||||
case SPA_ID_PARAM_Meta:
|
||||
switch (*index) {
|
||||
case 0:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param_meta.Meta,
|
||||
":", t->param_meta.type, "I", t->meta.Header,
|
||||
":", t->param_meta.size, "i", sizeof(struct spa_meta_header));
|
||||
id, SPA_ID_OBJECT_ParamMeta,
|
||||
":", SPA_PARAM_META_type, "I", SPA_META_Header,
|
||||
":", SPA_PARAM_META_size, "i", sizeof(struct spa_meta_header));
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
break;
|
||||
default:
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
(*index)++;
|
||||
|
||||
|
|
@ -577,17 +549,11 @@ impl_node_port_set_param(struct spa_node *node,
|
|||
uint32_t id, uint32_t flags,
|
||||
const struct spa_pod *param)
|
||||
{
|
||||
struct impl *this;
|
||||
struct type *t;
|
||||
|
||||
spa_return_val_if_fail(node != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
t = &this->type;
|
||||
spa_return_val_if_fail(CHECK_PORT(node, direction, port_id), -EINVAL);
|
||||
|
||||
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
|
||||
|
||||
if (id == t->param.idFormat) {
|
||||
if (id == SPA_ID_PARAM_Format) {
|
||||
return port_set_format(node, direction, port_id, flags, param);
|
||||
}
|
||||
else
|
||||
|
|
@ -603,7 +569,6 @@ impl_node_port_use_buffers(struct spa_node *node,
|
|||
{
|
||||
struct impl *this;
|
||||
uint32_t i;
|
||||
struct type *t;
|
||||
|
||||
spa_return_val_if_fail(node != NULL, -EINVAL);
|
||||
|
||||
|
|
@ -614,8 +579,6 @@ impl_node_port_use_buffers(struct spa_node *node,
|
|||
if (!this->have_format)
|
||||
return -EIO;
|
||||
|
||||
t = &this->type;
|
||||
|
||||
clear_buffers(this);
|
||||
|
||||
for (i = 0; i < n_buffers; i++) {
|
||||
|
|
@ -625,11 +588,11 @@ impl_node_port_use_buffers(struct spa_node *node,
|
|||
b = &this->buffers[i];
|
||||
b->outbuf = buffers[i];
|
||||
b->outstanding = true;
|
||||
b->h = spa_buffer_find_meta_data(buffers[i], t->meta.Header, sizeof(*b->h));
|
||||
b->h = spa_buffer_find_meta_data(buffers[i], SPA_META_Header, sizeof(*b->h));
|
||||
|
||||
if ((d[0].type == t->data.MemPtr ||
|
||||
d[0].type == t->data.MemFd ||
|
||||
d[0].type == t->data.DmaBuf) && d[0].data == NULL) {
|
||||
if ((d[0].type == SPA_DATA_MemPtr ||
|
||||
d[0].type == SPA_DATA_MemFd ||
|
||||
d[0].type == SPA_DATA_DmaBuf) && d[0].data == NULL) {
|
||||
spa_log_error(this->log, NAME " %p: invalid memory on buffer %p", this,
|
||||
buffers[i]);
|
||||
}
|
||||
|
|
@ -670,16 +633,14 @@ impl_node_port_set_io(struct spa_node *node,
|
|||
void *data, size_t size)
|
||||
{
|
||||
struct impl *this;
|
||||
struct type *t;
|
||||
|
||||
spa_return_val_if_fail(node != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
t = &this->type;
|
||||
|
||||
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
|
||||
|
||||
if (id == t->io.Buffers)
|
||||
if (id == SPA_ID_IO_Buffers)
|
||||
this->io = data;
|
||||
else
|
||||
return -ENOENT;
|
||||
|
|
@ -767,7 +728,7 @@ static int impl_get_interface(struct spa_handle *handle, uint32_t interface_id,
|
|||
|
||||
this = (struct impl *) handle;
|
||||
|
||||
if (interface_id == this->type.node)
|
||||
if (interface_id == SPA_ID_INTERFACE_Node)
|
||||
*interface = &this->node;
|
||||
else
|
||||
return -ENOENT;
|
||||
|
|
@ -816,18 +777,11 @@ impl_init(const struct spa_handle_factory *factory,
|
|||
this = (struct impl *) handle;
|
||||
|
||||
for (i = 0; i < n_support; i++) {
|
||||
if (strcmp(support[i].type, SPA_TYPE__TypeMap) == 0)
|
||||
this->map = support[i].data;
|
||||
else if (strcmp(support[i].type, SPA_TYPE__Log) == 0)
|
||||
if (support[i].type == SPA_ID_INTERFACE_Log)
|
||||
this->log = support[i].data;
|
||||
else if (strcmp(support[i].type, SPA_TYPE_LOOP__DataLoop) == 0)
|
||||
else if (support[i].type == SPA_ID_INTERFACE_DataLoop)
|
||||
this->data_loop = support[i].data;
|
||||
}
|
||||
if (this->map == NULL) {
|
||||
spa_log_error(this->log, "a type-map is needed");
|
||||
return -EINVAL;
|
||||
}
|
||||
init_type(&this->type, this->map);
|
||||
|
||||
this->node = impl_node;
|
||||
reset_props(this, &this->props);
|
||||
|
|
@ -857,7 +811,7 @@ impl_init(const struct spa_handle_factory *factory,
|
|||
}
|
||||
|
||||
static const struct spa_interface_info impl_interfaces[] = {
|
||||
{SPA_TYPE__Node,},
|
||||
{SPA_ID_INTERFACE_Node,},
|
||||
};
|
||||
|
||||
static int
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@
|
|||
#include <stdio.h>
|
||||
#include <sys/timerfd.h>
|
||||
|
||||
#include <spa/support/type-map.h>
|
||||
#include <spa/support/log.h>
|
||||
#include <spa/support/loop.h>
|
||||
#include <spa/utils/list.h>
|
||||
|
|
@ -38,39 +37,6 @@
|
|||
|
||||
#define NAME "fakesrc"
|
||||
|
||||
struct type {
|
||||
uint32_t node;
|
||||
uint32_t format;
|
||||
uint32_t props;
|
||||
uint32_t prop_live;
|
||||
uint32_t prop_pattern;
|
||||
struct spa_type_io io;
|
||||
struct spa_type_param param;
|
||||
struct spa_type_meta meta;
|
||||
struct spa_type_data data;
|
||||
struct spa_type_event_node event_node;
|
||||
struct spa_type_command_node command_node;
|
||||
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)
|
||||
{
|
||||
type->node = spa_type_map_get_id(map, SPA_TYPE__Node);
|
||||
type->format = spa_type_map_get_id(map, SPA_TYPE__Format);
|
||||
type->props = spa_type_map_get_id(map, SPA_TYPE__Props);
|
||||
type->prop_live = spa_type_map_get_id(map, SPA_TYPE_PROPS__live);
|
||||
type->prop_pattern = spa_type_map_get_id(map, SPA_TYPE_PROPS__patternType);
|
||||
spa_type_io_map(map, &type->io);
|
||||
spa_type_param_map(map, &type->param);
|
||||
spa_type_meta_map(map, &type->meta);
|
||||
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_buffers_map(map, &type->param_buffers);
|
||||
spa_type_param_meta_map(map, &type->param_meta);
|
||||
}
|
||||
|
||||
struct props {
|
||||
bool live;
|
||||
uint32_t pattern;
|
||||
|
|
@ -90,8 +56,6 @@ struct impl {
|
|||
struct spa_handle handle;
|
||||
struct spa_node node;
|
||||
|
||||
struct type type;
|
||||
struct spa_type_map *map;
|
||||
struct spa_log *log;
|
||||
struct spa_loop *data_loop;
|
||||
|
||||
|
|
@ -139,7 +103,6 @@ static int impl_node_enum_params(struct spa_node *node,
|
|||
struct spa_pod_builder *builder)
|
||||
{
|
||||
struct impl *this;
|
||||
struct type *t;
|
||||
struct spa_pod_builder b = { 0 };
|
||||
uint8_t buffer[1024];
|
||||
struct spa_pod *param;
|
||||
|
|
@ -149,33 +112,37 @@ static int impl_node_enum_params(struct spa_node *node,
|
|||
spa_return_val_if_fail(builder != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
t = &this->type;
|
||||
|
||||
next:
|
||||
spa_pod_builder_init(&b, buffer, sizeof(buffer));
|
||||
|
||||
if (id == t->param.idList) {
|
||||
switch (id) {
|
||||
case SPA_ID_PARAM_List:
|
||||
if (*index > 0)
|
||||
return 0;
|
||||
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param.List,
|
||||
":", t->param.listId, "I", t->param.idProps);
|
||||
}
|
||||
else if (id == t->param.idProps) {
|
||||
id, SPA_ID_OBJECT_ParamList,
|
||||
":", SPA_PARAM_LIST_id, "I", SPA_ID_PARAM_Props);
|
||||
break;
|
||||
|
||||
case SPA_ID_PARAM_Props:
|
||||
{
|
||||
struct props *p = &this->props;
|
||||
|
||||
if (*index > 0)
|
||||
return 0;
|
||||
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->props,
|
||||
":", t->prop_live, "b", p->live,
|
||||
":", t->prop_pattern, "Ie", p->pattern,
|
||||
1, p->pattern);
|
||||
id, SPA_ID_OBJECT_Props,
|
||||
":", SPA_PROP_live, "b", p->live,
|
||||
":", SPA_PROP_patternType, "Ie", p->pattern,
|
||||
SPA_POD_PROP_ENUM(1, p->pattern));
|
||||
break;
|
||||
}
|
||||
else
|
||||
default:
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
(*index)++;
|
||||
|
||||
|
|
@ -189,14 +156,14 @@ static int impl_node_set_param(struct spa_node *node, uint32_t id, uint32_t flag
|
|||
const struct spa_pod *param)
|
||||
{
|
||||
struct impl *this;
|
||||
struct type *t;
|
||||
|
||||
spa_return_val_if_fail(node != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
t = &this->type;
|
||||
|
||||
if (id == t->param.idProps) {
|
||||
switch (id) {
|
||||
case SPA_ID_PARAM_Props:
|
||||
{
|
||||
struct props *p = &this->props;
|
||||
|
||||
if (param == NULL) {
|
||||
|
|
@ -204,17 +171,18 @@ static int impl_node_set_param(struct spa_node *node, uint32_t id, uint32_t flag
|
|||
return 0;
|
||||
}
|
||||
spa_pod_object_parse(param,
|
||||
":", t->prop_live, "?b", &p->live,
|
||||
":", t->prop_pattern, "?I", &p->pattern, NULL);
|
||||
":", SPA_PROP_live, "?b", &p->live,
|
||||
":", SPA_PROP_patternType, "?I", &p->pattern, NULL);
|
||||
|
||||
if (p->live)
|
||||
this->info.flags |= SPA_PORT_INFO_FLAG_LIVE;
|
||||
else
|
||||
this->info.flags &= ~SPA_PORT_INFO_FLAG_LIVE;
|
||||
break;
|
||||
}
|
||||
else
|
||||
default:
|
||||
return -ENOENT;
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -317,7 +285,9 @@ static int impl_node_send_command(struct spa_node *node, const struct spa_comman
|
|||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
|
||||
if (SPA_COMMAND_TYPE(command) == this->type.command_node.Start) {
|
||||
switch (SPA_COMMAND_TYPE(command)) {
|
||||
case SPA_ID_COMMAND_NODE_Start:
|
||||
{
|
||||
struct timespec now;
|
||||
|
||||
if (!this->have_format)
|
||||
|
|
@ -339,7 +309,9 @@ static int impl_node_send_command(struct spa_node *node, const struct spa_comman
|
|||
|
||||
this->started = true;
|
||||
set_timer(this, true);
|
||||
} else if (SPA_COMMAND_TYPE(command) == this->type.command_node.Pause) {
|
||||
break;
|
||||
}
|
||||
case SPA_ID_COMMAND_NODE_Pause:
|
||||
if (!this->have_format)
|
||||
return -EIO;
|
||||
if (this->n_buffers == 0)
|
||||
|
|
@ -350,9 +322,10 @@ static int impl_node_send_command(struct spa_node *node, const struct spa_comman
|
|||
|
||||
this->started = false;
|
||||
set_timer(this, false);
|
||||
} else
|
||||
break;
|
||||
default:
|
||||
return -ENOTSUP;
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -481,8 +454,6 @@ impl_node_port_enum_params(struct spa_node *node,
|
|||
struct spa_pod **result,
|
||||
struct spa_pod_builder *builder)
|
||||
{
|
||||
struct impl *this;
|
||||
struct type *t;
|
||||
struct spa_pod_builder b = { 0 };
|
||||
uint8_t buffer[1024];
|
||||
struct spa_pod *param;
|
||||
|
|
@ -492,60 +463,62 @@ impl_node_port_enum_params(struct spa_node *node,
|
|||
spa_return_val_if_fail(index != NULL, -EINVAL);
|
||||
spa_return_val_if_fail(builder != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
t = &this->type;
|
||||
|
||||
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
|
||||
spa_return_val_if_fail(CHECK_PORT(node, direction, port_id), -EINVAL);
|
||||
|
||||
next:
|
||||
spa_pod_builder_init(&b, buffer, sizeof(buffer));
|
||||
|
||||
if (id == t->param.idList) {
|
||||
uint32_t list[] = { t->param.idEnumFormat,
|
||||
t->param.idFormat,
|
||||
t->param.idBuffers,
|
||||
t->param.idMeta };
|
||||
switch (id) {
|
||||
case SPA_ID_PARAM_List:
|
||||
{
|
||||
uint32_t list[] = { SPA_ID_PARAM_EnumFormat,
|
||||
SPA_ID_PARAM_Format,
|
||||
SPA_ID_PARAM_Buffers,
|
||||
SPA_ID_PARAM_Meta };
|
||||
|
||||
if (*index < SPA_N_ELEMENTS(list))
|
||||
param = spa_pod_builder_object(&b, id, t->param.List,
|
||||
":", t->param.listId, "I", list[*index]);
|
||||
param = spa_pod_builder_object(&b, id, SPA_ID_OBJECT_ParamList,
|
||||
":", SPA_PARAM_LIST_id, "I", list[*index]);
|
||||
else
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
else if (id == t->param.idEnumFormat) {
|
||||
case SPA_ID_PARAM_EnumFormat:
|
||||
if ((res = port_enum_formats(node, direction, port_id, index, filter, ¶m, &b)) <= 0)
|
||||
return res;
|
||||
}
|
||||
else if (id == t->param.idFormat) {
|
||||
break;
|
||||
case SPA_ID_PARAM_Format:
|
||||
if ((res = port_get_format(node, direction, port_id, index, filter, ¶m, &b)) <= 0)
|
||||
return res;
|
||||
}
|
||||
else if (id == t->param.idBuffers) {
|
||||
break;
|
||||
case SPA_ID_PARAM_Buffers:
|
||||
if (*index > 0)
|
||||
return 0;
|
||||
|
||||
param = spa_pod_builder_object(&b,
|
||||
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_buffers.align, "i", 16);
|
||||
}
|
||||
else if (id == t->param.idMeta) {
|
||||
id, SPA_ID_OBJECT_ParamBuffers,
|
||||
":", SPA_PARAM_BUFFERS_buffers, "ir", 32,
|
||||
SPA_POD_PROP_MIN_MAX(2, 32),
|
||||
":", SPA_PARAM_BUFFERS_blocks, "i", 1,
|
||||
":", SPA_PARAM_BUFFERS_size, "i", 128,
|
||||
":", SPA_PARAM_BUFFERS_stride, "i", 1,
|
||||
":", SPA_PARAM_BUFFERS_align, "i", 16);
|
||||
break;
|
||||
case SPA_ID_PARAM_Meta:
|
||||
switch (*index) {
|
||||
case 0:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param_meta.Meta,
|
||||
":", t->param_meta.type, "I", t->meta.Header,
|
||||
":", t->param_meta.size, "i", sizeof(struct spa_meta_header));
|
||||
id, SPA_ID_OBJECT_ParamMeta,
|
||||
":", SPA_PARAM_META_type, "I", SPA_META_Header,
|
||||
":", SPA_PARAM_META_size, "i", sizeof(struct spa_meta_header));
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
break;
|
||||
default:
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
(*index)++;
|
||||
|
||||
|
|
@ -592,17 +565,11 @@ impl_node_port_set_param(struct spa_node *node,
|
|||
uint32_t id, uint32_t flags,
|
||||
const struct spa_pod *param)
|
||||
{
|
||||
struct impl *this;
|
||||
struct type *t;
|
||||
|
||||
spa_return_val_if_fail(node != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
t = &this->type;
|
||||
spa_return_val_if_fail(CHECK_PORT(node, direction, port_id), -EINVAL);
|
||||
|
||||
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
|
||||
|
||||
if (id == t->param.idFormat) {
|
||||
if (id == SPA_ID_PARAM_Format) {
|
||||
return port_set_format(node, direction, port_id, flags, param);
|
||||
}
|
||||
else
|
||||
|
|
@ -637,11 +604,11 @@ impl_node_port_use_buffers(struct spa_node *node,
|
|||
b = &this->buffers[i];
|
||||
b->outbuf = buffers[i];
|
||||
b->outstanding = false;
|
||||
b->h = spa_buffer_find_meta_data(buffers[i], this->type.meta.Header, sizeof(*b->h));
|
||||
b->h = spa_buffer_find_meta_data(buffers[i], SPA_META_Header, sizeof(*b->h));
|
||||
|
||||
if ((d[0].type == this->type.data.MemPtr ||
|
||||
d[0].type == this->type.data.MemFd ||
|
||||
d[0].type == this->type.data.DmaBuf) && d[0].data == NULL) {
|
||||
if ((d[0].type == SPA_DATA_MemPtr ||
|
||||
d[0].type == SPA_DATA_MemFd ||
|
||||
d[0].type == SPA_DATA_DmaBuf) && d[0].data == NULL) {
|
||||
spa_log_error(this->log, NAME " %p: invalid memory on buffer %p", this,
|
||||
buffers[i]);
|
||||
}
|
||||
|
|
@ -684,16 +651,14 @@ impl_node_port_set_io(struct spa_node *node,
|
|||
void *data, size_t size)
|
||||
{
|
||||
struct impl *this;
|
||||
struct type *t;
|
||||
|
||||
spa_return_val_if_fail(node != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
t = &this->type;
|
||||
|
||||
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
|
||||
|
||||
if (id == t->io.Buffers)
|
||||
if (id == SPA_ID_IO_Buffers)
|
||||
this->io = data;
|
||||
else
|
||||
return -ENOENT;
|
||||
|
|
@ -799,7 +764,7 @@ static int impl_get_interface(struct spa_handle *handle, uint32_t interface_id,
|
|||
|
||||
this = (struct impl *) handle;
|
||||
|
||||
if (interface_id == this->type.node)
|
||||
if (interface_id == SPA_ID_INTERFACE_Node)
|
||||
*interface = &this->node;
|
||||
else
|
||||
return -ENOENT;
|
||||
|
|
@ -848,18 +813,11 @@ impl_init(const struct spa_handle_factory *factory,
|
|||
this = (struct impl *) handle;
|
||||
|
||||
for (i = 0; i < n_support; i++) {
|
||||
if (strcmp(support[i].type, SPA_TYPE__TypeMap) == 0)
|
||||
this->map = support[i].data;
|
||||
else if (strcmp(support[i].type, SPA_TYPE__Log) == 0)
|
||||
if (support[i].type == SPA_ID_INTERFACE_Log)
|
||||
this->log = support[i].data;
|
||||
else if (strcmp(support[i].type, SPA_TYPE_LOOP__DataLoop) == 0)
|
||||
else if (support[i].type == SPA_ID_INTERFACE_DataLoop)
|
||||
this->data_loop = support[i].data;
|
||||
}
|
||||
if (this->map == NULL) {
|
||||
spa_log_error(this->log, "a type-map is needed");
|
||||
return -EINVAL;
|
||||
}
|
||||
init_type(&this->type, this->map);
|
||||
|
||||
this->node = impl_node;
|
||||
reset_props(this, &this->props);
|
||||
|
|
@ -889,7 +847,7 @@ impl_init(const struct spa_handle_factory *factory,
|
|||
}
|
||||
|
||||
static const struct spa_interface_info impl_interfaces[] = {
|
||||
{SPA_TYPE__Node,},
|
||||
{SPA_ID_INTERFACE_Node,},
|
||||
};
|
||||
|
||||
static int
|
||||
|
|
|
|||
|
|
@ -27,9 +27,9 @@
|
|||
#include <libudev.h>
|
||||
|
||||
#include <spa/support/log.h>
|
||||
#include <spa/support/type-map.h>
|
||||
#include <spa/support/loop.h>
|
||||
#include <spa/support/plugin.h>
|
||||
#include <spa/utils/type.h>
|
||||
#include <spa/monitor/monitor.h>
|
||||
|
||||
#define NAME "v4l2-monitor"
|
||||
|
|
@ -40,23 +40,10 @@ struct item {
|
|||
struct udev_device *udevice;
|
||||
};
|
||||
|
||||
struct type {
|
||||
uint32_t handle_factory;
|
||||
struct spa_type_monitor monitor;
|
||||
};
|
||||
|
||||
static inline void init_type(struct type *type, struct spa_type_map *map)
|
||||
{
|
||||
type->handle_factory = spa_type_map_get_id(map, SPA_TYPE__HandleFactory);
|
||||
spa_type_monitor_map(map, &type->monitor);
|
||||
}
|
||||
|
||||
struct impl {
|
||||
struct spa_handle handle;
|
||||
struct spa_monitor monitor;
|
||||
|
||||
struct type type;
|
||||
struct spa_type_map *map;
|
||||
struct spa_log *log;
|
||||
struct spa_loop *main_loop;
|
||||
|
||||
|
|
@ -90,7 +77,6 @@ static void fill_item(struct impl *this, struct item *item, struct udev_device *
|
|||
struct spa_pod **result, struct spa_pod_builder *builder)
|
||||
{
|
||||
const char *str, *name;
|
||||
struct type *t = &this->type;
|
||||
|
||||
if (item->udevice)
|
||||
udev_device_unref(item->udevice);
|
||||
|
|
@ -112,14 +98,14 @@ static void fill_item(struct impl *this, struct item *item, struct udev_device *
|
|||
name = "Unknown";
|
||||
|
||||
spa_pod_builder_add(builder,
|
||||
"<", 0, t->monitor.MonitorItem,
|
||||
":", t->monitor.id, "s", udev_device_get_syspath(item->udevice),
|
||||
":", t->monitor.flags, "i", 0,
|
||||
":", t->monitor.state, "i", SPA_MONITOR_ITEM_STATE_AVAILABLE,
|
||||
":", t->monitor.name, "s", name,
|
||||
":", t->monitor.klass, "s", "Video/Source",
|
||||
":", t->monitor.factory, "p", t->handle_factory, &spa_v4l2_source_factory,
|
||||
":", t->monitor.info, "[",
|
||||
"<", 0, SPA_ID_OBJECT_MonitorItem,
|
||||
":", SPA_MONITOR_ITEM_id, "s", udev_device_get_syspath(item->udevice),
|
||||
":", SPA_MONITOR_ITEM_flags, "i", SPA_MONITOR_ITEM_FLAG_NONE,
|
||||
":", SPA_MONITOR_ITEM_state, "i", SPA_MONITOR_ITEM_STATE_AVAILABLE,
|
||||
":", SPA_MONITOR_ITEM_name, "s", name,
|
||||
":", SPA_MONITOR_ITEM_class, "s", "Video/Source",
|
||||
":", SPA_MONITOR_ITEM_factory, "p", SPA_ID_INTERFACE_HandleFactory, &spa_v4l2_source_factory,
|
||||
":", SPA_MONITOR_ITEM_info, "[",
|
||||
NULL);
|
||||
|
||||
spa_pod_builder_add(builder,
|
||||
|
|
@ -192,11 +178,11 @@ static void impl_on_fd_events(struct spa_source *source)
|
|||
action = "change";
|
||||
|
||||
if (strcmp(action, "add") == 0) {
|
||||
type = this->type.monitor.Added;
|
||||
type = SPA_ID_EVENT_MONITOR_Added;
|
||||
} else if (strcmp(action, "change") == 0) {
|
||||
type = this->type.monitor.Changed;
|
||||
type = SPA_ID_EVENT_MONITOR_Changed;
|
||||
} else if (strcmp(action, "remove") == 0) {
|
||||
type = this->type.monitor.Removed;
|
||||
type = SPA_ID_EVENT_MONITOR_Removed;
|
||||
} else
|
||||
return;
|
||||
|
||||
|
|
@ -314,7 +300,7 @@ static int impl_get_interface(struct spa_handle *handle, uint32_t interface_id,
|
|||
|
||||
this = (struct impl *) handle;
|
||||
|
||||
if (interface_id == this->type.monitor.Monitor)
|
||||
if (interface_id == SPA_ID_INTERFACE_Monitor)
|
||||
*interface = &this->monitor;
|
||||
else
|
||||
return -ENOENT;
|
||||
|
|
@ -364,22 +350,15 @@ impl_init(const struct spa_handle_factory *factory,
|
|||
this = (struct impl *) handle;
|
||||
|
||||
for (i = 0; i < n_support; i++) {
|
||||
if (strcmp(support[i].type, SPA_TYPE__TypeMap) == 0)
|
||||
this->map = support[i].data;
|
||||
else if (strcmp(support[i].type, SPA_TYPE__Log) == 0)
|
||||
if (support[i].type == SPA_ID_INTERFACE_Log)
|
||||
this->log = support[i].data;
|
||||
else if (strcmp(support[i].type, SPA_TYPE_LOOP__MainLoop) == 0)
|
||||
else if (support[i].type == SPA_ID_INTERFACE_MainLoop)
|
||||
this->main_loop = support[i].data;
|
||||
}
|
||||
if (this->map == NULL) {
|
||||
spa_log_error(this->log, "a type-map is needed");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (this->main_loop == NULL) {
|
||||
spa_log_error(this->log, "a main-loop is needed");
|
||||
return -EINVAL;
|
||||
}
|
||||
init_type(&this->type, this->map);
|
||||
|
||||
this->monitor = impl_monitor;
|
||||
|
||||
|
|
@ -387,7 +366,7 @@ impl_init(const struct spa_handle_factory *factory,
|
|||
}
|
||||
|
||||
static const struct spa_interface_info impl_interfaces[] = {
|
||||
{SPA_TYPE__Monitor,},
|
||||
{SPA_ID_INTERFACE_Monitor,},
|
||||
};
|
||||
|
||||
static int
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@
|
|||
|
||||
#include <linux/videodev2.h>
|
||||
|
||||
#include <spa/support/type-map.h>
|
||||
#include <spa/support/log.h>
|
||||
#include <spa/support/loop.h>
|
||||
#include <spa/utils/list.h>
|
||||
|
|
@ -66,71 +65,6 @@ struct buffer {
|
|||
void *ptr;
|
||||
};
|
||||
|
||||
struct type {
|
||||
uint32_t node;
|
||||
uint32_t format;
|
||||
uint32_t props;
|
||||
uint32_t prop_unknown;
|
||||
uint32_t prop_device;
|
||||
uint32_t prop_device_name;
|
||||
uint32_t prop_device_fd;
|
||||
uint32_t prop_brightness;
|
||||
uint32_t prop_contrast;
|
||||
uint32_t prop_saturation;
|
||||
uint32_t prop_hue;
|
||||
uint32_t prop_gamma;
|
||||
uint32_t prop_exposure;
|
||||
uint32_t prop_gain;
|
||||
uint32_t prop_sharpness;
|
||||
struct spa_type_io io;
|
||||
struct spa_type_param param;
|
||||
struct spa_type_media_type media_type;
|
||||
struct spa_type_media_subtype media_subtype;
|
||||
struct spa_type_media_subtype_video media_subtype_video;
|
||||
struct spa_type_format_video format_video;
|
||||
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_buffers param_buffers;
|
||||
struct spa_type_param_meta param_meta;
|
||||
struct spa_type_param_io param_io;
|
||||
struct spa_type_meta meta;
|
||||
struct spa_type_data data;
|
||||
};
|
||||
|
||||
static inline void init_type(struct type *type, struct spa_type_map *map)
|
||||
{
|
||||
type->node = spa_type_map_get_id(map, SPA_TYPE__Node);
|
||||
type->format = spa_type_map_get_id(map, SPA_TYPE__Format);
|
||||
type->props = spa_type_map_get_id(map, SPA_TYPE__Props);
|
||||
type->prop_unknown = spa_type_map_get_id(map, SPA_TYPE_PROPS__unknown);
|
||||
type->prop_device = spa_type_map_get_id(map, SPA_TYPE_PROPS__device);
|
||||
type->prop_device_name = spa_type_map_get_id(map, SPA_TYPE_PROPS__deviceName);
|
||||
type->prop_device_fd = spa_type_map_get_id(map, SPA_TYPE_PROPS__deviceFd);
|
||||
type->prop_brightness = spa_type_map_get_id(map, SPA_TYPE_PROPS__brightness);
|
||||
type->prop_contrast = spa_type_map_get_id(map, SPA_TYPE_PROPS__contrast);
|
||||
type->prop_saturation = spa_type_map_get_id(map, SPA_TYPE_PROPS__saturation);
|
||||
type->prop_hue = spa_type_map_get_id(map, SPA_TYPE_PROPS__hue);
|
||||
type->prop_gamma = spa_type_map_get_id(map, SPA_TYPE_PROPS__gamma);
|
||||
type->prop_exposure = spa_type_map_get_id(map, SPA_TYPE_PROPS__exposure);
|
||||
type->prop_gain = spa_type_map_get_id(map, SPA_TYPE_PROPS__gain);
|
||||
type->prop_sharpness = spa_type_map_get_id(map, SPA_TYPE_PROPS__sharpness);
|
||||
spa_type_meta_map(map, &type->meta);
|
||||
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);
|
||||
spa_type_media_subtype_video_map(map, &type->media_subtype_video);
|
||||
spa_type_format_video_map(map, &type->format_video);
|
||||
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_map(map, &type->param);
|
||||
spa_type_param_buffers_map(map, &type->param_buffers);
|
||||
spa_type_param_meta_map(map, &type->param_meta);
|
||||
spa_type_io_map(map, &type->io);
|
||||
spa_type_param_io_map(map, &type->param_io);
|
||||
}
|
||||
|
||||
#define MAX_CONTROLS 64
|
||||
|
||||
struct control {
|
||||
|
|
@ -184,9 +118,7 @@ struct impl {
|
|||
struct spa_handle handle;
|
||||
struct spa_node node;
|
||||
|
||||
struct spa_type_map *map;
|
||||
struct spa_log *log;
|
||||
struct type type;
|
||||
|
||||
uint32_t seq;
|
||||
|
||||
|
|
@ -212,7 +144,6 @@ static int impl_node_enum_params(struct spa_node *node,
|
|||
struct spa_pod_builder *builder)
|
||||
{
|
||||
struct impl *this;
|
||||
struct type *t;
|
||||
struct spa_pod *param;
|
||||
struct spa_pod_builder b = { 0 };
|
||||
uint8_t buffer[1024];
|
||||
|
|
@ -222,67 +153,74 @@ static int impl_node_enum_params(struct spa_node *node,
|
|||
spa_return_val_if_fail(builder != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
t = &this->type;
|
||||
|
||||
next:
|
||||
spa_pod_builder_init(&b, buffer, sizeof(buffer));
|
||||
|
||||
if (id == t->param.idList) {
|
||||
uint32_t list[] = { t->param.idPropInfo,
|
||||
t->param.idProps };
|
||||
switch (id) {
|
||||
case SPA_ID_PARAM_List:
|
||||
{
|
||||
uint32_t list[] = { SPA_ID_PARAM_PropInfo,
|
||||
SPA_ID_PARAM_Props };
|
||||
|
||||
if (*index < SPA_N_ELEMENTS(list))
|
||||
param = spa_pod_builder_object(&b, id, t->param.List,
|
||||
":", t->param.listId, "I", list[*index]);
|
||||
param = spa_pod_builder_object(&b, id, SPA_ID_OBJECT_ParamList,
|
||||
":", SPA_PARAM_LIST_id, "I", list[*index]);
|
||||
else
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
else if (id == t->param.idPropInfo) {
|
||||
case SPA_ID_PARAM_PropInfo:
|
||||
{
|
||||
struct props *p = &this->props;
|
||||
|
||||
switch (*index) {
|
||||
case 0:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param.PropInfo,
|
||||
":", t->param.propId, "I", t->prop_device,
|
||||
":", t->param.propName, "s", "The V4L2 device",
|
||||
":", t->param.propType, "S", p->device, sizeof(p->device));
|
||||
id, SPA_ID_OBJECT_PropInfo,
|
||||
":", SPA_PROP_INFO_id, "I", SPA_PROP_device,
|
||||
":", SPA_PROP_INFO_name, "s", "The V4L2 device",
|
||||
":", SPA_PROP_INFO_type, "S", p->device, sizeof(p->device));
|
||||
break;
|
||||
case 1:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param.PropInfo,
|
||||
":", t->param.propId, "I", t->prop_device_name,
|
||||
":", t->param.propName, "s", "The V4L2 device name",
|
||||
":", t->param.propType, "S-r", p->device_name, sizeof(p->device_name));
|
||||
id, SPA_ID_OBJECT_PropInfo,
|
||||
":", SPA_PROP_INFO_id, "I", SPA_PROP_deviceName,
|
||||
":", SPA_PROP_INFO_name, "s", "The V4L2 device name",
|
||||
":", SPA_PROP_INFO_type, "S-r", p->device_name, sizeof(p->device_name));
|
||||
break;
|
||||
case 2:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param.PropInfo,
|
||||
":", t->param.propId, "I", t->prop_device_fd,
|
||||
":", t->param.propName, "s", "The V4L2 fd",
|
||||
":", t->param.propType, "i-r", p->device_fd);
|
||||
id, SPA_ID_OBJECT_PropInfo,
|
||||
":", SPA_PROP_INFO_id, "I", SPA_PROP_deviceFd,
|
||||
":", SPA_PROP_INFO_name, "s", "The V4L2 fd",
|
||||
":", SPA_PROP_INFO_type, "i-r", p->device_fd);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
else if (id == t->param.idProps) {
|
||||
case SPA_ID_PARAM_Props:
|
||||
{
|
||||
struct props *p = &this->props;
|
||||
|
||||
switch (*index) {
|
||||
case 0:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->props,
|
||||
":", t->prop_device, "S", p->device, sizeof(p->device),
|
||||
":", t->prop_device_name, "S-r", p->device_name, sizeof(p->device_name),
|
||||
":", t->prop_device_fd, "i-r", p->device_fd);
|
||||
id, SPA_ID_OBJECT_Props,
|
||||
":", SPA_PROP_device, "S", p->device, sizeof(p->device),
|
||||
":", SPA_PROP_deviceName, "S-r", p->device_name, sizeof(p->device_name),
|
||||
":", SPA_PROP_deviceFd, "i-r", p->device_fd);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
else
|
||||
default:
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
(*index)++;
|
||||
|
||||
|
|
@ -297,14 +235,14 @@ static int impl_node_set_param(struct spa_node *node,
|
|||
const struct spa_pod *param)
|
||||
{
|
||||
struct impl *this;
|
||||
struct type *t;
|
||||
|
||||
spa_return_val_if_fail(node != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
t = &this->type;
|
||||
|
||||
if (id == t->param.idProps) {
|
||||
switch (id) {
|
||||
case SPA_ID_PARAM_Props:
|
||||
{
|
||||
struct props *p = &this->props;
|
||||
|
||||
if (param == NULL) {
|
||||
|
|
@ -312,11 +250,12 @@ static int impl_node_set_param(struct spa_node *node,
|
|||
return 0;
|
||||
}
|
||||
spa_pod_object_parse(param,
|
||||
":", t->prop_device, "?S", p->device, sizeof(p->device), NULL);
|
||||
":", SPA_PROP_device, "?S", p->device, sizeof(p->device), NULL);
|
||||
break;
|
||||
}
|
||||
else
|
||||
default:
|
||||
return -ENOENT;
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -330,7 +269,9 @@ static int impl_node_send_command(struct spa_node *node, const struct spa_comman
|
|||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
|
||||
if (SPA_COMMAND_TYPE(command) == this->type.command_node.Start) {
|
||||
switch (SPA_COMMAND_TYPE(command)) {
|
||||
case SPA_ID_COMMAND_NODE_Start:
|
||||
{
|
||||
struct port *port = GET_OUT_PORT(this, 0);
|
||||
|
||||
if (!port->have_format)
|
||||
|
|
@ -340,12 +281,15 @@ static int impl_node_send_command(struct spa_node *node, const struct spa_comman
|
|||
|
||||
if ((res = spa_v4l2_stream_on(this)) < 0)
|
||||
return res;
|
||||
|
||||
} else if (SPA_COMMAND_TYPE(command) == this->type.command_node.Pause) {
|
||||
break;
|
||||
}
|
||||
case SPA_ID_COMMAND_NODE_Pause:
|
||||
if ((res = spa_v4l2_stream_off(this)) < 0)
|
||||
return res;
|
||||
} else
|
||||
break;
|
||||
default:
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -443,7 +387,6 @@ static int port_get_format(struct spa_node *node,
|
|||
struct spa_pod_builder *builder)
|
||||
{
|
||||
struct impl *this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
struct type *t = &this->type;
|
||||
struct port *port = GET_PORT(this, direction, port_id);
|
||||
|
||||
if (!port->have_format)
|
||||
|
|
@ -451,28 +394,33 @@ static int port_get_format(struct spa_node *node,
|
|||
if (*index > 0)
|
||||
return 0;
|
||||
|
||||
spa_pod_builder_push_object(builder, t->param.idFormat, t->format);
|
||||
spa_pod_builder_push_object(builder, SPA_ID_PARAM_Format, SPA_ID_OBJECT_Format);
|
||||
|
||||
spa_pod_builder_add(builder,
|
||||
"I", port->current_format.media_type,
|
||||
"I", port->current_format.media_subtype, 0);
|
||||
|
||||
if (port->current_format.media_subtype == t->media_subtype.raw) {
|
||||
switch (port->current_format.media_subtype) {
|
||||
case SPA_MEDIA_SUBTYPE_raw:
|
||||
spa_pod_builder_add(builder,
|
||||
":", t->format_video.format, "I", port->current_format.info.raw.format,
|
||||
":", t->format_video.size, "R", &port->current_format.info.raw.size,
|
||||
":", t->format_video.framerate, "F", &port->current_format.info.raw.framerate, 0);
|
||||
} else if (port->current_format.media_subtype == t->media_subtype_video.mjpg ||
|
||||
port->current_format.media_subtype == t->media_subtype_video.jpeg) {
|
||||
":", SPA_FORMAT_VIDEO_format, "I", port->current_format.info.raw.format,
|
||||
":", SPA_FORMAT_VIDEO_size, "R", &port->current_format.info.raw.size,
|
||||
":", SPA_FORMAT_VIDEO_framerate, "F", &port->current_format.info.raw.framerate, 0);
|
||||
break;
|
||||
case SPA_MEDIA_SUBTYPE_mjpg:
|
||||
case SPA_MEDIA_SUBTYPE_jpeg:
|
||||
spa_pod_builder_add(builder,
|
||||
":", t->format_video.size, "R", &port->current_format.info.mjpg.size,
|
||||
":", t->format_video.framerate, "F", &port->current_format.info.mjpg.framerate, 0);
|
||||
} else if (port->current_format.media_subtype == t->media_subtype_video.h264) {
|
||||
":", SPA_FORMAT_VIDEO_size, "R", &port->current_format.info.mjpg.size,
|
||||
":", SPA_FORMAT_VIDEO_framerate, "F", &port->current_format.info.mjpg.framerate, 0);
|
||||
break;
|
||||
case SPA_MEDIA_SUBTYPE_h264:
|
||||
spa_pod_builder_add(builder,
|
||||
":", t->format_video.size, "R", &port->current_format.info.h264.size,
|
||||
":", t->format_video.framerate, "F", &port->current_format.info.h264.framerate, 0);
|
||||
} else
|
||||
":", SPA_FORMAT_VIDEO_size, "R", &port->current_format.info.h264.size,
|
||||
":", SPA_FORMAT_VIDEO_framerate, "F", &port->current_format.info.h264.framerate, 0);
|
||||
break;
|
||||
default:
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
*param = spa_pod_builder_pop(builder);
|
||||
|
||||
|
|
@ -490,7 +438,6 @@ static int impl_node_port_enum_params(struct spa_node *node,
|
|||
|
||||
struct impl *this;
|
||||
struct port *port;
|
||||
struct type *t;
|
||||
struct spa_pod *param;
|
||||
struct spa_pod_builder b = { 0 };
|
||||
uint8_t buffer[1024];
|
||||
|
|
@ -501,7 +448,6 @@ static int impl_node_port_enum_params(struct spa_node *node,
|
|||
spa_return_val_if_fail(builder != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
t = &this->type;
|
||||
|
||||
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
|
||||
|
||||
|
|
@ -510,81 +456,87 @@ static int impl_node_port_enum_params(struct spa_node *node,
|
|||
next:
|
||||
spa_pod_builder_init(&b, buffer, sizeof(buffer));
|
||||
|
||||
if (id == t->param.idList) {
|
||||
uint32_t list[] = { t->param.idEnumFormat,
|
||||
t->param.idFormat,
|
||||
t->param.idBuffers,
|
||||
t->param.idMeta,
|
||||
t->param_io.idPropsIn };
|
||||
switch (id) {
|
||||
case SPA_ID_PARAM_List:
|
||||
{
|
||||
uint32_t list[] = { SPA_ID_PARAM_PropInfo,
|
||||
SPA_ID_PARAM_EnumFormat,
|
||||
SPA_ID_PARAM_Format,
|
||||
SPA_ID_PARAM_Buffers,
|
||||
SPA_ID_PARAM_Meta,
|
||||
SPA_ID_PARAM_IO };
|
||||
|
||||
if (*index < SPA_N_ELEMENTS(list))
|
||||
param = spa_pod_builder_object(&b, id, t->param.List,
|
||||
":", t->param.listId, "I", list[*index]);
|
||||
param = spa_pod_builder_object(&b, id, SPA_ID_OBJECT_ParamList,
|
||||
":", SPA_PARAM_LIST_id, "I", list[*index]);
|
||||
else
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
else if (id == t->param.idEnumFormat) {
|
||||
case SPA_ID_PARAM_PropInfo:
|
||||
return spa_v4l2_enum_controls(this, index, filter, result, builder);
|
||||
|
||||
case SPA_ID_PARAM_EnumFormat:
|
||||
return spa_v4l2_enum_format(this, index, filter, result, builder);
|
||||
}
|
||||
else if (id == t->param.idFormat) {
|
||||
|
||||
case SPA_ID_PARAM_Format:
|
||||
if((res = port_get_format(node, direction, port_id, index, filter, ¶m, &b)) <= 0)
|
||||
return res;
|
||||
}
|
||||
else if (id == t->param.idBuffers) {
|
||||
break;
|
||||
case SPA_ID_PARAM_Buffers:
|
||||
if (!port->have_format)
|
||||
return -EIO;
|
||||
if (*index > 0)
|
||||
return 0;
|
||||
|
||||
param = spa_pod_builder_object(&b,
|
||||
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,
|
||||
id, SPA_ID_OBJECT_ParamBuffers,
|
||||
":", SPA_PARAM_BUFFERS_buffers, "iru", MAX_BUFFERS,
|
||||
SPA_POD_PROP_MIN_MAX(2, MAX_BUFFERS),
|
||||
":", t->param_buffers.align, "i", 16);
|
||||
}
|
||||
else if (id == t->param.idMeta) {
|
||||
":", SPA_PARAM_BUFFERS_blocks, "i", 1,
|
||||
":", SPA_PARAM_BUFFERS_size, "i", port->fmt.fmt.pix.sizeimage,
|
||||
":", SPA_PARAM_BUFFERS_stride, "i", port->fmt.fmt.pix.bytesperline,
|
||||
":", SPA_PARAM_BUFFERS_align, "i", 16);
|
||||
break;
|
||||
|
||||
case SPA_ID_PARAM_Meta:
|
||||
switch (*index) {
|
||||
case 0:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param_meta.Meta,
|
||||
":", t->param_meta.type, "I", t->meta.Header,
|
||||
":", t->param_meta.size, "i", sizeof(struct spa_meta_header));
|
||||
id, SPA_ID_OBJECT_ParamMeta,
|
||||
":", SPA_PARAM_META_type, "I", SPA_META_Header,
|
||||
":", SPA_PARAM_META_size, "i", sizeof(struct spa_meta_header));
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
#if 0
|
||||
else if (id == t->param_io.idPropsIn) {
|
||||
return spa_v4l2_enum_controls(this, index, filter, result, builder);
|
||||
}
|
||||
else if (id == t->param_io.idBuffers) {
|
||||
#endif
|
||||
case SPA_ID_PARAM_IO:
|
||||
switch (*index) {
|
||||
case 0:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param_io.Buffers,
|
||||
":", t->param_io.id, "I", t->io.Buffers,
|
||||
":", t->param_io.size, "i", sizeof(struct spa_io_buffers));
|
||||
id, SPA_ID_OBJECT_ParamIO,
|
||||
":", SPA_PARAM_IO_id, "I", SPA_ID_IO_Buffers,
|
||||
":", SPA_PARAM_IO_size, "i", sizeof(struct spa_io_buffers));
|
||||
break;
|
||||
case 1:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, SPA_ID_OBJECT_ParamIO,
|
||||
":", SPA_PARAM_IO_id, "I", SPA_ID_IO_Clock,
|
||||
":", SPA_PARAM_IO_size, "i", sizeof(struct spa_io_clock));
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if (id == t->param_io.idClock) {
|
||||
switch (*index) {
|
||||
case 0:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param_io.Clock,
|
||||
":", t->param_io.id, "I", t->io.Clock,
|
||||
":", t->param_io.size, "i", sizeof(struct spa_io_clock));
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
break;
|
||||
default:
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
(*index)++;
|
||||
|
||||
|
|
@ -601,7 +553,6 @@ static int port_set_format(struct spa_node *node,
|
|||
{
|
||||
struct impl *this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
struct spa_video_info info;
|
||||
struct type *t = &this->type;
|
||||
struct port *port = GET_PORT(this, direction, port_id);
|
||||
|
||||
if (format == NULL) {
|
||||
|
|
@ -615,13 +566,14 @@ static int port_set_format(struct spa_node *node,
|
|||
"I", &info.media_type,
|
||||
"I", &info.media_subtype);
|
||||
|
||||
if (info.media_type != t->media_type.video) {
|
||||
if (info.media_type != SPA_MEDIA_TYPE_video) {
|
||||
spa_log_error(this->log, "media type must be video");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (info.media_subtype == t->media_subtype.raw) {
|
||||
if (spa_format_video_raw_parse(format, &info.info.raw, &t->format_video) < 0) {
|
||||
switch (info.media_subtype) {
|
||||
case SPA_MEDIA_SUBTYPE_raw:
|
||||
if (spa_format_video_raw_parse(format, &info.info.raw) < 0) {
|
||||
spa_log_error(this->log, "can't parse video raw");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
@ -632,8 +584,9 @@ static int port_set_format(struct spa_node *node,
|
|||
info.info.raw.size.width == port->current_format.info.raw.size.width &&
|
||||
info.info.raw.size.height == port->current_format.info.raw.size.height)
|
||||
return 0;
|
||||
} else if (info.media_subtype == t->media_subtype_video.mjpg) {
|
||||
if (spa_format_video_mjpg_parse(format, &info.info.mjpg, &t->format_video) < 0)
|
||||
break;
|
||||
case SPA_MEDIA_SUBTYPE_mjpg:
|
||||
if (spa_format_video_mjpg_parse(format, &info.info.mjpg) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (port->have_format && info.media_type == port->current_format.media_type &&
|
||||
|
|
@ -641,8 +594,9 @@ static int port_set_format(struct spa_node *node,
|
|||
info.info.mjpg.size.width == port->current_format.info.mjpg.size.width &&
|
||||
info.info.mjpg.size.height == port->current_format.info.mjpg.size.height)
|
||||
return 0;
|
||||
} else if (info.media_subtype == t->media_subtype_video.h264) {
|
||||
if (spa_format_video_h264_parse(format, &info.info.h264, &t->format_video) < 0)
|
||||
break;
|
||||
case SPA_MEDIA_SUBTYPE_h264:
|
||||
if (spa_format_video_h264_parse(format, &info.info.h264) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (port->have_format && info.media_type == port->current_format.media_type &&
|
||||
|
|
@ -650,6 +604,9 @@ static int port_set_format(struct spa_node *node,
|
|||
info.info.h264.size.width == port->current_format.info.h264.size.width &&
|
||||
info.info.h264.size.height == port->current_format.info.h264.size.height)
|
||||
return 0;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -674,17 +631,11 @@ static int impl_node_port_set_param(struct spa_node *node,
|
|||
uint32_t id, uint32_t flags,
|
||||
const struct spa_pod *param)
|
||||
{
|
||||
struct impl *this;
|
||||
struct type *t;
|
||||
|
||||
spa_return_val_if_fail(node != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
t = &this->type;
|
||||
spa_return_val_if_fail(CHECK_PORT(node, direction, port_id), -EINVAL);
|
||||
|
||||
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
|
||||
|
||||
if (id == t->param.idFormat) {
|
||||
if (id == SPA_ID_PARAM_Format) {
|
||||
return port_set_format(node, direction, port_id, flags, param);
|
||||
}
|
||||
else
|
||||
|
|
@ -772,23 +723,21 @@ static int impl_node_port_set_io(struct spa_node *node,
|
|||
void *data, size_t size)
|
||||
{
|
||||
struct impl *this;
|
||||
struct type *t;
|
||||
struct port *port;
|
||||
struct control *control;
|
||||
|
||||
spa_return_val_if_fail(node != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
t = &this->type;
|
||||
|
||||
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
|
||||
|
||||
port = GET_PORT(this, direction, port_id);
|
||||
|
||||
if (id == t->io.Buffers) {
|
||||
if (id == SPA_ID_IO_Buffers) {
|
||||
port->io = data;
|
||||
}
|
||||
else if (id == t->io.Clock) {
|
||||
else if (id == SPA_ID_IO_Clock) {
|
||||
port->clock = data;
|
||||
}
|
||||
else if ((control = find_control(port, id))) {
|
||||
|
|
@ -934,7 +883,7 @@ static int impl_get_interface(struct spa_handle *handle, uint32_t interface_id,
|
|||
|
||||
this = (struct impl *) handle;
|
||||
|
||||
if (interface_id == this->type.node)
|
||||
if (interface_id == SPA_ID_INTERFACE_Node)
|
||||
*interface = &this->node;
|
||||
else
|
||||
return -ENOENT;
|
||||
|
|
@ -976,19 +925,13 @@ impl_init(const struct spa_handle_factory *factory,
|
|||
port = GET_OUT_PORT(this, 0);
|
||||
|
||||
for (i = 0; i < n_support; i++) {
|
||||
if (strcmp(support[i].type, SPA_TYPE__TypeMap) == 0)
|
||||
this->map = support[i].data;
|
||||
else if (strcmp(support[i].type, SPA_TYPE__Log) == 0)
|
||||
if (support[i].type == SPA_ID_INTERFACE_Log)
|
||||
this->log = support[i].data;
|
||||
else if (strcmp(support[i].type, SPA_TYPE_LOOP__MainLoop) == 0)
|
||||
else if (support[i].type == SPA_ID_INTERFACE_MainLoop)
|
||||
port->main_loop = support[i].data;
|
||||
else if (strcmp(support[i].type, SPA_TYPE_LOOP__DataLoop) == 0)
|
||||
else if (support[i].type == SPA_ID_INTERFACE_DataLoop)
|
||||
port->data_loop = support[i].data;
|
||||
}
|
||||
if (this->map == NULL) {
|
||||
spa_log_error(this->log, "a type-map is needed");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (port->main_loop == NULL) {
|
||||
spa_log_error(this->log, "a main_loop is needed");
|
||||
return -EINVAL;
|
||||
|
|
@ -997,7 +940,6 @@ impl_init(const struct spa_handle_factory *factory,
|
|||
spa_log_error(this->log, "a data_loop is needed");
|
||||
return -EINVAL;
|
||||
}
|
||||
init_type(&this->type, this->map);
|
||||
|
||||
this->node = impl_node;
|
||||
|
||||
|
|
@ -1023,7 +965,7 @@ impl_init(const struct spa_handle_factory *factory,
|
|||
}
|
||||
|
||||
static const struct spa_interface_info impl_interfaces[] = {
|
||||
{SPA_TYPE__Node,},
|
||||
{SPA_ID_INTERFACE_Node,},
|
||||
};
|
||||
|
||||
static int impl_enum_interface_info(const struct spa_handle_factory *factory,
|
||||
|
|
|
|||
|
|
@ -190,59 +190,59 @@ static int spa_v4l2_close(struct impl *this)
|
|||
|
||||
struct format_info {
|
||||
uint32_t fourcc;
|
||||
off_t format_offset;
|
||||
off_t media_type_offset;
|
||||
off_t media_subtype_offset;
|
||||
uint32_t format;
|
||||
uint32_t media_type;
|
||||
uint32_t media_subtype;
|
||||
};
|
||||
|
||||
#define VIDEO offsetof(struct type, media_type.video)
|
||||
#define IMAGE offsetof(struct type, media_type.image)
|
||||
#define VIDEO SPA_MEDIA_TYPE_video
|
||||
#define IMAGE SPA_MEDIA_TYPE_image
|
||||
|
||||
#define RAW offsetof(struct type, media_subtype.raw)
|
||||
#define RAW SPA_MEDIA_SUBTYPE_raw
|
||||
|
||||
#define BAYER offsetof(struct type, media_subtype_video.bayer)
|
||||
#define MJPG offsetof(struct type, media_subtype_video.mjpg)
|
||||
#define JPEG offsetof(struct type, media_subtype_video.jpeg)
|
||||
#define DV offsetof(struct type, media_subtype_video.dv)
|
||||
#define MPEGTS offsetof(struct type, media_subtype_video.mpegts)
|
||||
#define H264 offsetof(struct type, media_subtype_video.h264)
|
||||
#define H263 offsetof(struct type, media_subtype_video.h263)
|
||||
#define MPEG1 offsetof(struct type, media_subtype_video.mpeg1)
|
||||
#define MPEG2 offsetof(struct type, media_subtype_video.mpeg2)
|
||||
#define MPEG4 offsetof(struct type, media_subtype_video.mpeg4)
|
||||
#define XVID offsetof(struct type, media_subtype_video.xvid)
|
||||
#define VC1 offsetof(struct type, media_subtype_video.vc1)
|
||||
#define VP8 offsetof(struct type, media_subtype_video.vp8)
|
||||
#define BAYER SPA_MEDIA_SUBTYPE_bayer
|
||||
#define MJPG SPA_MEDIA_SUBTYPE_mjpg
|
||||
#define JPEG SPA_MEDIA_SUBTYPE_jpeg
|
||||
#define DV SPA_MEDIA_SUBTYPE_dv
|
||||
#define MPEGTS SPA_MEDIA_SUBTYPE_mpegts
|
||||
#define H264 SPA_MEDIA_SUBTYPE_h264
|
||||
#define H263 SPA_MEDIA_SUBTYPE_h263
|
||||
#define MPEG1 SPA_MEDIA_SUBTYPE_mpeg1
|
||||
#define MPEG2 SPA_MEDIA_SUBTYPE_mpeg2
|
||||
#define MPEG4 SPA_MEDIA_SUBTYPE_mpeg4
|
||||
#define XVID SPA_MEDIA_SUBTYPE_xvid
|
||||
#define VC1 SPA_MEDIA_SUBTYPE_vc1
|
||||
#define VP8 SPA_MEDIA_SUBTYPE_vp8
|
||||
|
||||
#define FORMAT_UNKNOWN offsetof(struct type, video_format.UNKNOWN)
|
||||
#define FORMAT_ENCODED offsetof(struct type, video_format.ENCODED)
|
||||
#define FORMAT_RGB15 offsetof(struct type, video_format.RGB15)
|
||||
#define FORMAT_BGR15 offsetof(struct type, video_format.BGR15)
|
||||
#define FORMAT_RGB16 offsetof(struct type, video_format.RGB16)
|
||||
#define FORMAT_BGR offsetof(struct type, video_format.BGR)
|
||||
#define FORMAT_RGB offsetof(struct type, video_format.RGB)
|
||||
#define FORMAT_BGRA offsetof(struct type, video_format.BGRA)
|
||||
#define FORMAT_BGRx offsetof(struct type, video_format.BGRx)
|
||||
#define FORMAT_ARGB offsetof(struct type, video_format.ARGB)
|
||||
#define FORMAT_xRGB offsetof(struct type, video_format.xRGB)
|
||||
#define FORMAT_GRAY8 offsetof(struct type, video_format.GRAY8)
|
||||
#define FORMAT_GRAY16_LE offsetof(struct type, video_format.GRAY16_LE)
|
||||
#define FORMAT_GRAY16_BE offsetof(struct type, video_format.GRAY16_BE)
|
||||
#define FORMAT_YVU9 offsetof(struct type, video_format.YVU9)
|
||||
#define FORMAT_YV12 offsetof(struct type, video_format.YV12)
|
||||
#define FORMAT_YUY2 offsetof(struct type, video_format.YUY2)
|
||||
#define FORMAT_YVYU offsetof(struct type, video_format.YVYU)
|
||||
#define FORMAT_UYVY offsetof(struct type, video_format.UYVY)
|
||||
#define FORMAT_Y42B offsetof(struct type, video_format.Y42B)
|
||||
#define FORMAT_Y41B offsetof(struct type, video_format.Y41B)
|
||||
#define FORMAT_YUV9 offsetof(struct type, video_format.YUV9)
|
||||
#define FORMAT_I420 offsetof(struct type, video_format.I420)
|
||||
#define FORMAT_NV12 offsetof(struct type, video_format.NV12)
|
||||
#define FORMAT_NV12_64Z32 offsetof(struct type, video_format.NV12_64Z32)
|
||||
#define FORMAT_NV21 offsetof(struct type, video_format.NV21)
|
||||
#define FORMAT_NV16 offsetof(struct type, video_format.NV16)
|
||||
#define FORMAT_NV61 offsetof(struct type, video_format.NV61)
|
||||
#define FORMAT_NV24 offsetof(struct type, video_format.NV24)
|
||||
#define FORMAT_UNKNOWN SPA_VIDEO_FORMAT_UNKNOWN
|
||||
#define FORMAT_ENCODED SPA_VIDEO_FORMAT_ENCODED
|
||||
#define FORMAT_RGB15 SPA_VIDEO_FORMAT_RGB15
|
||||
#define FORMAT_BGR15 SPA_VIDEO_FORMAT_BGR15
|
||||
#define FORMAT_RGB16 SPA_VIDEO_FORMAT_RGB16
|
||||
#define FORMAT_BGR SPA_VIDEO_FORMAT_BGR
|
||||
#define FORMAT_RGB SPA_VIDEO_FORMAT_RGB
|
||||
#define FORMAT_BGRA SPA_VIDEO_FORMAT_BGRA
|
||||
#define FORMAT_BGRx SPA_VIDEO_FORMAT_BGRx
|
||||
#define FORMAT_ARGB SPA_VIDEO_FORMAT_ARGB
|
||||
#define FORMAT_xRGB SPA_VIDEO_FORMAT_xRGB
|
||||
#define FORMAT_GRAY8 SPA_VIDEO_FORMAT_GRAY8
|
||||
#define FORMAT_GRAY16_LE SPA_VIDEO_FORMAT_GRAY16_LE
|
||||
#define FORMAT_GRAY16_BE SPA_VIDEO_FORMAT_GRAY16_BE
|
||||
#define FORMAT_YVU9 SPA_VIDEO_FORMAT_YVU9
|
||||
#define FORMAT_YV12 SPA_VIDEO_FORMAT_YV12
|
||||
#define FORMAT_YUY2 SPA_VIDEO_FORMAT_YUY2
|
||||
#define FORMAT_YVYU SPA_VIDEO_FORMAT_YVYU
|
||||
#define FORMAT_UYVY SPA_VIDEO_FORMAT_UYVY
|
||||
#define FORMAT_Y42B SPA_VIDEO_FORMAT_Y42B
|
||||
#define FORMAT_Y41B SPA_VIDEO_FORMAT_Y41B
|
||||
#define FORMAT_YUV9 SPA_VIDEO_FORMAT_YUV9
|
||||
#define FORMAT_I420 SPA_VIDEO_FORMAT_I420
|
||||
#define FORMAT_NV12 SPA_VIDEO_FORMAT_NV12
|
||||
#define FORMAT_NV12_64Z32 SPA_VIDEO_FORMAT_NV12_64Z32
|
||||
#define FORMAT_NV21 SPA_VIDEO_FORMAT_NV21
|
||||
#define FORMAT_NV16 SPA_VIDEO_FORMAT_NV16
|
||||
#define FORMAT_NV61 SPA_VIDEO_FORMAT_NV61
|
||||
#define FORMAT_NV24 SPA_VIDEO_FORMAT_NV24
|
||||
|
||||
static const struct format_info format_info[] = {
|
||||
/* RGB formats */
|
||||
|
|
@ -376,8 +376,7 @@ static const struct format_info *video_format_to_format_info(uint32_t format)
|
|||
}
|
||||
#endif
|
||||
|
||||
static const struct format_info *find_format_info_by_media_type(struct type *types,
|
||||
uint32_t type,
|
||||
static const struct format_info *find_format_info_by_media_type(uint32_t type,
|
||||
uint32_t subtype,
|
||||
uint32_t format,
|
||||
int startidx)
|
||||
|
|
@ -385,37 +384,33 @@ static const struct format_info *find_format_info_by_media_type(struct type *typ
|
|||
int i;
|
||||
|
||||
for (i = startidx; i < SPA_N_ELEMENTS(format_info); i++) {
|
||||
uint32_t media_type, media_subtype, media_format;
|
||||
|
||||
media_type = *SPA_MEMBER(types, format_info[i].media_type_offset, uint32_t);
|
||||
media_subtype = *SPA_MEMBER(types, format_info[i].media_subtype_offset, uint32_t);
|
||||
media_format = *SPA_MEMBER(types, format_info[i].format_offset, uint32_t);
|
||||
|
||||
if ((media_type == type) &&
|
||||
(media_subtype == subtype) && (format == 0 || media_format == format))
|
||||
if ((format_info[i].media_type == type) &&
|
||||
(format_info[i].media_subtype == subtype) &&
|
||||
(format == 0 || format_info[i].format == format))
|
||||
return &format_info[i];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
enum_filter_format(struct type *type, uint32_t media_type, int32_t media_subtype,
|
||||
enum_filter_format(uint32_t media_type, int32_t media_subtype,
|
||||
const struct spa_pod *filter, uint32_t index)
|
||||
{
|
||||
uint32_t video_format = 0;
|
||||
|
||||
if ((media_type == type->media_type.video ||
|
||||
media_type == type->media_type.image)) {
|
||||
if (media_subtype == type->media_subtype.raw) {
|
||||
switch (media_type) {
|
||||
case SPA_MEDIA_TYPE_video:
|
||||
case SPA_MEDIA_TYPE_image:
|
||||
if (media_subtype == SPA_MEDIA_SUBTYPE_raw) {
|
||||
struct spa_pod_prop *p;
|
||||
uint32_t n_values;
|
||||
const uint32_t *values;
|
||||
|
||||
if (!(p = spa_pod_find_prop(filter, type->format_video.format)))
|
||||
return type->video_format.UNKNOWN;
|
||||
if (!(p = spa_pod_find_prop(filter, SPA_FORMAT_VIDEO_format)))
|
||||
return SPA_VIDEO_FORMAT_UNKNOWN;
|
||||
|
||||
if (p->body.value.type != SPA_POD_TYPE_ID)
|
||||
return type->video_format.UNKNOWN;
|
||||
return SPA_VIDEO_FORMAT_UNKNOWN;
|
||||
|
||||
values = SPA_POD_BODY_CONST(&p->body.value);
|
||||
n_values = SPA_POD_PROP_N_VALUES(p);
|
||||
|
|
@ -429,7 +424,7 @@ enum_filter_format(struct type *type, uint32_t media_type, int32_t media_subtype
|
|||
}
|
||||
} else {
|
||||
if (index == 0)
|
||||
video_format = type->video_format.ENCODED;
|
||||
video_format = SPA_VIDEO_FORMAT_ENCODED;
|
||||
}
|
||||
}
|
||||
return video_format;
|
||||
|
|
@ -533,9 +528,7 @@ spa_v4l2_enum_format(struct impl *this,
|
|||
int res, n_fractions;
|
||||
const struct format_info *info;
|
||||
struct spa_pod_prop *prop;
|
||||
uint32_t media_type, media_subtype, video_format;
|
||||
uint32_t filter_media_type, filter_media_subtype;
|
||||
struct type *t = &this->type;
|
||||
uint32_t filter_media_type, filter_media_subtype, video_format;
|
||||
|
||||
if ((res = spa_v4l2_open(this)) < 0)
|
||||
return res;
|
||||
|
|
@ -564,16 +557,14 @@ spa_v4l2_enum_format(struct impl *this,
|
|||
|
||||
while (port->next_fmtdesc) {
|
||||
if (filter) {
|
||||
video_format = enum_filter_format(t,
|
||||
filter_media_type,
|
||||
video_format = enum_filter_format(filter_media_type,
|
||||
filter_media_subtype,
|
||||
filter, port->fmtdesc.index);
|
||||
|
||||
if (video_format == t->video_format.UNKNOWN)
|
||||
if (video_format == SPA_VIDEO_FORMAT_UNKNOWN)
|
||||
goto enum_end;
|
||||
|
||||
info = find_format_info_by_media_type(t,
|
||||
filter_media_type,
|
||||
info = find_format_info_by_media_type(filter_media_type,
|
||||
filter_media_subtype,
|
||||
video_format, 0);
|
||||
if (info == NULL)
|
||||
|
|
@ -602,7 +593,7 @@ spa_v4l2_enum_format(struct impl *this,
|
|||
struct spa_pod_prop *p;
|
||||
|
||||
/* check if we have a fixed frame size */
|
||||
if (!(p = spa_pod_find_prop(filter, t->format_video.size)))
|
||||
if (!(p = spa_pod_find_prop(filter, SPA_FORMAT_VIDEO_size)))
|
||||
goto do_frmsize;
|
||||
|
||||
if (p->body.value.type != SPA_POD_TYPE_RECTANGLE) {
|
||||
|
|
@ -638,7 +629,7 @@ spa_v4l2_enum_format(struct impl *this,
|
|||
uint32_t i, n_values;
|
||||
|
||||
/* check if we have a fixed frame size */
|
||||
if (!(p = spa_pod_find_prop(filter, t->format_video.size)))
|
||||
if (!(p = spa_pod_find_prop(filter, SPA_FORMAT_VIDEO_size)))
|
||||
goto have_size;
|
||||
|
||||
range = p->body.flags & SPA_POD_PROP_RANGE_MASK;
|
||||
|
|
@ -684,25 +675,21 @@ spa_v4l2_enum_format(struct impl *this,
|
|||
}
|
||||
}
|
||||
|
||||
media_type = *SPA_MEMBER(t, info->media_type_offset, uint32_t);
|
||||
media_subtype = *SPA_MEMBER(t, info->media_subtype_offset, uint32_t);
|
||||
video_format = *SPA_MEMBER(t, info->format_offset, uint32_t);
|
||||
|
||||
spa_pod_builder_push_object(builder, t->param.idEnumFormat, t->format);
|
||||
spa_pod_builder_push_object(builder, SPA_ID_PARAM_EnumFormat, SPA_ID_OBJECT_Format);
|
||||
spa_pod_builder_add(builder,
|
||||
"I", media_type,
|
||||
"I", media_subtype, 0);
|
||||
"I", info->media_type,
|
||||
"I", info->media_subtype, 0);
|
||||
|
||||
if (media_subtype == t->media_subtype.raw) {
|
||||
if (info->media_subtype == SPA_MEDIA_SUBTYPE_raw) {
|
||||
spa_pod_builder_add(builder,
|
||||
":", t->format_video.format, "I", video_format, 0);
|
||||
":", SPA_FORMAT_VIDEO_format, "I", info->format, 0);
|
||||
}
|
||||
spa_pod_builder_add(builder,
|
||||
":", t->format_video.size, "R", &SPA_RECTANGLE(port->frmsize.discrete.width,
|
||||
port->frmsize.discrete.height), 0);
|
||||
":", SPA_FORMAT_VIDEO_size, "R", &SPA_RECTANGLE(port->frmsize.discrete.width,
|
||||
port->frmsize.discrete.height), 0);
|
||||
|
||||
prop = spa_pod_builder_deref(builder,
|
||||
spa_pod_builder_push_prop(builder, t->format_video.framerate,
|
||||
spa_pod_builder_push_prop(builder, SPA_FORMAT_VIDEO_framerate,
|
||||
SPA_POD_PROP_RANGE_NONE | SPA_POD_PROP_FLAG_UNSET));
|
||||
n_fractions = 0;
|
||||
|
||||
|
|
@ -727,7 +714,7 @@ spa_v4l2_enum_format(struct impl *this,
|
|||
uint32_t i, n_values;
|
||||
const struct spa_fraction step = { 1, 1 }, *values;
|
||||
|
||||
if (!(p = spa_pod_find_prop(filter, t->format_video.framerate)))
|
||||
if (!(p = spa_pod_find_prop(filter, SPA_FORMAT_VIDEO_framerate)))
|
||||
goto have_framerate;
|
||||
|
||||
if (p->body.value.type != SPA_POD_TYPE_FRACTION)
|
||||
|
|
@ -824,32 +811,35 @@ static int spa_v4l2_set_format(struct impl *this, struct spa_video_info *format,
|
|||
uint32_t video_format;
|
||||
struct spa_rectangle *size = NULL;
|
||||
struct spa_fraction *framerate = NULL;
|
||||
struct type *t = &this->type;
|
||||
|
||||
spa_zero(fmt);
|
||||
spa_zero(streamparm);
|
||||
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
streamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
|
||||
if (format->media_subtype == this->type.media_subtype.raw) {
|
||||
switch (format->media_subtype) {
|
||||
case SPA_MEDIA_SUBTYPE_raw:
|
||||
video_format = format->info.raw.format;
|
||||
size = &format->info.raw.size;
|
||||
framerate = &format->info.raw.framerate;
|
||||
} else if (format->media_subtype == this->type.media_subtype_video.mjpg ||
|
||||
format->media_subtype == this->type.media_subtype_video.jpeg) {
|
||||
video_format = this->type.video_format.ENCODED;
|
||||
break;
|
||||
case SPA_MEDIA_SUBTYPE_mjpg:
|
||||
case SPA_MEDIA_SUBTYPE_jpeg:
|
||||
video_format = SPA_VIDEO_FORMAT_ENCODED;
|
||||
size = &format->info.mjpg.size;
|
||||
framerate = &format->info.mjpg.framerate;
|
||||
} else if (format->media_subtype == this->type.media_subtype_video.h264) {
|
||||
video_format = this->type.video_format.ENCODED;
|
||||
break;
|
||||
case SPA_MEDIA_SUBTYPE_h264:
|
||||
video_format = SPA_VIDEO_FORMAT_ENCODED;
|
||||
size = &format->info.h264.size;
|
||||
framerate = &format->info.h264.framerate;
|
||||
} else {
|
||||
video_format = this->type.video_format.ENCODED;
|
||||
break;
|
||||
default:
|
||||
video_format = SPA_VIDEO_FORMAT_ENCODED;
|
||||
break;
|
||||
}
|
||||
|
||||
info = find_format_info_by_media_type(t,
|
||||
format->media_type,
|
||||
info = find_format_info_by_media_type(format->media_type,
|
||||
format->media_subtype, video_format, 0);
|
||||
if (info == NULL || size == NULL || framerate == NULL) {
|
||||
spa_log_error(port->log, "v4l2: unknown media type %d %d %d", format->media_type,
|
||||
|
|
@ -965,23 +955,23 @@ static uint32_t control_to_prop_id(struct impl *impl, uint32_t control_id)
|
|||
{
|
||||
switch (control_id) {
|
||||
case V4L2_CID_BRIGHTNESS:
|
||||
return impl->type.prop_brightness;
|
||||
return SPA_PROP_brightness;
|
||||
case V4L2_CID_CONTRAST:
|
||||
return impl->type.prop_contrast;
|
||||
return SPA_PROP_contrast;
|
||||
case V4L2_CID_SATURATION:
|
||||
return impl->type.prop_saturation;
|
||||
return SPA_PROP_saturation;
|
||||
case V4L2_CID_HUE:
|
||||
return impl->type.prop_hue;
|
||||
return SPA_PROP_hue;
|
||||
case V4L2_CID_GAMMA:
|
||||
return impl->type.prop_gamma;
|
||||
return SPA_PROP_gamma;
|
||||
case V4L2_CID_EXPOSURE:
|
||||
return impl->type.prop_exposure;
|
||||
return SPA_PROP_exposure;
|
||||
case V4L2_CID_GAIN:
|
||||
return impl->type.prop_gain;
|
||||
return SPA_PROP_gain;
|
||||
case V4L2_CID_SHARPNESS:
|
||||
return impl->type.prop_sharpness;
|
||||
return SPA_PROP_sharpness;
|
||||
default:
|
||||
return impl->type.prop_unknown;
|
||||
return SPA_PROP_unknown;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -993,12 +983,10 @@ spa_v4l2_enum_controls(struct impl *this,
|
|||
struct spa_pod_builder *builder)
|
||||
{
|
||||
struct port *port = &this->out_ports[0];
|
||||
struct type *t = &this->type;
|
||||
struct v4l2_query_ext_ctrl queryctrl;
|
||||
struct spa_pod *param;
|
||||
struct spa_pod_builder b = { 0 };
|
||||
char type_id[128];
|
||||
uint32_t id, prop_id, ctrl_id;
|
||||
uint32_t prop_id, ctrl_id;
|
||||
uint8_t buffer[1024];
|
||||
int res;
|
||||
const unsigned next_fl = V4L2_CTRL_FLAG_NEXT_CTRL | V4L2_CTRL_FLAG_NEXT_COMPOUND;
|
||||
|
|
@ -1051,12 +1039,9 @@ spa_v4l2_enum_controls(struct impl *this,
|
|||
|
||||
spa_pod_builder_init(&b, buffer, sizeof(buffer));
|
||||
|
||||
snprintf(type_id, sizeof(type_id), SPA_TYPE_PARAM_IO_PROP_BASE"%08x", ctrl_id);
|
||||
id = spa_type_map_get_id(this->map, type_id);
|
||||
|
||||
prop_id = control_to_prop_id(this, ctrl_id);
|
||||
|
||||
port->controls[port->n_controls].id = id;
|
||||
port->controls[port->n_controls].id = prop_id;
|
||||
port->controls[port->n_controls].ctrl_id = ctrl_id;
|
||||
port->controls[port->n_controls].value = queryctrl.default_value;
|
||||
|
||||
|
|
@ -1067,42 +1052,36 @@ spa_v4l2_enum_controls(struct impl *this,
|
|||
switch (queryctrl.type) {
|
||||
case V4L2_CTRL_TYPE_INTEGER:
|
||||
param = spa_pod_builder_object(&b,
|
||||
t->param_io.idPropsIn, t->param_io.Prop,
|
||||
":", t->param_io.id, "I", id,
|
||||
":", t->param_io.size, "i", sizeof(struct spa_pod_int),
|
||||
":", t->param.propId, "I", prop_id,
|
||||
":", t->param.propType, "isu", queryctrl.default_value,
|
||||
3, queryctrl.minimum,
|
||||
queryctrl.maximum,
|
||||
queryctrl.step,
|
||||
":", t->param.propName, "s", queryctrl.name);
|
||||
SPA_ID_PARAM_PropInfo, SPA_ID_OBJECT_PropInfo,
|
||||
":", SPA_PROP_INFO_id, "I", prop_id,
|
||||
":", SPA_PROP_INFO_type, "isu", queryctrl.default_value,
|
||||
SPA_POD_PROP_STEP(queryctrl.minimum,
|
||||
queryctrl.maximum,
|
||||
queryctrl.step),
|
||||
":", SPA_PROP_INFO_name, "s", queryctrl.name);
|
||||
break;
|
||||
case V4L2_CTRL_TYPE_BOOLEAN:
|
||||
param = spa_pod_builder_object(&b,
|
||||
t->param_io.idPropsIn, t->param_io.Prop,
|
||||
":", t->param_io.id, "I", id,
|
||||
":", t->param_io.size, "i", sizeof(struct spa_pod_bool),
|
||||
":", t->param.propId, "I", prop_id,
|
||||
":", t->param.propType, "b-u", queryctrl.default_value,
|
||||
":", t->param.propName, "s", queryctrl.name);
|
||||
SPA_ID_PARAM_PropInfo, SPA_ID_OBJECT_PropInfo,
|
||||
":", SPA_PROP_INFO_id, "I", prop_id,
|
||||
":", SPA_PROP_INFO_type, "b-u", queryctrl.default_value,
|
||||
":", SPA_PROP_INFO_name, "s", queryctrl.name);
|
||||
break;
|
||||
case V4L2_CTRL_TYPE_MENU:
|
||||
{
|
||||
struct v4l2_querymenu querymenu;
|
||||
|
||||
spa_pod_builder_push_object(&b, t->param_io.idPropsIn, t->param_io.Prop);
|
||||
spa_pod_builder_push_object(&b, SPA_ID_PARAM_PropInfo, SPA_ID_OBJECT_PropInfo);
|
||||
spa_pod_builder_add(&b,
|
||||
":", t->param_io.id, "I", id,
|
||||
":", t->param_io.size, "i", sizeof(struct spa_pod_double),
|
||||
":", t->param.propId, "I", prop_id,
|
||||
":", t->param.propName, "s", queryctrl.name,
|
||||
":", t->param.propType, "i-u", queryctrl.default_value,
|
||||
":", SPA_PROP_INFO_id, "I", prop_id,
|
||||
":", SPA_PROP_INFO_type, "i-u", queryctrl.default_value,
|
||||
":", SPA_PROP_INFO_name, "s", queryctrl.name,
|
||||
NULL);
|
||||
|
||||
spa_zero(querymenu);
|
||||
querymenu.id = queryctrl.id;
|
||||
|
||||
spa_pod_builder_push_prop(&b, t->param.propLabels, 0);
|
||||
spa_pod_builder_push_prop(&b, SPA_PROP_INFO_labels, 0);
|
||||
spa_pod_builder_push_struct(&b);
|
||||
for (querymenu.index = queryctrl.minimum;
|
||||
querymenu.index <= queryctrl.maximum;
|
||||
|
|
@ -1218,14 +1197,13 @@ static int spa_v4l2_use_buffers(struct impl *this, struct spa_buffer **buffers,
|
|||
if (n_buffers > 0) {
|
||||
d = buffers[0]->datas;
|
||||
|
||||
if (d[0].type == this->type.data.MemFd ||
|
||||
(d[0].type == this->type.data.MemPtr && d[0].data != NULL)) {
|
||||
if (d[0].type == SPA_DATA_MemFd ||
|
||||
(d[0].type == SPA_DATA_MemPtr && d[0].data != NULL)) {
|
||||
port->memtype = V4L2_MEMORY_USERPTR;
|
||||
} else if (d[0].type == this->type.data.DmaBuf) {
|
||||
} else if (d[0].type == SPA_DATA_DmaBuf) {
|
||||
port->memtype = V4L2_MEMORY_DMABUF;
|
||||
} else {
|
||||
spa_log_error(port->log, "v4l2: can't use buffers of type %s (%d)",
|
||||
spa_type_map_get_type (this->map, d[0].type), d[0].type);
|
||||
spa_log_error(port->log, "v4l2: can't use buffers of type %d", d[0].type);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
|
@ -1251,7 +1229,7 @@ static int spa_v4l2_use_buffers(struct impl *this, struct spa_buffer **buffers,
|
|||
b = &port->buffers[i];
|
||||
b->outbuf = buffers[i];
|
||||
b->flags = BUFFER_FLAG_OUTSTANDING;
|
||||
b->h = spa_buffer_find_meta_data(buffers[i], this->type.meta.Header, sizeof(*b->h));
|
||||
b->h = spa_buffer_find_meta_data(buffers[i], SPA_META_Header, sizeof(*b->h));
|
||||
|
||||
spa_log_info(port->log, "v4l2: import buffer %p", buffers[i]);
|
||||
|
||||
|
|
@ -1345,7 +1323,7 @@ mmap_init(struct impl *this,
|
|||
b = &port->buffers[i];
|
||||
b->outbuf = buffers[i];
|
||||
b->flags = BUFFER_FLAG_OUTSTANDING;
|
||||
b->h = spa_buffer_find_meta_data(buffers[i], this->type.meta.Header, sizeof(*b->h));
|
||||
b->h = spa_buffer_find_meta_data(buffers[i], SPA_META_Header, sizeof(*b->h));
|
||||
|
||||
spa_zero(b->v4l2_buffer);
|
||||
b->v4l2_buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
|
|
@ -1375,12 +1353,12 @@ mmap_init(struct impl *this,
|
|||
spa_log_error(port->log, "VIDIOC_EXPBUF: %m");
|
||||
continue;
|
||||
}
|
||||
d[0].type = this->type.data.DmaBuf;
|
||||
d[0].type = SPA_DATA_DmaBuf;
|
||||
d[0].fd = expbuf.fd;
|
||||
d[0].data = NULL;
|
||||
SPA_FLAG_SET(b->flags, BUFFER_FLAG_ALLOCATED);
|
||||
} else {
|
||||
d[0].type = this->type.data.MemPtr;
|
||||
d[0].type = SPA_DATA_MemPtr;
|
||||
d[0].fd = -1;
|
||||
d[0].data = mmap(NULL,
|
||||
b->v4l2_buffer.length,
|
||||
|
|
|
|||
|
|
@ -135,13 +135,13 @@ static int drawing_data_init(DrawingData * dd, struct impl *this, char *data)
|
|||
struct spa_video_info *format = &this->current_format;
|
||||
struct spa_rectangle *size = &format->info.raw.size;
|
||||
|
||||
if ((format->media_type != this->type.media_type.video) ||
|
||||
(format->media_subtype != this->type.media_subtype.raw))
|
||||
if ((format->media_type != SPA_MEDIA_TYPE_video) ||
|
||||
(format->media_subtype != SPA_MEDIA_SUBTYPE_raw))
|
||||
return -ENOTSUP;
|
||||
|
||||
if (format->info.raw.format == this->type.video_format.RGB) {
|
||||
if (format->info.raw.format == SPA_VIDEO_FORMAT_RGB) {
|
||||
dd->draw_pixel = draw_pixel_rgb;
|
||||
} else if (format->info.raw.format == this->type.video_format.UYVY) {
|
||||
} else if (format->info.raw.format == SPA_VIDEO_FORMAT_UYVY) {
|
||||
dd->draw_pixel = draw_pixel_uyvy;
|
||||
} else
|
||||
return -ENOTSUP;
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@
|
|||
#include <stdio.h>
|
||||
#include <sys/timerfd.h>
|
||||
|
||||
#include <spa/support/type-map.h>
|
||||
#include <spa/support/log.h>
|
||||
#include <spa/support/loop.h>
|
||||
#include <spa/utils/list.h>
|
||||
|
|
@ -41,47 +40,6 @@
|
|||
#define FRAMES_TO_TIME(this,f) ((this->current_format.info.raw.framerate.denom * (f) * SPA_NSEC_PER_SEC) / \
|
||||
(this->current_format.info.raw.framerate.num))
|
||||
|
||||
struct type {
|
||||
uint32_t node;
|
||||
uint32_t format;
|
||||
uint32_t props;
|
||||
uint32_t prop_live;
|
||||
uint32_t prop_pattern;
|
||||
struct spa_type_io io;
|
||||
struct spa_type_param param;
|
||||
struct spa_type_meta meta;
|
||||
struct spa_type_data data;
|
||||
struct spa_type_media_type media_type;
|
||||
struct spa_type_media_subtype media_subtype;
|
||||
struct spa_type_format_video format_video;
|
||||
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_buffers param_buffers;
|
||||
struct spa_type_param_meta param_meta;
|
||||
};
|
||||
|
||||
static inline void init_type(struct type *type, struct spa_type_map *map)
|
||||
{
|
||||
type->node = spa_type_map_get_id(map, SPA_TYPE__Node);
|
||||
type->format = spa_type_map_get_id(map, SPA_TYPE__Format);
|
||||
type->props = spa_type_map_get_id(map, SPA_TYPE__Props);
|
||||
type->prop_live = spa_type_map_get_id(map, SPA_TYPE_PROPS__live);
|
||||
type->prop_pattern = spa_type_map_get_id(map, SPA_TYPE_PROPS__patternType);
|
||||
spa_type_io_map(map, &type->io);
|
||||
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);
|
||||
spa_type_media_subtype_map(map, &type->media_subtype);
|
||||
spa_type_format_video_map(map, &type->format_video);
|
||||
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_buffers_map(map, &type->param_buffers);
|
||||
spa_type_param_meta_map(map, &type->param_meta);
|
||||
}
|
||||
|
||||
enum pattern {
|
||||
PATTERN_SMPTE_SNOW,
|
||||
PATTERN_SNOW,
|
||||
|
|
@ -115,8 +73,6 @@ struct impl {
|
|||
struct spa_handle handle;
|
||||
struct spa_node node;
|
||||
|
||||
struct type type;
|
||||
struct spa_type_map *map;
|
||||
struct spa_log *log;
|
||||
struct spa_loop *data_loop;
|
||||
|
||||
|
|
@ -157,7 +113,6 @@ static int impl_node_enum_params(struct spa_node *node,
|
|||
struct spa_pod_builder *builder)
|
||||
{
|
||||
struct impl *this;
|
||||
struct type *t;
|
||||
struct spa_pod *param;
|
||||
struct spa_pod_builder b = { 0 };
|
||||
uint8_t buffer[1024];
|
||||
|
|
@ -166,62 +121,69 @@ static int impl_node_enum_params(struct spa_node *node,
|
|||
spa_return_val_if_fail(builder != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
t = &this->type;
|
||||
|
||||
next:
|
||||
spa_pod_builder_init(&b, buffer, sizeof(buffer));
|
||||
|
||||
if (id == t->param.idList) {
|
||||
uint32_t list[] = { t->param.idPropInfo,
|
||||
t->param.idProps };
|
||||
switch (id) {
|
||||
case SPA_ID_PARAM_List:
|
||||
{
|
||||
uint32_t list[] = { SPA_ID_PARAM_PropInfo,
|
||||
SPA_ID_PARAM_Props };
|
||||
|
||||
if (*index < SPA_N_ELEMENTS(list))
|
||||
param = spa_pod_builder_object(&b, id, t->param.List,
|
||||
":", t->param.listId, "I", list[*index]);
|
||||
param = spa_pod_builder_object(&b, id, SPA_ID_OBJECT_ParamList,
|
||||
":", SPA_PARAM_LIST_id, "I", list[*index]);
|
||||
else
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
else if (id == t->param.idPropInfo) {
|
||||
case SPA_ID_PARAM_PropInfo:
|
||||
{
|
||||
struct props *p = &this->props;
|
||||
|
||||
switch (*index) {
|
||||
case 0:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param.PropInfo,
|
||||
":", t->param.propId, "I", t->prop_live,
|
||||
":", t->param.propName, "s", "Configure live mode of the source",
|
||||
":", t->param.propType, "b", p->live);
|
||||
id, SPA_ID_OBJECT_PropInfo,
|
||||
":", SPA_PROP_INFO_id, "I", SPA_PROP_live,
|
||||
":", SPA_PROP_INFO_name, "s", "Configure live mode of the source",
|
||||
":", SPA_PROP_INFO_type, "b", p->live);
|
||||
break;
|
||||
case 1:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param.PropInfo,
|
||||
":", t->param.propId, "I", t->prop_pattern,
|
||||
":", t->param.propName, "s", "The pattern",
|
||||
":", t->param.propType, "i", p->pattern,
|
||||
":", t->param.propLabels, "[-i",
|
||||
id, SPA_ID_OBJECT_PropInfo,
|
||||
":", SPA_PROP_INFO_id, "I", SPA_PROP_patternType,
|
||||
":", SPA_PROP_INFO_name, "s", "The pattern",
|
||||
":", SPA_PROP_INFO_type, "i", p->pattern,
|
||||
":", SPA_PROP_INFO_labels, "[-i",
|
||||
"i", PATTERN_SMPTE_SNOW, "s", "SMPTE snow",
|
||||
"i", PATTERN_SNOW, "s", "Snow", "]");
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
else if (id == t->param.idProps) {
|
||||
case SPA_ID_PARAM_Props:
|
||||
{
|
||||
struct props *p = &this->props;
|
||||
|
||||
switch (*index) {
|
||||
case 0:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->props,
|
||||
":", t->prop_live, "b", p->live,
|
||||
":", t->prop_pattern, "i", p->pattern);
|
||||
id, SPA_ID_OBJECT_Props,
|
||||
":", SPA_PROP_live, "b", p->live,
|
||||
":", SPA_PROP_patternType, "i", p->pattern);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
else
|
||||
default:
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
(*index)++;
|
||||
|
||||
|
|
@ -235,14 +197,14 @@ static int impl_node_set_param(struct spa_node *node, uint32_t id, uint32_t flag
|
|||
const struct spa_pod *param)
|
||||
{
|
||||
struct impl *this;
|
||||
struct type *t;
|
||||
|
||||
spa_return_val_if_fail(node != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
t = &this->type;
|
||||
|
||||
if (id == t->param.idProps) {
|
||||
switch (id) {
|
||||
case SPA_ID_PARAM_Props:
|
||||
{
|
||||
struct props *p = &this->props;
|
||||
|
||||
if (param == NULL) {
|
||||
|
|
@ -250,8 +212,8 @@ static int impl_node_set_param(struct spa_node *node, uint32_t id, uint32_t flag
|
|||
return 0;
|
||||
}
|
||||
spa_pod_object_parse(param,
|
||||
":", t->prop_live, "?b", &p->live,
|
||||
":", t->prop_pattern, "?i", &p->pattern,
|
||||
":", SPA_PROP_live, "?b", &p->live,
|
||||
":", SPA_PROP_patternType, "?i", &p->pattern,
|
||||
NULL);
|
||||
|
||||
if (p->live)
|
||||
|
|
@ -259,9 +221,9 @@ static int impl_node_set_param(struct spa_node *node, uint32_t id, uint32_t flag
|
|||
else
|
||||
this->info.flags &= ~SPA_PORT_INFO_FLAG_LIVE;
|
||||
}
|
||||
else
|
||||
default:
|
||||
return -ENOENT;
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -365,7 +327,9 @@ static int impl_node_send_command(struct spa_node *node, const struct spa_comman
|
|||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
|
||||
if (SPA_COMMAND_TYPE(command) == this->type.command_node.Start) {
|
||||
switch (SPA_COMMAND_TYPE(command)) {
|
||||
case SPA_ID_COMMAND_NODE_Start:
|
||||
{
|
||||
struct timespec now;
|
||||
|
||||
if (!this->have_format)
|
||||
|
|
@ -386,7 +350,9 @@ static int impl_node_send_command(struct spa_node *node, const struct spa_comman
|
|||
|
||||
this->started = true;
|
||||
set_timer(this, true);
|
||||
} else if (SPA_COMMAND_TYPE(command) == this->type.command_node.Pause) {
|
||||
break;
|
||||
}
|
||||
case SPA_ID_COMMAND_NODE_Pause:
|
||||
if (!this->have_format)
|
||||
return -EIO;
|
||||
if (this->n_buffers == 0)
|
||||
|
|
@ -397,9 +363,10 @@ static int impl_node_send_command(struct spa_node *node, const struct spa_comman
|
|||
|
||||
this->started = false;
|
||||
set_timer(this, false);
|
||||
} else
|
||||
break;
|
||||
default:
|
||||
return -ENOTSUP;
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -494,22 +461,19 @@ static int port_enum_formats(struct spa_node *node,
|
|||
struct spa_pod **param,
|
||||
struct spa_pod_builder *builder)
|
||||
{
|
||||
struct impl *this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
struct type *t = &this->type;
|
||||
|
||||
switch (*index) {
|
||||
case 0:
|
||||
*param = spa_pod_builder_object(builder,
|
||||
t->param.idEnumFormat, t->format,
|
||||
"I", t->media_type.video,
|
||||
"I", t->media_subtype.raw,
|
||||
":", t->format_video.format, "Ieu", t->video_format.RGB,
|
||||
SPA_POD_PROP_ENUM(2, t->video_format.RGB,
|
||||
t->video_format.UYVY),
|
||||
":", t->format_video.size, "Rru", &SPA_RECTANGLE(320, 240),
|
||||
SPA_ID_PARAM_EnumFormat, SPA_ID_OBJECT_Format,
|
||||
"I", SPA_MEDIA_TYPE_video,
|
||||
"I", SPA_MEDIA_SUBTYPE_raw,
|
||||
":", SPA_FORMAT_VIDEO_format, "Ieu", SPA_VIDEO_FORMAT_RGB,
|
||||
SPA_POD_PROP_ENUM(2, SPA_VIDEO_FORMAT_RGB,
|
||||
SPA_VIDEO_FORMAT_UYVY),
|
||||
":", SPA_FORMAT_VIDEO_size, "Rru", &SPA_RECTANGLE(320, 240),
|
||||
SPA_POD_PROP_MIN_MAX(&SPA_RECTANGLE(1, 1),
|
||||
&SPA_RECTANGLE(INT32_MAX, INT32_MAX)),
|
||||
":", t->format_video.framerate, "Fru", &SPA_FRACTION(25,1),
|
||||
":", SPA_FORMAT_VIDEO_framerate, "Fru", &SPA_FRACTION(25,1),
|
||||
SPA_POD_PROP_MIN_MAX(&SPA_FRACTION(0, 1),
|
||||
&SPA_FRACTION(INT32_MAX, 1)));
|
||||
break;
|
||||
|
|
@ -527,7 +491,6 @@ static int port_get_format(struct spa_node *node,
|
|||
struct spa_pod_builder *builder)
|
||||
{
|
||||
struct impl *this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
struct type *t = &this->type;
|
||||
|
||||
if (!this->have_format)
|
||||
return -EIO;
|
||||
|
|
@ -535,12 +498,12 @@ static int port_get_format(struct spa_node *node,
|
|||
return 0;
|
||||
|
||||
*param = spa_pod_builder_object(builder,
|
||||
t->param.idFormat, t->format,
|
||||
"I", t->media_type.video,
|
||||
"I", t->media_subtype.raw,
|
||||
":", t->format_video.format, "I", this->current_format.info.raw.format,
|
||||
":", t->format_video.size, "R", &this->current_format.info.raw.size,
|
||||
":", t->format_video.framerate, "F", &this->current_format.info.raw.framerate);
|
||||
SPA_ID_PARAM_Format, SPA_ID_OBJECT_Format,
|
||||
"I", SPA_MEDIA_TYPE_video,
|
||||
"I", SPA_MEDIA_SUBTYPE_raw,
|
||||
":", SPA_FORMAT_VIDEO_format, "I", this->current_format.info.raw.format,
|
||||
":", SPA_FORMAT_VIDEO_size, "R", &this->current_format.info.raw.size,
|
||||
":", SPA_FORMAT_VIDEO_framerate, "F", &this->current_format.info.raw.framerate);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -554,7 +517,6 @@ impl_node_port_enum_params(struct spa_node *node,
|
|||
struct spa_pod_builder *builder)
|
||||
{
|
||||
struct impl *this;
|
||||
struct type *t;
|
||||
struct spa_pod_builder b = { 0 };
|
||||
uint8_t buffer[1024];
|
||||
struct spa_pod *param;
|
||||
|
|
@ -565,34 +527,39 @@ impl_node_port_enum_params(struct spa_node *node,
|
|||
spa_return_val_if_fail(builder != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
t = &this->type;
|
||||
|
||||
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
|
||||
|
||||
next:
|
||||
spa_pod_builder_init(&b, buffer, sizeof(buffer));
|
||||
|
||||
if (id == t->param.idList) {
|
||||
uint32_t list[] = { t->param.idEnumFormat,
|
||||
t->param.idFormat,
|
||||
t->param.idBuffers,
|
||||
t->param.idMeta };
|
||||
switch (id) {
|
||||
case SPA_ID_PARAM_List:
|
||||
{
|
||||
uint32_t list[] = { SPA_ID_PARAM_EnumFormat,
|
||||
SPA_ID_PARAM_Format,
|
||||
SPA_ID_PARAM_Buffers,
|
||||
SPA_ID_PARAM_Meta };
|
||||
|
||||
if (*index < SPA_N_ELEMENTS(list))
|
||||
param = spa_pod_builder_object(&b, id, t->param.List,
|
||||
":", t->param.listId, "I", list[*index]);
|
||||
param = spa_pod_builder_object(&b, id, SPA_ID_OBJECT_ParamList,
|
||||
":", SPA_PARAM_LIST_id, "I", list[*index]);
|
||||
else
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
else if (id == t->param.idEnumFormat) {
|
||||
case SPA_ID_PARAM_EnumFormat:
|
||||
if ((res = port_enum_formats(node, direction, port_id, index, filter, ¶m, &b)) <= 0)
|
||||
return res;
|
||||
}
|
||||
else if (id == t->param.idFormat) {
|
||||
break;
|
||||
|
||||
case SPA_ID_PARAM_Format:
|
||||
if ((res = port_get_format(node, direction, port_id, index, filter, ¶m, &b)) <= 0)
|
||||
return res;
|
||||
}
|
||||
else if (id == t->param.idBuffers) {
|
||||
break;
|
||||
|
||||
case SPA_ID_PARAM_Buffers:
|
||||
{
|
||||
struct spa_video_info_raw *raw_info = &this->current_format.info.raw;
|
||||
|
||||
if (!this->have_format)
|
||||
|
|
@ -601,31 +568,34 @@ impl_node_port_enum_params(struct spa_node *node,
|
|||
return 0;
|
||||
|
||||
param = spa_pod_builder_object(&b,
|
||||
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,
|
||||
id, SPA_ID_OBJECT_ParamBuffers,
|
||||
":", SPA_PARAM_BUFFERS_buffers, "ir", 2,
|
||||
SPA_POD_PROP_MIN_MAX(1, MAX_BUFFERS),
|
||||
":", t->param_buffers.align, "i", 16);
|
||||
":", SPA_PARAM_BUFFERS_blocks, "i", 1,
|
||||
":", SPA_PARAM_BUFFERS_size, "i", this->stride * raw_info->size.height,
|
||||
":", SPA_PARAM_BUFFERS_stride, "i", this->stride,
|
||||
":", SPA_PARAM_BUFFERS_align, "i", 16);
|
||||
break;
|
||||
}
|
||||
else if (id == t->param.idMeta) {
|
||||
case SPA_ID_PARAM_Meta:
|
||||
if (!this->have_format)
|
||||
return -EIO;
|
||||
|
||||
switch (*index) {
|
||||
case 0:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param_meta.Meta,
|
||||
":", t->param_meta.type, "I", t->meta.Header,
|
||||
":", t->param_meta.size, "i", sizeof(struct spa_meta_header));
|
||||
id, SPA_ID_OBJECT_ParamMeta,
|
||||
":", SPA_PARAM_META_type, "I", SPA_META_Header,
|
||||
":", SPA_PARAM_META_size, "i", sizeof(struct spa_meta_header));
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
break;
|
||||
default:
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
(*index)++;
|
||||
|
||||
|
|
@ -664,16 +634,16 @@ static int port_set_format(struct spa_node *node,
|
|||
"I", &info.media_type,
|
||||
"I", &info.media_subtype);
|
||||
|
||||
if (info.media_type != this->type.media_type.video &&
|
||||
info.media_subtype != this->type.media_subtype.raw)
|
||||
if (info.media_type != SPA_MEDIA_TYPE_video &&
|
||||
info.media_subtype != SPA_MEDIA_SUBTYPE_raw)
|
||||
return -EINVAL;
|
||||
|
||||
if (spa_format_video_raw_parse(format, &info.info.raw, &this->type.format_video) < 0)
|
||||
if (spa_format_video_raw_parse(format, &info.info.raw) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (info.info.raw.format == this->type.video_format.RGB)
|
||||
if (info.info.raw.format == SPA_VIDEO_FORMAT_RGB)
|
||||
this->bpp = 3;
|
||||
else if (info.info.raw.format == this->type.video_format.UYVY)
|
||||
else if (info.info.raw.format == SPA_VIDEO_FORMAT_UYVY)
|
||||
this->bpp = 2;
|
||||
else
|
||||
return -EINVAL;
|
||||
|
|
@ -696,17 +666,11 @@ impl_node_port_set_param(struct spa_node *node,
|
|||
uint32_t id, uint32_t flags,
|
||||
const struct spa_pod *param)
|
||||
{
|
||||
struct impl *this;
|
||||
struct type *t;
|
||||
|
||||
spa_return_val_if_fail(node != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
t = &this->type;
|
||||
spa_return_val_if_fail(CHECK_PORT(node, direction, port_id), -EINVAL);
|
||||
|
||||
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
|
||||
|
||||
if (id == t->param.idFormat) {
|
||||
if (id == SPA_ID_PARAM_Format) {
|
||||
return port_set_format(node, direction, port_id, flags, param);
|
||||
}
|
||||
else
|
||||
|
|
@ -722,7 +686,6 @@ impl_node_port_use_buffers(struct spa_node *node,
|
|||
{
|
||||
struct impl *this;
|
||||
uint32_t i;
|
||||
struct type *t;
|
||||
|
||||
spa_return_val_if_fail(node != NULL, -EINVAL);
|
||||
|
||||
|
|
@ -733,8 +696,6 @@ impl_node_port_use_buffers(struct spa_node *node,
|
|||
if (!this->have_format)
|
||||
return -EIO;
|
||||
|
||||
t = &this->type;
|
||||
|
||||
clear_buffers(this);
|
||||
|
||||
for (i = 0; i < n_buffers; i++) {
|
||||
|
|
@ -744,11 +705,11 @@ impl_node_port_use_buffers(struct spa_node *node,
|
|||
b = &this->buffers[i];
|
||||
b->outbuf = buffers[i];
|
||||
b->outstanding = false;
|
||||
b->h = spa_buffer_find_meta_data(buffers[i], t->meta.Header, sizeof(*b->h));
|
||||
b->h = spa_buffer_find_meta_data(buffers[i], SPA_META_Header, sizeof(*b->h));
|
||||
|
||||
if ((d[0].type == t->data.MemPtr ||
|
||||
d[0].type == t->data.MemFd ||
|
||||
d[0].type == t->data.DmaBuf) && d[0].data == NULL) {
|
||||
if ((d[0].type == SPA_DATA_MemPtr ||
|
||||
d[0].type == SPA_DATA_MemFd ||
|
||||
d[0].type == SPA_DATA_DmaBuf) && d[0].data == NULL) {
|
||||
spa_log_error(this->log, NAME " %p: invalid memory on buffer %p", this,
|
||||
buffers[i]);
|
||||
return -EINVAL;
|
||||
|
|
@ -791,16 +752,14 @@ impl_node_port_set_io(struct spa_node *node,
|
|||
void *data, size_t size)
|
||||
{
|
||||
struct impl *this;
|
||||
struct type *t;
|
||||
|
||||
spa_return_val_if_fail(node != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
t = &this->type;
|
||||
|
||||
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
|
||||
|
||||
if (id == t->io.Buffers)
|
||||
if (id == SPA_ID_IO_Buffers)
|
||||
this->io = data;
|
||||
else
|
||||
return -ENOENT;
|
||||
|
|
@ -912,7 +871,7 @@ static int impl_get_interface(struct spa_handle *handle, uint32_t interface_id,
|
|||
|
||||
this = (struct impl *) handle;
|
||||
|
||||
if (interface_id == this->type.node)
|
||||
if (interface_id == SPA_ID_INTERFACE_Node)
|
||||
*interface = &this->node;
|
||||
else
|
||||
return -ENOENT;
|
||||
|
|
@ -961,18 +920,11 @@ impl_init(const struct spa_handle_factory *factory,
|
|||
this = (struct impl *) handle;
|
||||
|
||||
for (i = 0; i < n_support; i++) {
|
||||
if (strcmp(support[i].type, SPA_TYPE__TypeMap) == 0)
|
||||
this->map = support[i].data;
|
||||
else if (strcmp(support[i].type, SPA_TYPE__Log) == 0)
|
||||
if (support[i].type == SPA_ID_INTERFACE_Log)
|
||||
this->log = support[i].data;
|
||||
else if (strcmp(support[i].type, SPA_TYPE_LOOP__DataLoop) == 0)
|
||||
else if (support[i].type == SPA_ID_INTERFACE_DataLoop)
|
||||
this->data_loop = support[i].data;
|
||||
}
|
||||
if (this->map == NULL) {
|
||||
spa_log_error(this->log, "a type-map is needed");
|
||||
return -EINVAL;
|
||||
}
|
||||
init_type(&this->type, this->map);
|
||||
|
||||
this->node = impl_node;
|
||||
reset_props(&this->props);
|
||||
|
|
@ -1002,7 +954,7 @@ impl_init(const struct spa_handle_factory *factory,
|
|||
}
|
||||
|
||||
static const struct spa_interface_info impl_interfaces[] = {
|
||||
{SPA_TYPE__Node,},
|
||||
{SPA_ID_INTERFACE_Node,},
|
||||
};
|
||||
|
||||
static int
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@
|
|||
#include <stddef.h>
|
||||
|
||||
#include <spa/support/log.h>
|
||||
#include <spa/support/type-map.h>
|
||||
#include <spa/utils/list.h>
|
||||
#include <spa/node/node.h>
|
||||
#include <spa/node/io.h>
|
||||
|
|
@ -72,55 +71,10 @@ struct port {
|
|||
struct spa_list empty;
|
||||
};
|
||||
|
||||
struct type {
|
||||
uint32_t node;
|
||||
uint32_t format;
|
||||
uint32_t props;
|
||||
uint32_t prop_volume;
|
||||
uint32_t prop_mute;
|
||||
struct spa_type_io io;
|
||||
struct spa_type_param param;
|
||||
struct spa_type_meta meta;
|
||||
struct spa_type_data data;
|
||||
struct spa_type_media_type media_type;
|
||||
struct spa_type_media_subtype media_subtype;
|
||||
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_buffers param_buffers;
|
||||
struct spa_type_param_meta param_meta;
|
||||
struct spa_type_param_io param_io;
|
||||
};
|
||||
|
||||
static inline void init_type(struct type *type, struct spa_type_map *map)
|
||||
{
|
||||
type->node = spa_type_map_get_id(map, SPA_TYPE__Node);
|
||||
type->format = spa_type_map_get_id(map, SPA_TYPE__Format);
|
||||
type->props = spa_type_map_get_id(map, SPA_TYPE__Props);
|
||||
type->prop_volume = spa_type_map_get_id(map, SPA_TYPE_PROPS__volume);
|
||||
type->prop_mute = spa_type_map_get_id(map, SPA_TYPE_PROPS__mute);
|
||||
spa_type_io_map(map, &type->io);
|
||||
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);
|
||||
spa_type_media_subtype_map(map, &type->media_subtype);
|
||||
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_buffers_map(map, &type->param_buffers);
|
||||
spa_type_param_meta_map(map, &type->param_meta);
|
||||
spa_type_param_io_map(map, &type->param_io);
|
||||
}
|
||||
|
||||
struct impl {
|
||||
struct spa_handle handle;
|
||||
struct spa_node node;
|
||||
|
||||
struct type type;
|
||||
struct spa_type_map *map;
|
||||
struct spa_log *log;
|
||||
|
||||
struct props props;
|
||||
|
|
@ -151,7 +105,6 @@ static int impl_node_enum_params(struct spa_node *node,
|
|||
struct spa_pod_builder *builder)
|
||||
{
|
||||
struct impl *this;
|
||||
struct type *t;
|
||||
struct spa_pod_builder b = { 0 };
|
||||
uint8_t buffer[1024];
|
||||
struct spa_pod *param;
|
||||
|
|
@ -162,57 +115,60 @@ static int impl_node_enum_params(struct spa_node *node,
|
|||
spa_return_val_if_fail(builder != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
t = &this->type;
|
||||
p = &this->props;
|
||||
|
||||
next:
|
||||
spa_pod_builder_init(&b, buffer, sizeof(buffer));
|
||||
|
||||
if (id == t->param.idList) {
|
||||
uint32_t list[] = { t->param.idPropInfo,
|
||||
t->param.idProps };
|
||||
switch (id) {
|
||||
case SPA_ID_PARAM_List:
|
||||
{
|
||||
uint32_t list[] = { SPA_ID_PARAM_PropInfo,
|
||||
SPA_ID_PARAM_Props };
|
||||
|
||||
if (*index < SPA_N_ELEMENTS(list))
|
||||
param = spa_pod_builder_object(&b, id, t->param.List,
|
||||
":", t->param.listId, "I", list[*index]);
|
||||
param = spa_pod_builder_object(&b, id, SPA_ID_OBJECT_ParamList,
|
||||
":", SPA_PARAM_LIST_id, "I", list[*index]);
|
||||
else
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
else if (id == t->param.idPropInfo) {
|
||||
case SPA_ID_PARAM_PropInfo:
|
||||
switch (*index) {
|
||||
case 0:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param.PropInfo,
|
||||
":", t->param.propId, "I", t->prop_volume,
|
||||
":", t->param.propName, "s", "The volume",
|
||||
":", t->param.propType, "dr", p->volume,
|
||||
id, SPA_ID_OBJECT_PropInfo,
|
||||
":", SPA_PROP_INFO_id, "I", SPA_PROP_volume,
|
||||
":", SPA_PROP_INFO_name, "s", "The volume",
|
||||
":", SPA_PROP_INFO_type, "dr", p->volume,
|
||||
SPA_POD_PROP_MIN_MAX(0.0, 10.0));
|
||||
break;
|
||||
case 1:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param.PropInfo,
|
||||
":", t->param.propId, "I", t->prop_mute,
|
||||
":", t->param.propName, "s", "Mute",
|
||||
":", t->param.propType, "b", p->mute);
|
||||
id, SPA_ID_OBJECT_PropInfo,
|
||||
":", SPA_PROP_INFO_id, "I", SPA_PROP_mute,
|
||||
":", SPA_PROP_INFO_name, "s", "Mute",
|
||||
":", SPA_PROP_INFO_type, "b", p->mute);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if (id == t->param.idProps) {
|
||||
break;
|
||||
case SPA_ID_PARAM_Props:
|
||||
switch (*index) {
|
||||
case 0:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->props,
|
||||
":", t->prop_volume, "d", p->volume,
|
||||
":", t->prop_mute, "b", p->mute);
|
||||
id, SPA_ID_OBJECT_Props,
|
||||
":", SPA_PROP_volume, "d", p->volume,
|
||||
":", SPA_PROP_mute, "b", p->mute);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
break;
|
||||
default:
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
(*index)++;
|
||||
|
||||
|
|
@ -226,14 +182,14 @@ static int impl_node_set_param(struct spa_node *node, uint32_t id, uint32_t flag
|
|||
const struct spa_pod *param)
|
||||
{
|
||||
struct impl *this;
|
||||
struct type *t;
|
||||
|
||||
spa_return_val_if_fail(node != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
t = &this->type;
|
||||
|
||||
if (id == t->param.idProps) {
|
||||
switch (id) {
|
||||
case SPA_ID_PARAM_Props:
|
||||
{
|
||||
struct props *p = &this->props;
|
||||
|
||||
if (param == NULL) {
|
||||
|
|
@ -241,11 +197,13 @@ static int impl_node_set_param(struct spa_node *node, uint32_t id, uint32_t flag
|
|||
return 0;
|
||||
}
|
||||
spa_pod_object_parse(param,
|
||||
":", t->prop_volume, "?d", &p->volume,
|
||||
":", t->prop_mute, "?b", &p->mute, NULL);
|
||||
":", SPA_PROP_volume, "?d", &p->volume,
|
||||
":", SPA_PROP_mute, "?b", &p->mute, NULL);
|
||||
break;
|
||||
}
|
||||
else
|
||||
default:
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -259,13 +217,16 @@ static int impl_node_send_command(struct spa_node *node, const struct spa_comman
|
|||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
|
||||
if (SPA_COMMAND_TYPE(command) == this->type.command_node.Start) {
|
||||
switch (SPA_COMMAND_TYPE(command)) {
|
||||
case SPA_ID_COMMAND_NODE_Start:
|
||||
this->started = true;
|
||||
} else if (SPA_COMMAND_TYPE(command) == this->type.command_node.Pause) {
|
||||
break;
|
||||
case SPA_ID_COMMAND_NODE_Pause:
|
||||
this->started = false;
|
||||
} else
|
||||
break;
|
||||
default:
|
||||
return -ENOTSUP;
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -365,21 +326,18 @@ static int port_enum_formats(struct spa_node *node,
|
|||
struct spa_pod **param,
|
||||
struct spa_pod_builder *builder)
|
||||
{
|
||||
struct impl *this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
struct type *t = &this->type;
|
||||
|
||||
switch (*index) {
|
||||
case 0:
|
||||
*param = spa_pod_builder_object(builder,
|
||||
t->param.idEnumFormat, t->format,
|
||||
"I", t->media_type.audio,
|
||||
"I", t->media_subtype.raw,
|
||||
":", t->format_audio.format, "Ieu", t->audio_format.S16,
|
||||
SPA_POD_PROP_ENUM(2, t->audio_format.S16,
|
||||
t->audio_format.S32),
|
||||
":", t->format_audio.rate, "iru", 44100,
|
||||
SPA_ID_PARAM_EnumFormat, SPA_ID_OBJECT_Format,
|
||||
"I", SPA_MEDIA_TYPE_audio,
|
||||
"I", SPA_MEDIA_SUBTYPE_raw,
|
||||
":", SPA_FORMAT_AUDIO_format, "Ieu", SPA_AUDIO_FORMAT_S16,
|
||||
SPA_POD_PROP_ENUM(2, SPA_AUDIO_FORMAT_S16,
|
||||
SPA_AUDIO_FORMAT_S32),
|
||||
":", SPA_FORMAT_AUDIO_rate, "iru", 44100,
|
||||
SPA_POD_PROP_MIN_MAX(1, INT32_MAX),
|
||||
":", t->format_audio.channels,"iru", 2,
|
||||
":", SPA_FORMAT_AUDIO_channels,"iru", 2,
|
||||
SPA_POD_PROP_MIN_MAX(1, INT32_MAX));
|
||||
break;
|
||||
default:
|
||||
|
|
@ -397,7 +355,6 @@ static int port_get_format(struct spa_node *node,
|
|||
{
|
||||
struct impl *this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
struct port *port;
|
||||
struct type *t = &this->type;
|
||||
|
||||
port = GET_PORT(this, direction, port_id);
|
||||
|
||||
|
|
@ -407,12 +364,12 @@ static int port_get_format(struct spa_node *node,
|
|||
return 0;
|
||||
|
||||
*param = spa_pod_builder_object(builder,
|
||||
t->param.idFormat, t->format,
|
||||
"I", t->media_type.audio,
|
||||
"I", t->media_subtype.raw,
|
||||
":", t->format_audio.format, "I", this->current_format.info.raw.format,
|
||||
":", t->format_audio.rate, "i", this->current_format.info.raw.rate,
|
||||
":", t->format_audio.channels, "i", this->current_format.info.raw.channels);
|
||||
SPA_ID_PARAM_Format, SPA_ID_OBJECT_Format,
|
||||
"I", SPA_MEDIA_TYPE_audio,
|
||||
"I", SPA_MEDIA_SUBTYPE_raw,
|
||||
":", SPA_FORMAT_AUDIO_format, "I", this->current_format.info.raw.format,
|
||||
":", SPA_FORMAT_AUDIO_rate, "i", this->current_format.info.raw.rate,
|
||||
":", SPA_FORMAT_AUDIO_channels, "i", this->current_format.info.raw.channels);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -426,7 +383,6 @@ impl_node_port_enum_params(struct spa_node *node,
|
|||
struct spa_pod_builder *builder)
|
||||
{
|
||||
struct impl *this;
|
||||
struct type *t;
|
||||
struct port *port;
|
||||
struct spa_pod_builder b = { 0 };
|
||||
uint8_t buffer[1024];
|
||||
|
|
@ -438,7 +394,6 @@ impl_node_port_enum_params(struct spa_node *node,
|
|||
spa_return_val_if_fail(builder != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
t = &this->type;
|
||||
|
||||
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
|
||||
|
||||
|
|
@ -447,81 +402,79 @@ impl_node_port_enum_params(struct spa_node *node,
|
|||
next:
|
||||
spa_pod_builder_init(&b, buffer, sizeof(buffer));
|
||||
|
||||
if (id == t->param.idList) {
|
||||
uint32_t list[] = { t->param.idEnumFormat,
|
||||
t->param.idFormat,
|
||||
t->param.idBuffers,
|
||||
t->param.idMeta,
|
||||
t->param_io.idBuffers,
|
||||
t->param_io.idControl };
|
||||
switch (id) {
|
||||
case SPA_ID_PARAM_List:
|
||||
{
|
||||
uint32_t list[] = { SPA_ID_PARAM_EnumFormat,
|
||||
SPA_ID_PARAM_Format,
|
||||
SPA_ID_PARAM_Buffers,
|
||||
SPA_ID_PARAM_Meta,
|
||||
SPA_ID_PARAM_IO };
|
||||
|
||||
if (*index < SPA_N_ELEMENTS(list))
|
||||
param = spa_pod_builder_object(&b, id, t->param.List,
|
||||
":", t->param.listId, "I", list[*index]);
|
||||
param = spa_pod_builder_object(&b, id, SPA_ID_OBJECT_ParamList,
|
||||
":", SPA_PARAM_LIST_id, "I", list[*index]);
|
||||
else
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
else if (id == t->param.idEnumFormat) {
|
||||
case SPA_ID_PARAM_EnumFormat:
|
||||
if ((res = port_enum_formats(node, direction, port_id, index, filter, ¶m, &b)) <= 0)
|
||||
return res;
|
||||
}
|
||||
else if (id == t->param.idFormat) {
|
||||
break;
|
||||
case SPA_ID_PARAM_Format:
|
||||
if ((res = port_get_format(node, direction, port_id, index, filter, ¶m, &b)) <= 0)
|
||||
return res;
|
||||
}
|
||||
else if (id == t->param.idBuffers) {
|
||||
break;
|
||||
case SPA_ID_PARAM_Buffers:
|
||||
if (!port->have_format)
|
||||
return -EIO;
|
||||
if (*index > 0)
|
||||
return 0;
|
||||
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param_buffers.Buffers,
|
||||
":", t->param_buffers.size, "iru", 1024 * this->bpf,
|
||||
SPA_POD_PROP_MIN_MAX(16 * this->bpf, INT32_MAX / this->bpf),
|
||||
":", t->param_buffers.stride, "i", 0,
|
||||
":", t->param_buffers.buffers, "iru", 2,
|
||||
id, SPA_ID_OBJECT_ParamBuffers,
|
||||
":", SPA_PARAM_BUFFERS_buffers, "iru", 2,
|
||||
SPA_POD_PROP_MIN_MAX(1, MAX_BUFFERS),
|
||||
":", t->param_buffers.align, "i", 16);
|
||||
}
|
||||
else if (id == t->param.idMeta) {
|
||||
":", SPA_PARAM_BUFFERS_blocks, "i", 1,
|
||||
":", SPA_PARAM_BUFFERS_size, "iru", 1024 * this->bpf,
|
||||
SPA_POD_PROP_MIN_MAX(16 * this->bpf, INT32_MAX / this->bpf),
|
||||
":", SPA_PARAM_BUFFERS_stride, "i", 0,
|
||||
":", SPA_PARAM_BUFFERS_align, "i", 16);
|
||||
break;
|
||||
case SPA_ID_PARAM_Meta:
|
||||
switch (*index) {
|
||||
case 0:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param_meta.Meta,
|
||||
":", t->param_meta.type, "I", t->meta.Header,
|
||||
":", t->param_meta.size, "i", sizeof(struct spa_meta_header));
|
||||
id, SPA_ID_OBJECT_ParamMeta,
|
||||
":", SPA_PARAM_META_type, "I", SPA_META_Header,
|
||||
":", SPA_PARAM_META_size, "i", sizeof(struct spa_meta_header));
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if (id == t->param_io.idBuffers) {
|
||||
break;
|
||||
case SPA_ID_PARAM_IO:
|
||||
switch (*index) {
|
||||
case 0:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param_io.Buffers,
|
||||
":", t->param_io.id, "I", t->io.Buffers,
|
||||
":", t->param_io.size, "i", sizeof(struct spa_io_buffers));
|
||||
id, SPA_ID_OBJECT_ParamIO,
|
||||
":", SPA_PARAM_IO_id, "I", SPA_ID_IO_Buffers,
|
||||
":", SPA_PARAM_IO_size, "i", sizeof(struct spa_io_buffers));
|
||||
break;
|
||||
case 1:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, SPA_ID_OBJECT_ParamIO,
|
||||
":", SPA_PARAM_IO_id, "I", SPA_ID_IO_ControlRange,
|
||||
":", SPA_PARAM_IO_size, "i", sizeof(struct spa_io_control_range));
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if (id == t->param_io.idControl) {
|
||||
switch (*index) {
|
||||
case 0:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param_io.Control,
|
||||
":", t->param_io.id, "I", t->io.ControlRange,
|
||||
":", t->param_io.size, "i", sizeof(struct spa_io_control_range));
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
break;
|
||||
default:
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
(*index)++;
|
||||
|
||||
|
|
@ -561,11 +514,11 @@ static int port_set_format(struct spa_node *node,
|
|||
"I", &info.media_type,
|
||||
"I", &info.media_subtype);
|
||||
|
||||
if (info.media_type != this->type.media_type.audio ||
|
||||
info.media_subtype != this->type.media_subtype.raw)
|
||||
if (info.media_type != SPA_MEDIA_TYPE_audio ||
|
||||
info.media_subtype != SPA_MEDIA_SUBTYPE_raw)
|
||||
return -EINVAL;
|
||||
|
||||
if (spa_format_audio_raw_parse(format, &info.info.raw, &this->type.format_audio) < 0)
|
||||
if (spa_format_audio_raw_parse(format, &info.info.raw) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
this->bpf = 2 * info.info.raw.channels;
|
||||
|
|
@ -582,17 +535,11 @@ impl_node_port_set_param(struct spa_node *node,
|
|||
uint32_t id, uint32_t flags,
|
||||
const struct spa_pod *param)
|
||||
{
|
||||
struct impl *this;
|
||||
struct type *t;
|
||||
|
||||
spa_return_val_if_fail(node != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
t = &this->type;
|
||||
spa_return_val_if_fail(CHECK_PORT(node, direction, port_id), -EINVAL);
|
||||
|
||||
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
|
||||
|
||||
if (id == t->param.idFormat) {
|
||||
if (id == SPA_ID_PARAM_Format) {
|
||||
return port_set_format(node, direction, port_id, flags, param);
|
||||
}
|
||||
else
|
||||
|
|
@ -609,7 +556,6 @@ impl_node_port_use_buffers(struct spa_node *node,
|
|||
struct impl *this;
|
||||
struct port *port;
|
||||
uint32_t i;
|
||||
struct type *t;
|
||||
|
||||
spa_return_val_if_fail(node != NULL, -EINVAL);
|
||||
|
||||
|
|
@ -622,8 +568,6 @@ impl_node_port_use_buffers(struct spa_node *node,
|
|||
if (!port->have_format)
|
||||
return -EIO;
|
||||
|
||||
t = &this->type;
|
||||
|
||||
clear_buffers(this, port);
|
||||
|
||||
for (i = 0; i < n_buffers; i++) {
|
||||
|
|
@ -633,11 +577,11 @@ impl_node_port_use_buffers(struct spa_node *node,
|
|||
b = &port->buffers[i];
|
||||
b->outbuf = buffers[i];
|
||||
b->outstanding = direction == SPA_DIRECTION_INPUT;
|
||||
b->h = spa_buffer_find_meta_data(buffers[i], t->meta.Header, sizeof(*b->h));
|
||||
b->h = spa_buffer_find_meta_data(buffers[i], SPA_META_Header, sizeof(*b->h));
|
||||
|
||||
if ((d[0].type == t->data.MemPtr ||
|
||||
d[0].type == t->data.MemFd ||
|
||||
d[0].type == t->data.DmaBuf) && d[0].data != NULL) {
|
||||
if ((d[0].type == SPA_DATA_MemPtr ||
|
||||
d[0].type == SPA_DATA_MemFd ||
|
||||
d[0].type == SPA_DATA_DmaBuf) && d[0].data != NULL) {
|
||||
b->ptr = d[0].data;
|
||||
b->size = d[0].maxsize;
|
||||
} else {
|
||||
|
|
@ -674,20 +618,18 @@ impl_node_port_set_io(struct spa_node *node,
|
|||
{
|
||||
struct impl *this;
|
||||
struct port *port;
|
||||
struct type *t;
|
||||
|
||||
spa_return_val_if_fail(node != NULL, -EINVAL);
|
||||
|
||||
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||
t = &this->type;
|
||||
|
||||
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
|
||||
|
||||
port = GET_PORT(this, direction, port_id);
|
||||
|
||||
if (id == t->io.Buffers)
|
||||
if (id == SPA_ID_IO_Buffers)
|
||||
port->io = data;
|
||||
else if (id == t->io.ControlRange)
|
||||
else if (id == SPA_ID_IO_ControlRange)
|
||||
port->range = data;
|
||||
else
|
||||
return -ENOENT;
|
||||
|
|
@ -888,7 +830,7 @@ static int impl_get_interface(struct spa_handle *handle, uint32_t interface_id,
|
|||
|
||||
this = (struct impl *) handle;
|
||||
|
||||
if (interface_id == this->type.node)
|
||||
if (interface_id == SPA_ID_INTERFACE_Node)
|
||||
*interface = &this->node;
|
||||
else
|
||||
return -ENOENT;
|
||||
|
|
@ -927,16 +869,9 @@ impl_init(const struct spa_handle_factory *factory,
|
|||
this = (struct impl *) handle;
|
||||
|
||||
for (i = 0; i < n_support; i++) {
|
||||
if (strcmp(support[i].type, SPA_TYPE__TypeMap) == 0)
|
||||
this->map = support[i].data;
|
||||
else if (strcmp(support[i].type, SPA_TYPE__Log) == 0)
|
||||
if (support[i].type == SPA_ID_INTERFACE_Log)
|
||||
this->log = support[i].data;
|
||||
}
|
||||
if (this->map == NULL) {
|
||||
spa_log_error(this->log, "a type-map is needed");
|
||||
return -EINVAL;
|
||||
}
|
||||
init_type(&this->type, this->map);
|
||||
|
||||
this->node = impl_node;
|
||||
reset_props(&this->props);
|
||||
|
|
@ -953,7 +888,7 @@ impl_init(const struct spa_handle_factory *factory,
|
|||
}
|
||||
|
||||
static const struct spa_interface_info impl_interfaces[] = {
|
||||
{SPA_TYPE__Node,},
|
||||
{SPA_ID_INTERFACE_Node,},
|
||||
};
|
||||
|
||||
static int
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue