mirror of
https://gitlab.freedesktop.org/pipewire/wireplumber.git
synced 2026-02-04 10:50:28 +01:00
object-manager: replace GPtrArray API with WpIterator
+ add the useful _find_proxy() method
This commit is contained in:
parent
fbddccd5bf
commit
1dccdcf415
11 changed files with 304 additions and 173 deletions
|
|
@ -579,50 +579,41 @@ wp_endpoint_get_n_streams (WpEndpoint * self)
|
|||
}
|
||||
|
||||
/**
|
||||
* wp_endpoint_get_stream:
|
||||
* wp_endpoint_find_stream:
|
||||
* @self: the endpoint
|
||||
* @bound_id: the bound id of the stream object to get
|
||||
* @bound_id: the bound id of the stream object to find
|
||||
*
|
||||
* Returns: (transfer full) (nullable): the endpoint stream that has the given
|
||||
* @bound_id, or %NULL if there is no such stream
|
||||
*/
|
||||
WpEndpointStream *
|
||||
wp_endpoint_get_stream (WpEndpoint * self, guint32 bound_id)
|
||||
wp_endpoint_find_stream (WpEndpoint * self, guint32 bound_id)
|
||||
{
|
||||
g_return_val_if_fail (WP_IS_ENDPOINT (self), NULL);
|
||||
g_return_val_if_fail (wp_proxy_get_features (WP_PROXY (self)) &
|
||||
WP_ENDPOINT_FEATURE_STREAMS, NULL);
|
||||
|
||||
WpEndpointPrivate *priv = wp_endpoint_get_instance_private (self);
|
||||
g_autoptr (GPtrArray) streams =
|
||||
wp_object_manager_get_objects (priv->streams_om, 0);
|
||||
|
||||
for (guint i = 0; i < streams->len; i++) {
|
||||
gpointer proxy = g_ptr_array_index (streams, i);
|
||||
g_return_val_if_fail (WP_IS_ENDPOINT_STREAM (proxy), NULL);
|
||||
|
||||
if (wp_proxy_get_bound_id (WP_PROXY (proxy)) == bound_id)
|
||||
return WP_ENDPOINT_STREAM (g_object_ref (proxy));
|
||||
}
|
||||
return NULL;
|
||||
return (WpEndpointStream *)
|
||||
wp_object_manager_find_proxy (priv->streams_om, bound_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* wp_endpoint_get_all_streams:
|
||||
* wp_endpoint_iterate_streams:
|
||||
* @self: the endpoint
|
||||
*
|
||||
* Returns: (transfer full) (element-type WpEndpointStream): array with all
|
||||
* Returns: (transfer full): a #WpIterator that iterates over all
|
||||
* the endpoint streams that belong to this endpoint
|
||||
*/
|
||||
GPtrArray *
|
||||
wp_endpoint_get_all_streams (WpEndpoint * self)
|
||||
WpIterator *
|
||||
wp_endpoint_iterate_streams (WpEndpoint * self)
|
||||
{
|
||||
g_return_val_if_fail (WP_IS_ENDPOINT (self), NULL);
|
||||
g_return_val_if_fail (wp_proxy_get_features (WP_PROXY (self)) &
|
||||
WP_ENDPOINT_FEATURE_STREAMS, NULL);
|
||||
|
||||
WpEndpointPrivate *priv = wp_endpoint_get_instance_private (self);
|
||||
return wp_object_manager_get_objects (priv->streams_om, 0);
|
||||
return wp_object_manager_iterate (priv->streams_om);
|
||||
}
|
||||
|
||||
/* WpImplEndpoint */
|
||||
|
|
@ -864,18 +855,20 @@ impl_create_link (void *object, const struct spa_dict *props)
|
|||
g_autoptr (WpEndpoint) peer_ep_proxy = NULL;
|
||||
g_autoptr (WpEndpointStream) peer_stream_proxy = NULL;
|
||||
|
||||
peer_ep_proxy = wp_session_get_endpoint (session, peer_ep_id);
|
||||
peer_ep_proxy = wp_session_find_endpoint (session, peer_ep_id);
|
||||
if (!peer_ep_proxy) {
|
||||
wp_warning_object (self, "endpoint %d not found in session", peer_ep_id);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (peer_stream_id != SPA_ID_INVALID) {
|
||||
peer_stream_proxy = wp_endpoint_get_stream (peer_ep_proxy, peer_stream_id);
|
||||
peer_stream_proxy = wp_endpoint_find_stream (peer_ep_proxy,
|
||||
peer_stream_id);
|
||||
} else {
|
||||
g_autoptr (GPtrArray) s = wp_endpoint_get_all_streams (peer_ep_proxy);
|
||||
peer_stream_proxy = (s->len > 0) ?
|
||||
g_object_ref (g_ptr_array_index (s, 0)) : NULL;
|
||||
g_autoptr (WpIterator) it = wp_endpoint_iterate_streams (peer_ep_proxy);
|
||||
g_auto (GValue) val = G_VALUE_INIT;
|
||||
if (wp_iterator_next (it, &val))
|
||||
peer_stream_proxy = g_value_dup_object (&val);
|
||||
}
|
||||
|
||||
if (!peer_stream_proxy) {
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
#include "proxy.h"
|
||||
#include "endpoint-stream.h"
|
||||
#include "iterator.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
|
@ -44,8 +45,8 @@ typedef enum {
|
|||
* wp_endpoint_get_control() and wp_endpoint_set_control() families of
|
||||
* functions to be able to work with endpoint-specific controls
|
||||
* @WP_ENDPOINT_FEATURE_STREAMS: caches information about streams, enabling
|
||||
* the use of wp_endpoint_get_n_streams(), wp_endpoint_get_stream() and
|
||||
* wp_endpoint_get_all_streams()
|
||||
* the use of wp_endpoint_get_n_streams(), wp_endpoint_find_stream() and
|
||||
* wp_endpoint_iterate_streams()
|
||||
*
|
||||
* An extension of #WpProxyFeatures
|
||||
*/
|
||||
|
|
@ -132,10 +133,10 @@ WP_API
|
|||
guint wp_endpoint_get_n_streams (WpEndpoint * self);
|
||||
|
||||
WP_API
|
||||
WpEndpointStream * wp_endpoint_get_stream (WpEndpoint * self, guint32 bound_id);
|
||||
WpEndpointStream * wp_endpoint_find_stream (WpEndpoint * self, guint32 bound_id);
|
||||
|
||||
WP_API
|
||||
GPtrArray * wp_endpoint_get_all_streams (WpEndpoint * self);
|
||||
WpIterator * wp_endpoint_iterate_streams (WpEndpoint * self);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
|
|
|||
|
|
@ -149,8 +149,8 @@ wp_iterator_next (WpIterator *self, GValue *item)
|
|||
* wp_iterator_fold:
|
||||
* @self: the iterator
|
||||
* @func: (scope call): the fold function
|
||||
* @ret: the accumulator data
|
||||
* @data: the user data
|
||||
* @ret: (inout): the accumulator data
|
||||
* @data: (closure): the user data
|
||||
*
|
||||
* Iterates over all items of the iterator calling a function.
|
||||
*
|
||||
|
|
@ -172,7 +172,7 @@ wp_iterator_fold (WpIterator *self, WpIteratorFoldFunc func, GValue *ret,
|
|||
* wp_iterator_foreach:
|
||||
* @self: the iterator
|
||||
* @func: (scope call): the foreach function
|
||||
* @data: the user data
|
||||
* @data: (closure): the user data
|
||||
*
|
||||
* Fold a function over the items of the iterator.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@
|
|||
*
|
||||
* Upon installing a #WpObjectManager on a #WpCore, any pre-existing objects
|
||||
* that match the interests of this #WpObjectManager will immediately become
|
||||
* available to get through wp_object_manager_get_objects() and the
|
||||
* available to get through wp_object_manager_iterate() and the
|
||||
* #WpObjectManager::object-added signal will be emitted for all of them.
|
||||
*/
|
||||
|
||||
|
|
@ -192,7 +192,7 @@ wp_object_manager_class_init (WpObjectManagerClass * klass)
|
|||
* from this object manager. This signal is useful to get notified only once
|
||||
* when multiple changes happen in a short timespan. The receiving callback
|
||||
* may retrieve the updated list of objects by calling
|
||||
* wp_object_manager_get_objects()
|
||||
* wp_object_manager_iterate()
|
||||
*/
|
||||
signals[SIGNAL_OBJECTS_CHANGED] = g_signal_new (
|
||||
"objects-changed", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_FIRST,
|
||||
|
|
@ -239,7 +239,7 @@ wp_object_manager_new (void)
|
|||
* wp_object_manager_add_interest (om, WP_TYPE_NODE, NULL,
|
||||
* WP_PROXY_FEATURES_STANDARD);
|
||||
* wp_core_install_object_manager (core, om);
|
||||
* GPtrArray *nodes = wp_object_manager_get_objects (om, 0);
|
||||
* WpIterator *nodes_it = wp_object_manager_iterate (om);
|
||||
* ]|
|
||||
*
|
||||
* and to discover all 'port' objects that belong to a specific 'node':
|
||||
|
|
@ -262,7 +262,7 @@ wp_object_manager_new (void)
|
|||
* WP_PROXY_FEATURES_STANDARD);
|
||||
*
|
||||
* wp_core_install_object_manager (core, om);
|
||||
* GPtrArray *ports = wp_object_manager_get_objects (om, 0);
|
||||
* WpIterator *ports_it = wp_object_manager_iterate (om);
|
||||
* ]|
|
||||
*/
|
||||
void
|
||||
|
|
@ -296,29 +296,125 @@ wp_object_manager_get_n_objects (WpObjectManager * self)
|
|||
return self->objects->len;
|
||||
}
|
||||
|
||||
/**
|
||||
* wp_object_manager_get_objects:
|
||||
* @self: the object manager
|
||||
* @type_filter: a #GType filter to get only the objects that are of this type,
|
||||
* or 0 ( %G_TYPE_INVALID ) to return all the objects
|
||||
*
|
||||
* Returns: (transfer full) (element-type GObject*): all the objects managed
|
||||
* by this #WpObjectManager that match the @type_filter
|
||||
*/
|
||||
GPtrArray *
|
||||
wp_object_manager_get_objects (WpObjectManager *self, GType type_filter)
|
||||
struct om_iterator_data
|
||||
{
|
||||
GPtrArray *result = g_ptr_array_new_with_free_func (g_object_unref);
|
||||
guint i;
|
||||
WpObjectManager *om;
|
||||
guint index;
|
||||
};
|
||||
|
||||
for (i = 0; i < self->objects->len; i++) {
|
||||
gpointer obj = g_ptr_array_index (self->objects, i);
|
||||
if (type_filter == 0 || g_type_is_a (G_OBJECT_TYPE (obj), type_filter)) {
|
||||
g_ptr_array_add (result, g_object_ref (obj));
|
||||
}
|
||||
static void
|
||||
om_iterator_reset (WpIterator *it)
|
||||
{
|
||||
struct om_iterator_data *it_data = wp_iterator_get_user_data (it);
|
||||
it_data->index = 0;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
om_iterator_next (WpIterator *it, GValue *item)
|
||||
{
|
||||
struct om_iterator_data *it_data = wp_iterator_get_user_data (it);
|
||||
GPtrArray *objects = it_data->om->objects;
|
||||
|
||||
if (G_LIKELY (it_data->index < objects->len)) {
|
||||
g_value_init_from_instance (item,
|
||||
g_ptr_array_index (objects, it_data->index++));
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
om_iterator_fold (WpIterator *it, WpIteratorFoldFunc func, GValue *ret,
|
||||
gpointer data)
|
||||
{
|
||||
struct om_iterator_data *it_data = wp_iterator_get_user_data (it);
|
||||
gpointer *obj, *base;
|
||||
guint len;
|
||||
|
||||
obj = base = it_data->om->objects->pdata;
|
||||
len = it_data->om->objects->len;
|
||||
|
||||
while ((obj - base) < len) {
|
||||
g_auto (GValue) item = G_VALUE_INIT;
|
||||
g_value_init_from_instance (&item, *obj);
|
||||
if (!func (&item, ret, data))
|
||||
return FALSE;
|
||||
obj++;
|
||||
}
|
||||
|
||||
return result;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
om_iterator_finalize (WpIterator *it)
|
||||
{
|
||||
struct om_iterator_data *it_data = wp_iterator_get_user_data (it);
|
||||
g_object_unref (it_data->om);
|
||||
}
|
||||
|
||||
static const WpIteratorMethods om_iterator_methods = {
|
||||
.reset = om_iterator_reset,
|
||||
.next = om_iterator_next,
|
||||
.fold = om_iterator_fold,
|
||||
.finalize = om_iterator_finalize,
|
||||
};
|
||||
|
||||
/**
|
||||
* wp_object_manager_iterate:
|
||||
* @self: the object manager
|
||||
*
|
||||
* Returns: (transfer full): a #WpIterator that iterates over all the managed
|
||||
* objects of this object manager
|
||||
*/
|
||||
WpIterator *
|
||||
wp_object_manager_iterate (WpObjectManager * self)
|
||||
{
|
||||
WpIterator *it;
|
||||
struct om_iterator_data *it_data;
|
||||
|
||||
g_return_val_if_fail (WP_IS_OBJECT_MANAGER (self), NULL);
|
||||
|
||||
it = wp_iterator_new (&om_iterator_methods, sizeof (struct om_iterator_data));
|
||||
it_data = wp_iterator_get_user_data (it);
|
||||
it_data->om = g_object_ref (self);
|
||||
it_data->index = 0;
|
||||
return it;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
find_proxy_fold_func (const GValue *item, GValue *ret, gpointer data)
|
||||
{
|
||||
if (g_type_is_a (G_VALUE_TYPE (item), WP_TYPE_PROXY)) {
|
||||
WpProxy *proxy = g_value_get_object (item);
|
||||
if (wp_proxy_get_bound_id (proxy) == GPOINTER_TO_UINT (data)) {
|
||||
g_value_init_from_instance (ret, proxy);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* wp_object_manager_find_proxy:
|
||||
* @self: the object manager
|
||||
* @bound_id: the bound id of the proxy to get
|
||||
*
|
||||
* Searches the managed objects to find a #WpProxy that has the given @bound_id
|
||||
*
|
||||
* Returns: (transfer full) (nullable): the proxy that has the given @bound_id,
|
||||
* or %NULL if there is no such proxy managed by this object manager
|
||||
*/
|
||||
WpProxy *
|
||||
wp_object_manager_find_proxy (WpObjectManager *self, guint bound_id)
|
||||
{
|
||||
g_autoptr (WpIterator) it = wp_object_manager_iterate (self);
|
||||
g_auto (GValue) ret = G_VALUE_INIT;
|
||||
|
||||
if (!wp_iterator_fold (it, find_proxy_fold_func, &ret,
|
||||
GUINT_TO_POINTER (bound_id)))
|
||||
return g_value_dup_object (&ret);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
#include <glib-object.h>
|
||||
#include "proxy.h"
|
||||
#include "iterator.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
|
@ -51,8 +52,10 @@ WP_API
|
|||
guint wp_object_manager_get_n_objects (WpObjectManager * self);
|
||||
|
||||
WP_API
|
||||
GPtrArray * wp_object_manager_get_objects (WpObjectManager *self,
|
||||
GType type_filter);
|
||||
WpIterator * wp_object_manager_iterate (WpObjectManager * self);
|
||||
|
||||
WP_API
|
||||
WpProxy * wp_object_manager_find_proxy (WpObjectManager *self, guint bound_id);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
|
|
|||
|
|
@ -150,12 +150,15 @@ wp_policy_manager_get_instance (WpCore *core)
|
|||
WpSession *
|
||||
wp_policy_manager_get_session (WpPolicyManager *self)
|
||||
{
|
||||
g_autoptr (GPtrArray) arr = NULL;
|
||||
g_autoptr (WpIterator) it = NULL;
|
||||
g_auto (GValue) val = G_VALUE_INIT;
|
||||
|
||||
g_return_val_if_fail (WP_IS_POLICY_MANAGER (self), NULL);
|
||||
|
||||
arr = wp_object_manager_get_objects (self->sessions_om, 0);
|
||||
return (arr->len > 0) ? g_object_ref (g_ptr_array_index (arr, 0)) : NULL;
|
||||
it = wp_object_manager_iterate (self->sessions_om);
|
||||
if (wp_iterator_next (it, &val))
|
||||
return g_value_dup_object (&val);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
|
|
@ -193,6 +196,17 @@ media_class_matches (const gchar * media_class, const gchar * lookup)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
list_endpoints_fold_func (const GValue *item, GValue *ret, gpointer data)
|
||||
{
|
||||
GPtrArray *ret_arr = g_value_get_boxed (ret);
|
||||
WpBaseEndpoint *ep = g_value_get_object (item);
|
||||
if (media_class_matches (wp_base_endpoint_get_media_class (ep),
|
||||
(const gchar *) data))
|
||||
g_ptr_array_add (ret_arr, g_object_ref (ep));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* wp_policy_manager_list_endpoints:
|
||||
* @self: the policy manager
|
||||
|
|
@ -205,18 +219,20 @@ GPtrArray *
|
|||
wp_policy_manager_list_endpoints (WpPolicyManager * self,
|
||||
const gchar * media_class)
|
||||
{
|
||||
GPtrArray * ret;
|
||||
guint i;
|
||||
g_autoptr (WpIterator) it = NULL;
|
||||
g_auto (GValue) val = G_VALUE_INIT;
|
||||
GPtrArray *ret_arr;
|
||||
|
||||
g_return_val_if_fail (WP_IS_POLICY_MANAGER (self), NULL);
|
||||
|
||||
ret = wp_object_manager_get_objects (self->endpoints_om, 0);
|
||||
for (i = ret->len; i > 0; i--) {
|
||||
WpBaseEndpoint *ep = g_ptr_array_index (ret, i-1);
|
||||
if (!media_class_matches (wp_base_endpoint_get_media_class (ep), media_class))
|
||||
g_ptr_array_remove_index_fast (ret, i-1);
|
||||
}
|
||||
return ret;
|
||||
ret_arr = g_ptr_array_new_with_free_func (g_object_unref);
|
||||
g_value_init (&val, G_TYPE_PTR_ARRAY);
|
||||
g_value_set_boxed (&val, ret_arr);
|
||||
|
||||
it = wp_object_manager_iterate (self->endpoints_om);
|
||||
wp_iterator_fold (it, list_endpoints_fold_func, &val, (gpointer) media_class);
|
||||
|
||||
return ret_arr;
|
||||
}
|
||||
|
||||
/* WpPolicy */
|
||||
|
|
|
|||
|
|
@ -470,50 +470,41 @@ wp_session_get_n_endpoints (WpSession * self)
|
|||
}
|
||||
|
||||
/**
|
||||
* wp_session_get_endpoint:
|
||||
* wp_session_find_endpoint:
|
||||
* @self: the session
|
||||
* @bound_id: the bound id of the endpoint object to get
|
||||
* @bound_id: the bound id of the endpoint object to find
|
||||
*
|
||||
* Returns: (transfer full) (nullable): the endpoint that has the given
|
||||
* @bound_id, or %NULL if there is no such endpoint
|
||||
*/
|
||||
WpEndpoint *
|
||||
wp_session_get_endpoint (WpSession * self, guint32 bound_id)
|
||||
wp_session_find_endpoint (WpSession * self, guint32 bound_id)
|
||||
{
|
||||
g_return_val_if_fail (WP_IS_SESSION (self), NULL);
|
||||
g_return_val_if_fail (wp_proxy_get_features (WP_PROXY (self)) &
|
||||
WP_SESSION_FEATURE_ENDPOINTS, NULL);
|
||||
|
||||
WpSessionPrivate *priv = wp_session_get_instance_private (self);
|
||||
g_autoptr (GPtrArray) endpoints =
|
||||
wp_object_manager_get_objects (priv->endpoints_om, 0);
|
||||
|
||||
for (guint i = 0; i < endpoints->len; i++) {
|
||||
gpointer proxy = g_ptr_array_index (endpoints, i);
|
||||
g_return_val_if_fail (WP_IS_ENDPOINT (proxy), NULL);
|
||||
|
||||
if (wp_proxy_get_bound_id (WP_PROXY (proxy)) == bound_id)
|
||||
return WP_ENDPOINT (g_object_ref (proxy));
|
||||
}
|
||||
return NULL;
|
||||
return (WpEndpoint *)
|
||||
wp_object_manager_find_proxy (priv->endpoints_om, bound_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* wp_session_get_all_endpoints:
|
||||
* wp_session_iterate_endpoints:
|
||||
* @self: the session
|
||||
*
|
||||
* Returns: (transfer full) (element-type WpEndpoint): array with all
|
||||
* Returns: (transfer full): a #WpIterator that iterates over all
|
||||
* the endpoints that belong to this session
|
||||
*/
|
||||
GPtrArray *
|
||||
wp_session_get_all_endpoints (WpSession * self)
|
||||
WpIterator *
|
||||
wp_session_iterate_endpoints (WpSession * self)
|
||||
{
|
||||
g_return_val_if_fail (WP_IS_SESSION (self), NULL);
|
||||
g_return_val_if_fail (wp_proxy_get_features (WP_PROXY (self)) &
|
||||
WP_SESSION_FEATURE_ENDPOINTS, NULL);
|
||||
|
||||
WpSessionPrivate *priv = wp_session_get_instance_private (self);
|
||||
return wp_object_manager_get_objects (priv->endpoints_om, 0);
|
||||
return wp_object_manager_iterate (priv->endpoints_om);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -534,50 +525,41 @@ wp_session_get_n_links (WpSession * self)
|
|||
}
|
||||
|
||||
/**
|
||||
* wp_session_get_link:
|
||||
* wp_session_find_link:
|
||||
* @self: the session
|
||||
* @bound_id: the bound id of the link object to get
|
||||
* @bound_id: the bound id of the link object to find
|
||||
*
|
||||
* Returns: (transfer full) (nullable): the endpoint link that has the given
|
||||
* @bound_id, or %NULL if there is no such endpoint link
|
||||
*/
|
||||
WpEndpointLink *
|
||||
wp_session_get_link (WpSession * self, guint32 bound_id)
|
||||
wp_session_find_link (WpSession * self, guint32 bound_id)
|
||||
{
|
||||
g_return_val_if_fail (WP_IS_SESSION (self), NULL);
|
||||
g_return_val_if_fail (wp_proxy_get_features (WP_PROXY (self)) &
|
||||
WP_SESSION_FEATURE_LINKS, NULL);
|
||||
|
||||
WpSessionPrivate *priv = wp_session_get_instance_private (self);
|
||||
g_autoptr (GPtrArray) links =
|
||||
wp_object_manager_get_objects (priv->links_om, 0);
|
||||
|
||||
for (guint i = 0; i < links->len; i++) {
|
||||
gpointer proxy = g_ptr_array_index (links, i);
|
||||
g_return_val_if_fail (WP_IS_ENDPOINT_LINK (proxy), NULL);
|
||||
|
||||
if (wp_proxy_get_bound_id (WP_PROXY (proxy)) == bound_id)
|
||||
return WP_ENDPOINT_LINK (g_object_ref (proxy));
|
||||
}
|
||||
return NULL;
|
||||
return (WpEndpointLink *)
|
||||
wp_object_manager_find_proxy (priv->links_om, bound_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* wp_session_get_all_links:
|
||||
* wp_session_iterate_links:
|
||||
* @self: the session
|
||||
*
|
||||
* Returns: (transfer full) (element-type WpEndpointLink): array with all
|
||||
* Returns: (transfer full): a #WpIterator that iterates over all
|
||||
* the endpoint links that belong to this session
|
||||
*/
|
||||
GPtrArray *
|
||||
wp_session_get_all_links (WpSession * self)
|
||||
WpIterator *
|
||||
wp_session_iterate_links (WpSession * self)
|
||||
{
|
||||
g_return_val_if_fail (WP_IS_SESSION (self), NULL);
|
||||
g_return_val_if_fail (wp_proxy_get_features (WP_PROXY (self)) &
|
||||
WP_SESSION_FEATURE_LINKS, NULL);
|
||||
|
||||
WpSessionPrivate *priv = wp_session_get_instance_private (self);
|
||||
return wp_object_manager_get_objects (priv->links_om, 0);
|
||||
return wp_object_manager_iterate (priv->links_om);
|
||||
}
|
||||
|
||||
/* WpImplSession */
|
||||
|
|
|
|||
|
|
@ -35,11 +35,11 @@ typedef enum {
|
|||
* wp_session_get_default_endpoint() and wp_session_set_default_endpoint()
|
||||
* to store default endpoint preferences on the session
|
||||
* @WP_SESSION_FEATURE_ENDPOINTS: caches information about endpoints, enabling
|
||||
* the use of wp_session_get_n_endpoints(), wp_session_get_endpoint() and
|
||||
* wp_session_get_all_endpoints()
|
||||
* the use of wp_session_get_n_endpoints(), wp_session_find_endpoint() and
|
||||
* wp_session_iterate_endpoints()
|
||||
* @WP_SESSION_FEATURE_LINKS: caches information about endpoint links, enabling
|
||||
* the use of wp_session_get_n_links(), wp_session_get_link() and
|
||||
* wp_session_get_all_links()
|
||||
* the use of wp_session_get_n_links(), wp_session_find_link() and
|
||||
* wp_session_iterate_links()
|
||||
*
|
||||
* An extension of #WpProxyFeatures
|
||||
*/
|
||||
|
|
@ -92,19 +92,19 @@ WP_API
|
|||
guint wp_session_get_n_endpoints (WpSession * self);
|
||||
|
||||
WP_API
|
||||
WpEndpoint * wp_session_get_endpoint (WpSession * self, guint32 bound_id);
|
||||
WpEndpoint * wp_session_find_endpoint (WpSession * self, guint32 bound_id);
|
||||
|
||||
WP_API
|
||||
GPtrArray * wp_session_get_all_endpoints (WpSession * self);
|
||||
WpIterator * wp_session_iterate_endpoints (WpSession * self);
|
||||
|
||||
WP_API
|
||||
guint wp_session_get_n_links (WpSession * self);
|
||||
|
||||
WP_API
|
||||
WpEndpointLink * wp_session_get_link (WpSession * self, guint32 bound_id);
|
||||
WpEndpointLink * wp_session_find_link (WpSession * self, guint32 bound_id);
|
||||
|
||||
WP_API
|
||||
GPtrArray * wp_session_get_all_links (WpSession * self);
|
||||
WpIterator * wp_session_iterate_links (WpSession * self);
|
||||
|
||||
/**
|
||||
* WP_TYPE_IMPL_SESSION:
|
||||
|
|
|
|||
|
|
@ -46,7 +46,6 @@ struct _WpAudioStreamPrivate
|
|||
|
||||
WpObjectManager *ports_om;
|
||||
WpObjectManager *audio_fade_source_ports_om;
|
||||
GVariantBuilder port_vb;
|
||||
gboolean port_config_done;
|
||||
gboolean port_control_pending;
|
||||
|
||||
|
|
@ -610,10 +609,11 @@ wp_audio_stream_get_info (WpAudioStream * self)
|
|||
return wp_proxy_get_info (WP_PROXY (priv->proxy));
|
||||
}
|
||||
|
||||
static void
|
||||
port_proxies_foreach_func(gpointer data, gpointer user_data)
|
||||
static gboolean
|
||||
port_proxies_fold_func (const GValue *item, GValue *ret, gpointer user_data)
|
||||
{
|
||||
WpProxy *port = WP_PROXY (data);
|
||||
WpProxy *port = g_value_get_object (item);
|
||||
GVariantBuilder *b = g_value_get_pointer (ret);
|
||||
WpAudioStream *self = WP_AUDIO_STREAM (user_data);
|
||||
WpAudioStreamPrivate *priv = wp_audio_stream_get_instance_private (self);
|
||||
const struct pw_node_info *node_info;
|
||||
|
|
@ -623,16 +623,16 @@ port_proxies_foreach_func(gpointer data, gpointer user_data)
|
|||
uint32_t channel_n = SPA_AUDIO_CHANNEL_UNKNOWN;
|
||||
|
||||
node_info = wp_proxy_get_info (WP_PROXY (priv->proxy));
|
||||
g_return_if_fail (node_info);
|
||||
g_return_val_if_fail (node_info, TRUE);
|
||||
|
||||
port_info = wp_proxy_get_info (port);
|
||||
g_return_if_fail (port_info);
|
||||
g_return_val_if_fail (port_info, TRUE);
|
||||
|
||||
props = wp_proxy_get_properties (port);
|
||||
|
||||
/* skip control ports */
|
||||
if (is_stream_control_port (WP_PORT (port)))
|
||||
return;
|
||||
return TRUE;
|
||||
|
||||
channel = wp_properties_get (props, PW_KEY_AUDIO_CHANNEL);
|
||||
if (channel) {
|
||||
|
|
@ -652,8 +652,9 @@ port_proxies_foreach_func(gpointer data, gpointer user_data)
|
|||
uint32 channel; // enum spa_audio_channel
|
||||
uint8 direction; // enum spa_direction
|
||||
*/
|
||||
g_variant_builder_add (&priv->port_vb, "(uuuy)", node_info->id,
|
||||
g_variant_builder_add (b, "(uuuy)", node_info->id,
|
||||
port_info->id, channel_n, (guint8) port_info->direction);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
|
|
@ -661,14 +662,19 @@ wp_audio_stream_prepare_link (WpAudioStream * self, GVariant ** properties,
|
|||
GError ** error)
|
||||
{
|
||||
WpAudioStreamPrivate *priv = wp_audio_stream_get_instance_private (self);
|
||||
g_autoptr (GPtrArray) port_proxies =
|
||||
wp_object_manager_get_objects (priv->ports_om, 0);
|
||||
GVariantBuilder b;
|
||||
g_auto (GValue) val = G_VALUE_INIT;
|
||||
g_autoptr (WpIterator) it = NULL;
|
||||
|
||||
/* Create a variant array with all the ports */
|
||||
g_variant_builder_init (&priv->port_vb, G_VARIANT_TYPE ("a(uuuy)"));
|
||||
g_ptr_array_foreach (port_proxies, port_proxies_foreach_func, self);
|
||||
*properties = g_variant_builder_end (&priv->port_vb);
|
||||
g_variant_builder_init (&b, G_VARIANT_TYPE ("a(uuuy)"));
|
||||
g_value_init (&val, G_TYPE_POINTER);
|
||||
g_value_set_pointer (&val, &b);
|
||||
|
||||
it = wp_object_manager_iterate (priv->ports_om);
|
||||
wp_iterator_fold (it, port_proxies_fold_func, &val, self);
|
||||
|
||||
*properties = g_variant_builder_end (&b);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@ struct _WpVideoEndpoint
|
|||
/* The task to signal the endpoint is initialized */
|
||||
GTask *init_task;
|
||||
|
||||
GVariantBuilder port_vb;
|
||||
WpObjectManager *ports_om;
|
||||
};
|
||||
|
||||
|
|
@ -65,19 +64,20 @@ wp_video_endpoint_get_global_id (WpBaseEndpoint *ep)
|
|||
return wp_proxy_get_bound_id (WP_PROXY (self->node));
|
||||
}
|
||||
|
||||
static void
|
||||
port_proxies_foreach_func (gpointer data, gpointer user_data)
|
||||
static gboolean
|
||||
port_proxies_fold_func (const GValue *item, GValue *ret, gpointer user_data)
|
||||
{
|
||||
WpProxy *port = WP_PROXY (data);
|
||||
WpProxy *port = g_value_get_object (item);
|
||||
GVariantBuilder *b = g_value_get_pointer (ret);
|
||||
WpVideoEndpoint *self = WP_VIDEO_ENDPOINT (user_data);
|
||||
const struct pw_node_info *node_info;
|
||||
const struct pw_port_info *port_info;
|
||||
|
||||
node_info = wp_proxy_get_info (WP_PROXY (self->node));
|
||||
g_return_if_fail (node_info);
|
||||
g_return_val_if_fail (node_info, TRUE);
|
||||
|
||||
port_info = wp_proxy_get_info (port);
|
||||
g_return_if_fail (port_info);
|
||||
g_return_val_if_fail (port_info, TRUE);
|
||||
|
||||
/* tuple format:
|
||||
uint32 node_id;
|
||||
|
|
@ -85,8 +85,9 @@ port_proxies_foreach_func (gpointer data, gpointer user_data)
|
|||
uint32 channel; // always 0 for video
|
||||
uint8 direction; // enum spa_direction
|
||||
*/
|
||||
g_variant_builder_add (&self->port_vb, "(uuuy)", node_info->id,
|
||||
g_variant_builder_add (b, "(uuuy)", node_info->id,
|
||||
port_info->id, 0, (guint8) port_info->direction);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
|
@ -94,14 +95,19 @@ wp_video_endpoint_prepare_link (WpBaseEndpoint * ep, guint32 stream_id,
|
|||
WpBaseEndpointLink * link, GVariant ** properties, GError ** error)
|
||||
{
|
||||
WpVideoEndpoint *self = WP_VIDEO_ENDPOINT (ep);
|
||||
g_autoptr (GPtrArray) port_proxies = wp_object_manager_get_objects (
|
||||
self->ports_om, 0);
|
||||
GVariantBuilder b;
|
||||
g_auto (GValue) val = G_VALUE_INIT;
|
||||
g_autoptr (WpIterator) it = NULL;
|
||||
|
||||
/* Create a variant array with all the ports */
|
||||
g_variant_builder_init (&self->port_vb, G_VARIANT_TYPE ("a(uuuy)"));
|
||||
g_ptr_array_foreach (port_proxies, port_proxies_foreach_func, self);
|
||||
*properties = g_variant_builder_end (&self->port_vb);
|
||||
g_variant_builder_init (&b, G_VARIANT_TYPE ("a(uuuy)"));
|
||||
g_value_init (&val, G_TYPE_POINTER);
|
||||
g_value_set_pointer (&val, &b);
|
||||
|
||||
it = wp_object_manager_iterate (self->ports_om);
|
||||
wp_iterator_fold (it, port_proxies_fold_func, &val, self);
|
||||
|
||||
*properties = g_variant_builder_end (&b);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -64,34 +64,52 @@ print_client_endpoint (WpEndpoint *ep)
|
|||
static void
|
||||
list_endpoints (WpObjectManager * om, struct WpCliData * d)
|
||||
{
|
||||
g_autoptr (GPtrArray) arr = NULL;
|
||||
g_autoptr (WpIterator) it = NULL;
|
||||
g_autoptr (WpSession) session = NULL;
|
||||
guint i;
|
||||
g_auto (GValue) val = G_VALUE_INIT;
|
||||
|
||||
arr = wp_object_manager_get_objects (om, WP_TYPE_SESSION);
|
||||
if (arr->len > 0)
|
||||
session = WP_SESSION (g_object_ref (g_ptr_array_index (arr, 0)));
|
||||
g_clear_pointer (&arr, g_ptr_array_unref);
|
||||
it = wp_object_manager_iterate (om);
|
||||
for (; wp_iterator_next (it, &val) &&
|
||||
g_type_is_a (G_VALUE_TYPE (&val), WP_TYPE_SESSION);
|
||||
g_value_unset (&val))
|
||||
{
|
||||
session = g_value_dup_object (&val);
|
||||
g_value_unset (&val);
|
||||
break;
|
||||
}
|
||||
|
||||
arr = wp_object_manager_get_objects (om, WP_TYPE_ENDPOINT);
|
||||
wp_iterator_reset (it);
|
||||
|
||||
g_print ("Audio capture devices:\n");
|
||||
for (i = 0; i < arr->len; i++) {
|
||||
WpEndpoint *ep = g_ptr_array_index (arr, i);
|
||||
for (; wp_iterator_next (it, &val) &&
|
||||
g_type_is_a (G_VALUE_TYPE (&val), WP_TYPE_ENDPOINT);
|
||||
g_value_unset (&val))
|
||||
{
|
||||
WpEndpoint *ep = g_value_get_object (&val);
|
||||
if (g_strcmp0 (wp_endpoint_get_media_class (ep), "Audio/Source") == 0)
|
||||
print_dev_endpoint (ep, session, WP_DEFAULT_ENDPOINT_TYPE_AUDIO_SOURCE);
|
||||
}
|
||||
|
||||
wp_iterator_reset (it);
|
||||
|
||||
g_print ("\nAudio playback devices:\n");
|
||||
for (i = 0; i < arr->len; i++) {
|
||||
WpEndpoint *ep = g_ptr_array_index (arr, i);
|
||||
for (; wp_iterator_next (it, &val) &&
|
||||
g_type_is_a (G_VALUE_TYPE (&val), WP_TYPE_ENDPOINT);
|
||||
g_value_unset (&val))
|
||||
{
|
||||
WpEndpoint *ep = g_value_get_object (&val);
|
||||
if (g_strcmp0 (wp_endpoint_get_media_class (ep), "Audio/Sink") == 0)
|
||||
print_dev_endpoint (ep, session, WP_DEFAULT_ENDPOINT_TYPE_AUDIO_SINK);
|
||||
}
|
||||
|
||||
wp_iterator_reset (it);
|
||||
|
||||
g_print ("\nClient streams:\n");
|
||||
for (i = 0; i < arr->len; i++) {
|
||||
WpEndpoint *ep = g_ptr_array_index (arr, i);
|
||||
for (; wp_iterator_next (it, &val) &&
|
||||
g_type_is_a (G_VALUE_TYPE (&val), WP_TYPE_ENDPOINT);
|
||||
g_value_unset (&val))
|
||||
{
|
||||
WpEndpoint *ep = g_value_get_object (&val);
|
||||
if (g_str_has_suffix (wp_endpoint_get_media_class (ep), "/Audio"))
|
||||
print_client_endpoint (ep);
|
||||
}
|
||||
|
|
@ -102,14 +120,20 @@ list_endpoints (WpObjectManager * om, struct WpCliData * d)
|
|||
static void
|
||||
set_default (WpObjectManager * om, struct WpCliData * d)
|
||||
{
|
||||
g_autoptr (GPtrArray) arr = NULL;
|
||||
g_autoptr (WpIterator) it = NULL;
|
||||
g_autoptr (WpSession) session = NULL;
|
||||
guint i;
|
||||
g_auto (GValue) val = G_VALUE_INIT;
|
||||
|
||||
arr = wp_object_manager_get_objects (om, WP_TYPE_SESSION);
|
||||
if (arr->len > 0)
|
||||
session = WP_SESSION (g_object_ref (g_ptr_array_index (arr, 0)));
|
||||
g_clear_pointer (&arr, g_ptr_array_unref);
|
||||
it = wp_object_manager_iterate (om);
|
||||
|
||||
for (; wp_iterator_next (it, &val) &&
|
||||
g_type_is_a (G_VALUE_TYPE (&val), WP_TYPE_SESSION);
|
||||
g_value_unset (&val))
|
||||
{
|
||||
session = g_value_dup_object (&val);
|
||||
g_value_unset (&val);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!session) {
|
||||
g_print ("No Session object - changing the default endpoint is not supported\n");
|
||||
|
|
@ -117,10 +141,13 @@ set_default (WpObjectManager * om, struct WpCliData * d)
|
|||
return;
|
||||
}
|
||||
|
||||
arr = wp_object_manager_get_objects (om, WP_TYPE_ENDPOINT);
|
||||
wp_iterator_reset (it);
|
||||
|
||||
for (i = 0; i < arr->len; i++) {
|
||||
WpEndpoint *ep = g_ptr_array_index (arr, i);
|
||||
for (; wp_iterator_next (it, &val) &&
|
||||
g_type_is_a (G_VALUE_TYPE (&val), WP_TYPE_ENDPOINT);
|
||||
g_value_unset (&val))
|
||||
{
|
||||
WpEndpoint *ep = g_value_get_object (&val);
|
||||
guint32 id = wp_proxy_get_bound_id (WP_PROXY (ep));
|
||||
|
||||
if (id == d->params.set_default.id) {
|
||||
|
|
@ -148,13 +175,13 @@ set_default (WpObjectManager * om, struct WpCliData * d)
|
|||
static void
|
||||
set_volume (WpObjectManager * om, struct WpCliData * d)
|
||||
{
|
||||
g_autoptr (GPtrArray) arr = NULL;
|
||||
guint i;
|
||||
g_autoptr (WpIterator) it = NULL;
|
||||
g_auto (GValue) val = G_VALUE_INIT;
|
||||
|
||||
arr = wp_object_manager_get_objects (om, WP_TYPE_ENDPOINT);
|
||||
it = wp_object_manager_iterate (om);
|
||||
|
||||
for (i = 0; i < arr->len; i++) {
|
||||
WpEndpoint *ep = g_ptr_array_index (arr, i);
|
||||
for (; wp_iterator_next (it, &val); g_value_unset (&val)) {
|
||||
WpEndpoint *ep = g_value_get_object (&val);
|
||||
guint32 id = wp_proxy_get_bound_id (WP_PROXY (ep));
|
||||
|
||||
if (id == d->params.set_volume.id) {
|
||||
|
|
@ -172,17 +199,17 @@ set_volume (WpObjectManager * om, struct WpCliData * d)
|
|||
static void
|
||||
device_node_props (WpObjectManager * om, struct WpCliData * d)
|
||||
{
|
||||
g_autoptr (GPtrArray) arr = NULL;
|
||||
guint i;
|
||||
g_autoptr (WpIterator) it = NULL;
|
||||
g_auto (GValue) val = G_VALUE_INIT;
|
||||
const struct spa_dict * dict;
|
||||
const struct spa_dict_item *item;
|
||||
|
||||
arr = wp_object_manager_get_objects (om, WP_TYPE_NODE);
|
||||
it = wp_object_manager_iterate (om);
|
||||
|
||||
g_print ("Capture device nodes:\n");
|
||||
|
||||
for (i = 0; i < arr->len; i++) {
|
||||
WpProxy *node = g_ptr_array_index (arr, i);
|
||||
for (; wp_iterator_next (it, &val); g_value_unset (&val)) {
|
||||
WpProxy *node = g_value_get_object (&val);
|
||||
g_autoptr (WpProperties) props = wp_proxy_get_properties (node);
|
||||
|
||||
if (g_strcmp0 (wp_properties_get (props, "media.class"), "Audio/Source") != 0)
|
||||
|
|
@ -198,10 +225,11 @@ device_node_props (WpObjectManager * om, struct WpCliData * d)
|
|||
g_print ("\n");
|
||||
}
|
||||
|
||||
wp_iterator_reset (it);
|
||||
g_print ("Playback device nodes:\n");
|
||||
|
||||
for (i = 0; i < arr->len; i++) {
|
||||
WpProxy *node = g_ptr_array_index (arr, i);
|
||||
for (; wp_iterator_next (it, &val); g_value_unset (&val)) {
|
||||
WpProxy *node = g_value_get_object (&val);
|
||||
g_autoptr (WpProperties) props = wp_proxy_get_properties (node);
|
||||
|
||||
if (g_strcmp0 (wp_properties_get (props, "media.class"), "Audio/Sink") != 0)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue