Add set_active method on node

Require that nodes need to be activated before they are scheduled.
Make method to activate remote node.
Add method to pause/resume stream.
This commit is contained in:
Wim Taymans 2017-10-13 16:18:42 +02:00
parent acfdc63f26
commit d96d40e30a
19 changed files with 135 additions and 46 deletions

View file

@ -896,6 +896,12 @@ client_node_port_update(void *data,
}
}
static void client_node_set_active(void *data, bool active)
{
struct impl *impl = data;
pw_node_set_active(impl->this.node, active);
}
static void client_node_event(void *data, struct spa_event *event)
{
struct impl *impl = data;
@ -914,6 +920,7 @@ static struct pw_client_node_proxy_methods client_node_methods = {
.done = client_node_done,
.update = client_node_update,
.port_update = client_node_port_update,
.set_active = client_node_set_active,
.event = client_node_event,
.destroy = client_node_destroy,
};
@ -1164,7 +1171,7 @@ struct pw_client_node *pw_client_node_new(struct pw_resource *resource,
pw_resource_get_client(this->resource),
NULL,
name,
true,
PW_SPA_NODE_FLAG_ASYNC,
&impl->proxy.node,
NULL,
properties, 0);

View file

@ -113,6 +113,18 @@ client_node_marshal_port_update(void *object,
pw_protocol_native_end_proxy(proxy, b);
}
static void client_node_marshal_set_active(void *object, bool active)
{
struct pw_proxy *proxy = object;
struct spa_pod_builder *b;
b = pw_protocol_native_begin_proxy(proxy, PW_CLIENT_NODE_PROXY_METHOD_SET_ACTIVE);
spa_pod_builder_struct(b, "b", active);
pw_protocol_native_end_proxy(proxy, b);
}
static void client_node_marshal_event_method(void *object, struct spa_event *event)
{
struct pw_proxy *proxy = object;
@ -749,6 +761,22 @@ static bool client_node_demarshal_port_update(void *object, void *data, size_t s
return true;
}
static bool client_node_demarshal_set_active(void *object, void *data, size_t size)
{
struct pw_resource *resource = object;
struct spa_pod_parser prs;
bool active;
spa_pod_parser_init(&prs, data, size, 0);
if (spa_pod_parser_get(&prs,
"["
"b", &active, NULL) < 0)
return false;
pw_resource_do(resource, struct pw_client_node_proxy_methods, set_active, active);
return true;
}
static bool client_node_demarshal_event_method(void *object, void *data, size_t size)
{
struct pw_resource *resource = object;
@ -783,6 +811,7 @@ static const struct pw_client_node_proxy_methods pw_protocol_native_client_node_
&client_node_marshal_done,
&client_node_marshal_update,
&client_node_marshal_port_update,
&client_node_marshal_set_active,
&client_node_marshal_event_method,
&client_node_marshal_destroy
};
@ -791,6 +820,7 @@ static const struct pw_protocol_native_demarshal pw_protocol_native_client_node_
{ &client_node_demarshal_done, 0 },
{ &client_node_demarshal_update, PW_PROTOCOL_NATIVE_REMAP },
{ &client_node_demarshal_port_update, PW_PROTOCOL_NATIVE_REMAP },
{ &client_node_demarshal_set_active, 0 },
{ &client_node_demarshal_event_method, PW_PROTOCOL_NATIVE_REMAP },
{ &client_node_demarshal_destroy, 0 },
};

View file

@ -94,7 +94,6 @@ static struct pw_node *make_node(struct impl *impl)
int res;
void *iface;
struct spa_node *spa_node;
struct spa_clock *spa_clock;
struct pw_node *node;
const struct spa_support *support;
uint32_t n_support;
@ -114,13 +113,8 @@ static struct pw_node *make_node(struct impl *impl)
}
spa_node = iface;
if ((res = spa_handle_get_interface(handle, impl->t->spa_clock, &iface)) < 0) {
iface = NULL;
}
spa_clock = iface;
node = pw_spa_node_new(impl->core, NULL, pw_module_get_global(impl->module),
"audiomixer", false, spa_node, spa_clock, NULL, 0);
"audiomixer", PW_SPA_NODE_FLAG_ACTIVATE, spa_node, handle, NULL, 0);
return node;

View file

@ -67,6 +67,7 @@ static void *create_object(void *_data,
lib,
factory_name,
name,
0,
properties, 0);
if (node == NULL)
goto no_mem;

View file

@ -65,6 +65,7 @@ bool pipewire__module_init(struct pw_module *module, const char *args)
NULL,
pw_module_get_global(module),
argv[0], argv[1], argv[2],
PW_SPA_NODE_FLAG_ACTIVATE,
props, 0);
pw_free_strv(argv);

View file

@ -64,7 +64,6 @@ static void add_item(struct pw_spa_monitor *this, struct spa_monitor_item *item)
struct spa_handle *handle;
struct monitor_item *mitem;
void *node_iface;
void *clock_iface;
struct pw_properties *props = NULL;
const char *name, *id, *klass;
struct spa_handle_factory *factory;
@ -114,17 +113,13 @@ static void add_item(struct pw_spa_monitor *this, struct spa_monitor_item *item)
pw_log_error("can't get NODE interface: %d", res);
return;
}
if ((res = spa_handle_get_interface(handle, t->spa_clock, &clock_iface)) < 0) {
pw_log_info("no CLOCK interface: %d", res);
clock_iface = NULL;
}
mitem = calloc(1, sizeof(struct monitor_item));
mitem->id = strdup(id);
mitem->handle = handle;
mitem->node = pw_spa_node_new(impl->core, NULL, impl->parent, name,
false, node_iface, clock_iface, props, 0);
PW_SPA_NODE_FLAG_ACTIVATE,
node_iface, handle, props, 0);
spa_list_append(&impl->item_list, &mitem->link);
}

View file

@ -40,6 +40,7 @@ struct impl {
struct pw_client *owner;
struct pw_global *parent;
enum pw_spa_node_flags flags;
bool async_init;
void *hnd;
@ -72,7 +73,8 @@ static void complete_init(struct impl *impl)
{
struct pw_node *this = impl->this;
pw_node_register(this, impl->owner, impl->parent);
pw_node_set_active(this, true);
if (impl->flags & PW_SPA_NODE_FLAG_ACTIVATE)
pw_node_set_active(this, true);
}
static void on_node_done(void *data, uint32_t seq, int res)
@ -98,32 +100,40 @@ pw_spa_node_new(struct pw_core *core,
struct pw_client *owner,
struct pw_global *parent,
const char *name,
bool async,
enum pw_spa_node_flags flags,
struct spa_node *node,
struct spa_clock *clock,
struct spa_handle *handle,
struct pw_properties *properties,
size_t user_data_size)
{
struct pw_node *this;
struct impl *impl;
void *iface = NULL;
struct pw_type *t = pw_core_get_type(core);
int res;
this = pw_node_new(core, name, properties, sizeof(struct impl) + user_data_size);
if (this == NULL)
return NULL;
this->clock = clock;
if (handle) {
if ((res = spa_handle_get_interface(handle, t->spa_clock, &iface)) < 0)
iface = NULL;
this->clock = iface;
}
impl = this->user_data;
impl->this = this;
impl->owner = owner;
impl->parent = parent;
impl->node = node;
impl->async_init = async;
impl->flags = flags;
impl->async_init = flags & PW_SPA_NODE_FLAG_ASYNC;
pw_node_add_listener(this, &impl->node_listener, &node_events, impl);
pw_node_set_implementation(this, impl->node);
if (!async)
if (!impl->async_init)
complete_init(impl);
return this;
@ -198,13 +208,13 @@ struct pw_node *pw_spa_node_load(struct pw_core *core,
const char *lib,
const char *factory_name,
const char *name,
enum pw_spa_node_flags flags,
struct pw_properties *properties,
size_t user_data_size)
{
struct pw_node *this;
struct impl *impl;
struct spa_node *spa_node;
struct spa_clock *spa_clock;
int res;
struct spa_handle *handle;
void *hnd;
@ -214,7 +224,6 @@ struct pw_node *pw_spa_node_load(struct pw_core *core,
void *iface;
char *filename;
const char *dir;
bool async;
const struct spa_support *support;
uint32_t n_support;
struct pw_type *t = pw_core_get_type(core);
@ -251,7 +260,8 @@ struct pw_node *pw_spa_node_load(struct pw_core *core,
pw_log_error("can't make factory instance: %d", res);
goto init_failed;
}
async = SPA_RESULT_IS_ASYNC(res);
if (SPA_RESULT_IS_ASYNC(res))
flags |= PW_SPA_NODE_FLAG_ASYNC;
if ((res = spa_handle_get_interface(handle, t->spa_node, &iface)) < 0) {
pw_log_error("can't get node interface %d", res);
@ -259,19 +269,14 @@ struct pw_node *pw_spa_node_load(struct pw_core *core,
}
spa_node = iface;
if ((res = spa_handle_get_interface(handle, t->spa_clock, &iface)) < 0) {
iface = NULL;
}
spa_clock = iface;
if (properties != NULL) {
if (setup_props(core, spa_node, properties) != SPA_RESULT_OK) {
pw_log_debug("Unrecognized properties");
}
}
this = pw_spa_node_new(core, owner, parent, name, async,
spa_node, spa_clock, properties, user_data_size);
this = pw_spa_node_new(core, owner, parent, name, flags,
spa_node, handle, properties, user_data_size);
impl = this->user_data;
impl->hnd = hnd;

View file

@ -30,14 +30,19 @@
extern "C" {
#endif
enum pw_spa_node_flags {
PW_SPA_NODE_FLAG_ASYNC = (1 << 0),
PW_SPA_NODE_FLAG_ACTIVATE = (1 << 1),
};
struct pw_node *
pw_spa_node_new(struct pw_core *core,
struct pw_client *owner, /**< optional owner */
struct pw_global *parent, /**< optional parent */
const char *name,
bool async,
enum pw_spa_node_flags flags,
struct spa_node *node,
struct spa_clock *clock,
struct spa_handle *handle,
struct pw_properties *properties,
size_t user_data_size);
@ -48,6 +53,7 @@ pw_spa_node_load(struct pw_core *core,
const char *lib,
const char *factory_name,
const char *name,
enum pw_spa_node_flags flags,
struct pw_properties *properties,
size_t user_data_size);